]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into terencehill/ons_spawn_patch
authorMario <mario@smbclan.net>
Sat, 24 Oct 2015 10:14:09 +0000 (20:14 +1000)
committerMario <mario@smbclan.net>
Sat, 24 Oct 2015 10:14:09 +0000 (20:14 +1000)
239 files changed:
.tx/merge-base
common.ast.po
common.be.po
common.bg.po
common.ca.po
common.cs.po
common.de.po
common.de_CH.po
common.el.po
common.en_AU.po
common.eo.po
common.es.po
common.es_MX.po
common.fi.po
common.fr.po
common.hu.po
common.it.po
common.ja_JP.po
common.kk@Cyrl.po
common.kw.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.uz@Latn.po
common.zh_CN.po
common.zh_TW.po
defaultXonotic.cfg
gamemodes.cfg
gfx/menu/luma/icon_mod_MinstaGib.tga [deleted file]
gfx/menu/luma/icon_mod_NewToys.tga [deleted file]
gfx/menu/luma/icon_mod_Overkill.tga [deleted file]
gfx/menu/luma/icon_mod_minstagib.tga [new file with mode: 0644]
gfx/menu/luma/icon_mod_newtoys.tga [new file with mode: 0644]
gfx/menu/luma/icon_mod_overkill.tga [new file with mode: 0644]
gfx/menu/luminos/icon_mod_MinstaGib.tga [deleted file]
gfx/menu/luminos/icon_mod_NewToys.tga [deleted file]
gfx/menu/luminos/icon_mod_Overkill.tga [deleted file]
gfx/menu/luminos/icon_mod_minstagib.tga [new file with mode: 0644]
gfx/menu/luminos/icon_mod_newtoys.tga [new file with mode: 0644]
gfx/menu/luminos/icon_mod_overkill.tga [new file with mode: 0644]
gfx/menu/wickedx/icon_mod_MinstaGib.tga [deleted file]
gfx/menu/wickedx/icon_mod_NewToys.tga [deleted file]
gfx/menu/wickedx/icon_mod_Overkill.tga [deleted file]
gfx/menu/wickedx/icon_mod_minstagib.tga [new file with mode: 0644]
gfx/menu/wickedx/icon_mod_newtoys.tga [new file with mode: 0644]
gfx/menu/wickedx/icon_mod_overkill.tga [new file with mode: 0644]
gfx/menu/xaw/icon_mod_MinstaGib.tga [deleted file]
gfx/menu/xaw/icon_mod_NewToys.tga [deleted file]
gfx/menu/xaw/icon_mod_Overkill.tga [deleted file]
gfx/menu/xaw/icon_mod_minstagib.tga [new file with mode: 0644]
gfx/menu/xaw/icon_mod_newtoys.tga [new file with mode: 0644]
gfx/menu/xaw/icon_mod_overkill.tga [new file with mode: 0644]
languages.txt
qcsrc/client/hook.qc
qcsrc/client/hud.qc
qcsrc/client/main.qc
qcsrc/client/progs.inc
qcsrc/common/gamemodes/gamemode/nexball/nexball.qc
qcsrc/common/gamemodes/gamemode/nexball/nexball.qh
qcsrc/common/mapinfo.qc
qcsrc/common/mapinfo.qh
qcsrc/common/monsters/all.qh
qcsrc/common/monsters/sv_monsters.qc
qcsrc/common/mutators/base.qh
qcsrc/common/mutators/mutator/instagib/instagib.qc
qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc
qcsrc/common/notifications.qc
qcsrc/common/physics.qc
qcsrc/common/triggers/target/music.qc
qcsrc/common/triggers/target/music.qh
qcsrc/common/triggers/trigger/multi.qc
qcsrc/common/turrets/sv_turrets.qc
qcsrc/common/weapons/all.qc
qcsrc/common/weapons/calculations.qc
qcsrc/common/weapons/calculations.qh
qcsrc/common/weapons/weapon/arc.qc
qcsrc/lib/_all.inc
qcsrc/lib/csqcmodel/cl_player.qc
qcsrc/lib/linkedlist.qh [new file with mode: 0644]
qcsrc/lib/net.qh
qcsrc/lib/static.qh
qcsrc/menu/item/listbox.qc
qcsrc/menu/menu.qc
qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc
qcsrc/menu/xonotic/dialog_settings_game.qc
qcsrc/menu/xonotic/dialog_settings_game_model.qc
qcsrc/menu/xonotic/gametypelist.qc
qcsrc/menu/xonotic/serverlist.qc
qcsrc/menu/xonotic/slider.qc
qcsrc/menu/xonotic/textslider.qc
qcsrc/server/autocvars.qh
qcsrc/server/bot/aim.qc
qcsrc/server/bot/bot.qc
qcsrc/server/bot/havocbot/_all.inc
qcsrc/server/bot/havocbot/role_keyhunt.qc [deleted file]
qcsrc/server/bot/havocbot/role_keyhunt.qh [deleted file]
qcsrc/server/bot/havocbot/roles.qc
qcsrc/server/cheats.qc
qcsrc/server/cl_client.qc
qcsrc/server/cl_client.qh
qcsrc/server/cl_player.qc
qcsrc/server/command/cmd.qc
qcsrc/server/command/common.qc
qcsrc/server/command/getreplies.qc
qcsrc/server/command/sv_cmd.qc
qcsrc/server/command/vote.qc
qcsrc/server/ent_cs.qc
qcsrc/server/g_damage.qc
qcsrc/server/g_damage.qh
qcsrc/server/g_hook.qc
qcsrc/server/g_world.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/miscfunctions.qh
qcsrc/server/mutators/all.inc [new file with mode: 0644]
qcsrc/server/mutators/all.qc [new file with mode: 0644]
qcsrc/server/mutators/all.qh [new file with mode: 0644]
qcsrc/server/mutators/events.qh
qcsrc/server/mutators/gamemode.qh
qcsrc/server/mutators/gamemode_assault.qc [deleted file]
qcsrc/server/mutators/gamemode_assault.qh [deleted file]
qcsrc/server/mutators/gamemode_ca.qc [deleted file]
qcsrc/server/mutators/gamemode_ca.qh [deleted file]
qcsrc/server/mutators/gamemode_ctf.qc [deleted file]
qcsrc/server/mutators/gamemode_ctf.qh [deleted file]
qcsrc/server/mutators/gamemode_cts.qc [deleted file]
qcsrc/server/mutators/gamemode_cts.qh [deleted file]
qcsrc/server/mutators/gamemode_deathmatch.qc [deleted file]
qcsrc/server/mutators/gamemode_domination.qc [deleted file]
qcsrc/server/mutators/gamemode_domination.qh [deleted file]
qcsrc/server/mutators/gamemode_freezetag.qc [deleted file]
qcsrc/server/mutators/gamemode_freezetag.qh [deleted file]
qcsrc/server/mutators/gamemode_invasion.qc [deleted file]
qcsrc/server/mutators/gamemode_invasion.qh [deleted file]
qcsrc/server/mutators/gamemode_keepaway.qc [deleted file]
qcsrc/server/mutators/gamemode_keepaway.qh [deleted file]
qcsrc/server/mutators/gamemode_keyhunt.qc [deleted file]
qcsrc/server/mutators/gamemode_keyhunt.qh [deleted file]
qcsrc/server/mutators/gamemode_lms.qc [deleted file]
qcsrc/server/mutators/gamemode_lms.qh [deleted file]
qcsrc/server/mutators/gamemode_onslaught.qc [deleted file]
qcsrc/server/mutators/gamemode_onslaught.qh [deleted file]
qcsrc/server/mutators/gamemode_race.qc [deleted file]
qcsrc/server/mutators/gamemode_race.qh [deleted file]
qcsrc/server/mutators/gamemode_tdm.qc [deleted file]
qcsrc/server/mutators/mutator.qh
qcsrc/server/mutators/mutator/gamemode_assault.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/gamemode_ca.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/gamemode_ctf.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/gamemode_cts.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/gamemode_deathmatch.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/gamemode_domination.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/gamemode_freezetag.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/gamemode_invasion.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/gamemode_keepaway.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/gamemode_keyhunt.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/gamemode_lms.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/gamemode_onslaught.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/gamemode_race.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/gamemode_tdm.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/mutator_bloodloss.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/mutator_breakablehook.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/mutator_buffs.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/mutator_campcheck.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/mutator_dodging.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/mutator_hook.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/mutator_invincibleproj.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/mutator_melee_only.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/mutator_midair.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/mutator_multijump.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/mutator_nades.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/mutator_new_toys.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/mutator_nix.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/mutator_overkill.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/mutator_physical_items.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/mutator_pinata.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/mutator_random_gravity.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/mutator_rocketflying.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/mutator_rocketminsta.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/mutator_spawn_near_teammate.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/mutator_superspec.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/mutator_touchexplode.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/mutator_vampire.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/mutator_vampirehook.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator/sandbox.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator_bloodloss.qc [deleted file]
qcsrc/server/mutators/mutator_breakablehook.qc [deleted file]
qcsrc/server/mutators/mutator_buffs.qc [deleted file]
qcsrc/server/mutators/mutator_buffs.qh [deleted file]
qcsrc/server/mutators/mutator_campcheck.qc [deleted file]
qcsrc/server/mutators/mutator_dodging.qc [deleted file]
qcsrc/server/mutators/mutator_dodging.qh [deleted file]
qcsrc/server/mutators/mutator_hook.qc [deleted file]
qcsrc/server/mutators/mutator_invincibleproj.qc [deleted file]
qcsrc/server/mutators/mutator_melee_only.qc [deleted file]
qcsrc/server/mutators/mutator_midair.qc [deleted file]
qcsrc/server/mutators/mutator_multijump.qc [deleted file]
qcsrc/server/mutators/mutator_nades.qc [deleted file]
qcsrc/server/mutators/mutator_nades.qh [deleted file]
qcsrc/server/mutators/mutator_new_toys.qc [deleted file]
qcsrc/server/mutators/mutator_nix.qc [deleted file]
qcsrc/server/mutators/mutator_overkill.qc [deleted file]
qcsrc/server/mutators/mutator_overkill.qh [deleted file]
qcsrc/server/mutators/mutator_physical_items.qc [deleted file]
qcsrc/server/mutators/mutator_pinata.qc [deleted file]
qcsrc/server/mutators/mutator_random_gravity.qc [deleted file]
qcsrc/server/mutators/mutator_rocketflying.qc [deleted file]
qcsrc/server/mutators/mutator_rocketminsta.qc [deleted file]
qcsrc/server/mutators/mutator_spawn_near_teammate.qc [deleted file]
qcsrc/server/mutators/mutator_superspec.qc [deleted file]
qcsrc/server/mutators/mutator_touchexplode.qc [deleted file]
qcsrc/server/mutators/mutator_vampire.qc [deleted file]
qcsrc/server/mutators/mutator_vampirehook.qc [deleted file]
qcsrc/server/mutators/mutators.qc [deleted file]
qcsrc/server/mutators/mutators.qh [deleted file]
qcsrc/server/mutators/mutators_include.qc [deleted file]
qcsrc/server/mutators/mutators_include.qh [deleted file]
qcsrc/server/mutators/sandbox.qc [deleted file]
qcsrc/server/portals.qc
qcsrc/server/progs.inc
qcsrc/server/race.qc
qcsrc/server/race.qh
qcsrc/server/scores.qc
qcsrc/server/spawnpoints.qc
qcsrc/server/sv_main.qc
qcsrc/server/t_items.qc
qcsrc/server/teamplay.qc
qcsrc/server/teamplay.qh
qcsrc/server/weapons/accuracy.qc
qcsrc/server/weapons/spawning.qc
qcsrc/server/weapons/throwing.qc
qcsrc/server/weapons/weaponsystem.qc
qcsrc/server/weapons/weaponsystem.qh

index db68ce74750b6e9d0ff3ab5b5d7502b8292c6d8f..699ec31da5d12b5258b2fedf33858473aef493bd 100644 (file)
@@ -1 +1 @@
-Tue Oct 13 21:18:19 CEST 2015
+Wed Oct 14 01:54:07 CEST 2015
index fa7fb8804f452dce481de67ef2502274f4ed6027..f9b498dfefe0e276c3282c31bd27f573942c474a 100644 (file)
@@ -12,8 +12,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:02+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: Asturian (http://www.transifex.com/team-xonotic/xonotic/"
 "language/ast/)\n"
@@ -5421,7 +5421,7 @@ msgid "Profile"
 msgstr "Perfil"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5446,185 +5446,127 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
-msgstr "TIMLIM^Por defeutu"
+#, c-format
+msgid "%d minutes"
+msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
-msgstr "TIMLIM^1 minutu"
+msgid "TIMLIM^Default"
+msgstr "TIMLIM^Por defeutu"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr "TIMLIM^2 minutos"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr "TIMLIM^3 minutos"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr "TIMLIM^4 minutos"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr "TIMLIM^5 minutos"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr "TIMLIM^6 minutos"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr "TIMLIM^7 minutos"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr "TIMLIM^8 minutos"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr "TIMLIM^9 minutos"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr "TIMLIM^10 minutos"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr "TIMLIM^15 minutos"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr "TIMLIM^20 minutos"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr "TIMLIM^25 minutos"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr "TIMLIM^30 minutos"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr "TIMLIM^40 minutos"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr "TIMLIM^50 minutos"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
-msgstr "TIMLIM^60 minutos"
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
+msgstr "1 minutu"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr "TIMLIM^Infinitu"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr "Llende d'asesinatos:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr "Equipos:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr "2 equipos"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr "3 equipos"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr "4 equipos"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr "Númberu de bots:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr "Ganarás"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr "Pues ganar"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr "Quiciabes ganes"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr "Avanzáu"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr "Espertu"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr "Profesional"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr "Asesín"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr "Inhumnanu"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr "Endiosáu"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr "Llistáu de mapes"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5632,75 +5574,75 @@ msgstr "Llistáu de mapes"
 msgid "Filter:"
 msgstr "Peñera:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr "Amestar too"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr "Desaniciar too"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr "¡Entamar partida multixugador!"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr "Llende de captura:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr "Vides:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr "Vueltes:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr "Goles:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr ""
 
@@ -6111,14 +6053,10 @@ msgid "Demos"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr "Captures de pantalla"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr ""
 
@@ -6294,8 +6232,8 @@ msgstr "Xéneru"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr "Aplicar nel intre"
 
@@ -6451,26 +6389,14 @@ msgstr ""
 msgid "Video"
 msgstr "Videu"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr "Efeutos"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr "Audiu"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr "Xuegu"
@@ -6479,10 +6405,6 @@ msgstr "Xuegu"
 msgid "Input"
 msgstr "Entrada"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr "Usuariu"
@@ -6491,10 +6413,6 @@ msgstr "Usuariu"
 msgid "Misc"
 msgstr "MIscelaina"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr "Maestru:"
@@ -6673,10 +6591,6 @@ msgstr ""
 msgid "WRN^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr "1 minutu"
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr "5 minutos"
@@ -6932,7 +6846,7 @@ msgid "Decals on models"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr "Distancia"
 
@@ -7072,11 +6986,15 @@ msgstr "Partícules"
 msgid "Spawnpoint effects"
 msgstr "Efeutos del aprucideru"
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr "Calidá:"
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 
@@ -7450,22 +7368,18 @@ msgid "Gibs:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr "GIBS^Dengún"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr "GIBS^Dellos"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr "GIBS^Munchos"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr ""
 
@@ -7519,7 +7433,7 @@ msgid "Field of view:"
 msgstr "Campu visión:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
+msgid "Field of vision in degrees (default: 100)"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
@@ -7761,94 +7675,95 @@ msgstr "Guardar"
 msgid "Cancel"
 msgstr "Encaboxar"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr "Rede"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr "Puertu UDP del veceru:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr "Anchor de banda:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr "56k"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr "ISDN"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr "ADSL lento"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr "ADSL rápido"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr "Banda ancha"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr "Paquetes entrantes/seg:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr "Peticiones del sirvidor/seg:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr "Descargues:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr "Velocidá (kB/s):"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr "Llatencia llocal:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr "Amosar gráficu de rede"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
 msgid "Client-side movement prediction"
 msgstr "Predicción de movimientu del veceru"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
 msgid "Movement error compensation"
 msgstr "Compensación de fallu de movimientu"
@@ -7865,50 +7780,6 @@ msgstr ""
 msgid "Maximum:"
 msgstr "Máximu:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr "MAXFPS^5 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr "MAXFPS^10 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr "MAXFPS^20 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr "MAXFPS^30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr "MAXFPS^40 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr "MAXFPS^50 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr "MAXFPS^60 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr "MAXFPS^70 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr "MAXFPS^100 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr "MAXFPS^125 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr "MAXFPS^200 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr "MAXFPS^Ensin llende"
@@ -7921,54 +7792,10 @@ msgstr "Oxetivu:"
 msgid "TRGT^Disabled"
 msgstr "TRGT^Deshabilitáu"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr "TRGT^30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr "TRGT^40 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr "TRGT^50 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr "TRGT^60 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr "TRGT^100 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr "TRGT^125 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr "TRGT^200 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr "IDLFPS^10 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr "IDLFPS^20 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr "IDLFPS^30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr "IDLFPS^60 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr "IDLFPS^Ensin llende"
@@ -8176,217 +8003,212 @@ msgid "Full screen"
 msgstr "Pantalla completa"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr "Sincronización vertical"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr "Voltiar vista horizontalmente"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr "Anisotrópicu:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr "ANISO^Deshabilitáu"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr "2x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr "4x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr "8x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr "16x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr "Suavizáu de berbesos:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr "AA^Deshabilitáu"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr "Buffer de marcu d'alta calidá"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr "Primer fondura:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr "DF^Deshabilitáu"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr "DF^Mundiu"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr "DF^Too"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr "Oxetos del buffer vertex (VBOs)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr "VBO^Deshabilitáu"
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr "Vértices, dellos triángulos (compatible)"
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr "Vértices, dellos triángulos (compatible)"
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr "Vértices"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr "Vértices y triángulos"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr "Rellumu:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr "Contraste:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr "Gamma:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr "Ameyora contraste:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr "Saturación:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr "Intensidá:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr "Esperar pola GPU pa finar cada marcu"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr "Usar shaders OpenGL 2.0 (GLSL)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr "Usar GLSL pa remanar el control de la color"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr "Color sicodélica (güevu de pascua)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr "Vértices trippy (güevu de pascua)"
 
index 49d9a48be7092a852e50348ca7ffa2f339023e70..f12e0ae27875e53f25a6c86de10e86a12359ae04 100644 (file)
@@ -9,8 +9,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:02+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: Belarusian (http://www.transifex.com/team-xonotic/xonotic/"
 "language/be/)\n"
@@ -5376,7 +5376,7 @@ msgid "Profile"
 msgstr "Профіль"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5401,185 +5401,127 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
-msgstr "TIMLIM^Стандартна"
+#, c-format
+msgid "%d minutes"
+msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
-msgstr "TIMLIM^1 хвіліна"
+msgid "TIMLIM^Default"
+msgstr "TIMLIM^Стандартна"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr "TIMLIM^2 хвіліны"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr "TIMLIM^3 хвіліны"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr "TIMLIM^4 хвіліны"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr "TIMLIM^5 хвілін"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr "TIMLIM^6 хвілін"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr "TIMLIM^7 хвілін"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr "TIMLIM^8 хвілін"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr "TIMLIM^9 хвілін"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr "TIMLIM^10 хвілін"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr "TIMLIM^15 хвілін"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr "TIMLIM^20 хвілін"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr "TIMLIM^25 хвілін"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr "TIMLIM^30 хвілін"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr "TIMLIM^40 хвілін"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr "TIMLIM^50 хвілін"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
-msgstr "TIMLIM^60 хвілін"
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
+msgstr "1 хвіліну"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr "TIMLIM^Бясконца"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr "Абмежаванне забойстваў:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr "Каманды:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr "2 каманды"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr "3 каманды"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr "4 каманды"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr "Колькасць гульцоў:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr "Колькасць ботаў:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr "Майстэрства ботаў:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr "Ботападобны"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr "Пачатковец"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr "Лёгка перамагчы"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr "Можна перамагчы"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr "Цяжка перамагчы"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr "Адмысловы"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr "Майстар"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr "Профі"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr "Забойца"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr "Звышчалавек"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr "Богападобны"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr "Мутатары..."
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr "Спіс мапаў"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5587,75 +5529,75 @@ msgstr "Спіс мапаў"
 msgid "Filter:"
 msgstr "Фільтр:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr "Дадаць паказаныя"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr "Выдаліць паказаныя"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr "Дадаць усе"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr "Выдаліць усе"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr "Пачаць сеткавую гульню!"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr "Абмежаванне захопаў:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr "Абмежаванне балаў:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr "Жыцці:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr "Колы:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr "Мэты:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr ""
 
@@ -6066,14 +6008,10 @@ msgid "Demos"
 msgstr "Дэмкі"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr "Здымкі экрана"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr "Музычны плэер"
 
@@ -6249,8 +6187,8 @@ msgstr "Пол"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr "Ужыць зараз"
 
@@ -6406,26 +6344,14 @@ msgstr ""
 msgid "Video"
 msgstr "Відарыс"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr "Эфекты"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr "Гук"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr "Гульня"
@@ -6434,10 +6360,6 @@ msgstr "Гульня"
 msgid "Input"
 msgstr "Увод"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr "Карыстальнік"
@@ -6446,10 +6368,6 @@ msgstr "Карыстальнік"
 msgid "Misc"
 msgstr "Іншае"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr "Галоўны:"
@@ -6628,10 +6546,6 @@ msgstr "Нагадванне пра таймаут за:"
 msgid "WRN^Disabled"
 msgstr "WRN^Адключана"
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr "1 хвіліну"
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr "5 хвілін"
@@ -6887,7 +6801,7 @@ msgid "Decals on models"
 msgstr "Дэкалі на аб'ектах"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr "Далечыня:"
 
@@ -7027,11 +6941,15 @@ msgstr "Часціны"
 msgid "Spawnpoint effects"
 msgstr "Эфекты пункта з'яўлення"
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr "Якасць:"
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 
@@ -7405,22 +7323,18 @@ msgid "Gibs:"
 msgstr "Шматкі:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr "GIBS^Не"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr "GIBS^Крыху"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr "GIBS^Багата"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr "GIBS^Дахалеры і трошкі"
 
@@ -7474,7 +7388,7 @@ msgid "Field of view:"
 msgstr "Сектар агляду, гр:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
+msgid "Field of vision in degrees (default: 100)"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
@@ -7716,94 +7630,95 @@ msgstr "Захаваць"
 msgid "Cancel"
 msgstr "Скасаваць"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr "Сетка"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr "UDP-порт кліента:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr "Прапускная здольнасць:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr "56k"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr "ISDN"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr "Марудны ADSL"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr "Хуткі ADSL"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr "Шырокапалоснае"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr "Пакетаў/с:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr "Запыты сервера/с:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr "Сцягванні:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr "Хуткасць (кБ/с):"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr "Лакальная затрымка:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr "Паказваць сеткавы графік"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
 msgid "Client-side movement prediction"
 msgstr "Прадказанне руху на баку кліента"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
 msgid "Movement error compensation"
 msgstr "Кампенсацыя памылак руху"
@@ -7820,50 +7735,6 @@ msgstr "Чашчыня кадраў"
 msgid "Maximum:"
 msgstr "Не больш за:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr "5 кадраў/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr "10 кадраў/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr "20 кадраў/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr "30 кадраў/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr "40 кадраў/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr "50 кадраў/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr "60 кадраў/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr "70 кадраў/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr "100 кадраў/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr "125 кадраў/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr "200 кадраў/с"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr "Неабмежавана"
@@ -7876,54 +7747,10 @@ msgstr "Мэтавая:"
 msgid "TRGT^Disabled"
 msgstr "Адключана"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr "30 кадраў/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr "40 кадраў/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr "50 кадраў/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr "60 кадраў/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr "100 кадраў/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr "125 кадраў/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr "200 кадраў/с"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr "Абмежаванне пры неактыўнасці:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr "10 кадраў/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr "20 кадраў/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr "30 кадраў/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr "60 кадраў/с"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr "Неабмежавана"
@@ -8130,217 +7957,212 @@ msgid "Full screen"
 msgstr "На ўвесь экран"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr "Вертыкальная сінхранізацыя"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr "Перакуліць відарыс па гарызанталі"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr "Анізатрапія:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr "ANISO^Адключана"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr "2x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr "4x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr "8x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr "16x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr "Згладжванне:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr "AA^Адключана"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr "Высакаякасны буфер кадраў"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr "Спачатку глыбіня:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr "DF^Адключана"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr "DF^Наваколле"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr "DF^Усё"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr "Vertex Buffer Objects (VBOs)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr "VBO^Адключана"
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr "Вяршыні, некаторыя трохкутнікі (сумяшчальна)"
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr "Вяршыні, некаторыя трохкутнікі (сумяшчальна)"
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr "Вяршыні"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr "Вяршыні ды трохкутнікі"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr "Яркасць:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr "Кантраст:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr "Гама:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr "Узмацненне кантрасту:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr "Насычанасць:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr "LIT^Навакольнае святло:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr "Велічыня:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr "Чакаць вылічэння на GPU кожнага кадра"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr "Выкарыстоўваць шэйдэры OpenGL 2.0 (GLSL)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr "Выкарыстоўваць GLSL для кіравання колерам"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr "Псіхадэлічная афарбоўка (вялікоднае яйка)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr "Файныя вяршыні (вялікоднае яйка)"
 
index 2cb25cb98ee60015f7cd076732ad16176f925b90..7db249b7c4f661b5f02ac0bdd3139d100ed337f2 100644 (file)
@@ -9,8 +9,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:02+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: Bulgarian (http://www.transifex.com/team-xonotic/xonotic/"
 "language/bg/)\n"
@@ -5451,7 +5451,7 @@ msgid "Profile"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5476,185 +5476,127 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
+#, c-format
+msgid "%d minutes"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
+msgid "TIMLIM^Default"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
-msgstr ""
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
+msgstr "1 минута"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr "Максимум убийства:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr "Отбори:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr "Брой играчи:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr "Брой ботове:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr "Умения на ботовете:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr "Като бот"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr "Начинаещ"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr "Ти ще спечелиш"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr "Ти може да спечелиш"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr "Ти може и да не спечелиш"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr "Напреднал"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr "Експерт"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr "Професионалист"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr "Наемен убиец"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr "Нечовек"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr "Господ"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr "Мутатори..."
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5662,75 +5604,75 @@ msgstr ""
 msgid "Filter:"
 msgstr "Филтър"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr "Започване на мрежова игра!"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr "Максимум хващания:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr "Максимум точки:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr "Животи:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr "Обиколки:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr "Максимум голове:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr ""
 
@@ -6141,14 +6083,10 @@ msgid "Demos"
 msgstr "Демота"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr ""
 
@@ -6324,8 +6262,8 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr "Прилагане веднага"
 
@@ -6481,26 +6419,14 @@ msgstr ""
 msgid "Video"
 msgstr "Видео"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr "Ефекти"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr "Звук"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr ""
@@ -6509,10 +6435,6 @@ msgstr ""
 msgid "Input"
 msgstr "Контроли"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr "Потребител"
@@ -6521,10 +6443,6 @@ msgstr "Потребител"
 msgid "Misc"
 msgstr "Разни"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr "Главен:"
@@ -6703,10 +6621,6 @@ msgstr "Обявяване на времето:"
 msgid "WRN^Disabled"
 msgstr "WRN^Изключено"
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr "1 минута"
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr "5 минути"
@@ -6962,7 +6876,7 @@ msgid "Decals on models"
 msgstr "Петна по моделите"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr "Разстояние:"
 
@@ -7102,11 +7016,15 @@ msgstr ""
 msgid "Spawnpoint effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 
@@ -7480,22 +7398,18 @@ msgid "Gibs:"
 msgstr "Мръвки:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr "GIBS^Няма"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr "GIBS^Малко"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr "GIBS^Повече"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr "GIBS^Много"
 
@@ -7549,7 +7463,7 @@ msgid "Field of view:"
 msgstr "Зрително поле:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
+msgid "Field of vision in degrees (default: 100)"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
@@ -7791,94 +7705,95 @@ msgstr "Запазване"
 msgid "Cancel"
 msgstr "Отказ"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr "Клиентски UDP порт:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr "56k"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr "ISDN"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr "Бавен ADSL"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr "Бърз ADSL"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr "Широколентова"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr "Входящи пакети/с:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr "Изтегляния:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr "Скорост (kB/s):"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr "Местно закъснение:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr "Показване на мрежова графика"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
 msgid "Client-side movement prediction"
 msgstr "Клиентско предвиждане на движението"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
 msgid "Movement error compensation"
 msgstr "Компенсиране на грешките при движение"
@@ -7895,50 +7810,6 @@ msgstr ""
 msgid "Maximum:"
 msgstr "Максимум:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr "MAXFPS^5 к/сек"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr "MAXFPS^10 к/сек"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr "MAXFPS^20 к/сек"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr "MAXFPS^30 к/сек"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr "MAXFPS^40 к/сек"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr "MAXFPS^50 к/сек"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr "MAXFPS^60 к/сек"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr "MAXFPS^70 к/сек"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr "MAXFPS^100 к/сек"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr "MAXFPS^125 к/сек"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr "MAXFPS^200 к/сек"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr "MAXFPS^Без ограничения"
@@ -7951,54 +7822,10 @@ msgstr "Цел:"
 msgid "TRGT^Disabled"
 msgstr "TRGT^Изключено"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr "TRGT^30 к/сек"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr "TRGT^40 к/сек"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr "TRGT^50 к/сек"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr "TRGT^60 к/сек"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr "TRGT^100 к/сек"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr "TRGT^125 к/сек"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr "TRGT^200 к/сек"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr "Лимит за бездействие:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr "IDLFPS^10 к/сек"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr "IDLFPS^20 к/сек"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr "IDLFPS^30 к/сек"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr "IDLFPS^60 к/сек"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr "IDLFPS^Без ограничения"
@@ -8205,217 +8032,212 @@ msgid "Full screen"
 msgstr "На цял екран"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr "Вертикална синхронизация"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr "Хоризонтално обръщане на изгледа"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr "Анизотропия:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr "ANISO^Изключена"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr "2x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr "4x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr "8x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr "16x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr "Заглаждане:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr "Изключено"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr "Висококачествен фрейм-буфер"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr "Първо дълбочината:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr "DF^Изключено"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr "DF^Околна среда"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr "DF^Всичко"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr "Vertex Buffer Обекти (VBO)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr "VBO^Изключено"
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr "Върхове, и малко триъгълници (съвместим режим)"
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr "Върхове, и малко триъгълници (съвместим режим)"
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr "Върхове"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr "Върхове и триъгълници"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr "Яркост:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr "Контраст:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr "Гама:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr "Засилен контраст:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr "Наситеност:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr "LIT^Фоново осветление:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr "Интензитет:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr "Изчакване на GPU да завърши всеки кадър"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr "Използване на OpenGL 2.0 шейдъри (GLSL)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr "Използване на GLSL за управление на цветовете"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr "Психо цветове (великденско яйце)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr "Изкривени форми (великденско яйце)"
 
index 54a6f2bde0102ab2951c9fe8ee8d4e55ad85623b..49eeb3cb970e045e68347daad5c83e5a52f9014f 100644 (file)
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:02+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: Catalan (http://www.transifex.com/team-xonotic/xonotic/"
 "language/ca/)\n"
@@ -5348,7 +5348,7 @@ msgid "Profile"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5373,185 +5373,127 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
+#, c-format
+msgid "%d minutes"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
+msgid "TIMLIM^Default"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5559,75 +5501,75 @@ msgstr ""
 msgid "Filter:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr ""
 
@@ -6038,14 +5980,10 @@ msgid "Demos"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr ""
 
@@ -6221,8 +6159,8 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr ""
 
@@ -6378,26 +6316,14 @@ msgstr ""
 msgid "Video"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr ""
@@ -6406,10 +6332,6 @@ msgstr ""
 msgid "Input"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr ""
@@ -6418,10 +6340,6 @@ msgstr ""
 msgid "Misc"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr ""
@@ -6600,10 +6518,6 @@ msgstr ""
 msgid "WRN^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr ""
@@ -6859,7 +6773,7 @@ msgid "Decals on models"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr ""
 
@@ -6999,11 +6913,15 @@ msgstr ""
 msgid "Spawnpoint effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 
@@ -7377,22 +7295,18 @@ msgid "Gibs:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr ""
 
@@ -7446,7 +7360,7 @@ msgid "Field of view:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
+msgid "Field of vision in degrees (default: 100)"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
@@ -7688,92 +7602,93 @@ msgstr ""
 msgid "Cancel"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
-msgid "Client-side movement prediction"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
+msgid "Client-side movement prediction"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
@@ -7792,50 +7707,6 @@ msgstr ""
 msgid "Maximum:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr ""
@@ -7848,54 +7719,10 @@ msgstr ""
 msgid "TRGT^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr ""
@@ -8102,217 +7929,212 @@ msgid "Full screen"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr ""
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr ""
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr ""
 
index d336f7170103cfc407f9eac0393d7943c58d4ff7..8dac079ecc8444ce3355743be23e582a65793a98 100644 (file)
@@ -10,8 +10,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:02+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: Czech (http://www.transifex.com/team-xonotic/xonotic/language/"
 "cs/)\n"
@@ -5352,7 +5352,7 @@ msgid "Profile"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5377,185 +5377,127 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
+#, c-format
+msgid "%d minutes"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
+msgid "TIMLIM^Default"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5563,75 +5505,75 @@ msgstr ""
 msgid "Filter:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr ""
 
@@ -6042,14 +5984,10 @@ msgid "Demos"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr ""
 
@@ -6225,8 +6163,8 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr ""
 
@@ -6382,26 +6320,14 @@ msgstr ""
 msgid "Video"
 msgstr "Video"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr "Efekty"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr "Audio"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr "Hra"
@@ -6410,10 +6336,6 @@ msgstr "Hra"
 msgid "Input"
 msgstr "Ovládání"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr ""
@@ -6422,10 +6344,6 @@ msgstr ""
 msgid "Misc"
 msgstr "Různé"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr "Celková hlasitost:"
@@ -6604,10 +6522,6 @@ msgstr ""
 msgid "WRN^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr ""
@@ -6863,7 +6777,7 @@ msgid "Decals on models"
 msgstr "Stopy na modelech"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr "Vzdálenost:"
 
@@ -7003,11 +6917,15 @@ msgstr "Částice"
 msgid "Spawnpoint effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr "Kvalita:"
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 
@@ -7381,22 +7299,18 @@ msgid "Gibs:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr ""
 
@@ -7450,7 +7364,7 @@ msgid "Field of view:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
+msgid "Field of vision in degrees (default: 100)"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
@@ -7692,92 +7606,93 @@ msgstr ""
 msgid "Cancel"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
-msgid "Client-side movement prediction"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
+msgid "Client-side movement prediction"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
@@ -7796,50 +7711,6 @@ msgstr ""
 msgid "Maximum:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr ""
@@ -7852,54 +7723,10 @@ msgstr ""
 msgid "TRGT^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr ""
@@ -8106,217 +7933,212 @@ msgid "Full screen"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr ""
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr ""
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr ""
 
index f84eec44003af898919e98ea213829520078a806..9bfb508a089f0c05229ad15943a9ff7e36413eca 100644 (file)
@@ -19,8 +19,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:05+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: German (http://www.transifex.com/team-xonotic/xonotic/"
 "language/de/)\n"
@@ -5503,7 +5503,7 @@ msgid "Profile"
 msgstr "Profil"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5530,107 +5530,49 @@ msgstr ""
 "diese Option"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
-msgstr "TIMLIM^Standard"
+#, c-format
+msgid "%d minutes"
+msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
-msgstr "TIMLIM^1 Minute"
+msgid "TIMLIM^Default"
+msgstr "TIMLIM^Standard"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr "TIMLIM^2 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr "TIMLIM^3 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr "TIMLIM^4 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr "TIMLIM^5 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr "TIMLIM^6 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr "TIMLIM^7 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr "TIMLIM^8 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr "TIMLIM^9 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr "TIMLIM^10 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr "TIMLIM^15 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr "TIMLIM^20 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr "TIMLIM^25 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr "TIMLIM^30 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr "TIMLIM^40 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr "TIMLIM^50 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
-msgstr "TIMLIM^60 Minuten"
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
+msgstr "1 Minute"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr "TIMLIM^Unendlich"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr "Punktelimit:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr "Teams:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr "2 Teams"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr "3 Teams"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr "4 Teams"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr "Spielerplätze:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
@@ -5638,79 +5580,79 @@ msgstr ""
 "Wähle die maximale Anzahl der Spieler, welche sich mit deinem Server "
 "gleichzeitig verbinden dürfen. Freie Plätze können mit Bots aufgefüllt werden"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr "Anzahl Bots:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr "Wähle die maximale Anzahl von Bots auf dem Server"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr "Spielstärke:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr "Stelle die Stärke der Bots ein"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr "Bots halt"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr "Anfänger"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr "Gewinnst schon"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr "Kannst gewinnen"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr "Könntest gewinnen"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr "Fortgeschritten"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr "Experte"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr "Profi"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr "Mörder"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr "Übermenschlich"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr "Gottgleich"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr "Mutators..."
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr "Wähle Mutators und Waffen-Arenen"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr "Mapliste"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5718,75 +5660,75 @@ msgstr "Mapliste"
 msgid "Filter:"
 msgstr "Filter:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr "Alle sichtbaren hinzufügen"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr "Alle sichtbaren entfernen"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr "Alle hinzufügen"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr "Alle entfernen"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr "Starten!"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr "Capture-Limit:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr "Punktelimit:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr "Leben:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr "Runden:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr "Tore:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr ""
 "Wähle die Anzahl an Frags die benötigt wird, damit die Map endet oder "
@@ -6222,14 +6164,10 @@ msgid "Demos"
 msgstr "Demos"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr "Schaue dir Demos an"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr "Screenshot"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr "Musikplayer"
 
@@ -6409,8 +6347,8 @@ msgstr "Geschlecht"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr "Sofort anwenden"
 
@@ -6566,26 +6504,14 @@ msgstr "Ändere die Spiel-Einstellungen"
 msgid "Video"
 msgstr "Grafik"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr "Grafik Einstellungen"
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr "Effekte"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr "Ton"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr "Audio Einstellungen"
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr "Spiel"
@@ -6594,10 +6520,6 @@ msgstr "Spiel"
 msgid "Input"
 msgstr "Eingabe"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr "Einstellungen der Eingabe"
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr "Benutzer"
@@ -6606,10 +6528,6 @@ msgstr "Benutzer"
 msgid "Misc"
 msgstr "Sonstiges"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr "Sonstige Einstellungen, wie Sprache, Menü-Skins"
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr "Master:"
@@ -6794,10 +6712,6 @@ msgstr "Zeitwarnung:"
 msgid "WRN^Disabled"
 msgstr "Aus"
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr "1 Minute"
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr "5 Minuten"
@@ -7071,7 +6985,7 @@ msgid "Decals on models"
 msgstr "auch auf Objekten"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr "Distanz:"
 
@@ -7230,11 +7144,15 @@ msgstr "Partikel"
 msgid "Spawnpoint effects"
 msgstr "Startpunkt-Effekte"
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr "Qualität:"
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 "Weiter, als eingestellt, entfernte Partikel werden nicht dargestellt "
@@ -7613,24 +7531,18 @@ msgid "Gibs:"
 msgstr "Fleischteile:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-"Verringere die Anzahl von Fleischteilen oder entferne sie vollständig "
-"(Standard: Viele)"
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr "Aus"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr "Wenige"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr "Einige"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr "Viele"
 
@@ -7684,9 +7596,8 @@ msgid "Field of view:"
 msgstr "Sichtfeld:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
+msgid "Field of vision in degrees (default: 100)"
 msgstr ""
-"Stelle den Wert für das Sichtfeld in Grad (60-130) ein - Standard ist 90"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
 msgid "ZOOM^Zoom factor:"
@@ -7939,100 +7850,101 @@ msgstr "Speichern"
 msgid "Cancel"
 msgstr "Abbrechen"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr "Netzwerk"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr "Client-UDP-Port:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 "Stelle den zu verwendenden UDP Port als Client ein.  Wenn der Port auf 0 "
 "gesetzt ist, wird kein Port erzwungen"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr "Bandbreite:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
-msgstr "Gib deine Netzwerkgeschwindigkeit mit dem Schieberegler an"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr "Modem"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr "ISDN"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr "Langsames ADSL"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr "Schnelles ADSL"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr "Breitband"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr "Eingabe-Pakete/s:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr ""
 "Anzahl der Pakete die pro Sekunde zum Server, mit dem du verbunden bist, "
 "geschickt werden sollen"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr "Server Anfragen/Sekunde:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr "Downloads:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr "Maximale Anzahl der gleichzeitigen HTTP/FTP Downloads"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr "Geschwindigkeit (kB/s):"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr "Stelle die maximale Download Geschwindigkeit ein"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr "Simulierte Latenz:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr "Netgraph anzeigen"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 "Anzeige eines Netzwerkgraphs für gesendete/empfangene Pakete und weitere "
 "Informationen"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
 msgid "Client-side movement prediction"
 msgstr "Client-seitige Bewegungssimulation"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
-msgstr "Aktiviere die Client-seitige Bewegungssimulation"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
 msgid "Movement error compensation"
 msgstr "Fehlerkompensation"
@@ -8049,50 +7961,6 @@ msgstr "Framerate"
 msgid "Maximum:"
 msgstr "Maximum:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr "5 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr "10 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr "20 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr "30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr "40 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr "50 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr "60 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr "70 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr "100 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr "125 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr "200 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr "Unbegrenzt"
@@ -8105,54 +7973,10 @@ msgstr "Ziel:"
 msgid "TRGT^Disabled"
 msgstr "Aus"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr "30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr "40 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr "50 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr "60 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr "100 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr "125 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr "200 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr "wenn inaktiv:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr "10 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr "20 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr "30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr "60 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr "Unbegrenzt"
@@ -8366,14 +8190,10 @@ msgid "Full screen"
 msgstr "Vollbild"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr "Aktiviere den Vollbildmodus (Standard: aktiviert)"
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr "Vertikale Synchronisation"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
@@ -8382,49 +8202,49 @@ msgstr ""
 "die FPS werden auf den Wert der Bildwiederholungsrate deines Monitors "
 "gesetzt (Standard: deaktiviert)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr "3D-Ansicht spiegeln"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr "Linkshänder Modus (Standard: deaktiviert)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr "Anisotropie:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr "Qualität für das Filtern von Anisotropie (Standard: Aus)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr "Aus"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr "2x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr "4x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr "8x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr "16x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr "Kantenglättung:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
@@ -8432,19 +8252,19 @@ msgstr ""
 "Aktiviere Antialiasing um Ecken der 3D-Geometire zu glätten. Kann die "
 "Leistung stark verringern (Standard: Aus)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr "Aus"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr "Genauerer Framebuffer"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr "Tiefe zuerst rendern:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
@@ -8452,30 +8272,33 @@ msgstr ""
 "Verhindere das Überblenden, in dem das Tiefenbild der Szene vor dem Licht "
 "gerendert wird (Standard: nur Map)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr "Aus"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr "nur Map"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr "Immer"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr "Vertex Buffer Objects (VBOs)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr "Aus"
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr "Ecken, einige Dreiecke (kompatibel)"
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
@@ -8484,39 +8307,35 @@ msgstr ""
 "Videospeicher um ein schnelleres Rendern zu ermöglichen (Standard: "
 "Eckpunkte, einige Dreiecke)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr "Ecken, einige Dreiecke (kompatibel)"
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr "Ecken"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr "Ecken und Dreiecke"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr "Helligkeit:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr "Helligkeit von Schwarz (Standard: 0)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr "Kontrast:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr "Helligkeit von Weiß (Standard: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr "Gamma:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
@@ -8524,20 +8343,20 @@ msgstr ""
 "Korrekturwert für die Kontraststärke (Gamma-Wert), Helligkeitseffekt, der "
 "keinen Einfluss auf Weiß und Schwarz hat (Standard: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr "Kontrasterhöhung:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 "Faktor für die Änderung des Kontrasts in dunklen Bildteilen (Standard: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr "Sättigung:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
@@ -8545,11 +8364,11 @@ msgstr ""
 "Sättigungskorrektur (0 = Graustufenbild, 1 = normales Bild, 2 = "
 "übersättigtes Bild), benötigt GLSL Farbkontrolle (Standard: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr "Umgebungslicht:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
@@ -8557,19 +8376,19 @@ msgstr ""
 "Umgebungslicht, ein zu hoch eingestellter Wert lässt die Map matt und flach "
 "erscheinen (Standard: 4)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr "Lichtstärke:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr "Globales Rendern der Lichtstärke (Standard: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr "Bei jedem Frame auf die Grafikkarte warten"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
@@ -8578,15 +8397,15 @@ msgstr ""
 "hat, dies kann bei merkwürdigen Verhalten der Eingabe helfen (Standard: "
 "deaktiviert)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr "OpenGL 2.0 Shaders verwenden (GLSL)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr "GLSL für Farbregelung verwenden"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
@@ -8594,11 +8413,11 @@ msgstr ""
 "Aktiviere die Verwendung von GLSL um die Gamma-Korrektur zu ermöglichen, "
 "kann die Leistung stark verringern (Standard: Aus)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr "Psycho-Farben (Osterei)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr "Alles total verbiegen (Osterei)"
 
index c15a3817b496fabde3722e916744d83d84a24b27..673fff82eeb6c233c65a27d76d83e42311df8bd1 100644 (file)
@@ -19,8 +19,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:05+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: German (http://www.transifex.com/team-xonotic/xonotic/"
 "language/de/)\n"
@@ -5503,7 +5503,7 @@ msgid "Profile"
 msgstr "Profil"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5530,107 +5530,49 @@ msgstr ""
 "diese Option"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
-msgstr "TIMLIM^Standard"
+#, c-format
+msgid "%d minutes"
+msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
-msgstr "TIMLIM^1 Minute"
+msgid "TIMLIM^Default"
+msgstr "TIMLIM^Standard"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr "TIMLIM^2 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr "TIMLIM^3 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr "TIMLIM^4 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr "TIMLIM^5 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr "TIMLIM^6 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr "TIMLIM^7 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr "TIMLIM^8 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr "TIMLIM^9 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr "TIMLIM^10 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr "TIMLIM^15 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr "TIMLIM^20 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr "TIMLIM^25 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr "TIMLIM^30 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr "TIMLIM^40 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr "TIMLIM^50 Minuten"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
-msgstr "TIMLIM^60 Minuten"
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
+msgstr "1 Minute"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr "TIMLIM^Unendlich"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr "Punktelimit:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr "Teams:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr "2 Teams"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr "3 Teams"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr "4 Teams"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr "Spielerplätze:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
@@ -5638,79 +5580,79 @@ msgstr ""
 "Wähle die maximale Anzahl der Spieler, welche sich mit deinem Server "
 "gleichzeitig verbinden dürfen. Freie Plätze können mit Bots aufgefüllt werden"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr "Anzahl Bots:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr "Wähle die maximale Anzahl von Bots auf dem Server"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr "Spielstärke:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr "Stelle die Stärke der Bots ein"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr "Bots halt"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr "Anfänger"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr "Gewinnst schon"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr "Kannst gewinnen"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr "Könntest gewinnen"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr "Fortgeschritten"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr "Experte"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr "Profi"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr "Mörder"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr "Übermenschlich"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr "Gottgleich"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr "Mutators..."
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr "Wähle Mutators und Waffen-Arenen"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr "Mapliste"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5718,75 +5660,75 @@ msgstr "Mapliste"
 msgid "Filter:"
 msgstr "Filter:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr "Alle sichtbaren hinzufügen"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr "Alle sichtbaren entfernen"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr "Alle hinzufügen"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr "Alle entfernen"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr "Starten!"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr "Capture-Limit:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr "Punktelimit:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr "Leben:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr "Runden:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr "Tore:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr ""
 "Wähle die Anzahl an Frags die benötigt wird, damit die Map endet oder "
@@ -6222,14 +6164,10 @@ msgid "Demos"
 msgstr "Demos"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr "Schaue dir Demos an"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr "Screenshot"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr "Musikplayer"
 
@@ -6409,8 +6347,8 @@ msgstr "Geschlecht"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr "Sofort anwenden"
 
@@ -6566,26 +6504,14 @@ msgstr "Ändere die Spiel-Einstellungen"
 msgid "Video"
 msgstr "Grafik"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr "Grafik Einstellungen"
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr "Effekte"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr "Ton"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr "Audio Einstellungen"
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr "Spiel"
@@ -6594,10 +6520,6 @@ msgstr "Spiel"
 msgid "Input"
 msgstr "Eingabe"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr "Einstellungen der Eingabe"
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr "Benutzer"
@@ -6606,10 +6528,6 @@ msgstr "Benutzer"
 msgid "Misc"
 msgstr "Sonstiges"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr "Sonstige Einstellungen, wie Sprache, Menü-Skins"
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr "Master:"
@@ -6794,10 +6712,6 @@ msgstr "Zeitwarnung:"
 msgid "WRN^Disabled"
 msgstr "Aus"
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr "1 Minute"
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr "5 Minuten"
@@ -7071,7 +6985,7 @@ msgid "Decals on models"
 msgstr "auch auf Objekten"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr "Distanz:"
 
@@ -7230,11 +7144,15 @@ msgstr "Partikel"
 msgid "Spawnpoint effects"
 msgstr "Startpunkt-Effekte"
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr "Qualität:"
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 "Weiter, als eingestellt, entfernte Partikel werden nicht dargestellt "
@@ -7613,24 +7531,18 @@ msgid "Gibs:"
 msgstr "Fleischteile:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-"Verringere die Anzahl von Fleischteilen oder entferne sie vollständig "
-"(Standard: Viele)"
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr "Aus"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr "Wenige"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr "Einige"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr "Viele"
 
@@ -7684,9 +7596,8 @@ msgid "Field of view:"
 msgstr "Sichtfeld:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
+msgid "Field of vision in degrees (default: 100)"
 msgstr ""
-"Stelle den Wert für das Sichtfeld in Grad (60-130) ein - Standard ist 90"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
 msgid "ZOOM^Zoom factor:"
@@ -7939,100 +7850,101 @@ msgstr "Speichern"
 msgid "Cancel"
 msgstr "Abbrechen"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr "Netzwerk"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr "Client-UDP-Port:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 "Stelle den zu verwendenden UDP Port als Client ein.  Wenn der Port auf 0 "
 "gesetzt ist, wird kein Port erzwungen"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr "Bandbreite:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
-msgstr "Gib deine Netzwerkgeschwindigkeit mit dem Schieberegler an"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr "Modem"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr "ISDN"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr "Langsames ADSL"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr "Schnelles ADSL"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr "Breitband"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr "Eingabe-Pakete/s:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr ""
 "Anzahl der Pakete die pro Sekunde zum Server, mit dem du verbunden bist, "
 "geschickt werden sollen"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr "Server Anfragen/Sekunde:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr "Downloads:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr "Maximale Anzahl der gleichzeitigen HTTP/FTP Downloads"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr "Geschwindigkeit (kB/s):"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr "Stelle die maximale Download Geschwindigkeit ein"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr "Simulierte Latenz:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr "Netgraph anzeigen"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 "Anzeige eines Netzwerkgraphs für gesendete/empfangene Pakete und weitere "
 "Informationen"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
 msgid "Client-side movement prediction"
 msgstr "Client-seitige Bewegungssimulation"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
-msgstr "Aktiviere die Client-seitige Bewegungssimulation"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
 msgid "Movement error compensation"
 msgstr "Fehlerkompensation"
@@ -8049,50 +7961,6 @@ msgstr "Framerate"
 msgid "Maximum:"
 msgstr "Maximum:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr "5 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr "10 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr "20 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr "30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr "40 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr "50 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr "60 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr "70 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr "100 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr "125 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr "200 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr "Unbegrenzt"
@@ -8105,54 +7973,10 @@ msgstr "Ziel:"
 msgid "TRGT^Disabled"
 msgstr "Aus"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr "30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr "40 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr "50 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr "60 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr "100 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr "125 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr "200 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr "wenn inaktiv:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr "10 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr "20 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr "30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr "60 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr "Unbegrenzt"
@@ -8366,14 +8190,10 @@ msgid "Full screen"
 msgstr "Vollbild"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr "Aktiviere den Vollbildmodus (Standard: aktiviert)"
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr "Vertikale Synchronisation"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
@@ -8382,49 +8202,49 @@ msgstr ""
 "unterdrücken, die FPS werden auf den Wert der Bildwiederholungsrate deines "
 "Monitors gesetzt (Standard: deaktiviert)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr "3D-Ansicht spiegeln"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr "Linkshänder Modus (Standard: deaktiviert)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr "Anisotropie:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr "Qualität für das Filtern von Anisotropie (Standard: Aus)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr "Aus"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr "2x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr "4x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr "8x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr "16x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr "Kantenglättung:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
@@ -8432,19 +8252,19 @@ msgstr ""
 "Aktiviere Antialiasing um Ecken der 3D-Geometire zu glätten. Kann die "
 "Leistung stark verringern (Standard: Aus)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr "Aus"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr "Genauerer Framebuffer"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr "Tiefe zuerst rendern:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
@@ -8452,30 +8272,33 @@ msgstr ""
 "Verhindere das Überblenden, in dem das Tiefenbild der Szene vor dem Licht "
 "gerendert wird (Standard: nur Map)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr "Aus"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr "nur Map"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr "Immer"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr "Vertex Buffer Objects (VBOs)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr "Aus"
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr "Ecken, einige Dreiecke (kompatibel)"
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
@@ -8484,39 +8307,35 @@ msgstr ""
 "Videospeicher um ein schnelleres Rendern zu ermöglichen (Standard: "
 "Eckpunkte, einige Dreiecke)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr "Ecken, einige Dreiecke (kompatibel)"
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr "Ecken"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr "Ecken und Dreiecke"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr "Helligkeit:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr "Helligkeit von Schwarz (Standard: 0)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr "Kontrast:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr "Helligkeit von Weiss (Standard: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr "Gamma:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
@@ -8524,20 +8343,20 @@ msgstr ""
 "Korrekturwert für die Kontraststärke (Gamma-Wert), Helligkeitseffekt, der "
 "keinen Einfluss auf Weiss und Schwarz hat (Standard: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr "Kontrasterhöhung:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 "Faktor für die Änderung des Kontrasts in dunklen Bildteilen (Standard: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr "Sättigung:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
@@ -8545,11 +8364,11 @@ msgstr ""
 "Sättigungskorrektur (0 = Graustufenbild, 1 = normales Bild, 2 = "
 "übersättigtes Bild), benötigt GLSL Farbkontrolle (Standard: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr "Umgebungslicht:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
@@ -8557,19 +8376,19 @@ msgstr ""
 "Umgebungslicht, ein zu hoch eingestellter Wert lässt die Map matt und flach "
 "erscheinen (Standard: 4)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr "Lichtstärke:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr "Globales Rendern der Lichtstärke (Standard: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr "Bei jedem Frame auf die Grafikkarte warten"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
@@ -8578,15 +8397,15 @@ msgstr ""
 "hat, dies kann bei merkwürdigen Verhalten der Eingabe helfen (Standard: "
 "deaktiviert)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr "OpenGL 2.0 Shaders verwenden (GLSL)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr "GLSL für Farbregelung verwenden"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
@@ -8594,11 +8413,11 @@ msgstr ""
 "Aktiviere die Verwendung von GLSL um die Gamma-Korrektur zu ermöglichen, "
 "kann die Leistung stark verringern (Standard: Aus)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr "Psycho-Farben (Osterei)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr "Alles total verbiegen (Osterei)"
 
index 25c7d9f385878a5a6a5ca626043c0106d8111402..7317becfc879644e28272725cd082a32247fbc66 100644 (file)
@@ -11,8 +11,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:02+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: Greek (http://www.transifex.com/team-xonotic/xonotic/language/"
 "el/)\n"
@@ -5359,7 +5359,7 @@ msgid "Profile"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5384,185 +5384,127 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
+#, c-format
+msgid "%d minutes"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
+msgid "TIMLIM^Default"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
-msgstr ""
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
+msgstr "1 λεπτό"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr "Ομάδες:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr "Θέσεις παικτών:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr "Αριθμός ρομπότ:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr "Ικανότητα bot:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr "Χαζό ρομπότ"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr "Αρχάριο"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr "Θα νικήσεις"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr "Μπορείς να νικήσεις"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr "Θα μπορούσες να νικήσεις"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr "Προχωρημένο"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr "Ειδικό"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr "Εππαγγελματικό"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr "Δολοφονικό"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr "Απάνθρωπο"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr "Θεικό"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5570,75 +5512,75 @@ msgstr ""
 msgid "Filter:"
 msgstr "Φίλτρο:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr "Εναρξή παιχνιδιού πολλαπλών παικτών!"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr "Όριο καταλύψεων:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr "Όριο βαθμολογίας:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr "Ζωές"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr "Γύροι:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr "Στόχοι:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr ""
 
@@ -6049,14 +5991,10 @@ msgid "Demos"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr ""
 
@@ -6232,8 +6170,8 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr "Άμεση εφαρμογή"
 
@@ -6389,26 +6327,14 @@ msgstr ""
 msgid "Video"
 msgstr "Βίντεο"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr "Εφέ"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr "Ήχος"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr ""
@@ -6417,10 +6343,6 @@ msgstr ""
 msgid "Input"
 msgstr "Εισαγωγή"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr "Χρήστης"
@@ -6429,10 +6351,6 @@ msgstr "Χρήστης"
 msgid "Misc"
 msgstr "Λοιπά"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr "Κύρια ένταση ήχου:"
@@ -6611,10 +6529,6 @@ msgstr "Προειδοποίηση χρόνου:"
 msgid "WRN^Disabled"
 msgstr "WRN^Απενεργοποιημένο"
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr "1 λεπτό"
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr "5 λεπτά"
@@ -6870,7 +6784,7 @@ msgid "Decals on models"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr "Απόσταση:"
 
@@ -7010,11 +6924,15 @@ msgstr ""
 msgid "Spawnpoint effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 
@@ -7388,22 +7306,18 @@ msgid "Gibs:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr ""
 
@@ -7457,7 +7371,7 @@ msgid "Field of view:"
 msgstr "Οπτικό πεδίο:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
+msgid "Field of vision in degrees (default: 100)"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
@@ -7699,92 +7613,93 @@ msgstr "Αποθήκευση"
 msgid "Cancel"
 msgstr "Ακύρωση"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr "56k"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr "ISDN"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr "Αργό ADSL"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr "Γρήγορο ADSL"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr "Ευρής ζώνης"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr "Λήψεις:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr "Ταχύτητα (kB/s):"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
-msgid "Client-side movement prediction"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
+msgid "Client-side movement prediction"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
@@ -7803,50 +7718,6 @@ msgstr ""
 msgid "Maximum:"
 msgstr "Μέγιστο:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr "MAXFPS^5 καρέ ανά δευτερόλεπτο"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr "MAXFPS^10 καρέ ανά δευτερόλεπτο"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr "MAXFPS^20 καρέ ανά δευτερόλεπτο"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr "MAXFPS^30 καρέ ανά δευτερόλεπτο"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr "MAXFPS^40 καρέ ανά δευτερόλεπτο"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr "MAXFPS^50 καρέ ανά δευτερόλεπτο"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr "MAXFPS^60 καρέ ανά δευτερόλεπτο"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr "MAXFPS^70 καρέ ανά δευτερόλεπτο"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr "MAXFPS^100 καρέ ανά δευτερόλεπτο"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr "MAXFPS^125 καρέ ανά δευτερόλεπτο"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr "MAXFPS^200 καρέ ανά δευτερόλεπτο"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr "MAXFPS^Απεριόριστος"
@@ -7859,54 +7730,10 @@ msgstr "Στόχος:"
 msgid "TRGT^Disabled"
 msgstr "AA^Απενεργοποιημένη"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr "TRGT^30 καρέ ανά δευτερόλεπτο"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr "TRGT^40 καρέ ανά δευτερόλεπτο"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr "TRGT^50 καρέ ανά δευτερόλεπτο"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr "TRGT^60 καρέ ανά δευτερόλεπτο"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr "TRGT^100 καρέ ανά δευτερόλεπτο"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr "TRGT^125 καρέ ανά δευτερόλεπτο"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr "TRGT^200 καρέ ανά δευτερόλεπτο"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr "Χρονικό όριο:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr "IDLFPS^10 καρέ ανά δευτερόλεπτο"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr "IDLFPS^20 καρέ ανά δευτερόλεπτο"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr "IDLFPS^30 καρέ ανά δευτερόλεπτο"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr "IDLFPS^60 καρέ ανά δευτερόλεπτο"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr "IDLFPS^Απεριόριστα"
@@ -8113,217 +7940,212 @@ msgid "Full screen"
 msgstr "Πλήρης οθόνη"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr "Κάθετος Συγχρονισμός"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr "Ανισοτροπία:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr "ANISO^Απενεργοποίηση"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr "2x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr "4x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr "8x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr "16x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr "Εξομάλυνση:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr "AA^Απενεργοποιημένη"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr "Ανενεργό"
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr ""
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr "Κορυφές"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr "Κορυφές και Τρίγωνα"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr "Φωτεινότητα:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr "Αντίθεση:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr "Γάμα:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr "Κορεσμός:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr "Ένταση:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr "Χρήση σκιών (shaders) OpenGL 2.0 (GLSL)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr ""
 
index 8e091de8dd59d96661ba5497a299060df80c8be6..57d3ff877d5e1515e2db1ac1ab389b92da9e7154 100644 (file)
@@ -10,8 +10,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:02+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: English (Australia) (http://www.transifex.com/team-xonotic/"
 "xonotic/language/en_AU/)\n"
@@ -5443,7 +5443,7 @@ msgid "Profile"
 msgstr "Profile"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5468,185 +5468,127 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
-msgstr "TIMLIM^Default"
+#, c-format
+msgid "%d minutes"
+msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
-msgstr "TIMLIM^1 minute"
+msgid "TIMLIM^Default"
+msgstr "TIMLIM^Default"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr "TIMLIM^2 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr "TIMLIM^3 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr "TIMLIM^4 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr "TIMLIM^5 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr "TIMLIM^6 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr "TIMLIM^7 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr "TIMLIM^8 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr "TIMLIM^9 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr "TIMLIM^10 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr "TIMLIM^15 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr "TIMLIM^20 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr "TIMLIM^25 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr "TIMLIM^30 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr "TIMLIM^40 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr "TIMLIM^50 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
-msgstr "TIMLIM^60 minutes"
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
+msgstr "1 minute"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr "TIMLIM^Infinite"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr "Frag limit:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr "Teams:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr "2 teams"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr "3 teams"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr "4 teams"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr "Player slots:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr "Number of bots:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr "Bot skill:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr "Botlike"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr "Beginner"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr "You will win"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr "You can win"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr "You might win"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr "Advanced"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr "Expert"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr "Pro"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr "Assassin"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr "Unhuman"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr "Godlike"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr "Maplist"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5654,75 +5596,75 @@ msgstr "Maplist"
 msgid "Filter:"
 msgstr "Filter:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr "Start Multiplayer!"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr "Capture limit:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr "Point limit:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr "Lives:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr "Laps:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr "Goals:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr ""
 
@@ -6133,14 +6075,10 @@ msgid "Demos"
 msgstr "Demos"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr "Screenshots"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr ""
 
@@ -6316,8 +6254,8 @@ msgstr "Gender"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr "Apply immediately"
 
@@ -6473,26 +6411,14 @@ msgstr ""
 msgid "Video"
 msgstr "Video"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr "Effects"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr "Audio"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr "Game"
@@ -6501,10 +6427,6 @@ msgstr "Game"
 msgid "Input"
 msgstr "Input"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr "User"
@@ -6513,10 +6435,6 @@ msgstr "User"
 msgid "Misc"
 msgstr "Misc"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr "Master:"
@@ -6695,10 +6613,6 @@ msgstr "Time announcer:"
 msgid "WRN^Disabled"
 msgstr "WRN^Disabled"
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr "1 minute"
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr "5 minutes"
@@ -6954,7 +6868,7 @@ msgid "Decals on models"
 msgstr "Decals on models"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr "Distance:"
 
@@ -7094,11 +7008,15 @@ msgstr "Particles"
 msgid "Spawnpoint effects"
 msgstr "Spawnpoint effects"
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr "Quality:"
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 
@@ -7472,22 +7390,18 @@ msgid "Gibs:"
 msgstr "Gibs:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr "GIBS^None"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr "GIBS^Few"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr "GIBS^Many"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr "GIBS^Lots"
 
@@ -7541,7 +7455,7 @@ msgid "Field of view:"
 msgstr "Field of view:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
+msgid "Field of vision in degrees (default: 100)"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
@@ -7783,94 +7697,95 @@ msgstr "Save"
 msgid "Cancel"
 msgstr "Cancel"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr "Network"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr "Client UDP port:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr "Bandwidth:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr "56k"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr "ISDN"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr "Slow ADSL"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr "Fast ADSL"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr "Broadband"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr "Input packets/s:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr "Server queries/s:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr "Downloads:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr "Speed (kB/s):"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr "Local latency:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr "Show netgraph"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
 msgid "Client-side movement prediction"
 msgstr "Client-side movement prediction"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
 msgid "Movement error compensation"
 msgstr "Movement error compensation"
@@ -7887,50 +7802,6 @@ msgstr "Framerate"
 msgid "Maximum:"
 msgstr "Maximum:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr "MAXFPS^5 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr "MAXFPS^10 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr "MAXFPS^20 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr "MAXFPS^30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr "MAXFPS^40 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr "MAXFPS^50 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr "MAXFPS^60 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr "MAXFPS^70 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr "MAXFPS^100 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr "MAXFPS^125 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr "MAXFPS^200 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr "MAXFPS^Unlimited"
@@ -7943,54 +7814,10 @@ msgstr "Target:"
 msgid "TRGT^Disabled"
 msgstr "TRGT^Disabled"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr "TRGT^30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr "TRGT^40 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr "TRGT^50 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr "TRGT^60 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr "TRGT^100 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr "TRGT^125 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr "TRGT^200 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr "Idle limit:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr "IDLFPS^10 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr "IDLFPS^20 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr "IDLFPS^30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr "IDLFPS^60 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr "IDLFPS^Unlimited"
@@ -8197,217 +8024,212 @@ msgid "Full screen"
 msgstr "Full screen"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr "Vertical Synchronization"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr "Flip view horizontally"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr "Anisotropy:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr "ANISO^Disabled"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr "2x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr "4x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr "8x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr "16x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr "Antialiasing:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr "AA^Disabled"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr "High-quality frame buffer"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr "Depth first:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr "DF^Disabled"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr "DF^World"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr "DF^All"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr "Vertex Buffer Objects (VBOs)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr "VBO^Off"
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr "Vertices, some Tris (compatible)"
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr "Vertices, some Tris (compatible)"
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr "Vertices"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr "Vertices and Triangles"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr "Brightness:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr "Contrast:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr "Gamma:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr "Contrast boost:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr "Saturation:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr "LIT^Ambient:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr "Intensity:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr "Wait for GPU to finish each frame"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr "Use OpenGL 2.0 shaders (GLSL)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr "Use GLSL to handle colour control"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr "Psycho colouring (Easter egg)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr "Trippy vertices (Easter egg)"
 
index 9e62b600833b355ef888a29fcdcd11a32b6a8167..eb8a9d805d2cc393c149c0c9f5155a68fd176765 100644 (file)
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:02+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: Esperanto (http://www.transifex.com/team-xonotic/xonotic/"
 "language/eo/)\n"
@@ -5348,7 +5348,7 @@ msgid "Profile"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5373,185 +5373,127 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
+#, c-format
+msgid "%d minutes"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
+msgid "TIMLIM^Default"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5559,75 +5501,75 @@ msgstr ""
 msgid "Filter:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr ""
 
@@ -6038,14 +5980,10 @@ msgid "Demos"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr ""
 
@@ -6221,8 +6159,8 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr ""
 
@@ -6378,26 +6316,14 @@ msgstr ""
 msgid "Video"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr ""
@@ -6406,10 +6332,6 @@ msgstr ""
 msgid "Input"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr ""
@@ -6418,10 +6340,6 @@ msgstr ""
 msgid "Misc"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr ""
@@ -6600,10 +6518,6 @@ msgstr ""
 msgid "WRN^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr ""
@@ -6859,7 +6773,7 @@ msgid "Decals on models"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr ""
 
@@ -6999,11 +6913,15 @@ msgstr ""
 msgid "Spawnpoint effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 
@@ -7377,22 +7295,18 @@ msgid "Gibs:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr ""
 
@@ -7446,7 +7360,7 @@ msgid "Field of view:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
+msgid "Field of vision in degrees (default: 100)"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
@@ -7688,92 +7602,93 @@ msgstr ""
 msgid "Cancel"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
-msgid "Client-side movement prediction"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
+msgid "Client-side movement prediction"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
@@ -7792,50 +7707,6 @@ msgstr ""
 msgid "Maximum:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr ""
@@ -7848,54 +7719,10 @@ msgstr ""
 msgid "TRGT^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr ""
@@ -8102,217 +7929,212 @@ msgid "Full screen"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr ""
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr ""
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr ""
 
index 3fd07007c4a82e718cfc104a54a2c959ce634ce5..46442dc08cf47ed0610653efc8f8cd1527cf807c 100644 (file)
@@ -18,8 +18,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:05+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: Spanish (http://www.transifex.com/team-xonotic/xonotic/"
 "language/es/)\n"
@@ -5452,7 +5452,7 @@ msgid "Profile"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5477,107 +5477,49 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr "Límite de tiempo en minutos que cuando pase, terminara el combate"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
+#, c-format
+msgid "%d minutes"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
+msgid "TIMLIM^Default"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
-msgstr ""
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
+msgstr "1 minuto"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr "Límite de muertes:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr "Equipos:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr "Espacios para jugadores:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
@@ -5585,79 +5527,79 @@ msgstr ""
 "La máxima cantidad de jugadores o bots que pueden conectarse a tu servidor a "
 "la vez"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr "Número de bots:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr "Cantidad de bots en tu servidor"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr "Habilidad del bot:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr "Especificar que experiencia tendran los bots"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr "Bot"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr "Iniciado"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr "Ganarás"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr "Puedes ganar"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr "Podrías ganar"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr "Avanzado"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr "Experto"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr "Profesional"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr "Asesino"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr "Inhumano"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr "Divino"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr "Mutadores..."
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr "Mutators"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr "Lista de Mapas"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5665,75 +5607,75 @@ msgstr "Lista de Mapas"
 msgid "Filter:"
 msgstr "Filtro:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr "¡Jugar!"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr "Límite de capturas:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr "Límite de puntos:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr "Vidas:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr "Vueltas:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr "Puntos:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr "Cantidad de puntos necesarios antes de que termine el combate"
 
@@ -6152,14 +6094,10 @@ msgid "Demos"
 msgstr "Demos"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr "Navegar y ver demos"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr "Capturas de Pantalla"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr ""
 
@@ -6335,8 +6273,8 @@ msgstr "Sexo"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr "Realizar cambios"
 
@@ -6492,26 +6430,14 @@ msgstr "Cambiar la configuración del juego"
 msgid "Video"
 msgstr "Video"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr "configuración de video"
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr "Efectos"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr "Sonido"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr "configuración de audio"
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr "Juego"
@@ -6520,10 +6446,6 @@ msgstr "Juego"
 msgid "Input"
 msgstr "Entrada"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr "configuración de entrada"
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr "Usuario"
@@ -6532,10 +6454,6 @@ msgstr "Usuario"
 msgid "Misc"
 msgstr "Misc"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr "configuración misc"
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr "Principal:"
@@ -6718,10 +6636,6 @@ msgstr "Anunciador de tiempo:"
 msgid "WRN^Disabled"
 msgstr "Deshabilitado"
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr "1 minuto"
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr "5 minutos"
@@ -6989,7 +6903,7 @@ msgid "Decals on models"
 msgstr "Marcas en los jugadores"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr "Distancia:"
 
@@ -7146,11 +7060,15 @@ msgstr "Partículas "
 msgid "Spawnpoint effects"
 msgstr "Efectos de puntos de reaparición"
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr "Calidad:"
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 "Las partículas que se alejen de esto no se dibujarán (por defecto: 1000)"
@@ -7529,23 +7447,18 @@ msgid "Gibs:"
 msgstr "Gibs:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-"Reduce la cantidad de tripas o lo remueve completamente (por defecto: muchos)"
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr "Ninguno"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr "Pocas"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr "Muchos"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr "Abundante"
 
@@ -7599,8 +7512,8 @@ msgid "Field of view:"
 msgstr "Campo de visión:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
-msgstr "Campo de visión en grados de 60 a 130, 90 es el default"
+msgid "Field of vision in degrees (default: 100)"
+msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
 msgid "ZOOM^Zoom factor:"
@@ -7849,95 +7762,96 @@ msgstr "Guardar"
 msgid "Cancel"
 msgstr "Cancelar"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr "Red"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr "Puerto UDP del Cliente:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 "Forzar al cliente a usar un puerto elegido a menos que se establezca en 0"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr "Ancho de banda:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
-msgstr "Especificar tu velocidad de conección con este separador"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr "56k"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr "ISDN"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr "ADSL lenta"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr "ADSL rápida"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr "Banda ancha"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr "Paquetes de entrada /s"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr "Cuantos paquetes de entrada mandar a un servidor por cada segundo"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr "Descargas:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr "Número máximo de descargas concurrentes de HTTP/FTP"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr "Velocidad (kB/s):"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr "Velocidad de descarga máxima"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr "Retraso local:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr "Mostrar gráfico de red"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr "Activar un gráfico de tamaño de paquetes y otra información"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
 msgid "Client-side movement prediction"
 msgstr "Predicción de movimento de lado del cliente"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
-msgstr "Activar predicción de movimiento del lado del cliente"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
 msgid "Movement error compensation"
 msgstr "Compensacion de errores de movimento"
@@ -7954,50 +7868,6 @@ msgstr ""
 msgid "Maximum:"
 msgstr "Máximo:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr "5 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr "10 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr "30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr "40 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr "50 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr "50 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr "60 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr "70 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr "100 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr "125fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr "200fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr "Ilimitado"
@@ -8010,54 +7880,10 @@ msgstr "Objetivo:"
 msgid "TRGT^Disabled"
 msgstr "Deshabilitado"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr "30fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr "50fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr "Ilimitado"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr "60 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr "100 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr "125 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr "200 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr "Limite de inactividad:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr "10 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr "20 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr "30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr "60 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr "Ilimitado"
@@ -8268,14 +8094,10 @@ msgid "Full screen"
 msgstr "Pantalla entera"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr "Habilitar el modo de pantalla completa (habilitado por defecto)"
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr "Sincronizacion vertical"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
@@ -8283,49 +8105,49 @@ msgstr ""
 "Habilitar sincronización vertical para prevenir rasgaduras en la imagen, "
 "limitara los fps a la tasa de refresco del monitor (desactivado por defecto)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr "Invertir vista horizontalmente"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr "Invertir la imagen horizontalmente (por defecto: desactivado)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr "Filtro Anisotrópico:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr "Calidad de filtrado anisotrópico (por defecto: 1x)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr "Deshabilitado"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr "2x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr "4x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr "8x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr "16x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr "Antialiasing:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
@@ -8333,19 +8155,19 @@ msgstr ""
 "activar antialiasing, el cual suaviza los bordes en geometrias en 3D. Note "
 "que esto puede disminuir bastante el rendimiento (por defecto: desactivado)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr "Deshabilitado"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr "Regulador de alta calidad"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr "Profundidad primero:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
@@ -8354,30 +8176,33 @@ msgstr ""
 "escena antes de que comience la renderización normal (desactivado por "
 "defecto)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr "Desactivado"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr "Mundo"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr "Todos"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr "Vertex Buffer Objects (VBOs)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr "Desactivado"
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr "Vértices, algunos triangulos (compatible)"
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
@@ -8386,39 +8211,35 @@ msgstr ""
 "la memoria de video para acelerar el renderizado (Vertices y Triangulos por "
 "defecto)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr "Vértices, algunos triangulos (compatible)"
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr "Vértices"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr "Vertices y triangulos"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr "Brillo:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr "Brillo en negros (por defecto: 0)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr "Contraste:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr "Brillo en blancos (por defecto: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr "Gamma:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
@@ -8426,19 +8247,19 @@ msgstr ""
 "Valor de corrección de gama inverso, un efecto de brillo que no afecta a "
 "blancos o negros (por defecto: 1.125)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr "Resaltador de contraste"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr "Por cuanto multiplicar el contraste en areas oscuras (por defecto: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr "Saturacion de color:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
@@ -8446,11 +8267,11 @@ msgstr ""
 "Ajuste de saturación (0 = escala de grises, 1 = normal, 2 = sobresaturado), "
 "requiere un control de color (por defecto: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr "Ambiente:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
@@ -8458,19 +8279,19 @@ msgstr ""
 "iluminación del ambiente, si se configura en muy elevado, tiende a hacer luz "
 "en los mapas de imagen aburrida y plana (por defecto: 4)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr "Intensidad:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr "Brillo del renderizador global (por defecto: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr "Esperar a la GPU para terminar cada frame"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
@@ -8479,15 +8300,15 @@ msgstr ""
 "con algunas extrañas entradas o retraso de video en algunas máquinas "
 "(desactivado por defecto)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr "Usar shaders OpenGL2.0 (GLSL)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr "Usar GLSL como manejador de colores"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
@@ -8495,11 +8316,11 @@ msgstr ""
 "Abilita el uso de GLSL para aplicar en la corrección gama, note que esto "
 "podría disminuir mucho el rendimiento (default: disabled)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr "Coloracion psicopata (secreto)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr "Vertices drogados (secreto)"
 
index 05809c006599ad114f3e001a2f5d500b76c5f9ce..867a743c43f44d57ac3e5dfd9a6c4589f966ab5a 100644 (file)
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:02+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: Spanish (Mexico) (http://www.transifex.com/team-xonotic/"
 "xonotic/language/es_MX/)\n"
@@ -5348,7 +5348,7 @@ msgid "Profile"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5373,185 +5373,127 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
+#, c-format
+msgid "%d minutes"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
+msgid "TIMLIM^Default"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5559,75 +5501,75 @@ msgstr ""
 msgid "Filter:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr ""
 
@@ -6038,14 +5980,10 @@ msgid "Demos"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr ""
 
@@ -6221,8 +6159,8 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr ""
 
@@ -6378,26 +6316,14 @@ msgstr ""
 msgid "Video"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr ""
@@ -6406,10 +6332,6 @@ msgstr ""
 msgid "Input"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr ""
@@ -6418,10 +6340,6 @@ msgstr ""
 msgid "Misc"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr ""
@@ -6600,10 +6518,6 @@ msgstr ""
 msgid "WRN^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr ""
@@ -6859,7 +6773,7 @@ msgid "Decals on models"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr ""
 
@@ -6999,11 +6913,15 @@ msgstr ""
 msgid "Spawnpoint effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 
@@ -7377,22 +7295,18 @@ msgid "Gibs:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr ""
 
@@ -7446,7 +7360,7 @@ msgid "Field of view:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
+msgid "Field of vision in degrees (default: 100)"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
@@ -7688,92 +7602,93 @@ msgstr ""
 msgid "Cancel"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
-msgid "Client-side movement prediction"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
+msgid "Client-side movement prediction"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
@@ -7792,50 +7707,6 @@ msgstr ""
 msgid "Maximum:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr ""
@@ -7848,54 +7719,10 @@ msgstr ""
 msgid "TRGT^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr ""
@@ -8102,217 +7929,212 @@ msgid "Full screen"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr ""
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr ""
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr ""
 
index bfd4f7e21eece623017fc13aac4dd11a787b1a99..a7e51e17d91719adb22e748cd426b0f89e50b7e2 100644 (file)
@@ -9,8 +9,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:02+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: Finnish (http://www.transifex.com/team-xonotic/xonotic/"
 "language/fi/)\n"
@@ -5355,7 +5355,7 @@ msgid "Profile"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5380,185 +5380,127 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
+#, c-format
+msgid "%d minutes"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
+msgid "TIMLIM^Default"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
-msgstr ""
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
+msgstr "1 minuutti"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr "Tapporaja:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr "Joukkueet:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr "Pelaajamäärä:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr "Bottien lukumäärä:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr "Bottien taitotaso:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr "Typerä kone"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr "Aloittelija"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr "Helppo voitto"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr "Helpohko"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr "Keskitaso"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr "Kehittynyt"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr "Ekspertti"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr "Mestari"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr "Murhaaja"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr "Epäinhimillinen"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr "Jumalainen"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr "Muokkaukset..."
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5566,75 +5508,75 @@ msgstr ""
 msgid "Filter:"
 msgstr "Suodatin:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr "Aloita moninpeli!"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr "Lipunryöstöraja"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr "Pisteraja:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr "Elämät:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr "Kierrokset:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr "Maalit:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr ""
 
@@ -6045,14 +5987,10 @@ msgid "Demos"
 msgstr "Demot"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr ""
 
@@ -6228,8 +6166,8 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr "Ota heti käyttöön"
 
@@ -6385,26 +6323,14 @@ msgstr ""
 msgid "Video"
 msgstr "Video"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr "Effektit"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr "Ääni"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr ""
@@ -6413,10 +6339,6 @@ msgstr ""
 msgid "Input"
 msgstr "Ohjaus"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr "Käyttäjä"
@@ -6425,10 +6347,6 @@ msgstr "Käyttäjä"
 msgid "Misc"
 msgstr "Sekalainen"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr "Pääkanava:"
@@ -6607,10 +6525,6 @@ msgstr "Aikavaroitus:"
 msgid "WRN^Disabled"
 msgstr "WRN^Pois päältä"
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr "1 minuutti"
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr "5 minuuttia"
@@ -6866,7 +6780,7 @@ msgid "Decals on models"
 msgstr "Hahmojen siirtokuvat"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr "Etäisyys:"
 
@@ -7006,11 +6920,15 @@ msgstr ""
 msgid "Spawnpoint effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 
@@ -7385,22 +7303,18 @@ msgid "Gibs:"
 msgstr "Raajat:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr "GIBS^Ei mitään"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr "GIBS^Vähän"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr "GIBS^Paljon"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr "GIBS^Runsaasti"
 
@@ -7454,7 +7368,7 @@ msgid "Field of view:"
 msgstr "Näkökenttä:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
+msgid "Field of vision in degrees (default: 100)"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
@@ -7696,94 +7610,95 @@ msgstr "Tallenna"
 msgid "Cancel"
 msgstr "Peruuta"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr "Asiakkaan UDP portti"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr "56k"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr "ISDN"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr "Hidas ASL"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr "Nopea ADSL"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr "Laajakaista"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr "Vastaanottopaketit /s:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr "Lataukset:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr "Nopeus (kb/s)"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr "Paikallinen viive"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr "Näytä verkkograafi"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
 msgid "Client-side movement prediction"
 msgstr "Asiakasohjelman liikkeen ennustus"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
 msgid "Movement error compensation"
 msgstr "Liikkeen virhekompensaatio"
@@ -7800,50 +7715,6 @@ msgstr ""
 msgid "Maximum:"
 msgstr "Maksimi:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr "MAXFPS^5 fps "
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr "MAXFPS^10 fps "
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr "MAXFPS^20 fps "
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr "MAXFPS^30 fps "
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr "MAXFPS^40 fps "
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr "MAXFPS^50 fps "
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr "MAXFPS^60 fps "
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr "MAXFPS^70 fps "
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr "MAXFPS^100 fps "
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr "MAXFPS^125 fps "
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr "MAXFPS^200 fps "
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr "MAXFPS^Rajaton "
@@ -7856,54 +7727,10 @@ msgstr "Kohde:"
 msgid "TRGT^Disabled"
 msgstr "TRGT^Pois päältä"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr "TRGT^30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr "TRGT^40 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr "TRGT^50 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr "TRGT^60 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr "TRGT^100 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr "TRGT^125 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr "TRGT^200 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr "Aikaraja"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr "IDLFPS^10 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr "IDLFPS^20 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr "IDLFPS^30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr "IDLFPS^60 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr "IDLFPS^Rajaton"
@@ -8110,217 +7937,212 @@ msgid "Full screen"
 msgstr "Kokoruutu"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr "Pystytahdistus (VSYNC)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr "Käännä näkymä horisontaalisesti"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr "Anisotropia:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr "ANISO^Pois päältä"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr "2x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr "4x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr "8x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr "16x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr "Reunojenpehmennys (Antialiasing):"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr "AA^Pois päältä"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr "Korkeanlaatuinen kehyspuskuri"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr "Syvyyssuuntainen renderöinti:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr "DF^Pois"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr "DF^Maailma"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr "DF^Kaikki"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr "Vertex Buffer Object (VBO)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr "VBO^Pois"
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr "Verteksit, vähän kolmioita (yhteensopivin)"
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr "Verteksit, vähän kolmioita (yhteensopivin)"
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr "Verteksit"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr "Verteksit ja kolmiot"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr "Kirkkaus:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr "Kontrasti:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr "Gamma:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr "Kontrastin lisäys:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr "Kylläisyys:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr "LIT^Ympäristö:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr "Intensiivisyys:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr "Anna näytönohjaimen viimeistellä jokainen ruutu"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr "Käytä OpenGL 2.0 shaders-varjostuksia (GLSL)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr "Käytä GLSL:ää värien hallinnassa"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr "Psyko-väritys (easter egg)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr "Oudot kärjet (easter egg)"
 
index 8d4ea8c822902dfee0a6ebeecff65e0a221d9abe..b51220fa5242a903a3f85ddef61dafe8b1fd1594 100644 (file)
@@ -15,8 +15,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:06+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: French (http://www.transifex.com/team-xonotic/xonotic/"
 "language/fr/)\n"
@@ -5567,7 +5567,7 @@ msgid "Profile"
 msgstr "Profil"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5592,186 +5592,128 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr "Limite de temps, le match se termine lorsque celle-ci est atteinte"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
-msgstr "Par défaut"
+#, c-format
+msgid "%d minutes"
+msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
-msgstr "1 minute"
+msgid "TIMLIM^Default"
+msgstr "Par défaut"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr "2 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr "3 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr "4 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr "5 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr "6 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr "7 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr "8 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr "9 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr "10 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr "15 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr "20 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr "25 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr "30 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr "40 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr "50 minutes"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
-msgstr "60 minutes"
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
+msgstr "1 minute"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr "illimité"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr "Limite de frags :"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr "Équipes :"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr "2 équipes"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr "3 équipes"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr "4 équipes"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr "Nombre de joueurs :"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
 msgstr ""
 "Le nombre maximum de personnes pouvant jouer sur votre serveur en même temps"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr "Nombre de bots :"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr "Nombre d'adversaires contrôlés par ordinateur"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr "Niveau des bots :"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr "Spécifier la difficulté des adversaires ordinateur"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr "Mauvais"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr "Débutant"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr "Vous allez gagner"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr "Vous pouvez gagner"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr "Vous risquez de gagner"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr "Avancé"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr "Expert"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr "Pro"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr "Assassin"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr "Inhumain"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr "Comme un Dieu"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr "Mutateurs…"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr "Mutators et arènes avec une seule arme"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr "Liste des cartes"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5779,75 +5721,75 @@ msgstr "Liste des cartes"
 msgid "Filter:"
 msgstr "Filtre :"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr "Ajouter les filtrés"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr "Supprimer les filtrés"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr "Tout ajouter"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr "Tout supprimer"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr "Démarrer !"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr "Limite de captures :"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr "Score limite :"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr "Vies :"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr "Nombre de tours :"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr "Nombre de buts :"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr ""
 "Limite de frags pour le match, le match se termine lorsque celle-ci est "
@@ -6272,14 +6214,10 @@ msgid "Demos"
 msgstr "Démos"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr "Parcourir et regarder vos démos"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr "Captures d'écran"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr "Lecteur de musique"
 
@@ -6455,8 +6393,8 @@ msgstr "Genre"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr "Appliquer maintenant"
 
@@ -6612,26 +6550,14 @@ msgstr "Changer les paramètres du jeu"
 msgid "Video"
 msgstr "Vidéo"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr "Paramètres vidéo"
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr "Effets"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr "Audio"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr "Paramètres audio"
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr "Jeu"
@@ -6640,10 +6566,6 @@ msgstr "Jeu"
 msgid "Input"
 msgstr "Contrôles"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr "Paramètres contrôle souris/clavier"
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr "Utilisateur"
@@ -6652,10 +6574,6 @@ msgstr "Utilisateur"
 msgid "Misc"
 msgstr "Autres"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr "Autres paramètres"
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr "Général :"
@@ -6836,10 +6754,6 @@ msgstr "Annonce du temps restant :"
 msgid "WRN^Disabled"
 msgstr "Désactivé"
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr "1 minute"
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr "5 minutes"
@@ -7109,7 +7023,7 @@ msgid "Decals on models"
 msgstr "Impacts sur les modèles"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr "Distance :"
 
@@ -7276,11 +7190,15 @@ msgstr "Particules"
 msgid "Spawnpoint effects"
 msgstr "Effets de point d'apparition"
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr "Qualité :"
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 "Toutes les particules situées au-delà de cette distance ne seront pas "
@@ -7661,23 +7579,18 @@ msgid "Gibs:"
 msgstr "Effets sanglants :"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-"Réduire les effets gores ou les désactiver totalement (par défaut : beaucoup)"
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr "Aucun"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr "Légers"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr "Normaux"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr "Gores"
 
@@ -7731,10 +7644,8 @@ msgid "Field of view:"
 msgstr "Champ de vue :"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
+msgid "Field of vision in degrees (default: 100)"
 msgstr ""
-"Champ de vision en degrés, par défaut 90, certains joueurs préfèrent entre "
-"110 et 130"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
 msgid "ZOOM^Zoom factor:"
@@ -7984,97 +7895,96 @@ msgstr "Enregistrer"
 msgid "Cancel"
 msgstr "Annuler"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr "Réseau"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr "Port UDP client :"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr "Forcer le client à passer par le port choisi sauf s'il est défini à 0"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr "Bande passante :"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
-msgstr "Spécifier la vitesse de votre réseau avec ce curseur"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr "56k"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr "ISDN"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr "ADSL lent"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr "ADSL rapide"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr "Très haut débit"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr "Paquets entrants/s :"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr "Nombre maximum de paquets à envoyer au serveur chaque seconde"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr "Requêtes serveur/s :"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr "Téléchargements :"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr "Nombre maximum de téléchargements simultanés en HTTP/FTP"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr "Vitesse (ko/s) :"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr "Vitesse maximale de téléchargement"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr "Latence locale :"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr "Afficher le netgraphe"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 "Afficher la taille des paquets et d'autres informations dans un graphique"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
 msgid "Client-side movement prediction"
 msgstr "Prédiction des mouvements joueur"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
-msgstr ""
-"Activer la prédiction des mouvements du joueur pour éviter les saccades lors "
-"de parties en réseau"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
 msgid "Movement error compensation"
 msgstr "Compensation des erreurs de mouvement"
@@ -8091,50 +8001,6 @@ msgstr "Taux de rafraîchissement"
 msgid "Maximum:"
 msgstr "Maximum :"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr "5 ips"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr "10 ips"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr "20 ips"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr "30 ips"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr "40 ips"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr "50 ips"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr "60 ips"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr "70 ips"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr "100 ips"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr "125 ips"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr "200 ips"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr "Illimité"
@@ -8147,54 +8013,10 @@ msgstr "Cible :"
 msgid "TRGT^Disabled"
 msgstr "Désactivé"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr "30 ips"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr "40 ips"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr "50 ips"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr "60 ips"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr "100 ips"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr "125 ips"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr "200 ips"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr "Cible quand inactif :"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr "10 ips"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr "20 ips"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr "30 ips"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr "60 ips"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr "Illimité"
@@ -8414,14 +8236,10 @@ msgid "Full screen"
 msgstr "Plein écran"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr "Activer le mode plein écran (par défaut : activé)"
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr "Synchronisation Verticale"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
@@ -8429,49 +8247,49 @@ msgstr ""
 "Activer la syncronisation verticale pour éviter des problèmes d'affichage, "
 "limite le nombre maximum d'images par seconde (par défaut : désactivé)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr "Retourner la vue horizontalement"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr "Mode miroir (par défaut : désactivé)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr "Anisotropie :"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr "Qualité du filtrage anistrope (par défaut : 1x)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr "Désactivée"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr "2×"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr "4×"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr "8×"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr "16×"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr "Anticrénelage :"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
@@ -8479,19 +8297,19 @@ msgstr ""
 "Activer l'anticrénelage, réduit l'effet d'escalier sur les modèles 3D, mais "
 "augmente fortement l'utilisation des ressources (par défaut : désactivé)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr "Désactivé"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr "Anticrénelage de haute qualité"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr "Profondeur d'abord :"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
@@ -8500,30 +8318,33 @@ msgstr ""
 "profondeur de la carte/joueurs avant le rendu \"standard\" (par défaut : "
 "désactivé)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr "Désactivé"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr "Carte"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr "Tout"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr "Objets en Tampon Mémoire (VBOs)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr "Off"
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr "Points, quelques Triangles (compatible)"
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
@@ -8531,39 +8352,35 @@ msgstr ""
 "Utiliser les VBOs pour stocker les modèles 3D statiques dans la mémoire pour "
 "une meilleure performance (par défaut : Points et Triangles)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr "Points, quelques Triangles (compatible)"
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr "Points"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr "Points et Triangles"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr "Luminosité :"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr "Luminosité du noir (par défaut : 0)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr "Contraste :"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr "Luminosité du blanc (par défaut : 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr "Gamma :"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
@@ -8571,19 +8388,19 @@ msgstr ""
 "Correction du gamma n'affectant pas la luminosité du noir ou du blanc (par "
 "défaut : 1.125)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr "Boost du contraste :"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr "Multiplier le constraste dans les salles sombres (par défaut : 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr "Saturation :"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
@@ -8591,11 +8408,11 @@ msgstr ""
 "Ajustement de la saturation (0 = noir et blanc, 1 = normal, 2 = saturé) des "
 "couleurs (par défaut : 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr "Ambiance :"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
@@ -8603,19 +8420,19 @@ msgstr ""
 "Lumière ambiante, si elle est trop élévée, les cartes auront un éclairage "
 "plus \"plat\" et moins contrasté (par défaut : 4)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr "Intensité :"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr "Éclairage du rendu global (par défaut : 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr "Attendre le GPU pour finir chaque trame"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
@@ -8623,15 +8440,15 @@ msgstr ""
 "Demander au processeur d'attendre la fin du rendu graphique afin éviter des "
 "problèmes d'affichage divers (par défaut : désactivé)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr "Utiliser les shaders OpenGL 2.0 (GLSL)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr "Utiliser GLSL pour gérer les couleurs"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
@@ -8639,11 +8456,11 @@ msgstr ""
 "Utiliser GLSL pour corriger le gamma, attention, cela risque d'augementer "
 "fortement l'utilisation de ressources (par défaut : désactivé)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr "Couleurs psychédéliques (bonus)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr "Points délirants (bonus)"
 
index 155f3ddf9848fdf2f1e0965f558c89a1c89cb60e..cc10f8d7a4fa854e280acccaabe63930e77a311c 100644 (file)
@@ -10,8 +10,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:06+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: Hungarian (http://www.transifex.com/team-xonotic/xonotic/"
 "language/hu/)\n"
@@ -5393,7 +5393,7 @@ msgid "Profile"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5418,107 +5418,49 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr "Időhatár percekben mérve, aminek elérése után vége a meccsnek"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
+#, c-format
+msgid "%d minutes"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
+msgid "TIMLIM^Default"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
-msgstr ""
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
+msgstr "1 perc"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr "Gyilok határérték:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr "Csapatok:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr "Maximális játékosszám"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
@@ -5526,79 +5468,79 @@ msgstr ""
 "A játékosok és botok maximális összlétszáma, ahányan egyszerre a szerverre "
 "csatlakozhatnak"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr "Botok száma:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr "Botok száma a szervereden"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr "Botok szintje"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr "A botok ügyességi szintjének meghatározása"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr "Béna"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr "Kezdő"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr "Te fogsz nyerni"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr "Nyerhetsz"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr "Talán győzhetsz"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr "Rutinos"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr "Tapasztalt"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr "Hivatásos"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr "Gyilkológép"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr "Embertelen"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr "MAGA AZ ISTEN"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr "Módosítók..."
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr "Módosítók és fegyverarénák"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5606,75 +5548,75 @@ msgstr ""
 msgid "Filter:"
 msgstr "Szűrés:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr "Minden pálya kiválasztása"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr "Egyik pálya sincs kiválasztva"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr "Többjátékos indítása!"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr "Zászlórablások száma:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr "Ponthatár:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr "Életek:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr "Körök:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr "Célok:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr "Gyilokok száma, amit a meccs vége előtt el kell érni"
 
@@ -6096,14 +6038,10 @@ msgid "Demos"
 msgstr "Demók"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr "Demók böngészése és megtekintése"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr ""
 
@@ -6281,8 +6219,8 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr "Azonnali alkalmazás"
 
@@ -6440,29 +6378,14 @@ msgstr ""
 msgid "Video"
 msgstr "Videó"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr ""
-"Videó beállítások: képernyő felbontás, színmélység, fényerő, kontraszt, stb."
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr "Effektek"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr "Hang"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr ""
-"Hang beállítások: sávok és csatornák hangerejének beállítása, figyelmeztető "
-"hangok, gúnyolódások stb."
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr ""
@@ -6471,10 +6394,6 @@ msgstr ""
 msgid "Input"
 msgstr "Bemenet"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr "Billentyűzetkiosztás, egér és botkormány beállítások"
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr "Felhasználó"
@@ -6483,10 +6402,6 @@ msgstr "Felhasználó"
 msgid "Misc"
 msgstr "Egyéb"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr "Játékosmodell, célkereszt, HUD, és egyéb játékosorientált beállítások"
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr "Általános:"
@@ -6669,10 +6584,6 @@ msgstr "Időre figyelmeztetés:"
 msgid "WRN^Disabled"
 msgstr "AA^Letiltva"
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr "1 perc"
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr "5 perc"
@@ -6956,7 +6867,7 @@ msgid "Decals on models"
 msgstr "Foltok a modelleken"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr "Megjelenítés távolsága:"
 
@@ -7128,11 +7039,15 @@ msgstr ""
 msgid "Spawnpoint effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 "A különböző effektek (robbanások, becsapódások) által létrehozott effekt-"
@@ -7516,24 +7431,18 @@ msgid "Gibs:"
 msgstr "Húscafatok:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-"A csúszkával a felrobbantott ellendelek húscafatainak mennyiségének tudod "
-"beállítani (alapértelmezett: sok)"
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr "GIBS^Nincs"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr "GIBS^Kevés"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr "GIBS^Sok"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr "GIBS^Rengeteg"
 
@@ -7587,8 +7496,8 @@ msgid "Field of view:"
 msgstr "Látómező:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
-msgstr "A látószög fokokban mérve 60-tól 130-ig, az alapérték 90 fok"
+msgid "Field of vision in degrees (default: 100)"
+msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
 msgid "ZOOM^Zoom factor:"
@@ -7850,102 +7759,99 @@ msgstr "Mentés"
 msgid "Cancel"
 msgstr "Mégsem"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr "Kliens UDP port:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr "Az adott UDP port használata az alapértelmezett helyett"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
 msgstr ""
-"A csúszkával a hálózati kapcsolatod sebessége és típusát tudod meghatározni"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr "56k"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr "ISDN"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr "Lassú ADSL"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr "Gyors ADSL"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr "Szélessávú"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr "Bemeneti csomagok/s:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr ""
 "A csúszkával a szerver felé küldött adatcsomagok másodpercenkénti számát "
 "tudod beállítani. Magasabb érték finomabb mozgást eredményezhet."
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr "Letöltések:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr "Sebesség (kB/s):"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr "A csúszkával a maximális letöltési sebességet tudod beállítani"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr "Helyi késleltetés:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr "Hálózati forgalom megjelenítése"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 "Csomagméret és egyéb információk grafikonjának kirajzolása játék közben a "
 "képernyő jobb alsó sarkába"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
 msgid "Client-side movement prediction"
 msgstr "Kliensoldali mozgásbecslés"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
-msgstr ""
-"Kliensoldali mozgásbecslés engedélyezése. Ez az opció rossz minőségű, vagy "
-"lassú kapcsolat esetén segíthet a késés (lag) okozta mozgási problémák "
-"javításában"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
 msgid "Movement error compensation"
 msgstr "Mozgási hibák javítása"
@@ -7962,50 +7868,6 @@ msgstr ""
 msgid "Maximum:"
 msgstr "Maximum:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr "MAXFPS^5 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr "MAXFPS^10 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr "MAXFPS^20 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr "MAXFPS^30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr "MAXFPS^40 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr "MAXFPS^50 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr "MAXFPS^60 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr "MAXFPS^70 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr "MAXFPS^100 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr "MAXFPS^125 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr "MAXFPS^200 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr "MAXFPS^Korlátlan"
@@ -8018,54 +7880,10 @@ msgstr "Cél érték:"
 msgid "TRGT^Disabled"
 msgstr "TRGT^Letiltva"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr "TRGT^30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr "TRGT^40 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr "TRGT^50 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr "TRGT^60 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr "TRGT^100 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr "TRGT^125 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr "TRGT^200 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr "Tétlenség esetén:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr "IDLFPS^10 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr "IDLFPS^20 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr "IDLFPS^30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr "IDLFPS^60 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr "IDLFPS^Korlátlan"
@@ -8281,14 +8099,10 @@ msgid "Full screen"
 msgstr "Teljes képernyő"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr "Teljes képernyős mód engedélyezése (alapértelmezett: engedélyezve)"
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr "Szinkronizálás a képernyő frissítéshez"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
@@ -8297,54 +8111,54 @@ msgstr ""
 "megakadályozására. A másodpercenként leképzett képkockák számát (FPS) a "
 "képernyő frissítési frekvenciájához igazítja (alapértelmezett: kikapcsolva)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr "A képernyő vízszintes tükrözése"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr ""
 "A teljes képernyő vízszintes tükrözése, \"szegény ember bal kezes módja\". "
 "(alapértelmezett: ki)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr "Anizotrópia:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr ""
 "Az anizotrópikus szűrés használatával a megjelenített textúrák távolságtól "
 "függetlenül is élesek maradnak, így javul a képminőség. FIGYELEM! Jelentősen "
 "csökkenheti a teljesítményt gyengébb számítógépeken (alapérték: 1x)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr "ANISO^Letiltva"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr "2x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr "4x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr "8x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr "16x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr "Élsimítás:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
@@ -8353,19 +8167,19 @@ msgstr ""
 "\"csipkézettsége\" csökken. FIGYELEM! Jelentősen csökkenheti a teljesítményt "
 "gyengébb számítógépeken (alapértelmezett: letiltva)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr "AA^Letiltva"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr "Jó minőségű Framebuffer engedélyezése"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr "Mélység először:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
@@ -8374,30 +8188,33 @@ msgstr ""
 "közelebbi eseményekkel, tárgyakkal kezdődik. Ez vonatkozhat csak a világ "
 "geometriájára, illetve a modellekre is (alapértelmezett: letiltva)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr "Kikapcsolva"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr "DF^Világ"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr "DF^Minden"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr "Vertex Buffer Objektumok (VBO)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr "VBO^Letiltva"
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr "Csúcspontok, néhány háromszög (kompatibilis)"
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
@@ -8406,43 +8223,39 @@ msgstr ""
 "memóriában ún. Vertex Buffer Objectként kerül tárolásra (alapértelmezett: "
 "Csúcspontok és háromszögek, kompatibilis)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr "Csúcspontok, néhány háromszög (kompatibilis)"
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr "Csúcspontok"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr "Csúcspontok és háromszögek"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr "Fényerő:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr ""
 "A képernyő fényereje, a fekete szín fényességének változtatásával "
 "(alapérték: 0)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr "Kontraszt:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr ""
 "A csúszkával a képernyő kontrasztját tud szabályozni, azaz a fehér szín "
 "fényességét (alapérték: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr "Gamma:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
@@ -8450,20 +8263,20 @@ msgstr ""
 "Fordított gamma korrekciós érték, egy fényességi hatás , ami nem "
 "befolyásolja a fehéret vagy feketét (alapérték: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr "Kontraszt növelés:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 "A csúszkával a sötét területek kontrasztját tudod növelni (alapérték: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr "Színtelítettség:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
@@ -8471,11 +8284,11 @@ msgstr ""
 "Színtelítettség beállítása  (0 = szürke, 1 = normál, 2 = túltelített ), GLSL "
 "színkezelés szükséges (alapérték: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr "Környezet:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
@@ -8483,19 +8296,19 @@ msgstr ""
 "Környezeti világítás, a túl magasra beállítás a kép fakóságát eredményezheti "
 "(alapérték: 4)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr "Erősség:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr "Általános világosság  (alapérték: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr "Várakozás a GPU-ra minden képkockánál"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
@@ -8504,15 +8317,15 @@ msgstr ""
 "segíthet egyes gépeken jelentkező furcsa bemeneti és videó késés problémák "
 "kiküszöbölésében (alapértelmezett: letiltva)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr "OpenGL 2.0 shaderek (GLSL) használata"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr "GLSL használata a színvezérlés kezeléséhez"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
@@ -8520,11 +8333,11 @@ msgstr ""
 "A GLSL alkalmazása a gamma korrekcióhoz, Megjegyzendő, hogy jelentősen "
 "csökkenheti a teljesítményt  (alapértelmezett: letiltva)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr "Pszichedelikus fények (csak a poén kedvéért)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr "Mint aki be van rúgva (csak a poén kedvéért)"
 
index 1814e3216acc7e4b7852c9594d13cdf91a1532b4..8a1b05d7cdf5c9f43a24a4c7e2d243b498a7d03e 100644 (file)
@@ -12,8 +12,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:07+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: Italian (http://www.transifex.com/team-xonotic/xonotic/"
 "language/it/)\n"
@@ -539,11 +539,11 @@ msgstr "Diminuisci velocità"
 
 #: qcsrc/client/quickmenu.qc:838
 msgid "QMCMD^Wall collision off"
-msgstr "Collisione con muri attivo"
+msgstr "Collisione con muri spento"
 
 #: qcsrc/client/quickmenu.qc:839
 msgid "QMCMD^Wall collision on"
-msgstr "Collisione con muri disattivo"
+msgstr "Collisione con muri attivo"
 
 #: qcsrc/client/quickmenu.qc:843
 msgid "QMCMD^Fullscreen"
@@ -5560,7 +5560,7 @@ msgid "Profile"
 msgstr "Profilo"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5585,107 +5585,49 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr "Tempo limite in minuti che appena raggiunto terminerà la partita"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
-msgstr "Predefinito"
+#, c-format
+msgid "%d minutes"
+msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
-msgstr "TIMLIM^1 minuto"
+msgid "TIMLIM^Default"
+msgstr "Predefinito"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr "2 minuti"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr "3 minuti"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr "4 minuti"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr "5 minuti"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr "6 minuti"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr "7 minuti"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr "8 minuti"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr "9 minuti"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr "10 minuti"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr "15 minuti"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr "20 minuti"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr "25 minuti"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr "30 minuti"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr "40 minuti"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr "50 minuti"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
-msgstr "60 minuti"
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
+msgstr "1 minuto"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr "Infinito"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr "Limite di frag:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr "Squadre:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr "2 squadre"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr "3 squadre"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr "4 squadre"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr "Posti per giocatori:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
@@ -5693,79 +5635,79 @@ msgstr ""
 "Il massimo numero di giocatori o bot che possono essere connessi al tuo "
 "server alla volta"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr "Numero di bot:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr "Numero di bot nel tuo server"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr "Abilità bot:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr "Specifica quanto i bot saranno esperti"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr "\"Come un bot\""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr "Principiante"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr "Vincerai"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr "Puoi vincere"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr "Potresti vincere"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr "Avanzato"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr "Esperto"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr "Pro"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr "Assassino"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr "Inumano"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr "\"Come un Dio\""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr "Mutatori..."
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr "Mutatori e arene di armi"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr "Lista mappe"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5773,75 +5715,75 @@ msgstr "Lista mappe"
 msgid "Filter:"
 msgstr "Filtro:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr "Aggiungi mostrate"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr "Rimuovi mostrate"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr "Aggiungi tutte"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr "Rimuovi tutte"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr "Inizia Multiplayer!"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr "Limite catture:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr "Limite di punteggio:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr "Vite:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr "Giri:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr "Goal:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr "Il numero di frag necessari prima che la partita finisca"
 
@@ -6266,14 +6208,10 @@ msgid "Demos"
 msgstr "Demo"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr "Naviga e vedi le demo"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr "Screenshots"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr "Lettore musicale"
 
@@ -6450,8 +6388,8 @@ msgstr "Genere:"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr "Applica immediatamente"
 
@@ -6607,26 +6545,14 @@ msgstr "Cambia le impostazioni del gioco"
 msgid "Video"
 msgstr "Video"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr "Impostazioni video"
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr "Effetti"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr "Audio"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr "Impostazioni audio"
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr "Gioco"
@@ -6635,10 +6561,6 @@ msgstr "Gioco"
 msgid "Input"
 msgstr "Comandi"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr "Impostazioni input"
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr "Utente"
@@ -6647,10 +6569,6 @@ msgstr "Utente"
 msgid "Misc"
 msgstr "Vari"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr "Impostazioni varie"
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr "Master:"
@@ -6831,10 +6749,6 @@ msgstr "Annunciatore tempo:"
 msgid "WRN^Disabled"
 msgstr "Disabilitato"
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr "1 minuto"
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr "5 minuti"
@@ -7105,7 +7019,7 @@ msgid "Decals on models"
 msgstr "Decal sui modelli"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr "Distanza:"
 
@@ -7262,11 +7176,15 @@ msgstr "Particelle"
 msgid "Spawnpoint effects"
 msgstr "Effetti punto di nascita"
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr "Qualità:"
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 "Distanza per cui le particelle non vengono mostrate (predefinito: 1000)"
@@ -7643,23 +7561,18 @@ msgid "Gibs:"
 msgstr "Gib:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-"Riduci il numero di gib o rimuovili completamente (predefinito: parecchi)"
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr "Nessuno"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr "Pochi"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr "Molti"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr "Parecchi"
 
@@ -7706,15 +7619,15 @@ msgstr "Distanza in su"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:76
 msgid "Allow passing through walls while spectating"
-msgstr "Consenti di passare attraverso i muri mentre si osserva"
+msgstr "Consenti attraversamento dei muri mentre si osserva"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:79
 msgid "Field of view:"
 msgstr "Campo visuale:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
-msgstr "Il campo di vista da 60 a 130 gradi, di default è a 90 gradi"
+msgid "Field of vision in degrees (default: 100)"
+msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
 msgid "ZOOM^Zoom factor:"
@@ -7965,96 +7878,97 @@ msgstr "Salva"
 msgid "Cancel"
 msgstr "Annulla"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr "Rete"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr "Porta UDP del client:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 "Forza il client a usare la porta selezionata a meno che non è impostata a 0"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr "Largh. di banda:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
-msgstr "Specifica la velocità della tua rete con questa barra"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr "56k"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr "ISDN"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr "ADSL lenta"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr "ADSL veloce"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr "Banda larga"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr "Pacchetti/s in entrata:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr "Quanti pacchetti in ingresso inviare al server ogni secondo"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr "Ricerche server/s:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr "N° di download:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr "Massimo numero di download HTTP/FTP contemporanei"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr "Velocità (kB/s):"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr "Velocità massima di download"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr "Latenza locale:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr "Mostra grafico di rete"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 "Mostra un grafico delle dimensioni dei pacchetti e di altre informazioni"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
 msgid "Client-side movement prediction"
 msgstr "Predizione del movimento lato client"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
-msgstr "Abilita predizione del movimento lato client"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
 msgid "Movement error compensation"
 msgstr "Compensazione errori movimento"
@@ -8071,50 +7985,6 @@ msgstr "FPS"
 msgid "Maximum:"
 msgstr "Massimo:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr "5 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr "10 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr "20 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr "30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr "40 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr "50 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr "60 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr "70 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr "100 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr "125 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr "200 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr "Illimitato"
@@ -8127,54 +7997,10 @@ msgstr "Obiettivo:"
 msgid "TRGT^Disabled"
 msgstr "Disabilitato"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr "30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr "40 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr "50 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr "60 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr "100 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr "125 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr "200 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr "Limite se inattivo:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr "10 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr "20 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr "30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr "60 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr "Illimitato"
@@ -8387,14 +8213,10 @@ msgid "Full screen"
 msgstr "Schermo intero"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr "Abilita modalità a tutto schermo (predefinito: abilitato)"
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr "Sincronizzazione verticale"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
@@ -8403,49 +8225,49 @@ msgstr ""
 "(tearing), imposta il limite massimo di fps alla velocità di aggiornamento "
 "dello schermo (predefinito: disabilitato)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr "Capovolgi la vista orizzontalmente"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr "Modalità mancino (Predefinito: off)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr "Anisotropia:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr "Qualità del filtro anisotropico (predefinito: 1x)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr "Disabilitata"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr "2x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr "4x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr "8x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr "16x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr "Antialiasing:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
@@ -8453,19 +8275,19 @@ msgstr ""
 "Abilita l'antialiasing, che smussa i bordi dei modelli in 3D. Nota che le "
 "performance potrebbero decrementare di un bel pò (predefinito: disabilitato)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr "Disabilitato"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr "Frame buffer di alta qualità"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr "Profondità prima:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
@@ -8474,30 +8296,33 @@ msgstr ""
 "profondità della scena prima di iniziare il rendering \"standard"
 "\" (predefinito: disabilitato)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr "Disabilitato"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr "Globale"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr "Tutto"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr "Vertex Buffer Objects (VBOs)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr "Non attivo"
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr "Vertici, alcuni Triangoli (compatibile)"
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
@@ -8506,39 +8331,35 @@ msgstr ""
 "geometria statica per un rendering più veloce (predefinito: Vertici e "
 "Triangoli)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr "Vertici, alcuni Triangoli (compatibile)"
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr "Vertici"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr "Vertici e Triangoli"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr "Luminosità:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr "Luminosità del nero (predefinito: 0)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr "Contrasto:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr "Luminosità del bianco (predefinito: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr "Gamma:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
@@ -8546,20 +8367,20 @@ msgstr ""
 "Valore della correzione gamma inversa, un effetto di luminosità che non "
 "tocca il bianco o il nero (predefinito: 1.125)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr "Aumenta contrasto:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 "Di quanto viene moltiplicato il contrasto nelle aree oscure (predefinito: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr "Saturazione:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
@@ -8567,11 +8388,11 @@ msgstr ""
 "Adattamento saturazione (0 = scala di grigi, 1 = normale, 2 = sovra-saturo), "
 "richiede il GLSL color control (predefinito: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr "Ambiente:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
@@ -8579,19 +8400,19 @@ msgstr ""
 "Luminosità dell'ambiente, se è impostato ad un valore troppo alto tende a "
 "rendere la luce delle mappe opaca e piatta (predefinito: 4)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr "Intensità:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr "Luminosità del rendering globale (predefinito: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr "Attendi che la GPU finisca di elaborare ogni frame"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
@@ -8600,15 +8421,15 @@ msgstr ""
 "può aiutare con alcuni strani input o in presenza di video lag in alcune "
 "macchine (predefinito: disabilitato)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr "Usa gli shader OpenGL 2.0 (GLSL)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr "Usa GLSL per gestire il controllo del colore"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
@@ -8616,11 +8437,11 @@ msgstr ""
 "Abilita l'uso delle GLSL per applicare la correzione gamma, nota che le "
 "performance potrebbero decrementare di tanto (predefinito: disabilitato)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr "Colorazione psico (easter egg)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr "Vertici da viaggio (easter egg)"
 
index fed0a744fef856c2e04dc409a1c47d2ba6e3248e..357f643910407fb6a04cc59d65d4a104c05d5c91 100644 (file)
@@ -8,8 +8,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:02+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: Japanese (Japan) (http://www.transifex.com/team-xonotic/"
 "xonotic/language/ja_JP/)\n"
@@ -5349,7 +5349,7 @@ msgid "Profile"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5374,185 +5374,127 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
+#, c-format
+msgid "%d minutes"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
+msgid "TIMLIM^Default"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5560,75 +5502,75 @@ msgstr ""
 msgid "Filter:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr ""
 
@@ -6039,14 +5981,10 @@ msgid "Demos"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr ""
 
@@ -6222,8 +6160,8 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr ""
 
@@ -6379,26 +6317,14 @@ msgstr ""
 msgid "Video"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr ""
@@ -6407,10 +6333,6 @@ msgstr ""
 msgid "Input"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr ""
@@ -6419,10 +6341,6 @@ msgstr ""
 msgid "Misc"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr ""
@@ -6601,10 +6519,6 @@ msgstr ""
 msgid "WRN^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr ""
@@ -6860,7 +6774,7 @@ msgid "Decals on models"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr ""
 
@@ -7000,11 +6914,15 @@ msgstr ""
 msgid "Spawnpoint effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 
@@ -7378,22 +7296,18 @@ msgid "Gibs:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr ""
 
@@ -7447,7 +7361,7 @@ msgid "Field of view:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
+msgid "Field of vision in degrees (default: 100)"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
@@ -7689,92 +7603,93 @@ msgstr ""
 msgid "Cancel"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
-msgid "Client-side movement prediction"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
+msgid "Client-side movement prediction"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
@@ -7793,50 +7708,6 @@ msgstr ""
 msgid "Maximum:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr ""
@@ -7849,54 +7720,10 @@ msgstr ""
 msgid "TRGT^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr ""
@@ -8103,217 +7930,212 @@ msgid "Full screen"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr ""
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr ""
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr ""
 
index 120b4a0b27005728f888374bca399213f61bc96d..99d8651bf5d192ec0b48a29dfa8318ea9b3cd8b8 100644 (file)
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:02+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: Kazakh (Cyrillic) (http://www.transifex.com/team-xonotic/"
 "xonotic/language/kk@Cyrl/)\n"
@@ -5348,7 +5348,7 @@ msgid "Profile"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5373,185 +5373,127 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
+#, c-format
+msgid "%d minutes"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
+msgid "TIMLIM^Default"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5559,75 +5501,75 @@ msgstr ""
 msgid "Filter:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr ""
 
@@ -6038,14 +5980,10 @@ msgid "Demos"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr ""
 
@@ -6221,8 +6159,8 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr ""
 
@@ -6378,26 +6316,14 @@ msgstr ""
 msgid "Video"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr ""
@@ -6406,10 +6332,6 @@ msgstr ""
 msgid "Input"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr ""
@@ -6418,10 +6340,6 @@ msgstr ""
 msgid "Misc"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr ""
@@ -6600,10 +6518,6 @@ msgstr ""
 msgid "WRN^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr ""
@@ -6859,7 +6773,7 @@ msgid "Decals on models"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr ""
 
@@ -6999,11 +6913,15 @@ msgstr ""
 msgid "Spawnpoint effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 
@@ -7377,22 +7295,18 @@ msgid "Gibs:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr ""
 
@@ -7446,7 +7360,7 @@ msgid "Field of view:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
+msgid "Field of vision in degrees (default: 100)"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
@@ -7688,92 +7602,93 @@ msgstr ""
 msgid "Cancel"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
-msgid "Client-side movement prediction"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
+msgid "Client-side movement prediction"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
@@ -7792,50 +7707,6 @@ msgstr ""
 msgid "Maximum:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr ""
@@ -7848,54 +7719,10 @@ msgstr ""
 msgid "TRGT^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr ""
@@ -8102,217 +7929,212 @@ msgid "Full screen"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr ""
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr ""
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr ""
 
index 209918f68ba8b6d241b24d64d2a8d3290b377282..9f971a0a3829559f2c7d6014c9eff0ad3d9500a1 100644 (file)
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:02+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: Cornish (http://www.transifex.com/team-xonotic/xonotic/"
 "language/kw/)\n"
@@ -5349,7 +5349,7 @@ msgid "Profile"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5374,185 +5374,127 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
+#, c-format
+msgid "%d minutes"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
+msgid "TIMLIM^Default"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5560,75 +5502,75 @@ msgstr ""
 msgid "Filter:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr ""
 
@@ -6039,14 +5981,10 @@ msgid "Demos"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr ""
 
@@ -6222,8 +6160,8 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr ""
 
@@ -6379,26 +6317,14 @@ msgstr ""
 msgid "Video"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr ""
@@ -6407,10 +6333,6 @@ msgstr ""
 msgid "Input"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr ""
@@ -6419,10 +6341,6 @@ msgstr ""
 msgid "Misc"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr ""
@@ -6601,10 +6519,6 @@ msgstr ""
 msgid "WRN^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr ""
@@ -6860,7 +6774,7 @@ msgid "Decals on models"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr ""
 
@@ -7000,11 +6914,15 @@ msgstr ""
 msgid "Spawnpoint effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 
@@ -7378,22 +7296,18 @@ msgid "Gibs:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr ""
 
@@ -7447,7 +7361,7 @@ msgid "Field of view:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
+msgid "Field of vision in degrees (default: 100)"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
@@ -7689,92 +7603,93 @@ msgstr ""
 msgid "Cancel"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
-msgid "Client-side movement prediction"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
+msgid "Client-side movement prediction"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
@@ -7793,50 +7708,6 @@ msgstr ""
 msgid "Maximum:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr ""
@@ -7849,54 +7720,10 @@ msgstr ""
 msgid "TRGT^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr ""
@@ -8103,217 +7930,212 @@ msgid "Full screen"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr ""
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr ""
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr ""
 
index 1b4063b1ce4b359adfae27041f2d3eaccc9e67e7..d65342fa2e7a61551dfe49823baddf8d2d094921 100644 (file)
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:02+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: Macedonian (http://www.transifex.com/team-xonotic/xonotic/"
 "language/mk/)\n"
@@ -5348,7 +5348,7 @@ msgid "Profile"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5373,185 +5373,127 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
+#, c-format
+msgid "%d minutes"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
+msgid "TIMLIM^Default"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5559,75 +5501,75 @@ msgstr ""
 msgid "Filter:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr ""
 
@@ -6038,14 +5980,10 @@ msgid "Demos"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr ""
 
@@ -6221,8 +6159,8 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr ""
 
@@ -6378,26 +6316,14 @@ msgstr ""
 msgid "Video"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr ""
@@ -6406,10 +6332,6 @@ msgstr ""
 msgid "Input"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr ""
@@ -6418,10 +6340,6 @@ msgstr ""
 msgid "Misc"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr ""
@@ -6600,10 +6518,6 @@ msgstr ""
 msgid "WRN^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr ""
@@ -6859,7 +6773,7 @@ msgid "Decals on models"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr ""
 
@@ -6999,11 +6913,15 @@ msgstr ""
 msgid "Spawnpoint effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 
@@ -7377,22 +7295,18 @@ msgid "Gibs:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr ""
 
@@ -7446,7 +7360,7 @@ msgid "Field of view:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
+msgid "Field of vision in degrees (default: 100)"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
@@ -7688,92 +7602,93 @@ msgstr ""
 msgid "Cancel"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
-msgid "Client-side movement prediction"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
+msgid "Client-side movement prediction"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
@@ -7792,50 +7707,6 @@ msgstr ""
 msgid "Maximum:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr ""
@@ -7848,54 +7719,10 @@ msgstr ""
 msgid "TRGT^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr ""
@@ -8102,217 +7929,212 @@ msgid "Full screen"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr ""
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr ""
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr ""
 
index edb56ee52da77ba55c91343a5a3f91d09d79c8f3..6c59db4c9e4d4d3f86d21b9e75424bf28dc90cf4 100644 (file)
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:02+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: Dutch (http://www.transifex.com/team-xonotic/xonotic/language/"
 "nl/)\n"
@@ -5389,7 +5389,7 @@ msgid "Profile"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5414,185 +5414,127 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
+#, c-format
+msgid "%d minutes"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
+msgid "TIMLIM^Default"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
-msgstr ""
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
+msgstr "1 minuut"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr "Frag limiet:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr "Teams:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr "Aantal spelers:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr "Aantal bots:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr "Bot vaardigheid:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr "Botlike"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr "Beginner"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr "Je zal winnen"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr "Je kan winnen"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr "Je zou kunnen winnen"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr "Geavanceerd"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr "Expert"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr "Pro"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr "Sluipmoordenaar"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr "Onmenselijk"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr "Goddelijk"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr "Mutaties..."
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5600,75 +5542,75 @@ msgstr ""
 msgid "Filter:"
 msgstr "Filter:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr "Start Multiplayer!"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr "Vlaggen limiet:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr "Punten limiet:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr "Levens:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr "Rondes:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr "Goals:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr ""
 
@@ -6079,14 +6021,10 @@ msgid "Demos"
 msgstr "Demo’s"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr ""
 
@@ -6262,8 +6200,8 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr "Meteen toepassen"
 
@@ -6419,26 +6357,14 @@ msgstr ""
 msgid "Video"
 msgstr "Video"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr "Effecten"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr "Geluid"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr ""
@@ -6447,10 +6373,6 @@ msgstr ""
 msgid "Input"
 msgstr "Input"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr "User"
@@ -6459,10 +6381,6 @@ msgstr "User"
 msgid "Misc"
 msgstr "Misc"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr "Volume:"
@@ -6641,10 +6559,6 @@ msgstr "Tijd notificatie:"
 msgid "WRN^Disabled"
 msgstr "Uitgeschakeld"
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr "1 minuut"
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr "5 minuten"
@@ -6900,7 +6814,7 @@ msgid "Decals on models"
 msgstr "Decals op modellen"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr "Afstand:"
 
@@ -7040,11 +6954,15 @@ msgstr ""
 msgid "Spawnpoint effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 
@@ -7418,22 +7336,18 @@ msgid "Gibs:"
 msgstr "Gibs:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr "GIBS^Geen"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr "GIBS^Weinig"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr "GIBS^Veel"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr "GIBS^Erg veel"
 
@@ -7487,7 +7401,7 @@ msgid "Field of view:"
 msgstr "Kijkhoek (FoV):"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
+msgid "Field of vision in degrees (default: 100)"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
@@ -7729,94 +7643,95 @@ msgstr "Opslaan"
 msgid "Cancel"
 msgstr "Annuleren"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr "Client UDP poort:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr "56k"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr "ISDN"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr "Langzaam ADSL"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr "Snel ADSL"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr "Breedband"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr "Inkomende pakketten/s"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr "Downloads:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr "Snelheid (kB/s):"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr "Lokale latency:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr "Netwerk grafiek tonen"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
 msgid "Client-side movement prediction"
 msgstr "Client beweging voorspelling"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
 msgid "Movement error compensation"
 msgstr "Beweging error compensatie"
@@ -7833,50 +7748,6 @@ msgstr ""
 msgid "Maximum:"
 msgstr "Maximum:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr "5 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr "10 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr "20 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr "30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr "40 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr "MAXFPS^50 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr "MAXFPS^60 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr "MAXFPS^70 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr "MAXFPS^100 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr "MAXFPS^125 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr "MAXFPS^200 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr "MAXFPS^Onbeperkt"
@@ -7889,54 +7760,10 @@ msgstr "Doel:"
 msgid "TRGT^Disabled"
 msgstr "TRGT^Uitgeschakeld"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr "TRGT^30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr "40 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr "50 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr "60 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr "100 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr "125 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr "200 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr "Idle limiet:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr "10 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr "20 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr "30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr "IDLFPS^60 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr "IDLFPS^Onbeperkt"
@@ -8143,217 +7970,212 @@ msgid "Full screen"
 msgstr "Volledig scherm"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr "Verticale synchronisatie"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr "Spiegel zicht horizontaal"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr "Anisotropie"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr "ANISO^Uitgeschakeld"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr "2x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr "4x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr "8x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr "16x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr "Antialiasing:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr "AA^Uitgeschakeld"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr "Hoge kwaliteit frame buffer"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr "Diepte eerst:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr "DF^Uitgeschakeld"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr "DF^Wereld"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr "DF^Alles"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr "Vertex Buffer Objecten (VBOs)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr "VBO^Uit"
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr "Vertices, sommige Tris (compatibel)"
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr "Vertices, sommige Tris (compatibel)"
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr "Vertices"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr "Vertices en Tris"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr "Helderheid:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr "Contrast:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr "Gamma:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr "Verhoog contrast:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr "Verzadiging:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr "LIT^Omgevingslicht"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr "Intensiteit:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr "Wacht op GPU voor elk frame"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr "Gebruik OpenGL 2.0 shaders (GLSL)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr "Gebruik GLSL voor gamma correctie"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr "Psycho kleuren (easter egg)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr "Trippy vertices (easter egg)"
 
index e4d14bfb7586db834de0c1886d06d2fa4bc53ef6..342827d8992a30f5b00b84c853135f447c000a37 100644 (file)
@@ -13,8 +13,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:02+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: Polish (http://www.transifex.com/team-xonotic/xonotic/"
 "language/pl/)\n"
@@ -5409,7 +5409,7 @@ msgid "Profile"
 msgstr "Profil"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5434,185 +5434,127 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
-msgstr "Domyślny"
+#, c-format
+msgid "%d minutes"
+msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
-msgstr "1 minuta"
+msgid "TIMLIM^Default"
+msgstr "Domyślny"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr "2 minuty"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr "3 minuty"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr "4 minuty"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr "5 minut"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr "6 minut"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr "7 minut"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr "8 minut"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr "9 minut"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr "10 minut"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr "15 minut"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr "20 minut"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr "25 minut"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr "30 minut"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr "40 minut"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr "50 minut"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
-msgstr "60 minut"
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
+msgstr "1 minuta"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr "Nieskończony"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr "Limit zabójstw:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr "Drużyny:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr "2 drużyny"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr "3 drużyny"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr "4 drużyny"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr "Ilość botów:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr "Umiejętności botów:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr "Jak bot"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr "Początkujący"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr "Wygrasz"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr "Możesz wygrać"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr "Być może wygrasz"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr "Zaawansowany"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr "Ekspert"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr "Zawodowiec"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr "Zabójca"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr "Nieludzki"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr "Bóg wojny"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr "Lista map"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5620,75 +5562,75 @@ msgstr "Lista map"
 msgid "Filter:"
 msgstr "Filtr:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr "Życia:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr "Okrążenia:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr "Cele:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr ""
 
@@ -6099,14 +6041,10 @@ msgid "Demos"
 msgstr "Demonstracje"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr "Zrzuty z ekranu"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr ""
 
@@ -6282,8 +6220,8 @@ msgstr "Płeć"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr "Zastosuj od razu"
 
@@ -6439,26 +6377,14 @@ msgstr ""
 msgid "Video"
 msgstr "Wideo"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr "Efekty"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr "Audio"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr "Gra"
@@ -6467,10 +6393,6 @@ msgstr "Gra"
 msgid "Input"
 msgstr "Wkład"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr "Użytkownik"
@@ -6479,10 +6401,6 @@ msgstr "Użytkownik"
 msgid "Misc"
 msgstr "Różne"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr "Mistrz:"
@@ -6661,10 +6579,6 @@ msgstr "Ostrzeżenie o pozostałym czasie:"
 msgid "WRN^Disabled"
 msgstr "Wyłączone"
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr "1 minuta"
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr "5 minut"
@@ -6920,7 +6834,7 @@ msgid "Decals on models"
 msgstr "Naklejki na modelach"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr "Odległość: "
 
@@ -7060,11 +6974,15 @@ msgstr "Cząsteczki"
 msgid "Spawnpoint effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr "Jakość:"
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 
@@ -7439,22 +7357,18 @@ msgid "Gibs:"
 msgstr "Flaki:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr "Żadne"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr "Kilka"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr "Wiele"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr "Dużo"
 
@@ -7508,7 +7422,7 @@ msgid "Field of view:"
 msgstr "Pole widzenia:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
+msgid "Field of vision in degrees (default: 100)"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
@@ -7750,92 +7664,93 @@ msgstr "Zapisz"
 msgid "Cancel"
 msgstr "Anuluj"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr "Sieć"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr "Klient UDP port:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr "Przepustowość:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr "56k"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr "Sieć cyfrowa z integracją usług - ISDN"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr "Powolna, asymetryczna cyfrowa linia abonencka - ADSL"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr "Szybka, asymetryczna cyfrowa linia abonencka - ADSL"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr "Szerokopasmowy "
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr "Pakiety wejściowe / s:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr "Downloads:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr "Prędkość (kB/s):"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
-msgid "Client-side movement prediction"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
+msgid "Client-side movement prediction"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
@@ -7854,50 +7769,6 @@ msgstr "Klatki na sekundę"
 msgid "Maximum:"
 msgstr "Maksymalna:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr "5 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr "10 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr "20 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr "30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr "40 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr "50 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr "60 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr "70 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr "100 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr "125 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr "200 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr "Bez limitu"
@@ -7910,54 +7781,10 @@ msgstr "Docelowo:"
 msgid "TRGT^Disabled"
 msgstr "Wyłączone"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr "30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr "40 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr "50 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr "60 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr "100 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr "125 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr "200 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr "Brak limitu:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr "10 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr "20 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr "30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr "60 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr "Nieograniczony"
@@ -8165,217 +7992,212 @@ msgid "Full screen"
 msgstr "Pełny ekran"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr "Synchronizacja pionowa"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr "Obróć obraz w poziomie"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr "Anizotropia:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr "Wyłączona"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr "2x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr "4x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr "8x "
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr "16x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr "Antyaliasing:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr "Wyłączony"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr "Wysokiej jakości bufor klatek"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr "Najpierw głębia:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr "DF^Świat"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr "DF^Wszystko"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr "Vertex Buffer Objexts (VBOs)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr "Wyłączone"
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr "Wierzchołki, niektóre Trójkąty (kompatybilne)"
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr "Wierzchołki, niektóre Trójkąty (kompatybilne)"
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr "Wierzchołki"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr "Wierzchołki i Trójkąty"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr "Jasność:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr "Kontrast:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr "Zakres:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr "Wzmocnienie kontrastu:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr "Nasycenie:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr "LIT^Otoczenia:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr "Intensywność:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr "Czekaj na GPU by dokończył każdą klatkę"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr "Użyj shaderów OpenGL 2.0 (GLSL)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr "Użyj GLSL do kontroli koloru"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr "Psychoza w kolorzie (easter egg)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr "Wierzchołki na fazie (easter egg)"
 
index d12a53532c85df5f59dfb45a2af9a2fbb040545b..8e3022833b3acc62b6d47b1d1192e51aefb7d245 100644 (file)
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -5347,7 +5347,7 @@ msgid "Profile"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5372,185 +5372,127 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
+#, c-format
+msgid "%d minutes"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
+msgid "TIMLIM^Default"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5558,75 +5500,75 @@ msgstr ""
 msgid "Filter:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr ""
 
@@ -6037,14 +5979,10 @@ msgid "Demos"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr ""
 
@@ -6220,8 +6158,8 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr ""
 
@@ -6377,26 +6315,14 @@ msgstr ""
 msgid "Video"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr ""
@@ -6405,10 +6331,6 @@ msgstr ""
 msgid "Input"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr ""
@@ -6417,10 +6339,6 @@ msgstr ""
 msgid "Misc"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr ""
@@ -6599,10 +6517,6 @@ msgstr ""
 msgid "WRN^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr ""
@@ -6858,7 +6772,7 @@ msgid "Decals on models"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr ""
 
@@ -6998,11 +6912,15 @@ msgstr ""
 msgid "Spawnpoint effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 
@@ -7376,22 +7294,18 @@ msgid "Gibs:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr ""
 
@@ -7445,7 +7359,7 @@ msgid "Field of view:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
+msgid "Field of vision in degrees (default: 100)"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
@@ -7687,92 +7601,93 @@ msgstr ""
 msgid "Cancel"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
-msgid "Client-side movement prediction"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
+msgid "Client-side movement prediction"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
@@ -7791,50 +7706,6 @@ msgstr ""
 msgid "Maximum:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr ""
@@ -7847,54 +7718,10 @@ msgstr ""
 msgid "TRGT^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr ""
@@ -8101,217 +7928,212 @@ msgid "Full screen"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr ""
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr ""
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr ""
 
index e2163fb849c148db3118b8512c6f8ec6ccfb18b5..564976f1191a21d30101fb7794f22adf2f642b13 100644 (file)
@@ -8,8 +8,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:02+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: Portuguese (http://www.transifex.com/team-xonotic/xonotic/"
 "language/pt/)\n"
@@ -5357,7 +5357,7 @@ msgid "Profile"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5382,185 +5382,127 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
+#, c-format
+msgid "%d minutes"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
+msgid "TIMLIM^Default"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
-msgstr ""
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
+msgstr "1 minuto"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr "Limite de Frags:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr "Equipas:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr "Slots para Jogadores:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr "Número de jogadores controlados pelo computador:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr "Nível de dificuldade:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr "Bot"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr "Iniciado"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr "Vais ganhar"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr "Podes ganhar"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr "Talvez ganhes"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr "Avançado"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr "Perito"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr "Profissional"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr "Assassino"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr "Desumano"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr "Divinal"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr "Mutators..."
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5568,75 +5510,75 @@ msgstr ""
 msgid "Filter:"
 msgstr "Filtrar:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr "Começar Multijogador!"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr "Limite de capturas:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr "Limite de pontos:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr "Vidas:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr "Voltas:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr "Golos:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr ""
 
@@ -6047,14 +5989,10 @@ msgid "Demos"
 msgstr "Demos"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr ""
 
@@ -6230,8 +6168,8 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr "Aplicar imediatamente"
 
@@ -6387,26 +6325,14 @@ msgstr ""
 msgid "Video"
 msgstr "Vídeo"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr "Efeitos"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr "Som"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr ""
@@ -6415,10 +6341,6 @@ msgstr ""
 msgid "Input"
 msgstr "Input"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr "Utilizador"
@@ -6427,10 +6349,6 @@ msgstr "Utilizador"
 msgid "Misc"
 msgstr "Misc"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr "Principal:"
@@ -6609,10 +6527,6 @@ msgstr "Aviso de tempo:"
 msgid "WRN^Disabled"
 msgstr "WRN^Desligado"
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr "1 minuto"
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr "5 minutos"
@@ -6868,7 +6782,7 @@ msgid "Decals on models"
 msgstr "Marcas nos modelos"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr "Distância:"
 
@@ -7008,11 +6922,15 @@ msgstr ""
 msgid "Spawnpoint effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 
@@ -7386,22 +7304,18 @@ msgid "Gibs:"
 msgstr "Tripas:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr "Nenhum"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr "Poucas"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr "Muitas"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr "Imensas"
 
@@ -7455,7 +7369,7 @@ msgid "Field of view:"
 msgstr "Campo de visão:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
+msgid "Field of vision in degrees (default: 100)"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
@@ -7697,94 +7611,95 @@ msgstr "Guardar"
 msgid "Cancel"
 msgstr "Cancelar"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr "Port UDP do Cliente:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr "56k"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr "ISDN"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr "ADSL Lenta"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr "ADSL Rápida"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr "Banda-larga"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr "Pacotes Entrada /s"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr "Transferências:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr "Velocidade (kB/s):"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr "Latência local:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr "Mostrar gráfico-net"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
 msgid "Client-side movement prediction"
 msgstr "Previsão de movimento pelo Cliente"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
 msgid "Movement error compensation"
 msgstr "Compensação do erro do movimento"
@@ -7801,50 +7716,6 @@ msgstr ""
 msgid "Maximum:"
 msgstr "Máximo:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr "MAXFPS^5 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr "MAXFPS^10 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr "MAXFPS^20 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr "MAXFPS^30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr "MAXFPS^40 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr "MAXFPS^50 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr "MAXFPS^60 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr "MAXFPS^70 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr "MAXFPS^100 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr "MAXFPS^125 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr "MAXFPS^200 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr "MAXFPS^Ilimitado fps"
@@ -7857,54 +7728,10 @@ msgstr "Alvo:"
 msgid "TRGT^Disabled"
 msgstr "TRGT^Desligado"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr "TRGT^30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr "TRGT^40 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr "TRGT^50 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr "TRGT^60 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr "TRGT^100 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr "TRGT^125 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr "TRGT^200 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr "Tempo parado limite:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr "IDLFPS^10 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr "IDLFPS^20 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr "IDLFPS^30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr "IDLFPS^60 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr "IDLFPS^Unlimited"
@@ -8111,217 +7938,212 @@ msgid "Full screen"
 msgstr "Ecrã Inteiro"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr "Sincronização Vertical"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr "Trocar vista horizontal"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr "Filtro Anisotrópico:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr "Desligado"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr "2 passagens"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr "4 passagens"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr "8x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr "16x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr "Antialiasing:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr "Desligado"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr "Buffer de Alta-qualidade"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr "Profundidade primeiro:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr "Desligado"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr "Mundo"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr "Todos"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr "Objectos Vertex Buffers (VBOs)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr "Desligado"
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr "Vértices, alguns Triângulos (compatível)"
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr "Vértices, alguns Triângulos (compatível)"
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr "Vértices"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr "Vértices e Triângulos"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr "Brilho:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr "Contraste:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr "Gamma:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr "Contraste - Boost"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr "Saturação da Cor:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr "Som Ambiente:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr "Intensidade:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr "Esperar que a placa gráfica termine cada frame"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr "Usar shaders OpenGL2.0 (GLSL)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr "Usar GLSL para o controlo de cores"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr "Cores 'Psycho' "
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr "Vértices 'Trip'"
 
index 93f3ac01954cef2d5fb6e78345b58c4aabbf9bd6..886f844be10adb90228d4672ab937ebb3e7bf8c2 100644 (file)
@@ -13,8 +13,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:02+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: Romanian (http://www.transifex.com/team-xonotic/xonotic/"
 "language/ro/)\n"
@@ -5524,7 +5524,7 @@ msgid "Profile"
 msgstr "Profil"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5549,185 +5549,127 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
-msgstr "TIMLIM^Default"
+#, c-format
+msgid "%d minutes"
+msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
-msgstr "TIMLIM^1 minut"
+msgid "TIMLIM^Default"
+msgstr "TIMLIM^Default"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr "TIMLIM^2 minute"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr "TIMLIM^3 minute"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr "TIMLIM^4 minute"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr "TIMLIM^5 minute"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr "TIMLIM^6 minute"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr "TIMLIM^7 minute"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr "TIMLIM^8 minute"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr "TIMLIM^9 minute"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr "TIMLIM^10 minute"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr "TIMLIM^15 minute"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr "TIMLIM^20 de minute"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr "TIMLIM^25 de minute"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr "TIMLIM^30 de minute"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr "TIMLIM^40 de minute"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr "TIMLIM^50 de minute"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
-msgstr "TIMLIM^60 de minute"
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
+msgstr "1 minut"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr "TIMLIM^Infinit"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr "Limita de omoruri:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr "Echipe:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr "2 echipe"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr "3 echipe"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr "4 echipe"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr "Număr maxim jucători:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr "Număr de boți:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr "Dificultate boți:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr "Ca de bot"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr "Începător"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr "Vei câștiga"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr "Poti castiga"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr "Ai putea câștiga"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr "Avansat"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr "Expert"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr "Profesional"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr "Asasin"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr "Inuman"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr "Dumnezeiesc"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr "Modificari speciale..."
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr "Listă Hărți"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5735,75 +5677,75 @@ msgstr "Listă Hărți"
 msgid "Filter:"
 msgstr "Filtrare:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr "Adaugă arătat"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr "Înlătură arătat"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr "Adaugă tot"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr "Înlătură tot"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr "Pornește joc Multiplayer!"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr "Limită de capturări:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr "Limită de puncte:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr "Vieți:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr "Ture:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr "Goluri:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr ""
 
@@ -6214,14 +6156,10 @@ msgid "Demos"
 msgstr "Demonstrații"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr "Capturi de ecran"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr "Player de Muzică"
 
@@ -6397,8 +6335,8 @@ msgstr "Sex"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr "Aplică imediat"
 
@@ -6554,26 +6492,14 @@ msgstr ""
 msgid "Video"
 msgstr "Video"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr "Efecte"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr "Audio"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr "Joc"
@@ -6582,10 +6508,6 @@ msgstr "Joc"
 msgid "Input"
 msgstr "Control"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr "Utilizator"
@@ -6594,10 +6516,6 @@ msgstr "Utilizator"
 msgid "Misc"
 msgstr "Altele"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr "General:"
@@ -6776,10 +6694,6 @@ msgstr "Avertisment timp:"
 msgid "WRN^Disabled"
 msgstr "WRN^Dezactivat"
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr "1 minut"
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr "5 minute"
@@ -7035,7 +6949,7 @@ msgid "Decals on models"
 msgstr "Decal-uri pe modele"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr "Distanță:"
 
@@ -7175,11 +7089,15 @@ msgstr "Particule"
 msgid "Spawnpoint effects"
 msgstr "Efecte de spawnpoint"
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr "Calitate:"
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 
@@ -7553,22 +7471,18 @@ msgid "Gibs:"
 msgstr "Cotlete:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr "GIBS^Nici unul"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr "GIBS^Puține"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr "GIBS^Multe"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr "GIBS^Foarte multe"
 
@@ -7622,7 +7536,7 @@ msgid "Field of view:"
 msgstr "Câmp vizual:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
+msgid "Field of vision in degrees (default: 100)"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
@@ -7864,94 +7778,95 @@ msgstr "Salvare"
 msgid "Cancel"
 msgstr "Anulare"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr "Rețea"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr "Port UDP client:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr "Lățime de bandă"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr "56k"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr "ISDN"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr "ADSL lent"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr "ADSL rapid"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr "VDSL/Fibră optică"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr "Pachete intrare/sec:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr "Cereri server/sec:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr "Descărcări:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr "Viteză (kB/s):"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr "Latență locala:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr "Afișaj grafic retea"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
 msgid "Client-side movement prediction"
 msgstr "Predicție miscare"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
 msgid "Movement error compensation"
 msgstr "Compensare eroare mișcare"
@@ -7968,50 +7883,6 @@ msgstr "Cadre pe secundă"
 msgid "Maximum:"
 msgstr "Maxim:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr "MAXFPS^5 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr "MAXFPS^10 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr "MAXFPS^20 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr "MAXFPS^30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr "MAXFPS^40 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr "MAXFPS^50 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr "MAXFPS^60 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr "MAXFPS^70 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr "MAXFPS^100 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr "MAXFPS^125 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr "MAXFPS^200 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr "MAXFPS^Nelimitat"
@@ -8024,54 +7895,10 @@ msgstr "Țintă:"
 msgid "TRGT^Disabled"
 msgstr "TRGT^Dezactivat"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr "TRGT^30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr "TRGT^40 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr "TRGT^50 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr "TRGT^60 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr "TRGT^100 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr "TRGT^125 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr "TRGT^200 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr "Limită de inactivitate:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr "IDLFPS^10 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr "IDLFPS^20 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr "IDLFPS^30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr "IDLFPS^60 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr "IDLFPS^Nelimitat"
@@ -8279,217 +8106,212 @@ msgid "Full screen"
 msgstr "Ecran mare"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr "Sincronizare Verticală"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr "Întoarce ecranul orizontal"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr "Filtrare anisotropică:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr "Dezactivat"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr "2x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr "4x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr "8x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr "16x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr "Antialising:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr "Dezactivat"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr "Frame-buffer de înaltă calitate"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr "Calcul profunzime:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr "DF^Dezactivat"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr "DF^Mediul"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr "DF^Totul"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr "Obiecte Buffer Vertex (VBOs)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr "Dezactivat"
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr "Puncte, unele Triunghiuri (compatibil)"
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr "Puncte, unele Triunghiuri (compatibil)"
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr "Puncte"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr "Puncte și Triunghiuri"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr "Luminozitate:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr "Contrast:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr "Gamma:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr "Stimulează contrast:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr "Saturație:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr "Ambianță:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr "Intensitate:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr "Așteaptă ca GPU-ul să termine fiecare cadru"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr "Utilizare OpenGL 2.0 (GLSL)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr "Utilizare GLSL pentru culori"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr "Colorare psycho (easter egg)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr "Deformare vertice (easter egg)"
 
index 15648712def5ff0fa56483b0fcf69727b062f514..49465ac0390ac8696a402131ffb4ab9f9c7805bf 100644 (file)
@@ -13,9 +13,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:09+0000\n"
-"Last-Translator: Andrei Stepanov\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
+"Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: Russian (http://www.transifex.com/team-xonotic/xonotic/"
 "language/ru/)\n"
 "Language: ru\n"
@@ -5481,7 +5481,7 @@ msgid "Profile"
 msgstr "Профиль"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5507,107 +5507,49 @@ msgstr ""
 "Ограничение времени в минутах, состязание закончится при его достижении"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
-msgstr "Стандартно"
+#, c-format
+msgid "%d minutes"
+msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
-msgstr "1 минута"
+msgid "TIMLIM^Default"
+msgstr "Стандартно"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr "2 минуты"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr "3 минуты"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr "4 минуты"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr "5 минут"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr "6 минут"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr "7 минут"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr "8 минут"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr "9 минут"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr "10 минут"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr "15 минут"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr "20 минут"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr "25 минут"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr "30 минут"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr "40 минут"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr "50 минут"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
-msgstr "60 минут"
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
+msgstr "1 минуту"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr "Бесконечно"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr "Предел фрагов:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr "Команды:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr "2 команды"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr "3 команды"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr "4 команды"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr "Слоты игроков:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
@@ -5615,79 +5557,79 @@ msgstr ""
 "Предельное количество игроков и ботов, которые могут быть одновременно "
 "подключены к серверу"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr "Кол-во ботов:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr "Количество ботов на сервере"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr "Уровень ботов:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr "Насколько искусными будут боты"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr "Ботоподобный"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr "Новичок"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr "Легко победить"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr "Можно победить"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr "Возможно победить"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr "Продвинутый"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr "Опытный"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr "Профессионал"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr "Убийца"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr "Сверхчеловек"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr "Божественный"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr "Мутаторы..."
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr "Мутаторы и арены оружий"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr "Список карт"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5695,75 +5637,75 @@ msgstr "Список карт"
 msgid "Filter:"
 msgstr "Фильтр:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr "Добавить показанное"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr "Удалить показанное"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr "Добавить все"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr "Убрать все"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr "Начать игру по сети!"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr "Предел захватов:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr "Предел очков:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr "Жизни:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr "Круги:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr "Цели:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr "Количество очков, необходимых для завершения состязания"
 
@@ -6177,14 +6119,10 @@ msgid "Demos"
 msgstr "Демки"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr "Список демо для просмотра"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr "Скриншоты"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr "Музыкальный плеер"
 
@@ -6360,8 +6298,8 @@ msgstr "Пол"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr "Применить"
 
@@ -6517,26 +6455,14 @@ msgstr "Изменить настройки игры"
 msgid "Video"
 msgstr "Изображение"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr "Настройки изображения"
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr "Эффекты"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr "Звук"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr "Настройки звука"
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr "Игра"
@@ -6545,10 +6471,6 @@ msgstr "Игра"
 msgid "Input"
 msgstr "Ввод"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr "Настройки устройств ввода"
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr "Пользователь"
@@ -6557,10 +6479,6 @@ msgstr "Пользователь"
 msgid "Misc"
 msgstr "Разное"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr "Разные настройки"
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr "Главный:"
@@ -6739,10 +6657,6 @@ msgstr "Аннонсы времени:"
 msgid "WRN^Disabled"
 msgstr "Отключено"
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr "1 минуту"
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr "5 минут"
@@ -6998,7 +6912,7 @@ msgid "Decals on models"
 msgstr "Следы на моделях"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr "Дальность:"
 
@@ -7138,11 +7052,15 @@ msgstr "Частицы"
 msgid "Spawnpoint effects"
 msgstr "Эффекты точек возрождения"
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr "Качество:"
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 
@@ -7516,22 +7434,18 @@ msgid "Gibs:"
 msgstr "Ошмётки:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr "Нет"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr "Мало"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr "Много"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr "Тонны"
 
@@ -7585,9 +7499,8 @@ msgid "Field of view:"
 msgstr "Угол обзора:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
+msgid "Field of vision in degrees (default: 100)"
 msgstr ""
-"Угол обзора в градусах, допустимы значения от 60 то 130, по умолчанию 90"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
 msgid "ZOOM^Zoom factor:"
@@ -7829,94 +7742,95 @@ msgstr "Сохранение"
 msgid "Cancel"
 msgstr "Отмена"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr "Сеть"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr "UDP порт клиента:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr "Ширина канала:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
-msgstr "Укажите скорость вашей сети с помощью этого ползунка"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr "56k"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr "ISDN"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr "Медленный ADSL"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr "Быстрый ADSL"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr "Широкополосная"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr "Кол-во пакетов/с:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr "Сколько пакетов посылать серверу каждую секунду"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr "Опросы сервера/с:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr "Загрузки:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr "Предел одновременных HTTP/FTP загрузок"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr "Скорость (кБ/с):"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr "Предел скорости скачивания"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr "Местная задержка:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr "Показывать сетевой монитор"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr "Показывать график размеров пакетов и других сведений"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
 msgid "Client-side movement prediction"
 msgstr "Предсказание движения на стороне клиента"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
-msgstr "Включить предсказание движения на стороне клиента"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
 msgid "Movement error compensation"
 msgstr "Компенсация ошибки движения"
@@ -7933,50 +7847,6 @@ msgstr "Частота кадров"
 msgid "Maximum:"
 msgstr "Предельная:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr "5 кадров/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr "10 кадров/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr "20 кадров/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr "30 кадров/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr "40 кадров/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr "50 кадров/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr "60 кадров/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr "70 кадров/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr "100 кадров/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr "125 кадров/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr "200 кадров/с"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr "Неограниченно"
@@ -7989,54 +7859,10 @@ msgstr "Целевая:"
 msgid "TRGT^Disabled"
 msgstr "Отключено"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr "30 кадров/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr "40 кадров/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr "50 кадров/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr "60 кадров/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr "100 кадров/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr "125 кадров/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr "200 кадров/с"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr "Ограничение при бездействии:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr "10 кадров/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr "20 кадров/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr "30 кадров/с"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr "60 кадров/с"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr "Неограниченно"
@@ -8244,175 +8070,170 @@ msgid "Full screen"
 msgstr "Во весь экран"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr "Включить полноэкранный режим (по умолчанию: включено)"
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr "Вертикальная синхронизация"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr "Перевернуть изображение по горизонтали"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr "Анизотропия:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr "Отключена"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr "2x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr "4x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr "8x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr "16x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr "Сглаживание:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr "Отключено"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr "Высококачественный буфер кадров"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr "Сперва глубина:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr "Отключено"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr "Мир"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr "Всё"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr "Использовать Vertex Buffer Objects (VBO)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr "Отключено"
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr "Вершины и отдельные треугольники (безопасно)"
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr "Вершины и отдельные треугольники (безопасно)"
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr "Вершины"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr "Вершины и треугольники"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr "Яркость:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr "Яркость чёрного (по умолчанию: 0)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr "Контраст:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr "Яркость белого (по умолчанию: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr "Гамма:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr "Усиление контраста:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr "Насыщенность:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr "Общее освещение:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
@@ -8420,43 +8241,43 @@ msgstr ""
 "Окружающее освещение, если выставлено слишком сильным, приводит к тому, что "
 "свет на картах выглядит блёклым и плоским (по умолчанию: 4)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr "Мощность:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr "Общая яркость вывода (по умолчанию: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr "Ждать завершения каждого кадра ГП"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr "Использовать GLSL шейдеры OpenGL 2.0"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr "Использовать GLSL для управления цветом"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr "Психоделическая расцветка (пасхалка)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr "Психоделические вершины (пасхалка)"
 
index 76d85cfc5168700b5b20c3e175c4b93ab961ee00..034e3392eb0daf47775ffa2f07341baa0d07ea94 100644 (file)
@@ -11,8 +11,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:02+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: Serbian (http://www.transifex.com/team-xonotic/xonotic/"
 "language/sr/)\n"
@@ -5358,7 +5358,7 @@ msgid "Profile"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5383,185 +5383,127 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
+#, c-format
+msgid "%d minutes"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
+msgid "TIMLIM^Default"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5569,75 +5511,75 @@ msgstr ""
 msgid "Filter:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr ""
 
@@ -6048,14 +5990,10 @@ msgid "Demos"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr ""
 
@@ -6231,8 +6169,8 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr ""
 
@@ -6388,26 +6326,14 @@ msgstr ""
 msgid "Video"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr ""
@@ -6416,10 +6342,6 @@ msgstr ""
 msgid "Input"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr ""
@@ -6428,10 +6350,6 @@ msgstr ""
 msgid "Misc"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr ""
@@ -6610,10 +6528,6 @@ msgstr ""
 msgid "WRN^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr ""
@@ -6869,7 +6783,7 @@ msgid "Decals on models"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr ""
 
@@ -7009,11 +6923,15 @@ msgstr ""
 msgid "Spawnpoint effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 
@@ -7387,22 +7305,18 @@ msgid "Gibs:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr ""
 
@@ -7456,7 +7370,7 @@ msgid "Field of view:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
+msgid "Field of vision in degrees (default: 100)"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
@@ -7698,92 +7612,93 @@ msgstr ""
 msgid "Cancel"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
-msgid "Client-side movement prediction"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
+msgid "Client-side movement prediction"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
@@ -7802,50 +7717,6 @@ msgstr ""
 msgid "Maximum:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr ""
@@ -7858,54 +7729,10 @@ msgstr ""
 msgid "TRGT^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr ""
@@ -8112,217 +7939,212 @@ msgid "Full screen"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr ""
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr ""
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr "Kontrast:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr "Intenzitet:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr ""
 
index e854ca4474671a2f108619febbffa3a46741ac79..d51a5c0350efce33d24b7e4fc0dbc271ad8c4abd 100644 (file)
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:02+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: Swedish (http://www.transifex.com/team-xonotic/xonotic/"
 "language/sv/)\n"
@@ -5354,7 +5354,7 @@ msgid "Profile"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5379,185 +5379,127 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
+#, c-format
+msgid "%d minutes"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
+msgid "TIMLIM^Default"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
-msgstr ""
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
+msgstr "1 minut"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr "Fraggräns:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr "Lag:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr "Spelarplatser:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr "Antal bottar:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr "Bot skicklighet:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr "Botliknande"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr "Nybörjare"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr "Du kommer att vinna"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr "Du kan vinna"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr "Du kanske vinner"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr "Avancerad"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr "Expert"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr "Pro"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr "Lönnmördare"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr "Omänsklig"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr "Gudliknande"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr "Mutators..."
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5565,75 +5507,75 @@ msgstr ""
 msgid "Filter:"
 msgstr "Filter:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr "Starta Flerspelarläge!"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr "Kapningsgräns:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr "Poänggräns:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr "Liv:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr "Varv:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr "Mål:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr ""
 
@@ -6044,14 +5986,10 @@ msgid "Demos"
 msgstr "Demonstrationer"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr ""
 
@@ -6227,8 +6165,8 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr "Tillämpa direkt"
 
@@ -6384,26 +6322,14 @@ msgstr ""
 msgid "Video"
 msgstr "Video"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr "Effekter"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr "Ljud"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr ""
@@ -6412,10 +6338,6 @@ msgstr ""
 msgid "Input"
 msgstr "Inmatning"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr ""
@@ -6424,10 +6346,6 @@ msgstr ""
 msgid "Misc"
 msgstr "Blandat"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr "Master:"
@@ -6606,10 +6524,6 @@ msgstr ""
 msgid "WRN^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr "1 minut"
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr "5 minuter"
@@ -6865,7 +6779,7 @@ msgid "Decals on models"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr ""
 
@@ -7005,11 +6919,15 @@ msgstr ""
 msgid "Spawnpoint effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 
@@ -7383,22 +7301,18 @@ msgid "Gibs:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr ""
 
@@ -7452,7 +7366,7 @@ msgid "Field of view:"
 msgstr "Synfält:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
+msgid "Field of vision in degrees (default: 100)"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
@@ -7694,94 +7608,95 @@ msgstr "Spara"
 msgid "Cancel"
 msgstr "Avbryt"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr "Klientens UDB-port:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr "Långsam ADSL"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr "Snabb ADSL"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr "Bredband"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr "Inputpaket/s"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr "Nedladdningar:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr "Hastighet (kB/s):"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr "Visa nätgraf"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
 msgid "Client-side movement prediction"
 msgstr "Rörelseprediktering i klienten"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
 msgid "Movement error compensation"
 msgstr ""
@@ -7798,50 +7713,6 @@ msgstr ""
 msgid "Maximum:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr ""
@@ -7854,54 +7725,10 @@ msgstr ""
 msgid "TRGT^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr ""
@@ -8108,217 +7935,212 @@ msgid "Full screen"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr "Av"
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr ""
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr ""
 
index c6c397e4ed60172e95b02e05a7e080d6ae403bdb..c48065a006728a31cb307a15c207ff05c9ed5241 100644 (file)
@@ -9,8 +9,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:07+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: Ukrainian (http://www.transifex.com/team-xonotic/xonotic/"
 "language/uk/)\n"
@@ -5410,7 +5410,7 @@ msgid "Profile"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5435,185 +5435,127 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr "Час, після якого матч закінчиться"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
+#, c-format
+msgid "%d minutes"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
+msgid "TIMLIM^Default"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
-msgstr ""
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
+msgstr "1 хвилина"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr "Ліміт фрагів:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr "Команди:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr "Місць для гравців:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
 msgstr "Максимальна кількість гравців та ботів на вашому сервері"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr "Кількість ботів:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr "Кількість ботів на вашому сервері"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr "Майстерність ботів:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr "Вкажіть досвідченість ботів"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr "Ботоподібний"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr "Початківець"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr "Ви переможете"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr "Ви можете перемогти"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr "Ви переможете... можливо"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr "Удосконалений"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr "Експерт"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr "Професіонал"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr "Убивця"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr "Нелюд"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr "Богоподібний"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr "Мутатори..."
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr "Мутатори і арени"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5621,75 +5563,75 @@ msgstr ""
 msgid "Filter:"
 msgstr "Фільтр:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr "Почати Мультиплеєр!"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr "Ліміт захоплень:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr "Ліміт очок:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr "Життів:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr "Кругів:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr "Голів:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr "Кількість фрагів, яка потрібна для закінчення матчу"
 
@@ -6106,14 +6048,10 @@ msgid "Demos"
 msgstr "Демо"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr "Знайдіть та перегляньте демо записи"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr ""
 
@@ -6289,8 +6227,8 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr "Вжити негайно"
 
@@ -6446,26 +6384,14 @@ msgstr "Змінити налаштування гри"
 msgid "Video"
 msgstr "Відео"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr "Налаштування відео"
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr "Ефекти"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr "Звук"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr "Налаштування аудіо"
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr ""
@@ -6474,10 +6400,6 @@ msgstr ""
 msgid "Input"
 msgstr "Керування"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr "Налаштування керування"
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr "Користувач"
@@ -6486,10 +6408,6 @@ msgstr "Користувач"
 msgid "Misc"
 msgstr "Різне"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr "Різні налаштування"
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr "Гучність:"
@@ -6670,10 +6588,6 @@ msgstr "Попередження про час:"
 msgid "WRN^Disabled"
 msgstr "Вимкнуто"
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr "1 хвилина"
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr "5 хвилин"
@@ -6942,7 +6856,7 @@ msgid "Decals on models"
 msgstr "Декалі на моделях"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr "Відстань:"
 
@@ -7099,11 +7013,15 @@ msgstr ""
 msgid "Spawnpoint effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 "Частки на відстані більшій ніж ця не будуть створюватись (за замовчуванням: "
@@ -7480,24 +7398,18 @@ msgid "Gibs:"
 msgstr "Шматки тіл:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-"Зменшити кількість шматків тіла, або відключити їх зовсім (за замовчуванням: "
-"багато)"
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr "Вимкнуто"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr "Мало"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr "Більше"
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr "Багато"
 
@@ -7551,8 +7463,8 @@ msgid "Field of view:"
 msgstr "Поле зору:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
-msgstr "Поле огляду у градусах, від 60 до 130, 90 за замовчуванням"
+msgid "Field of vision in degrees (default: 100)"
+msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
 msgid "ZOOM^Zoom factor:"
@@ -7796,95 +7708,96 @@ msgstr "Зберегти"
 msgid "Cancel"
 msgstr "Відміна"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr "UDP порт клієнта:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 "Змушувати клієнта використовувати обраний порт, але тільки якщо значення не 0"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
-msgstr "Вкажіть швидкість вашої мережі"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr "56k"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr "ISDN"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr "Повільний ADSL"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr "Швидкій ADSL"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr "Широкополосний доступ"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr "Вхідні пакети:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr "Скільки вхідних пакетів посилати серверу кожну секунду"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr "Завантажень:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr "Максимальна кількість одночасних HTTP/FTP завантажень"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr "Швидкість (кб/с):"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr "Максимальна швидкість завантаження"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr "Локальна затримка:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr "Показувати графік мережі"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr "Показувати графік розмірів пакетів та іншої інформації"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
 msgid "Client-side movement prediction"
 msgstr "Передбачення руху зі сторони клієнта"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
-msgstr "Увімкнути передбачення руху зі сторони клієнта"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
 msgid "Movement error compensation"
 msgstr "Компенсація помилок руху"
@@ -7901,50 +7814,6 @@ msgstr ""
 msgid "Maximum:"
 msgstr "Максимум:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr "5 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr "10 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr "20 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr "30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr "40 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr "50 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr "60 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr "70 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr "100 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr "125 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr "200 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr "Необмежено"
@@ -7957,54 +7826,10 @@ msgstr "Ціль:"
 msgid "TRGT^Disabled"
 msgstr "Вимкнуто"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr "30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr "40 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr "50 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr "60 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr "100 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr "125 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr "200 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr "Ліміт часу бездіяльності:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr "10 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr "20 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr "30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr "60 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr "Необмежено"
@@ -8215,14 +8040,10 @@ msgid "Full screen"
 msgstr "На повний екран"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr "На повний екран (за замовчуванням: увімкнуто)"
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr "Вертикальна синхронізація"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
@@ -8231,49 +8052,49 @@ msgstr ""
 "не будуть підніматися вище швидкості оновлення монітору (за замовчуванням: "
 "увімкнуто)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr "Поміняти місцями вид горизонтально"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr "Простий режим для лівші (за замовчуванням: вимкнуто)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr "Анізотропна фільтрація:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr "Якість анізотропної фільтрації (за замовчуванням: 1x)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr "Вимкнуто"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr "2x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr "4x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr "8x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr "16x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr "Антиаліасінг:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
@@ -8282,19 +8103,19 @@ msgstr ""
 "до уваги, що це може сильно зменшити продуктивність. (за замовчуванням: "
 "вимкнуто)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr "Вимкнуто"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr "Високоякісний буфер кадрів"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr "Глибина спершу:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
@@ -8302,30 +8123,33 @@ msgstr ""
 "Прибирає перекриття одних пікселів іншими створюючи спочатку версію сцени з "
 "лише глибиною (за замовчуванням: вимкнуто)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr "Вимкнуто"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr "Світ"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr "Все"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr "Vertex Buffer Objects (VBOs)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr "Вимкнуто"
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr "Вершини, деякі трикутники (сумісний)"
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
@@ -8334,58 +8158,54 @@ msgstr ""
 "відеопам'яті для прискорення рендеренгу (за замовчуванням: вершини та "
 "трикутники)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr "Вершини, деякі трикутники (сумісний)"
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr "Вершини"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr "Вершини та трикутники"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr "Яскравість:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr "Яскравіcть чорного (за замовчуванням: 0)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr "Контраст:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr "Яскравість білого (за замовчуванням: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr "Гамма:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
 msgstr ""
 "Яскравість що не впливає на білий та чорний колір (за замовчуванням: 1.125)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr "Підсилення контрасту:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr "На скільки збільшувати контраст в темних місцях (за замовчуванням: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr "Насиченість:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
@@ -8394,11 +8214,11 @@ msgstr ""
 "необхідно використовувати шейдери GLSL для контролю кольором (за "
 "замовчуванням: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr "Навколишне освітлення:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
@@ -8406,19 +8226,19 @@ msgstr ""
 "Навколишнє освітлення, якщо значення надто високе, то освітлення на мапах "
 "стає приглушеним та плоским (за замовчуванням: 4)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr "Інтенсивність:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr "Яскравість (за замовчуванням: 1)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr "Чекати поки GPU закінчить кожний кадр"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
@@ -8427,15 +8247,15 @@ msgstr ""
 "може допомогти на деяких системах при деяких проблемах (за замовчуванням: "
 "вимкнуто)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr "Використовувати шейдери OpenGL 2.0 (GLSL)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr "Використовувати GLSL для управління кольором"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
@@ -8443,11 +8263,11 @@ msgstr ""
 "Вмикає GLSL для використання корекції гамми, може мати сильній вплив на "
 "продуктивність (за замовчуванням: вимкнуто)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr "Психо-кольори (великоднє яйце)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr "Божевільні вершини (великоднє яйце)"
 
index aa1ca88a0a5f030978c11ee2f57c0ee5bb5b9615..e4f59caed2941976dfb6496adfcb40294bb8bf03 100644 (file)
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:02+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: Uzbek (Latin) (http://www.transifex.com/team-xonotic/xonotic/"
 "language/uz@Latn/)\n"
@@ -5348,7 +5348,7 @@ msgid "Profile"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5373,185 +5373,127 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
+#, c-format
+msgid "%d minutes"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
+msgid "TIMLIM^Default"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5559,75 +5501,75 @@ msgstr ""
 msgid "Filter:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr ""
 
@@ -6038,14 +5980,10 @@ msgid "Demos"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr ""
 
@@ -6221,8 +6159,8 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr ""
 
@@ -6378,26 +6316,14 @@ msgstr ""
 msgid "Video"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr ""
@@ -6406,10 +6332,6 @@ msgstr ""
 msgid "Input"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr ""
@@ -6418,10 +6340,6 @@ msgstr ""
 msgid "Misc"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr ""
@@ -6600,10 +6518,6 @@ msgstr ""
 msgid "WRN^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr ""
@@ -6859,7 +6773,7 @@ msgid "Decals on models"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr ""
 
@@ -6999,11 +6913,15 @@ msgstr ""
 msgid "Spawnpoint effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 
@@ -7377,22 +7295,18 @@ msgid "Gibs:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr ""
 
@@ -7446,7 +7360,7 @@ msgid "Field of view:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
+msgid "Field of vision in degrees (default: 100)"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
@@ -7688,92 +7602,93 @@ msgstr ""
 msgid "Cancel"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
-msgid "Client-side movement prediction"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
+msgid "Client-side movement prediction"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
@@ -7792,50 +7707,6 @@ msgstr ""
 msgid "Maximum:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr ""
@@ -7848,54 +7719,10 @@ msgstr ""
 msgid "TRGT^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr ""
@@ -8102,217 +7929,212 @@ msgid "Full screen"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr ""
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr ""
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr ""
 
index 3738797725205eb67abbea9fdf6373844a35cf5d..0892aef9756f6525a4e8559cf764f79570dad466 100644 (file)
@@ -11,8 +11,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:02+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: Chinese (China) (http://www.transifex.com/team-xonotic/"
 "xonotic/language/zh_CN/)\n"
@@ -5352,7 +5352,7 @@ msgid "Profile"
 msgstr "配置文件"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5377,185 +5377,127 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
-msgstr "TIMLIM^默认"
+#, c-format
+msgid "%d minutes"
+msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
-msgstr "TIMLIM^1 分钟"
+msgid "TIMLIM^Default"
+msgstr "TIMLIM^默认"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr "TIMLIM^2 分钟"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr "TIMLIM^3 分钟"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr "TIMLIM^4 分钟"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr "TIMLIM^5 分钟"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr "TIMLIM^6 分钟"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr "TIMLIM^7 分钟"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr "TIMLIM^8 分钟"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr "TIMLIM^9 分钟"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr "TIMLIM^10 分钟"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr "TIMLIM^15 分钟"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr "TIMLIM^20 分钟"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr "TIMLIM^25 分钟"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr "TIMLIM^30 分钟"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr "TIMLIM^40 分钟"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr "TIMLIM^50 分钟"
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
-msgstr "TIMLIM^60 分钟"
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
+msgstr "1 分钟"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr "TIMLIM^无限时间"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr "炸弹限制:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr "团队:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr "团队2"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr "团队3"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr "团队4"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr "玩家位置:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr "机器人数量:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr "机器人技能"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr "僵尸"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr "新手"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr "你会赢的"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr "你能赢的"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr "你可能会赢"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr "高级"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr "专家"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr "强化"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr "刺客"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr "极限"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr "超神"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr "地图列表"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5563,75 +5505,75 @@ msgstr "地图列表"
 msgid "Filter:"
 msgstr "筛选器:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr "开始游戏!"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr "捕捉限制:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr "点数限制:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr "活动:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr "范围:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr "目标:"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr ""
 
@@ -6042,14 +5984,10 @@ msgid "Demos"
 msgstr "预览"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr "屏幕截图"
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr ""
 
@@ -6225,8 +6163,8 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr ""
 
@@ -6382,26 +6320,14 @@ msgstr ""
 msgid "Video"
 msgstr "影像"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr "效果"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr "声音"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr "游戏"
@@ -6410,10 +6336,6 @@ msgstr "游戏"
 msgid "Input"
 msgstr "输入"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr "用户"
@@ -6422,10 +6344,6 @@ msgstr "用户"
 msgid "Misc"
 msgstr "杂项"
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr "主要:"
@@ -6604,10 +6522,6 @@ msgstr "时间提示器:"
 msgid "WRN^Disabled"
 msgstr "WRN^已禁用"
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr "1 分钟"
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr "5 分钟"
@@ -6863,7 +6777,7 @@ msgid "Decals on models"
 msgstr "模型涂鸦"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr "距离:"
 
@@ -7003,11 +6917,15 @@ msgstr "粒子效果"
 msgid "Spawnpoint effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr "品质:"
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 
@@ -7381,22 +7299,18 @@ msgid "Gibs:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr ""
 
@@ -7450,7 +7364,7 @@ msgid "Field of view:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
+msgid "Field of vision in degrees (default: 100)"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
@@ -7692,92 +7606,93 @@ msgstr "保存"
 msgid "Cancel"
 msgstr "取消"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr "互联网"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr "客户端 UDP 端口:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr "带宽:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr "56k"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr "ISDN"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr "低速 ADSL"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr "高速 ADSL"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr "宽带"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr "Input packets/s:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr "Server queries/s:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr "下载"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr "速度 (kB/s):"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr "本地延迟:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr "显示网络图"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
-msgid "Client-side movement prediction"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
+msgid "Client-side movement prediction"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
@@ -7796,50 +7711,6 @@ msgstr "帧率"
 msgid "Maximum:"
 msgstr "最大值:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr "MAXFPS^5 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr "MAXFPS^10 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr "MAXFPS^20 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr "MAXFPS^30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr "MAXFPS^40 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr "MAXFPS^50 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr "MAXFPS^60 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr "MAXFPS^70 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr "MAXFPS^100 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr "MAXFPS^125 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr "MAXFPS^200 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr "MAXFPS^无限制"
@@ -7852,54 +7723,10 @@ msgstr "目标值:"
 msgid "TRGT^Disabled"
 msgstr "TRGT^已禁用"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr "TRGT^30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr "TRGT^40 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr "TRGT^50 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr "TRGT^60 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr "TRGT^100 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr "TRGT^125 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr "TRGT^200 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr "空余时间限制:"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr "IDLFPS^10 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr "IDLFPS^20 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr "IDLFPS^30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr "IDLFPS^60 fps"
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr "IDLFPS^无限制"
@@ -8106,217 +7933,212 @@ msgid "Full screen"
 msgstr "全屏幕"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr "垂直同步"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr "翻转横向视图"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr "各向异性:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr "ANISO^已禁用"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr "2x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr "4x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr "8x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr "16x"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr "抗锯齿:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr "AA^已禁用"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr "高品质帧缓冲区"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr "深度优先:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr "DF^已禁用"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr "DF^世界"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr "DF^全部"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr "顶点缓冲区对象 (VBOs)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr "VBO^关"
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr "顶点,部分三角形 (兼容模式)"
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr "顶点,部分三角形 (兼容模式)"
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr "顶点"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr "顶点和三角形"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr "亮度:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr "对比度:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr "伽玛值:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr "对比度增强:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr "饱和度:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr "LIT^环境:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr "明暗度:"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr "等待 GPU 来完成每一帧的渲染"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr "使用 OpenGL 2.0 着色器 (GLSL)"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr "使用 GLSL 来处理色彩控制"
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr ""
 
index 0e7a98790156587e1f65137152fb906622705cba..09502497d593cb117e3874d60a9e4e8afdce9895 100644 (file)
@@ -10,8 +10,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-10-13 21:14+0200\n"
-"PO-Revision-Date: 2015-10-13 19:02+0000\n"
+"POT-Creation-Date: 2015-10-14 01:50+0200\n"
+"PO-Revision-Date: 2015-10-13 23:50+0000\n"
 "Last-Translator: divVerent <divVerent@xonotic.org>\n"
 "Language-Team: Chinese (Taiwan) (http://www.transifex.com/team-xonotic/"
 "xonotic/language/zh_TW/)\n"
@@ -5351,7 +5351,7 @@ msgid "Profile"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:46
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:190
 #: qcsrc/menu/xonotic/skinlist.qc:123 qcsrc/menu/xonotic/util.qc:743
 #: qcsrc/menu/xonotic/util.qc:759 qcsrc/menu/xonotic/util.qc:768
@@ -5376,185 +5376,127 @@ msgid "Timelimit in minutes that when hit, will end the match"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:80
-msgid "TIMLIM^Default"
+#, c-format
+msgid "%d minutes"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
-msgid "TIMLIM^1 minute"
+msgid "TIMLIM^Default"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
-msgid "TIMLIM^2 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
-msgid "TIMLIM^3 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
-msgid "TIMLIM^4 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:85
-msgid "TIMLIM^5 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:86
-msgid "TIMLIM^6 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:87
-msgid "TIMLIM^7 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:88
-msgid "TIMLIM^8 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:89
-msgid "TIMLIM^9 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:90
-msgid "TIMLIM^10 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:91
-msgid "TIMLIM^15 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:92
-msgid "TIMLIM^20 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:93
-msgid "TIMLIM^25 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:94
-msgid "TIMLIM^30 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:95
-msgid "TIMLIM^40 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:96
-msgid "TIMLIM^50 minutes"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:97
-msgid "TIMLIM^60 minutes"
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "1 minute"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:98
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:99
 msgid "TIMLIM^Infinite"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:103
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "Frag limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:107
 msgid "Teams:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:108
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
 msgid "2 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
 msgid "3 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:110
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "4 teams"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
 msgid "Player slots:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:115
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
 msgid "Number of bots:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Amount of bots on your server"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Bot skill:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:124
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
 msgid "Specify how experienced the bots will be"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
 msgid "Botlike"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:126
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Beginner"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:127
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "You will win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
 msgid "You can win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
 msgid "You might win"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
 msgid "Advanced"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
 msgid "Expert"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
 msgid "Pro"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
 msgid "Assassin"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
 msgid "Unhuman"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
 msgid "Godlike"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:151
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:153
 msgid "Mutators..."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:152
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:154
 msgid "Mutators and weapon arenas"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:161
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:163
 msgid "Maplist"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:169
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:29
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:29
@@ -5562,75 +5504,75 @@ msgstr ""
 msgid "Filter:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:171
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
 msgid ""
-"Click here or Ctrl-F to provide a keyword to narrow down the maplist above. "
-"Ctrl-Delete to clear; Enter when done."
+"Click here or Ctrl-F to provide a keyword to narrow down the map list. Ctrl-"
+"Delete to clear; Enter when done."
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:181
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:183
 msgid "Add shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:182
-msgid "Add the maps shown in Maplist above to your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
+msgid "Add the maps shown in the list to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:187
 msgid "Remove shown"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:186
-msgid "Remove the maps shown in Maplist above from your selection"
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove the maps shown in the list from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:191
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:193
 msgid "Add all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:192
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add every available map to your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:197
 msgid "Remove all"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:196
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all the maps from your selection"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:203
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:205
 msgid "Start Multiplayer!"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:222
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
 msgid "Capture limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:223
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:224
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:230
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:231
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:232
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:234
 msgid "Point limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:225
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
 msgid "Lives:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:226
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:228
 msgid "Laps:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:227
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:229
 msgid "Goals:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:233
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:235
 msgid "The amount of frags needed before the match will end"
 msgstr ""
 
@@ -6041,14 +5983,10 @@ msgid "Demos"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:29
-msgid "Browse and view demos"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Screenshots"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:31
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:30
 msgid "Music Player"
 msgstr ""
 
@@ -6224,8 +6162,8 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:164
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:178
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:237
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:238
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:164
 msgid "Apply immediately"
 msgstr ""
 
@@ -6381,26 +6319,14 @@ msgstr ""
 msgid "Video"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:21
-msgid "Video settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:22
-msgid "Effects settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Audio"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:23
-msgid "Audio settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:25
 msgid "Game"
 msgstr ""
@@ -6409,10 +6335,6 @@ msgstr ""
 msgid "Input"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:26
-msgid "Input settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings.qc:27
 msgid "User"
 msgstr ""
@@ -6421,10 +6343,6 @@ msgstr ""
 msgid "Misc"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings.qc:28
-msgid "Misc settings"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
 msgstr ""
@@ -6603,10 +6521,6 @@ msgstr ""
 msgid "WRN^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
-msgid "1 minute"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
 msgid "5 minutes"
 msgstr ""
@@ -6862,7 +6776,7 @@ msgid "Decals on models"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:230
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:231
 msgid "Distance:"
 msgstr ""
 
@@ -7002,11 +6916,15 @@ msgstr ""
 msgid "Spawnpoint effects"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
 msgid "Quality:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
 msgid "Particles further away than this will not be drawn (default: 1000)"
 msgstr ""
 
@@ -7380,22 +7298,18 @@ msgid "Gibs:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:70
-msgid "Reduce the amount of gibs or remove them completely (default: lots)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^None"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:71
 msgid "GIBS^Few"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:72
 msgid "GIBS^Many"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:74
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:73
 msgid "GIBS^Lots"
 msgstr ""
 
@@ -7449,7 +7363,7 @@ msgid "Field of view:"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
-msgid "Field of vision in degrees from 60 to 130, default is 90"
+msgid "Field of vision in degrees (default: 100)"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:85
@@ -7691,92 +7605,93 @@ msgstr ""
 msgid "Cancel"
 msgstr "取消"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:14
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:28
 msgid "Network"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:30
 msgid "Client UDP port:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:32
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:35
 msgid "Bandwidth:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
-msgid "Specify your network speed with this slider"
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "Specify your network speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "56k"
 msgstr "56k"
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "ISDN"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Slow ADSL"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Fast ADSL"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:42
 msgid "Broadband"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:45
 msgid "Input packets/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:47
 msgid "How many input packets to send to the server each second"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:49
 msgid "Server queries/s:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:53
 msgid "Downloads:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:55
 msgid "Maximum number of concurrent HTTP/FTP downloads"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:57
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:58
 msgid "Speed (kB/s):"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Maximum download speed"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:63
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Local latency:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:67
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
 msgid "Show netgraph"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Show a graph of packet sizes and other information"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
-msgid "Client-side movement prediction"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:71
-msgid "Enable clientside movement prediction"
+msgid "Client-side movement prediction"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
@@ -7795,50 +7710,6 @@ msgstr ""
 msgid "Maximum:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:84
-msgid "MAXFPS^5 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
-msgid "MAXFPS^10 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:86
-msgid "MAXFPS^20 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
-msgid "MAXFPS^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:88
-msgid "MAXFPS^40 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:89
-msgid "MAXFPS^50 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:90
-msgid "MAXFPS^60 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:91
-msgid "MAXFPS^70 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:92
-msgid "MAXFPS^100 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
-msgid "MAXFPS^125 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:94
-msgid "MAXFPS^200 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:95
 msgid "MAXFPS^Unlimited"
 msgstr ""
@@ -7851,54 +7722,10 @@ msgstr "目標:"
 msgid "TRGT^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:101
-msgid "TRGT^30 fps"
-msgstr "TRGT^30 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
-msgid "TRGT^40 fps"
-msgstr "TRGT^40 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:103
-msgid "TRGT^50 fps"
-msgstr "TRGT^50 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
-msgid "TRGT^60 fps"
-msgstr "TRGT^60 fps"
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:105
-msgid "TRGT^100 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:106
-msgid "TRGT^125 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:107
-msgid "TRGT^200 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:110
 msgid "Idle limit:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:112
-msgid "IDLFPS^10 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:113
-msgid "IDLFPS^20 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:114
-msgid "IDLFPS^30 fps"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
-msgid "IDLFPS^60 fps"
-msgstr ""
-
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "IDLFPS^Unlimited"
 msgstr ""
@@ -8105,217 +7932,212 @@ msgid "Full screen"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
-msgid "Enable fullscreen mode (default: enabled)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid "Vertical Synchronization"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:52
 msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:57
 msgid "Flip view horizontally"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:58
 msgid "Poor man's left handed mode (default: off)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Anisotropy:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:63
 msgid "Anisotropic filtering quality (default: 1x)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "ANISO^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:65
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 msgid "2x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:66
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "4x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "8x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:69
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "16x"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:72
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Antialiasing:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 msgid "AA^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:82
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "High-quality frame buffer"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "Depth first:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:88
 msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:89
 msgid "DF^Disabled"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "DF^World"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:91
 msgid "DF^All"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:95
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:94
 msgid "Vertex Buffer Objects (VBOs)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "VBO^Off"
 msgstr ""
 
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:98
+msgid "Vertices, some Tris (compatible)"
+msgstr ""
+
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:103
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:105
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:107
 msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering (default: Vertex and Triangles)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
-msgid "Vertices, some Tris (compatible)"
-msgstr ""
-
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
 msgid "Vertices"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:106
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:104
 msgid "Vertices and Triangles"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
 msgid "Brightness:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
 msgid "Brightness of black (default: 0)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:112
 msgid "Contrast:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
 msgid "Brightness of white (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:118
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
 msgid "Gamma:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black (default: 1.125)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:124
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:122
 msgid "Contrast boost:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "By how much to multiply the contrast in dark areas (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:128
 msgid "Saturation:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:131
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:135
 msgid "LIT^Ambient:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:137
 msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat (default: 4)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Intensity:"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:143
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:141
 msgid "Global rendering brightness (default: 1)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:144
 msgid "Wait for GPU to finish each frame"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:145
 msgid ""
 "Make the CPU wait for the GPU to finish each frame, can help with some "
 "strange input or video lag on some machines (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:149
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:147
 msgid "Use OpenGL 2.0 shaders (GLSL)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Use GLSL to handle color control"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:153
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:151
 msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot (default: disabled)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid "Psycho coloring (easter egg)"
 msgstr ""
 
-#: qcsrc/menu/xonotic/dialog_settings_video.qc:161
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:159
 msgid "Trippy vertices (easter egg)"
 msgstr ""
 
index 3735e55349da0713a11e59317ead64ebe0d13610..5bd49b8ff4af75e2ece339e0d1e1f7eafa2966da 100644 (file)
@@ -410,7 +410,6 @@ pausable 0
 set g_spawnshieldtime 1 "number of seconds you are invincible after you spawned, this shield is lost after you fire"
 set g_antilag 2        "AntiLag (0 = no AntiLag, 1 = verified client side hit scan, 2 = server side hit scan in the past, 3 = unverified client side hit scan)"
 set g_antilag_nudge 0 "don't touch"
-set g_shootfromclient 2 "let client decide if it has the gun left or right; if set to 2, center handedness is allowed; see also cl_gunalign"
 set g_shootfromeye 0 "shots are fired from your eye/crosshair; visual gun position can still be influenced by cl_gunalign 1 and 2"
 set g_shootfromcenter 0 "weapon gets moved to the center, shots still come from the barrel of your weapon; visual gun position can still be influenced by cl_gunalign 1 and 2"
 set g_shootfromfixedorigin "" "if set to a string like 0 y z, the gun is moved to the given y and z coordinates. If set to a string like x y z, the whole shot origin is used"
@@ -1340,6 +1339,12 @@ set g_weapon_charge_colormod_red_full 1
 set g_weapon_charge_colormod_green_full -0.5
 set g_weapon_charge_colormod_blue_full -1
 
+// frozen
+set g_frozen_revive_falldamage 0 "Enable reviving from this amount of fall damage"
+set g_frozen_revive_falldamage_health 40 "Amount of health player has if they revived from falling"
+set g_frozen_damage_trigger 1 "if 1, frozen players falling into the void will die instead of teleporting to spawn"
+set g_frozen_force 0.6 "How much to multiply the force on a frozen player with"
+
 // player statistics server URI
 set g_playerstats_uri "" "Output player statistics information to either: URL (with ://), console (with a dash like this: -), or supply a filename to output to data directory."
 
index 31a0f33d3b04116ccafc567b3e5bb0e8de509ab1..2d8d54067f17038c15779770e1381e08828c59d1 100644 (file)
@@ -380,11 +380,7 @@ set g_freezetag_revive_clearspeed 1.6 "Speed at which reviving progress gets los
 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
 set g_freezetag_team_spawns 0 "when 1, players spawn from the team spawnpoints of the map, if any"
diff --git a/gfx/menu/luma/icon_mod_MinstaGib.tga b/gfx/menu/luma/icon_mod_MinstaGib.tga
deleted file mode 100644 (file)
index ce8c2d5..0000000
Binary files a/gfx/menu/luma/icon_mod_MinstaGib.tga and /dev/null differ
diff --git a/gfx/menu/luma/icon_mod_NewToys.tga b/gfx/menu/luma/icon_mod_NewToys.tga
deleted file mode 100644 (file)
index c5f212c..0000000
Binary files a/gfx/menu/luma/icon_mod_NewToys.tga and /dev/null differ
diff --git a/gfx/menu/luma/icon_mod_Overkill.tga b/gfx/menu/luma/icon_mod_Overkill.tga
deleted file mode 100644 (file)
index aeeaeb8..0000000
Binary files a/gfx/menu/luma/icon_mod_Overkill.tga and /dev/null differ
diff --git a/gfx/menu/luma/icon_mod_minstagib.tga b/gfx/menu/luma/icon_mod_minstagib.tga
new file mode 100644 (file)
index 0000000..ce8c2d5
Binary files /dev/null and b/gfx/menu/luma/icon_mod_minstagib.tga differ
diff --git a/gfx/menu/luma/icon_mod_newtoys.tga b/gfx/menu/luma/icon_mod_newtoys.tga
new file mode 100644 (file)
index 0000000..c5f212c
Binary files /dev/null and b/gfx/menu/luma/icon_mod_newtoys.tga differ
diff --git a/gfx/menu/luma/icon_mod_overkill.tga b/gfx/menu/luma/icon_mod_overkill.tga
new file mode 100644 (file)
index 0000000..aeeaeb8
Binary files /dev/null and b/gfx/menu/luma/icon_mod_overkill.tga differ
diff --git a/gfx/menu/luminos/icon_mod_MinstaGib.tga b/gfx/menu/luminos/icon_mod_MinstaGib.tga
deleted file mode 100644 (file)
index 065b844..0000000
Binary files a/gfx/menu/luminos/icon_mod_MinstaGib.tga and /dev/null differ
diff --git a/gfx/menu/luminos/icon_mod_NewToys.tga b/gfx/menu/luminos/icon_mod_NewToys.tga
deleted file mode 100644 (file)
index 00acb71..0000000
Binary files a/gfx/menu/luminos/icon_mod_NewToys.tga and /dev/null differ
diff --git a/gfx/menu/luminos/icon_mod_Overkill.tga b/gfx/menu/luminos/icon_mod_Overkill.tga
deleted file mode 100644 (file)
index 42e92c6..0000000
Binary files a/gfx/menu/luminos/icon_mod_Overkill.tga and /dev/null differ
diff --git a/gfx/menu/luminos/icon_mod_minstagib.tga b/gfx/menu/luminos/icon_mod_minstagib.tga
new file mode 100644 (file)
index 0000000..065b844
Binary files /dev/null and b/gfx/menu/luminos/icon_mod_minstagib.tga differ
diff --git a/gfx/menu/luminos/icon_mod_newtoys.tga b/gfx/menu/luminos/icon_mod_newtoys.tga
new file mode 100644 (file)
index 0000000..00acb71
Binary files /dev/null and b/gfx/menu/luminos/icon_mod_newtoys.tga differ
diff --git a/gfx/menu/luminos/icon_mod_overkill.tga b/gfx/menu/luminos/icon_mod_overkill.tga
new file mode 100644 (file)
index 0000000..42e92c6
Binary files /dev/null and b/gfx/menu/luminos/icon_mod_overkill.tga differ
diff --git a/gfx/menu/wickedx/icon_mod_MinstaGib.tga b/gfx/menu/wickedx/icon_mod_MinstaGib.tga
deleted file mode 100644 (file)
index 065b844..0000000
Binary files a/gfx/menu/wickedx/icon_mod_MinstaGib.tga and /dev/null differ
diff --git a/gfx/menu/wickedx/icon_mod_NewToys.tga b/gfx/menu/wickedx/icon_mod_NewToys.tga
deleted file mode 100644 (file)
index 00acb71..0000000
Binary files a/gfx/menu/wickedx/icon_mod_NewToys.tga and /dev/null differ
diff --git a/gfx/menu/wickedx/icon_mod_Overkill.tga b/gfx/menu/wickedx/icon_mod_Overkill.tga
deleted file mode 100644 (file)
index 42e92c6..0000000
Binary files a/gfx/menu/wickedx/icon_mod_Overkill.tga and /dev/null differ
diff --git a/gfx/menu/wickedx/icon_mod_minstagib.tga b/gfx/menu/wickedx/icon_mod_minstagib.tga
new file mode 100644 (file)
index 0000000..065b844
Binary files /dev/null and b/gfx/menu/wickedx/icon_mod_minstagib.tga differ
diff --git a/gfx/menu/wickedx/icon_mod_newtoys.tga b/gfx/menu/wickedx/icon_mod_newtoys.tga
new file mode 100644 (file)
index 0000000..00acb71
Binary files /dev/null and b/gfx/menu/wickedx/icon_mod_newtoys.tga differ
diff --git a/gfx/menu/wickedx/icon_mod_overkill.tga b/gfx/menu/wickedx/icon_mod_overkill.tga
new file mode 100644 (file)
index 0000000..42e92c6
Binary files /dev/null and b/gfx/menu/wickedx/icon_mod_overkill.tga differ
diff --git a/gfx/menu/xaw/icon_mod_MinstaGib.tga b/gfx/menu/xaw/icon_mod_MinstaGib.tga
deleted file mode 100644 (file)
index 065b844..0000000
Binary files a/gfx/menu/xaw/icon_mod_MinstaGib.tga and /dev/null differ
diff --git a/gfx/menu/xaw/icon_mod_NewToys.tga b/gfx/menu/xaw/icon_mod_NewToys.tga
deleted file mode 100644 (file)
index 00acb71..0000000
Binary files a/gfx/menu/xaw/icon_mod_NewToys.tga and /dev/null differ
diff --git a/gfx/menu/xaw/icon_mod_Overkill.tga b/gfx/menu/xaw/icon_mod_Overkill.tga
deleted file mode 100644 (file)
index 42e92c6..0000000
Binary files a/gfx/menu/xaw/icon_mod_Overkill.tga and /dev/null differ
diff --git a/gfx/menu/xaw/icon_mod_minstagib.tga b/gfx/menu/xaw/icon_mod_minstagib.tga
new file mode 100644 (file)
index 0000000..065b844
Binary files /dev/null and b/gfx/menu/xaw/icon_mod_minstagib.tga differ
diff --git a/gfx/menu/xaw/icon_mod_newtoys.tga b/gfx/menu/xaw/icon_mod_newtoys.tga
new file mode 100644 (file)
index 0000000..00acb71
Binary files /dev/null and b/gfx/menu/xaw/icon_mod_newtoys.tga differ
diff --git a/gfx/menu/xaw/icon_mod_overkill.tga b/gfx/menu/xaw/icon_mod_overkill.tga
new file mode 100644 (file)
index 0000000..42e92c6
Binary files /dev/null and b/gfx/menu/xaw/icon_mod_overkill.tga differ
index af95bdef4782cdaa4cff2979072f70a1a60bd9d7..a43c6cff46fa58a65421361b1356a0ded506dc95 100644 (file)
@@ -1,18 +1,18 @@
-ast Asturian "Asturianu (61%)"
-de German "Deutsch (91%)"
-de_CH German "Deutsch (Schweiz) (91%)"
-en_AU en_AU "en_AU (78%)"
+ast Asturian "Asturianu (60%)"
+de German "Deutsch (90%)"
+de_CH German "Deutsch (Schweiz) (90%)"
+en_AU en_AU "en_AU (77%)"
 en English "English"
 es Spanish "Español (68%)"
 fr French "Français (98%)"
-it Italian "Italiano (98%)"
+it Italian "Italiano (97%)"
 hu Hungarian "Magyar (50%)"
 nl Dutch "Nederlands (45%)"
-pl Polish "Polski (61%)"
+pl Polish "Polski (60%)"
 pt Portuguese "Português (42%)"
 ro Romanian "Romana (90%)"
 fi Finnish "Suomi (35%)"
-el Greek "Ελληνική (26%)"
+el Greek "Ελληνική (25%)"
 be Belarusian "Беларуская (65%)"
 bg Bulgarian "Български (65%)"
 ru Russian "Русский (93%)"
index 3f623b276ed068bb3baeb4582680b37c495b0ea7..5b8d09312049202197e379e5cb616b504fb8892b 100644 (file)
@@ -31,7 +31,6 @@ void Draw_GrapplingHook(entity this)
        string tex;
        vector rgb;
        float t;
-       int s;
        vector vs;
        float intensity, offset;
 
@@ -44,10 +43,8 @@ void Draw_GrapplingHook(entity this)
 
        InterpolateOrigin_Do();
 
-       s = autocvar_cl_gunalign;
-       if(s != 1 && s != 2 && s != 4)
-               s = 3; // default value
-       --s;
+       int s = W_GetGunAlignment(world);
+
        switch(self.HookType)
        {
                default:
index 90be935df3b43528717b39aa53e0eefc1404ab4e..042536aa767e91250fbd49d7dc504e56869f057d 100644 (file)
@@ -13,7 +13,8 @@
 #include "../common/nades/all.qh"
 #include "../common/stats.qh"
 #include "../lib/csqcmodel/cl_player.qh"
-#include "../server/mutators/gamemode_ctf.qh"
+// TODO: remove
+#include "../server/mutators/mutator/gamemode_ctf.qc"
 
 
 /*
index c641bf61e0f5911d78310e943b9922e5a321b972..bcbe32bb9e6b189a90db26599f47aa1343a8ccdf 100644 (file)
@@ -130,6 +130,7 @@ void CSQC_Init(void)
 
        // needs to be done so early because of the constants they create
        static_init();
+       static_init_late();
 
        // precaches
 
@@ -678,11 +679,11 @@ void Ent_ReadSpawnPoint(float is_new) // entity for spawnpoint
        spn_origin.y = ReadShort();
        spn_origin.z = ReadShort();
 
-       if(is_new)
-       {
+       //if(is_new)
+       //{
                self.origin = spn_origin;
                setsize(self, PL_MIN_CONST, PL_MAX_CONST);
-               droptofloor();
+               //droptofloor();
 
                /*if(autocvar_cl_spawn_point_model) // needs a model first
                {
@@ -711,7 +712,7 @@ void Ent_ReadSpawnPoint(float is_new) // entity for spawnpoint
 
                        self.draw = Spawn_Draw;
                }
-       }
+       //}
 
        //printf("Ent_ReadSpawnPoint(is_new = %d); origin = %s, team = %d, effect = %d\n", is_new, vtos(self.origin), teamnum, self.cnt);
 }
index 0c3884f6797a489efb9b1ddb3f0d5fc4d711993a..5c110e2b8986547e93e16b0e3bc1ba96b4cf24ce 100644 (file)
 #include "../lib/csqcmodel/cl_player.qc"
 #include "../lib/csqcmodel/interpolate.qc"
 
-#include "../server/mutators/mutator_multijump.qc"
+// TODO: move to common
+#include "../server/mutators/mutator/mutator_multijump.qc"
+#define IMPLEMENTATION
+#include "../server/mutators/mutator/mutator_multijump.qc"
+#undef IMPLEMENTATION
 
 #include "../lib/warpzone/anglestransform.qc"
 #include "../lib/warpzone/client.qc"
index 7958d66f6a7c0114687a08f75da18a76bdf734de..93f60fe67ac1a7ee576fbe578e162c5348810cd3 100644 (file)
@@ -2,6 +2,9 @@
 
 #ifdef IMPLEMENTATION
 #ifdef SVQC
+int autocvar_g_nexball_goalleadlimit;
+#define autocvar_g_nexball_goallimit cvar("g_nexball_goallimit")
+
 float autocvar_g_nexball_basketball_bouncefactor;
 float autocvar_g_nexball_basketball_bouncestop;
 float autocvar_g_nexball_basketball_carrier_highspeed;
@@ -24,6 +27,15 @@ float autocvar_g_nexball_viewmodel_scale;
 float autocvar_g_nexball_tackling;
 vector autocvar_g_nexball_viewmodel_offset;
 
+float autocvar_g_balance_nexball_primary_animtime;
+float autocvar_g_balance_nexball_primary_refire;
+float autocvar_g_balance_nexball_primary_speed;
+float autocvar_g_balance_nexball_secondary_animtime;
+float autocvar_g_balance_nexball_secondary_force;
+float autocvar_g_balance_nexball_secondary_lifetime;
+float autocvar_g_balance_nexball_secondary_refire;
+float autocvar_g_balance_nexball_secondary_speed;
+
 void basketball_touch();
 void football_touch();
 void ResetBall();
@@ -883,15 +895,31 @@ float ball_customize()
                return true;
        }
 
-MUTATOR_HOOKFUNCTION(nexball_BallDrop)
+void nb_DropBall(entity player)
+{
+       if(player.ballcarried && g_nexball)
+               DropBall(player.ballcarried, player.origin, player.velocity);
+}
+
+MUTATOR_HOOKFUNCTION(nb, ClientDisconnect)
 {SELFPARAM();
-       if(self.ballcarried && g_nexball)
-               DropBall(self.ballcarried, self.origin, self.velocity);
+       nb_DropBall(self);
+       return false;
+}
 
-       return 0;
+MUTATOR_HOOKFUNCTION(nb, PlayerDies)
+{SELFPARAM();
+       nb_DropBall(self);
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(nb, MakePlayerObserver)
+{SELFPARAM();
+       nb_DropBall(self);
+       return false;
 }
 
-MUTATOR_HOOKFUNCTION(nexball_PlayerPreThink)
+MUTATOR_HOOKFUNCTION(nb, PlayerPreThink)
 {SELFPARAM();
        makevectors(self.v_angle);
        if(nexball_mode & NBM_BASKETBALL)
@@ -956,7 +984,7 @@ MUTATOR_HOOKFUNCTION(nexball_PlayerPreThink)
        return false;
 }
 
-MUTATOR_HOOKFUNCTION(nexball_PlayerSpawn)
+MUTATOR_HOOKFUNCTION(nb, PlayerSpawn)
 {SELFPARAM();
        self.weaponentity.weapons = '0 0 0';
 
@@ -971,7 +999,7 @@ MUTATOR_HOOKFUNCTION(nexball_PlayerSpawn)
 .float stat_sv_airspeedlimit_nonqw;
 .float stat_sv_maxspeed;
 
-MUTATOR_HOOKFUNCTION(nexball_PlayerPhysics)
+MUTATOR_HOOKFUNCTION(nb, PlayerPhysics)
 {SELFPARAM();
        if(self.ballcarried)
        {
@@ -981,15 +1009,17 @@ MUTATOR_HOOKFUNCTION(nexball_PlayerPhysics)
        return false;
 }
 
-MUTATOR_HOOKFUNCTION(nexball_ForbidThrowing)
+MUTATOR_HOOKFUNCTION(nb, ForbidThrowCurrentWeapon)
 {SELFPARAM();
-       if(self.weapon == WEP_NEXBALL.m_id)
-               return true;
+       return self.weapon == WEP_NEXBALL.m_id;
+}
 
-       return false;
+MUTATOR_HOOKFUNCTION(nb, ForbidDropCurrentWeapon)
+{SELFPARAM();
+       return self.weapon == WEP_MORTAR.m_id; // TODO: what is this for?
 }
 
-MUTATOR_HOOKFUNCTION(nexball_FilterItem)
+MUTATOR_HOOKFUNCTION(nb, FilterItem)
 {SELFPARAM();
        if(self.classname == "droppedweapon")
        if(self.weapon == WEP_NEXBALL.m_id)
@@ -998,16 +1028,37 @@ MUTATOR_HOOKFUNCTION(nexball_FilterItem)
        return false;
 }
 
-MUTATOR_DEFINITION(gamemode_nexball)
+MUTATOR_HOOKFUNCTION(nb, GetTeamCount)
+{
+       ret_string = "nexball_team";
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(nb, WantWeapon)
+{
+       ret_float = 0; // weapon is set a few lines later, apparently
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(nb, DropSpecialItems)
+{
+       if(frag_target.ballcarried)
+               DropBall(frag_target.ballcarried, frag_target.origin, frag_target.velocity);
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(nb, SendWaypoint)
+{
+       wp_sendflags &= ~0x80;
+       return false;
+}
+
+REGISTER_MUTATOR(nb, g_nexball)
 {
-       MUTATOR_HOOK(PlayerDies, nexball_BallDrop, CBC_ORDER_ANY);
-       MUTATOR_HOOK(MakePlayerObserver, nexball_BallDrop, CBC_ORDER_ANY);
-       MUTATOR_HOOK(ClientDisconnect, nexball_BallDrop, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerSpawn, nexball_PlayerSpawn, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerPreThink, nexball_PlayerPreThink, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerPhysics, nexball_PlayerPhysics, CBC_ORDER_ANY);
-       MUTATOR_HOOK(ForbidThrowCurrentWeapon, nexball_ForbidThrowing, CBC_ORDER_ANY);
-       MUTATOR_HOOK(FilterItem, nexball_FilterItem, CBC_ORDER_ANY);
+       ActivateTeamplay();
+       SetLimits(autocvar_g_nexball_goallimit, autocvar_g_nexball_goalleadlimit, -1, -1);
+       have_team_spawns = -1; // request team spawns
 
        MUTATOR_ONADD
        {
index 7d19c50e752292dc0b7e70ae826fa857556d6fba..58bf6ec4dd41032fdce793e9fce985bbbdb7604a 100644 (file)
@@ -4,8 +4,6 @@
 #include "weapon.qc"
 
 #ifdef SVQC
-MUTATOR_DECLARATION(gamemode_nexball);
-
 //EF_BRIGHTFIELD|EF_BRIGHTLIGHT|EF_DIMLIGHT|EF_BLUE|EF_RED|EF_FLAME
 const float BALL_EFFECTMASK = 1229;
 const vector BALL_MINS = '-16 -16 -16'; // The model is 24*24*24
index 1daf862b6dec7e0b5aae6e6d30bdc0a60dc6fb67..4f856670b8110ee26731dffc67b5305159439e6d 100644 (file)
@@ -611,13 +611,8 @@ float _MapInfo_GetTeamPlayBool(float t)
 
 void _MapInfo_Map_ApplyGametypeEx(string s, int pWantedType, int pThisType)
 {
-       string sa, k, v;
-       float p;
-       string fraglimit_normal;
-       string fraglimit_teams;
-
        MapInfo_Map_supportedGametypes |= pThisType;
-       if(!(pThisType & pWantedType))
+       if (!(pThisType & pWantedType))
                return;
 
        // reset all the cvars to their defaults
@@ -625,74 +620,60 @@ void _MapInfo_Map_ApplyGametypeEx(string s, int pWantedType, int pThisType)
        cvar_set("timelimit", cvar_defstring("timelimit"));
        cvar_set("leadlimit", cvar_defstring("leadlimit"));
        cvar_set("fraglimit", cvar_defstring("fraglimit"));
-       cvar_set("g_tdm_teams", cvar_defstring("g_tdm_teams"));
-       cvar_set("g_ca_teams", cvar_defstring("g_ca_teams"));
-       cvar_set("g_freezetag_teams", cvar_defstring("g_freezetag_teams"));
-       cvar_set("g_keyhunt_teams", cvar_defstring("g_keyhunt_teams"));
-       cvar_set("g_domination_default_teams", cvar_defstring("g_domination_default_teams"));
-       cvar_set("g_race_qualifying_timelimit", cvar_defstring("g_race_qualifying_timelimit"));
-
-       fraglimit_normal = string_null;
-       fraglimit_teams = string_null;
-
-       s = strcat(_MapInfo_GetDefaultEx(pWantedType), " ", s);
-       while(s != "")
-       {
-               sa = car(s);
-               s = cdr(s);
+       FOREACH(Gametypes, true, LAMBDA(it.m_parse_mapinfo(string_null, string_null)));
 
-               if(sa == "")
-                       continue;
+       string fraglimit_normal = string_null;
+       string fraglimit_teams = string_null;
 
-               p = strstrofs(sa, "=", 0);
-               if(p < 0)
-               {
-                       LOG_INFO("Invalid gametype setting in mapinfo for gametype ", MapInfo_Type_ToString(pWantedType), ": ", sa, "\n");
+       for (s = strcat(_MapInfo_GetDefaultEx(pWantedType), " ", s); s != ""; s = cdr(s)) {
+               string sa = car(s);
+               if (sa == "") continue;
+               int p = strstrofs(sa, "=", 0);
+               if (p < 0) {
+                       LOG_WARNINGF("Invalid gametype setting in mapinfo for gametype %s: %s\n", MapInfo_Type_ToString(pWantedType), sa);
                        continue;
                }
-               k = substring(sa, 0, p);
-               v = substring(sa, p+1, -1);
-
-               if(k == "timelimit")
-               {
-                       cvar_set("timelimit", v);
-               }
-               else if(k == "leadlimit")
-               {
-                       cvar_set("leadlimit", v);
-               }
-               else if(k == "pointlimit" || k == "fraglimit" || k == "lives" || k == "laplimit" || k == "caplimit")
-               {
-                       fraglimit_normal = v;
-               }
-               else if(k == "teampointlimit" || k == "teamlaplimit")
-               {
-                       fraglimit_teams = v;
-               }
-               else if(k == "teams")
-               {
-                       cvar_set("g_tdm_teams", v);
-                       cvar_set("g_ca_teams", v);
-                       cvar_set("g_freezetag_teams", v);
-                       cvar_set("g_keyhunt_teams", v);
-                       cvar_set("g_domination_default_teams", v);
-                       cvar_set("g_invasion_teams", v);
-               }
-               else if(k == "qualifying_timelimit")
-               {
-                       cvar_set("g_race_qualifying_timelimit", v);
-               }
-               else if(k == "skill")
-               {
-                       // ignore
-               }
-               else
-               {
-                       LOG_INFO("Invalid gametype setting in mapinfo for gametype ", MapInfo_Type_ToString(pWantedType), ": ", sa, "\n");
+               string k = substring(sa, 0, p);
+               string v = substring(sa, p + 1, -1);
+               bool handled = true;
+               switch (k) {
+                       case "timelimit":
+                       {
+                               cvar_set("timelimit", v);
+                               break;
+                       }
+                       case "leadlimit":
+                       {
+                               cvar_set("leadlimit", v);
+                               break;
+                       }
+                       case "pointlimit":
+                       case "fraglimit":
+                       case "lives":
+                       case "laplimit":
+                       case "caplimit":
+                       {
+                               fraglimit_normal = v;
+                               break;
+                       }
+                       case "teampointlimit":
+                       case "teamlaplimit":
+                       {
+                               fraglimit_teams = v;
+                               break;
+                       }
+                       default:
+                       {
+                           handled = false;
+                           break;
+                       }
                }
+               FOREACH(Gametypes, true, LAMBDA(handled |= it.m_parse_mapinfo(k, v)));
+               if (!handled)
+            LOG_WARNINGF("Invalid gametype setting in mapinfo for gametype %s: %s\n", MapInfo_Type_ToString(pWantedType), sa);
        }
 
-       if(pWantedType == MAPINFO_TYPE_RACE && cvar("g_race_teams") >= 2)
+       if (pWantedType == MAPINFO_TYPE_RACE && cvar("g_race_teams") >= 2)
        {
                if(fraglimit_teams)
                        cvar_set("fraglimit", fraglimit_teams);
@@ -704,6 +685,12 @@ void _MapInfo_Map_ApplyGametypeEx(string s, int pWantedType, int pThisType)
        }
 }
 
+Gametype MapInfo_Type(int t)
+{
+       FOREACH(Gametypes, it.items == t, LAMBDA(return it));
+       return NULL;
+}
+
 int MapInfo_Type_FromString(string t)
 {
 #define deprecate(from, to) do { \
index 6faef6e05716be116e414e9db8615186f2b618e4..4107290fc0ee97d387b204e43795de8a6269eec5 100644 (file)
@@ -20,19 +20,23 @@ CLASS(Gametype, Object)
     /** game type description */
     ATTRIB(Gametype, gametype_description, string, string_null)
 
+    ATTRIB(Gametype, m_mutators, string, string_null)
+    ATTRIB(Gametype, m_parse_mapinfo, bool(string k, string v), func_null)
+
     METHOD(Gametype, describe, string(entity this)) { return this.gametype_description; }
 
     METHOD(Gametype, display, void(entity this, void(string name, string icon) returns)) {
         returns(this.message, strcat("gametype_", this.mdl));
     }
 
-    CONSTRUCTOR(Gametype, string hname, string sname, string g_name, bool gteamplay, string defaults, string gdescription)
+    CONSTRUCTOR(Gametype, string hname, string sname, string g_name, bool gteamplay, string mutators, string defaults, string gdescription)
     {
         CONSTRUCT(Gametype);
         this.netname = g_name;
         this.mdl = sname;
         this.message = hname;
         this.team = gteamplay;
+        this.m_mutators = mutators;
         this.model2 = defaults;
         this.gametype_description = gdescription;
     }
@@ -41,63 +45,132 @@ ENDCLASS(Gametype)
 REGISTRY(Gametypes, BIT(4))
 REGISTER_REGISTRY(RegisterGametypes)
 int MAPINFO_TYPE_ALL;
-#define REGISTER_GAMETYPE(hname, sname, g_name, NAME, gteamplay, defaults, gdescription)                    \
+#define REGISTER_GAMETYPE(hname, sname, g_name, NAME, gteamplay, mutators, defaults, gdescription)          \
     int MAPINFO_TYPE_##NAME;                                                                                \
+    bool NAME##_mapinfo(string k, string v) { return = false; }                                             \
     REGISTER(RegisterGametypes, MAPINFO_TYPE, Gametypes, g_name, m_id,                                      \
-        NEW(Gametype, hname, #sname, #g_name, gteamplay, defaults, gdescription)                            \
+        NEW(Gametype, hname, #sname, #g_name, gteamplay, #sname " " mutators, defaults, gdescription)       \
     ) {                                                                                                     \
         /* same as `1 << m_id` */                                                                           \
         MAPINFO_TYPE_##NAME = MAPINFO_TYPE_ALL + 1; MAPINFO_TYPE_ALL |= MAPINFO_TYPE_##NAME;                \
         this.items = MAPINFO_TYPE_##NAME;                                                                   \
-    }
+        this.m_parse_mapinfo = NAME##_mapinfo;                                                              \
+    }                                                                                                       \
+    [[accumulate]] bool NAME##_mapinfo(string k, string v)
 
 #define IS_GAMETYPE(NAME) \
     (MapInfo_LoadedGametype == MAPINFO_TYPE_##NAME)
 
-REGISTER_GAMETYPE(_("Deathmatch"),dm,g_dm,DEATHMATCH,false,"timelimit=20 pointlimit=30 leadlimit=0",_("Score as many frags as you can."));
-#define g_dm IS_GAMETYPE(DEATHMATCH)
+REGISTER_GAMETYPE(_("Deathmatch"),dm,g_dm,DEATHMATCH,false,"","timelimit=20 pointlimit=30 leadlimit=0",_("Score as many frags as you can"));
 
-REGISTER_GAMETYPE(_("Last Man Standing"),lms,g_lms,LMS,false,"timelimit=20 lives=9 leadlimit=0",_("Survive and kill until the enemies have no lives left."));
-#define g_lms IS_GAMETYPE(LMS)
+REGISTER_GAMETYPE(_("Last Man Standing"),lms,g_lms,LMS,false,"","timelimit=20 lives=9 leadlimit=0",_("Survive and kill until the enemies have no lives left"));
 
-REGISTER_GAMETYPE(_("Race"),rc,g_race,RACE,false,"timelimit=20 qualifying_timelimit=5 laplimit=7 teamlaplimit=15 leadlimit=0",_("Race against other players to the finish line."));
+REGISTER_GAMETYPE(_("Race"),rc,g_race,RACE,false,"","timelimit=20 qualifying_timelimit=5 laplimit=7 teamlaplimit=15 leadlimit=0",_("Race against other players to the finish line"))
+{
+    if (!k) {
+       cvar_set("g_race_qualifying_timelimit", cvar_defstring("g_race_qualifying_timelimit"));
+        return true;
+    }
+    switch (k) {
+        case "qualifying_timelimit":
+            cvar_set("g_race_qualifying_timelimit", v);
+            return true;
+    }
+}
 #define g_race IS_GAMETYPE(RACE)
 
-REGISTER_GAMETYPE(_("Race CTS"),cts,g_cts,CTS,false,"timelimit=20 skill=-1",_("Race for fastest time."));
+REGISTER_GAMETYPE(_("Race CTS"),cts,g_cts,CTS,false,"","timelimit=20",_("Race for fastest time."));
 #define g_cts IS_GAMETYPE(CTS)
 
-REGISTER_GAMETYPE(_("Team Deathmatch"),tdm,g_tdm,TEAM_DEATHMATCH,true,"timelimit=20 pointlimit=50 teams=2 leadlimit=0",_("Help your team score the most frags against the enemy team."));
+REGISTER_GAMETYPE(_("Team Deathmatch"),tdm,g_tdm,TEAM_DEATHMATCH,true,"","timelimit=20 pointlimit=50 teams=2 leadlimit=0",_("Help your team score the most frags against the enemy team"))
+{
+    if (!k) {
+        cvar_set("g_tdm_teams", cvar_defstring("g_tdm_teams"));
+        return true;
+    }
+    switch (k) {
+        case "teams":
+            cvar_set("g_tdm_teams", v);
+            return true;
+    }
+}
 #define g_tdm IS_GAMETYPE(TEAM_DEATHMATCH)
 
-REGISTER_GAMETYPE(_("Capture the Flag"),ctf,g_ctf,CTF,true,"timelimit=20 caplimit=10 leadlimit=6",_("Find and bring the enemy flag to your base to capture it, defend your base from the other team."));
+REGISTER_GAMETYPE(_("Capture the Flag"),ctf,g_ctf,CTF,true,"","timelimit=20 caplimit=10 leadlimit=6",_("Find and bring the enemy flag to your base to capture it, defend your base from the other team"));
 #define g_ctf IS_GAMETYPE(CTF)
 
-REGISTER_GAMETYPE(_("Clan Arena"),ca,g_ca,CA,true,"timelimit=20 pointlimit=10 teams=2 leadlimit=0",_("Kill all enemy teammates to win the round."));
+REGISTER_GAMETYPE(_("Clan Arena"),ca,g_ca,CA,true,"","timelimit=20 pointlimit=10 teams=2 leadlimit=0",_("Kill all enemy teammates to win the round"))
+{
+    if (!k) {
+        cvar_set("g_ca_teams", cvar_defstring("g_ca_teams"));
+        return true;
+    }
+    switch (k) {
+        case "teams":
+            cvar_set("g_ca_teams", v);
+            return true;
+    }
+}
 #define g_ca IS_GAMETYPE(CA)
 
-REGISTER_GAMETYPE(_("Domination"),dom,g_domination,DOMINATION,true,"timelimit=20 pointlimit=200 teams=2 leadlimit=0",_("Capture and defend all the control points to win."));
-#define g_domination IS_GAMETYPE(DOMINATION)
+REGISTER_GAMETYPE(_("Domination"),dom,g_domination,DOMINATION,true,"","timelimit=20 pointlimit=200 teams=2 leadlimit=0",_("Capture and defend all the control points to win"))
+{
+    if (!k) {
+        cvar_set("g_domination_default_teams", cvar_defstring("g_domination_default_teams"));
+        return true;
+    }
+    switch (k) {
+        case "teams":
+            cvar_set("g_domination_default_teams", v);
+            return true;
+    }
+}
 
-REGISTER_GAMETYPE(_("Key Hunt"),kh,g_keyhunt,KEYHUNT,true,"timelimit=20 pointlimit=1000 teams=3 leadlimit=0",_("Gather all the keys to win the round."));
-#define g_keyhunt IS_GAMETYPE(KEYHUNT)
+REGISTER_GAMETYPE(_("Key Hunt"),kh,g_keyhunt,KEYHUNT,true,"","timelimit=20 pointlimit=1000 teams=3 leadlimit=0",_("Gather all the keys to win the round"))
+{
+    if (!k) {
+       cvar_set("g_keyhunt_teams", cvar_defstring("g_keyhunt_teams"));
+       return true;
+    }
+    switch (k) {
+        case "teams":
+            cvar_set("g_keyhunt_teams", v);
+            return true;
+    }
+}
 
-REGISTER_GAMETYPE(_("Assault"),as,g_assault,ASSAULT,true,"timelimit=20",_("Destroy obstacles to find and destroy the enemy power core before time runs out."));
+REGISTER_GAMETYPE(_("Assault"),as,g_assault,ASSAULT,true,"","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,true,"pointlimit=1 timelimit=20",_("Capture control points to reach and destroy the enemy generator."));
-#define g_onslaught IS_GAMETYPE(ONSLAUGHT)
+REGISTER_GAMETYPE(_("Onslaught"),ons,g_onslaught,ONSLAUGHT,true,"","pointlimit=1 timelimit=20",_("Capture control points to reach and destroy the enemy generator"));
 
-REGISTER_GAMETYPE(_("Nexball"),nb,g_nexball,NEXBALL,true,"timelimit=20 pointlimit=5 leadlimit=0",_("Shoot and kick the ball into the enemies goal, keep your goal clean."));
+REGISTER_GAMETYPE(_("Nexball"),nb,g_nexball,NEXBALL,true,"","timelimit=20 pointlimit=5 leadlimit=0",_("Shoot and kick the ball into the enemies goal, keep your goal clean"));
 #define g_nexball IS_GAMETYPE(NEXBALL)
 
-REGISTER_GAMETYPE(_("Freeze Tag"),ft,g_freezetag,FREEZETAG,true,"timelimit=20 pointlimit=10 teams=2 leadlimit=0",_("Kill enemies to freeze them, stand next to teammates to revive them, freeze the most enemies to win."));
+REGISTER_GAMETYPE(_("Freeze Tag"),ft,g_freezetag,FREEZETAG,true,"","timelimit=20 pointlimit=10 teams=2 leadlimit=0",_("Kill enemies to freeze them, stand next to teammates to revive them, freeze the most enemies to win"))
+{
+    if (!k) {
+        cvar_set("g_freezetag_teams", cvar_defstring("g_freezetag_teams"));
+        return true;
+    }
+    switch (k) {
+        case "teams":
+            cvar_set("g_freezetag_teams", v);
+            return true;
+    }
+}
 #define g_freezetag IS_GAMETYPE(FREEZETAG)
 
-REGISTER_GAMETYPE(_("Keepaway"),ka,g_keepaway,KEEPAWAY,true,"timelimit=20 pointlimit=30",_("Hold the ball to get points for kills."));
-#define g_keepaway IS_GAMETYPE(KEEPAWAY)
+REGISTER_GAMETYPE(_("Keepaway"),ka,g_keepaway,KEEPAWAY,true,"","timelimit=20 pointlimit=30",_("Hold the ball to get points for kills"));
 
-REGISTER_GAMETYPE(_("Invasion"),inv,g_invasion,INVASION,false,"pointlimit=50 teams=0",_("Survive against waves of monsters."));
-#define g_invasion IS_GAMETYPE(INVASION)
+REGISTER_GAMETYPE(_("Invasion"),inv,g_invasion,INVASION,false,"","pointlimit=50 teams=0",_("Survive against waves of monsters"))
+{
+    switch (k) {
+        case "teams":
+            cvar_set("g_invasion_teams", v);
+            return true;
+    }
+}
 
 const int MAPINFO_FEATURE_WEAPONS       = 1; // not defined for instagib-only maps
 const int MAPINFO_FEATURE_VEHICLES      = 2;
@@ -163,6 +236,7 @@ string MapInfo_ListAllAllowedMaps(float pFlagsRequired, float pFlagsForbidden);
 // gets a gametype from a string
 string _MapInfo_GetDefaultEx(float t);
 float _MapInfo_GetTeamPlayBool(float t);
+Gametype MapInfo_Type(int t);
 float MapInfo_Type_FromString(string t);
 string MapInfo_Type_Description(float t);
 string MapInfo_Type_ToString(float t);
index 39a928a85749b98f4299e728d583f9d6e4aaa47c..05eb4346db90d2cf958358410ec2d02e5546879a 100644 (file)
@@ -3,7 +3,7 @@
 
 #include "monster.qh"
 
-REGISTRY(Monsters, BIT(3))
+REGISTRY(Monsters, BIT(4))
 REGISTER_REGISTRY(RegisterMonsters)
 const int MON_FIRST = 1;
 #define MON_LAST (Monsters_COUNT - 1)
index 1155c6427108eb51320c3c382e3789d3e2b52683..ac642fd3cbee0586793d5bf9639d6cadc02bdd23 100644 (file)
@@ -11,7 +11,7 @@
     #include "../../server/autocvars.qh"
     #include "../../server/defs.qh"
     #include "../deathtypes/all.qh"
-    #include "../../server/mutators/mutators_include.qh"
+    #include "../../server/mutators/all.qh"
        #include "../../server/steerlib.qh"
        #include "../turrets/sv_turrets.qh"
        #include "../turrets/util.qh"
@@ -571,7 +571,6 @@ vector Monster_Move_Target(entity targ)
                        || (self.enemy.takedamage == DAMAGE_NO)
                        || (vlen(self.origin - targ_origin) > self.target_range)
                        || ((trace_fraction < 1) && (trace_ent != self.enemy)))
-                       //|| (time > self.ctf_droptime + autocvar_g_ctf_pass_timelimit)) // TODO: chase timelimit?
                {
                        self.enemy = world;
                        self.pass_distance = 0;
index f6fa534d6164a36c6fab9b8897e8ce4693104140..ce98cd508e90a9fe0314e70d1baaa09a0cecc8e8 100644 (file)
@@ -119,7 +119,6 @@ ENDCLASS(CallbackChain)
 
 void RegisterHooks() {};
 void RegisterCallbacks() {};
-void RegisterMutators() {};
 
 #define _MUTATOR_HOOKABLE(id, ...) CallbackChain HOOK_##id; bool __Mutator_Send_##id(__VA_ARGS__)
 #define MUTATOR_HOOKABLE(id, params) \
@@ -145,23 +144,23 @@ typedef bool(int) mutatorfunc_t;
 
 CLASS(Mutator, Object)
     ATTRIB(Mutator, m_id, int, 0)
-    ATTRIB(Mutator, mutatorname, string, string_null)
+    ATTRIB(Mutator, m_name, string, string_null)
     ATTRIB(Mutator, mutatorfunc, mutatorfunc_t, func_null)
     ATTRIB(Mutator, mutatorcheck, bool(), func_null)
     CONSTRUCTOR(Mutator, string _name, mutatorfunc_t func) {
         CONSTRUCT(Mutator);
-        this.mutatorname = _name;
+        this.m_name = _name;
         this.mutatorfunc = func;
     }
 ENDCLASS(Mutator)
 
-const int MAX_MUTATORS = 30;
-Mutator loaded_mutators[MAX_MUTATORS];
+REGISTRY(Mutators, BITS(6))
+Mutator loaded_mutators[Mutators_MAX];
 
 bool Mutator_Add(Mutator mut)
 {
     int j = -1;
-    for (int i = 0; i < MAX_MUTATORS; ++i) {
+    for (int i = 0; i < Mutators_MAX; ++i) {
         if (loaded_mutators[i] == mut)
             return true; // already added
         if (!(loaded_mutators[i]))
@@ -188,10 +187,10 @@ bool Mutator_Add(Mutator mut)
 void Mutator_Remove(Mutator mut)
 {
     int i;
-    for (i = 0; i < MAX_MUTATORS; ++i)
+    for (i = 0; i < Mutators_MAX; ++i)
         if (loaded_mutators[i] == mut)
             break;
-    if (i >= MAX_MUTATORS) {
+    if (i >= Mutators_MAX) {
         backtrace("WARNING: removing not-added mutator\n");
         return;
     }
@@ -203,16 +202,6 @@ void Mutator_Remove(Mutator mut)
     }
 }
 
-#define MUTATOR_DECLARATION(name) \
-    Mutator MUTATOR_##name
-#define MUTATOR_DEFINITION(name) \
-    bool MUTATORFUNCTION_##name(int mode); \
-    [[accumulate]] void RegisterMutators() { MUTATOR_##name = NEW(Mutator, #name, MUTATORFUNCTION_##name); } \
-    [[last]] bool MUTATORFUNCTION_##name(int mode)
-
-const int MUTATORS_MAX = MAX_MUTATORS;
-noref entity MUTATORS[MUTATORS_MAX], MUTATORS_first, MUTATORS_last;
-noref int MUTATORS_COUNT;
 #define REGISTER_MUTATOR(id, dependence) \
     bool MUTATORFUNCTION_##id##_hooks(int mode) { return = false; } \
     bool MUTATORFUNCTION_##id(int mode) { \
@@ -220,7 +209,7 @@ noref int MUTATORS_COUNT;
         bool ret = MUTATORFUNCTION_##id##_hooks(mode); if (ret) return ret; \
     } \
     bool MUTATOR_##id##_check() { return dependence; } \
-    REGISTER(RegisterMutators, MUTATOR, MUTATORS, id, m_id, NEW(Mutator, #id, MUTATORFUNCTION_##id)) \
+    REGISTER(RegisterMutators, MUTATOR, Mutators, id, m_id, NEW(Mutator, #id, MUTATORFUNCTION_##id)) \
     { this.mutatorcheck = MUTATOR_##id##_check; } \
     [[accumulate]] bool MUTATORFUNCTION_##id(int mode)
 
@@ -231,7 +220,7 @@ STATIC_INIT(Mutators) {
 }
 
 STATIC_INIT_LATE(Mutators) {
-    FOREACH(MUTATORS, it.mutatorcheck(), LAMBDA(Mutator_Add(it)));
+    FOREACH(Mutators, it.mutatorcheck(), LAMBDA(Mutator_Add(it)));
 }
 
 #define MUTATOR_ONADD                   if (mode == MUTATOR_ADDING)
@@ -249,10 +238,6 @@ STATIC_INIT_LATE(Mutators) {
 #define MUTATOR_HOOKFUNCTION(...) \
     EVAL(OVERLOAD(MUTATOR_HOOKFUNCTION, __VA_ARGS__))
 
-#define MUTATOR_HOOKFUNCTION_1(name) \
-    _MUTATOR_CALLBACK(name, HOOKFUNCTION_##name) \
-    bool HOOKFUNCTION_##name()
-
 #define MUTATOR_HOOKFUNCTION_2(mut, cb) \
     MUTATOR_HOOKFUNCTION_3(mut, cb, CBC_ORDER_ANY)
 
index 2acb1839b2ddd65ede7c5dce5f35d7ed440e70b7..9d5caef000380495b5b24ce91db02d07ed316db9 100644 (file)
@@ -472,7 +472,7 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, BuildMutatorsPrettyString)
 
 MUTATOR_HOOKFUNCTION(mutator_instagib, SetModname)
 {
-       modname = "instagib";
+       modname = "InstaGib";
        return true;
 }
 
index b83c96a61679cf413e902ded6fc46182802be533..f0b768c5741986aca921eb5a77be1ee83e73947c 100644 (file)
@@ -12,11 +12,17 @@ bool WaypointSprite_SendEntity(entity this, entity to, float sendflags)
 
     sendflags = sendflags & 0x7F;
 
-    if (g_nexball)
-        sendflags &= ~0x80;
-    else if (self.max_health || (self.pain_finished && (time < self.pain_finished + 0.25)))
+    if (self.max_health || (self.pain_finished && (time < self.pain_finished + 0.25)))
         sendflags |= 0x80;
 
+    int f = 0;
+    if(self.currentammo)
+        f |= 1; // hideable
+    if(self.exteriormodeltoclient == to)
+        f |= 2; // my own
+
+    MUTATOR_CALLHOOK(SendWaypoint, this, to, sendflags, f);
+
     WriteByte(MSG_ENTITY, sendflags);
     WriteByte(MSG_ENTITY, self.wp_extra);
 
@@ -62,27 +68,6 @@ bool WaypointSprite_SendEntity(entity this, entity to, float sendflags)
         WriteCoord(MSG_ENTITY, self.fade_time);
         WriteCoord(MSG_ENTITY, self.teleport_time);
         WriteShort(MSG_ENTITY, self.fade_rate); // maxdist
-        float f = 0;
-        if (self.currentammo)
-            f |= 1; // hideable
-        if (self.exteriormodeltoclient == to)
-            f |= 2; // my own
-        if (g_onslaught)
-        {
-            if (self.owner.classname == "onslaught_controlpoint")
-            {
-                entity wp_owner = self.owner;
-                entity e = WaypointSprite_getviewentity(to);
-                if (SAME_TEAM(e, wp_owner) && wp_owner.goalentity.health >= wp_owner.goalentity.max_health) { f |= 2; }
-                if (!ons_ControlPoint_Attackable(wp_owner, e.team)) { f |= 2; }
-            }
-            if (self.owner.classname == "onslaught_generator")
-            {
-                entity wp_owner = self.owner;
-                if (wp_owner.isshielded && wp_owner.health >= wp_owner.max_health) { f |= 2; }
-                if (wp_owner.health <= 0) { f |= 2; }
-            }
-        }
         WriteByte(MSG_ENTITY, f);
     }
 
@@ -993,7 +978,7 @@ void WaypointSprite_Reset()
 {SELFPARAM();
     // if a WP wants to time out, let it time out immediately; other WPs ought to be reset/killed by their owners
 
-    if (self.fade_time) // there was there before: || g_keyhunt, do we really need this?
+    if (self.fade_time)
         WaypointSprite_Kill(self);
 }
 
index 600ddaa1b3237301833480c7ef92cb901333b1a0..811e7007c63e21b69548a607de73d3918698efa2 100644 (file)
@@ -7,7 +7,7 @@
     #include "../server/constants.qh"
     #include "../server/defs.qh"
     #include "notifications.qh"
-    #include "../server/mutators/mutators_include.qh"
+    #include "../server/mutators/all.qh"
 #endif
 
 // ================================================
index 54a7002056f9b681e4a741034ec24656911a6742..b3954d2eefd8cead759f5cde23e747fc8b463a64 100644 (file)
@@ -975,17 +975,6 @@ void SpecialCommand()
 #endif
 }
 
-void PM_check_race_movetime(void)
-{SELFPARAM();
-#ifdef SVQC
-       self.race_movetime_frac += PHYS_INPUT_TIMELENGTH;
-       float f = floor(self.race_movetime_frac);
-       self.race_movetime_frac -= f;
-       self.race_movetime_count += f;
-       self.race_movetime = self.race_movetime_frac + self.race_movetime_count;
-#endif
-}
-
 float PM_check_specialcommand(float buttons)
 {SELFPARAM();
 #ifdef SVQC
@@ -1145,40 +1134,6 @@ void PM_check_blocked(void)
 #endif
 }
 
-#ifdef SVQC
-float speedaward_lastsent;
-float speedaward_lastupdate;
-#endif
-void PM_check_race(void)
-{SELFPARAM();
-#ifdef SVQC
-       if(!(g_cts || g_race))
-               return;
-       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 = (g_cts) ? CTS_RECORD : RACE_RECORD;
-               race_send_speedaward(MSG_ALL);
-               speedaward_lastsent = speedaward_speed;
-               if (speedaward_speed > speedaward_alltimebest && speedaward_uid != "")
-               {
-                       speedaward_alltimebest = speedaward_speed;
-                       speedaward_alltimebest_holder = speedaward_holder;
-                       speedaward_alltimebest_uid = speedaward_uid;
-                       db_put(ServerProgsDB, strcat(GetMapname(), rr, "speed/speed"), ftos(speedaward_alltimebest));
-                       db_put(ServerProgsDB, strcat(GetMapname(), rr, "speed/crypto_idfp"), speedaward_alltimebest_uid);
-                       race_send_speedaward_alltimebest(MSG_ALL);
-               }
-       }
-#endif
-}
-
 void PM_check_vortex(void)
 {SELFPARAM();
 #ifdef SVQC
@@ -1675,7 +1630,6 @@ void PM_Main()
                        return;
 #endif
 
-       PM_check_race_movetime();
 #ifdef SVQC
        anticheat_physics();
 #endif
@@ -1708,17 +1662,7 @@ void PM_Main()
        if (IS_PLAYER(self))
 #endif
        {
-#ifdef SVQC
-               if (self.race_penalty)
-                       if (time > self.race_penalty)
-                               self.race_penalty = 0;
-#endif
-
                bool not_allowed_to_move = false;
-#ifdef SVQC
-               if (self.race_penalty)
-                       not_allowed_to_move = true;
-#endif
 #ifdef SVQC
                if (time < game_starttime)
                        not_allowed_to_move = true;
@@ -1893,10 +1837,6 @@ void PM_Main()
        else
                PM_air(buttons_prev, maxspeed_mod);
 
-#ifdef SVQC
-       if (!IS_OBSERVER(self))
-               PM_check_race();
-#endif
        PM_check_vortex();
 
 :end
index 257de8be5708c52bf2a11e1410f7173a179fa53a..ebecb18e317e3da64b8999a4624914722d298a0a 100644 (file)
@@ -33,6 +33,17 @@ void target_music_reset()
        if(self.targetname == "")
                target_music_sendto(MSG_ALL, 1);
 }
+void target_music_kill()
+{
+       for(self = world; (self = find(self, classname, "target_music")); )
+       {
+               self.volume = 0;
+               if(self.targetname == "")
+                       target_music_sendto(MSG_ALL, 1);
+               else
+                       target_music_sendto(MSG_ALL, 0);
+       }
+}
 void target_music_use()
 {
        if(!activator)
index 712d412f6ac4b003daee36eca37de96aa33b804a..d46c460554c83d26829ecc0083cec760926017e4 100644 (file)
@@ -23,6 +23,9 @@ void Ent_TriggerMusic_Think();
 void Ent_TriggerMusic_Remove();
 
 void Ent_ReadTriggerMusic();
+
+#elif defined(SVQC)
+void target_music_kill();
 #endif
 
 #endif
index 3261520d7a19e951ebdd198c7293facdf38a1de0..bc5821c809383597f1b8d1d92b0fea2229b86436 100644 (file)
@@ -23,6 +23,10 @@ void multi_trigger()
                return;         // allready been triggered
        }
 
+       if(self.spawnflags & 16384)
+       if(!IS_PLAYER(self.enemy))
+               return; // only players
+
        if (self.classname == "trigger_secret")
        {
                if (!IS_PLAYER(self.enemy))
index e1c23c7ab0e476022d01e7bf501a6cb362d612b8..ec7ce3711e95f21c13a0834703bb4962045c9afb 100644 (file)
@@ -708,9 +708,8 @@ float turret_validate_target(entity e_turret, entity e_target, float validate_fl
        if(e_target.alpha <= 0.3)
                return -1;
 
-       if(g_onslaught)
-               if (substring(e_target.classname, 0, 10) == "onslaught_") // don't attack onslaught targets, that's the player's job!
-                       return - 3;
+       if(MUTATOR_CALLHOOK(TurretValidateTarget, e_turret, e_target, validate_flags))
+               return ret_float;
 
        if (validate_flags & TFL_TARGETSELECT_NO)
                return -4;
@@ -1019,24 +1018,9 @@ void turret_fire()
 
 void turret_think()
 {SELFPARAM();
-       entity e;
-
        self.nextthink = time + self.ticrate;
 
-       // ONS uses somewhat backwards linking.
-       if (teamplay)
-       {
-               if (g_onslaught)
-                       if (self.target)
-                       {
-                               e = find(world, targetname,self.target);
-                               if (e != world)
-                                       self.team = e.team;
-                       }
-
-               if (self.team != self.tur_head.team)
-                       turret_respawn();
-       }
+       MUTATOR_CALLHOOK(TurretThink, self);
 
 #ifdef TURRET_DEBUG
        if (self.tur_debug_tmr1 < time)
@@ -1065,7 +1049,7 @@ void turret_think()
        if (self.shoot_flags & TFL_SHOOT_HITALLVALID)
        {
                // Do a self.turret_fire for every valid target.
-               e = findradius(self.origin,self.target_range);
+               entity e = findradius(self.origin,self.target_range);
                while (e)
                {
                        if(e.takedamage)
index e603cb16c195a3ce3c3067e1f4f112979f0724b9..ffbc0712da186a0d5d73972c7f385ed3498b016e 100644 (file)
@@ -39,7 +39,7 @@
     #include "../../server/defs.qh"
     #include "../notifications.qh"
     #include "../deathtypes/all.qh"
-    #include "../../server/mutators/mutators_include.qh"
+    #include "../../server/mutators/all.qh"
     #include "../mapinfo.qh"
     #include "../../server/command/common.qh"
     #include "../../lib/csqcmodel/sv_model.qh"
index 16b507d14eee683e65c13e28a42399efdd48054f..97c1999f84299fc98642f2c2597b84891f215cef 100644 (file)
@@ -142,6 +142,20 @@ vector findperpendicular(vector v)
        return normalize(cliptoplane(p, v));
 }
 
+int W_GetGunAlignment(entity player)
+{
+#ifdef SVQC
+       int gunalign = player.cvar_cl_gunalign;
+#else
+       int gunalign = autocvar_cl_gunalign;
+#endif
+       if(gunalign < 1 || gunalign > 4)
+               gunalign = 3; // default value
+       --gunalign;
+
+       return gunalign;
+}
+
 vector W_CalculateSpread(vector forward, float spread, float spreadfactor, float spreadstyle)
 {
        float sigma;
index d91d22c67c2c0491c9da5bad2b5d2d09ad034aae..4feed9fc549e16a48d44c204435f4a83e21672d7 100644 (file)
@@ -2,4 +2,5 @@
 #define CALCULATIONS_H
 vector damage_explosion_calcpush(vector explosion_f, vector target_v, float speedfactor);
 vector W_CalculateSpread(vector forward, float spread, float spreadfactor, float spreadstyle);
+int W_GetGunAlignment(entity player);
 #endif
index 99eb17d031b89453a0d2da13ec56fd7fedb83702..8d8f4c43b47737354e23fe19c897d6916c75cedb 100644 (file)
@@ -1156,11 +1156,7 @@ void Ent_ReadArcBeam(float isnew)
 
        if(isnew)
        {
-               // calculate shot origin offset from gun alignment
-               int gunalign = autocvar_cl_gunalign;
-               if(gunalign != 1 && gunalign != 2 && gunalign != 4)
-                       gunalign = 3; // default value
-               --gunalign;
+               int gunalign = W_GetGunAlignment(world);
 
                self.beam_shotorigin = arc_shotorigin[gunalign];
 
index 49b8ef7798bccac4f833edb868f31cb79c7161fd..9bc9ca2aefdc29f1cd96ffa5d8cbb0af8497659e 100644 (file)
@@ -41,6 +41,7 @@
 #include "int.qh"
 #include "iter.qh"
 #include "lazy.qh"
+#include "linkedlist.qh"
 #include "log.qh"
 #include "math.qh"
 #include "misc.qh"
index ae4e55ac1cad74e41fa261429444c545ce10f6fc..c39ee879708a8aba8f0d4fa2b6a9370a91d8c952 100644 (file)
@@ -28,6 +28,7 @@
 #include "../../client/defs.qh"
 #include "../../client/main.qh"
 #include "../../common/constants.qh"
+#include "../../common/physics.qh"
 #include "../../common/stats.qh"
 #include "../../common/triggers/trigger/viewloc.qh"
 #include "../../common/util.qh"
diff --git a/qcsrc/lib/linkedlist.qh b/qcsrc/lib/linkedlist.qh
new file mode 100644 (file)
index 0000000..be57bb5
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef LINKEDLIST_H
+#define LINKEDLIST_H
+
+CLASS(LinkedListNode, Object)
+    ATTRIB(LinkedListNode, ll_data, entity, NULL)
+    ATTRIB(LinkedListNode, ll_prev, LinkedListNode, NULL)
+    ATTRIB(LinkedListNode, ll_next, LinkedListNode, NULL)
+ENDCLASS(LinkedListNode)
+
+CLASS(LinkedList, Object)
+    ATTRIB(LinkedList, ll_head, LinkedListNode, NULL);
+    ATTRIB(LinkedList, ll_tail, LinkedListNode, NULL);
+ENDCLASS(LinkedList)
+
+#define LL_NEW() NEW(LinkedList)
+
+/**
+ * Push to tail
+ */
+entity LL_PUSH(LinkedList this, entity e) {
+    LinkedListNode n = NEW(LinkedListNode);
+    n.ll_data = e;
+    n.ll_prev = this.ll_tail;
+    LinkedListNode tail = this.ll_tail;
+    if (tail) {
+        tail.ll_next = n;
+    } else {
+        this.ll_head = this.ll_tail = n;
+    }
+    return e;
+}
+
+/**
+ * Pop from tail
+ */
+entity LL_POP(LinkedList this) {
+    if (!this.ll_tail) return NULL;
+    LinkedListNode n = this.ll_tail;
+    entity e = n.ll_data;
+    LinkedListNode prev = n.ll_prev;
+    if (prev) {
+        prev.ll_next = NULL;
+    } else {
+        this.ll_head = this.ll_tail = NULL;
+    }
+    return e;
+}
+
+#define LL_EACH(list, cond, body) do {                                  \
+    noref int i = 0;                                                    \
+    for (entity _it = list.ll_head; _it; (_it = _it.ll_next, ++i)) {    \
+        noref entity it = _it.ll_data;                                  \
+        if (cond) { body }                                              \
+    }                                                                   \
+} while(0)
+
+#endif
index 04faffc4a07ef4bc02178706186af916b735ed7e..834de760f503e8a2739b3b3bcda3b448bc811566 100644 (file)
@@ -11,9 +11,9 @@ bool SendEntity_self(entity to, int sendflags) { return self.SendEntity3(self, t
 
 void Net_LinkEntity(entity e, bool docull, float dt, bool(entity this, entity to, int sendflags) sendfunc)
 {
-    if (!e.classname) e.classname = "net_linked";
+    if (e.classname == "") e.classname = "net_linked";
 
-    if (!e.model || !self.modelindex) {
+    if (e.model == "" || self.modelindex == 0) {
         vector mi = e.mins;
         vector ma = e.maxs;
         _setmodel(e, "null");
index d51a8717532677a9e55b54d9119096fd4b90a1d2..f7bcdcc296688e5ac8303a424284544561147e16 100644 (file)
@@ -1,17 +1,19 @@
 #ifndef STATIC_H
 #define STATIC_H
 
-void __static_init_early() { }
-void __static_init() { CALL_ACCUMULATED_FUNCTION(__static_init_early); }
+void __static_init() { }
 #define static_init() CALL_ACCUMULATED_FUNCTION(__static_init)
-#define REGISTER_REGISTRY(func) ACCUMULATE_FUNCTION(__static_init_early, func)
+void __static_init_late() {  }
+#define static_init_late() CALL_ACCUMULATED_FUNCTION(__static_init_late)
+
+#define REGISTER_REGISTRY(func) ACCUMULATE_FUNCTION(__static_init, func)
 
 #define _STATIC_INIT(where, func) \
     void _static_##func(); \
     ACCUMULATE_FUNCTION(where, _static_##func) \
     void _static_##func()
 
-#define STATIC_INIT(func)       _STATIC_INIT(__static_init_early,   func##_early)
-#define STATIC_INIT_LATE(func)  _STATIC_INIT(__static_init,         func)
+#define STATIC_INIT(func)       _STATIC_INIT(__static_init,         func)
+#define STATIC_INIT_LATE(func)  _STATIC_INIT(__static_init_late,    func##_late)
 
 #endif
index 87f1719b4e14779f5abe809d1c39d8a9b1b52bd5..9210e14b384c90e262ece0be368b87e397cd1178 100644 (file)
@@ -14,6 +14,7 @@ CLASS(ListBox, Item)
        ATTRIB(ListBox, focusable, float, 1)
        ATTRIB(ListBox, focusedItem, int, -1)
        ATTRIB(ListBox, focusedItemAlpha, float, 0.3)
+       METHOD(ListBox, setFocusedItem, void(entity, int));
        ATTRIB(ListBox, mouseMoveOffset, float, -1) // let know where the cursor is when the list scrolls without moving the cursor
        ATTRIB(ListBox, allowFocusSound, float, 1)
        ATTRIB(ListBox, selectedItem, int, 0)
@@ -21,6 +22,7 @@ CLASS(ListBox, Item)
        ATTRIB(ListBox, origin, vector, '0 0 0')
        ATTRIB(ListBox, scrollPos, float, 0) // measured in window heights, fixed when needed
        ATTRIB(ListBox, scrollPosTarget, float, 0)
+       METHOD(ListBox, isScrolling, bool(entity));
        ATTRIB(ListBox, needScrollToItem, float, -1)
        METHOD(ListBox, scrollToItem, void(entity, int));
        ATTRIB(ListBox, previousValue, float, 0)
@@ -53,6 +55,7 @@ CLASS(ListBox, Item)
        METHOD(ListBox, clickListBoxItem, void(entity, float, vector)); // item number, relative clickpos
        METHOD(ListBox, doubleClickListBoxItem, void(entity, float, vector)); // item number, relative clickpos
        METHOD(ListBox, setSelected, void(entity, float));
+       METHOD(ListBox, focusedItemChangeNotify, void(entity));
 
        METHOD(ListBox, getLastFullyVisibleItemAtScrollPos, float(entity, float));
        METHOD(ListBox, getFirstFullyVisibleItemAtScrollPos, float(entity, float));
@@ -84,6 +87,11 @@ ENDCLASS(ListBox)
 #endif
 
 #ifdef IMPLEMENTATION
+bool ListBox_isScrolling(entity me)
+{
+       return (me.scrollPos != me.scrollPosTarget);
+}
+
 void ListBox_scrollToItem(entity me, int i)
 {
        // scroll doesn't work properly until itemHeight is set to the correct value
@@ -163,7 +171,7 @@ float ListBox_keyDown(entity me, float key, float ascii, float shift)
        }
        else if(key == K_MWHEELDOWN)
        {
-               me.scrollPosTarget = min(me.scrollPosTarget + 0.5, me.getTotalHeight(me) - 1);
+               me.scrollPosTarget = min(me.scrollPosTarget + 0.5, max(0, me.getTotalHeight(me) - 1));
        }
        else if(key == K_PGUP || key == K_KP_PGUP)
        {
@@ -246,7 +254,7 @@ float ListBox_mouseMove(entity me, vector pos)
                me.mouseMoveOffset = pos.y;
        else
        {
-               me.focusedItem = -1;
+               me.setFocusedItem(me, -1);
                me.mouseMoveOffset = -1;
        }
        return 1;
@@ -278,7 +286,7 @@ float ListBox_mouseDrag(entity me, vector pos)
        else if(me.pressed == 2)
        {
                me.setSelected(me, me.getItemAtPos(me, me.scrollPos + pos.y));
-               me.focusedItem = me.selectedItem;
+               me.setFocusedItem(me, me.selectedItem);
                me.mouseMoveOffset = -1;
        }
        return 1;
@@ -317,10 +325,21 @@ float ListBox_mousePress(entity me, vector pos)
                me.pressed = 2;
                // an item has been clicked. Select it, ...
                me.setSelected(me, me.getItemAtPos(me, me.scrollPos + pos.y));
-               me.focusedItem = me.selectedItem;
+               me.setFocusedItem(me, me.selectedItem);
        }
        return 1;
 }
+void ListBox_setFocusedItem(entity me, int item)
+{
+       float focusedItem_save = me.focusedItem;
+       me.focusedItem = (item < me.nItems) ? item : -1;
+       if(focusedItem_save != me.focusedItem)
+       {
+               me.focusedItemChangeNotify(me);
+               if(me.focusedItem >= 0)
+                       me.focusedItemAlpha = SKINALPHA_LISTBOX_FOCUSED;
+       }
+}
 float ListBox_mouseRelease(entity me, vector pos)
 {
        if(me.pressed == 1)
@@ -334,7 +353,7 @@ float ListBox_mouseRelease(entity me, vector pos)
                // item dragging mode
                // select current one one last time...
                me.setSelected(me, me.getItemAtPos(me, me.scrollPos + pos.y));
-               me.focusedItem = me.selectedItem;
+               me.setFocusedItem(me, me.selectedItem);
                // and give it a nice click event
                if(me.nItems > 0)
                {
@@ -358,7 +377,7 @@ void ListBox_focusLeave(entity me)
        // by a mouse click on an item of the list
        // for example showing a dialog on right click
        me.pressed = 0;
-       me.focusedItem = -1;
+       me.setFocusedItem(me, -1);
        me.mouseMoveOffset = -1;
 }
 void ListBox_updateControlTopBottom(entity me)
@@ -407,12 +426,8 @@ void ListBox_draw(entity me)
        vector oldshift, oldscale;
 
        // we can't do this in mouseMove as the list can scroll without moving the cursor
-       float focusedItem_save = me.focusedItem;
        if(me.mouseMoveOffset != -1)
-               me.focusedItem = me.getItemAtPos(me, me.scrollPos + me.mouseMoveOffset);
-       if(me.focusedItem >= 0)
-       if(focusedItem_save != me.focusedItem)
-               me.focusedItemAlpha = SKINALPHA_LISTBOX_FOCUSED;
+               me.setFocusedItem(me, me.getItemAtPos(me, me.scrollPos + me.mouseMoveOffset));
 
        if(me.needScrollToItem >= 0)
        {
@@ -476,6 +491,10 @@ void ListBox_draw(entity me)
        SUPER(ListBox).draw(me);
 }
 
+void ListBox_focusedItemChangeNotify(entity me)
+{
+}
+
 void ListBox_clickListBoxItem(entity me, float i, vector where)
 {
        // template method
index fde2c3c1eb7594125c82cb2cac15eb99ae68284d..13d8fcd49ef2d1b154b544ad02c0d09f344b29f8 100644 (file)
@@ -82,6 +82,7 @@ void m_init()
 
        // needs to be done so early because of the constants they create
        static_init();
+       static_init_late();
 
        RegisterSLCategories();
 
@@ -407,7 +408,7 @@ vector menuTooltipOrigin;
 vector menuTooltipSize;
 float menuTooltipAlpha;
 string menuTooltipText;
-float menuTooltipState; // 0: static, 1: fading in, 2: fading out
+float menuTooltipState; // 0: static, 1: fading in, 2: fading out, 3: forced fading out
 float m_testmousetooltipbox(vector pos)
 {
        if(pos.x >= menuTooltipOrigin.x && pos.x < menuTooltipOrigin.x + menuTooltipSize.x)
@@ -534,6 +535,7 @@ string gettooltip()
        }
        return menuTooltipItem.tooltip;
 }
+string prev_tooltip;
 void m_tooltip(vector pos)
 {
        float f, i, w;
@@ -556,13 +558,30 @@ void m_tooltip(vector pos)
                menuTooltipAveragedMousePos = menuTooltipAveragedMousePos * (1 - f) + pos * f;
                f = vlen(pos - menuTooltipAveragedMousePos);
                if(f < 0.01)
+               {
                        it = m_findtooltipitem(main, pos);
+
+                       if(it.instanceOfListBox && it.isScrolling(it))
+                               it = world;
+
+                       if(it && prev_tooltip != it.tooltip)
+                       {
+                               // fade out if tooltip of a certain item has changed
+                               menuTooltipState = 3;
+                               if(prev_tooltip)
+                                       strunzone(prev_tooltip);
+                               prev_tooltip = strzone(it.tooltip);
+                       }
+                       else if(menuTooltipItem && !m_testmousetooltipbox(pos))
+                               menuTooltipState = 3; // fade out if mouse touches it
+
+               }
                else
                        it = NULL;
        }
        fontsize = '1 0 0' * (SKINFONTSIZE_TOOLTIP / conwidth) + '0 1 0' * (SKINFONTSIZE_TOOLTIP / conheight);
 
-       // float menuTooltipState; // 0: static, 1: fading in, 2: fading out
+       // float menuTooltipState; // 0: static, 1: fading in, 2: fading out, 3: forced fading out
        if(it != menuTooltipItem)
        {
                switch(menuTooltipState)
@@ -613,18 +632,15 @@ void m_tooltip(vector pos)
        else if(menuTooltipState == 2) // re-fade in?
                menuTooltipState = 1;
 
-       if(menuTooltipItem)
-               if(!m_testmousetooltipbox(pos))
-                       menuTooltipState = 2; // fade out if mouse touches it
-
        switch(menuTooltipState)
        {
-               case 1:
+               case 1: // fade in
                        menuTooltipAlpha = bound(0, menuTooltipAlpha + 5 * frametime, 1);
                        if(menuTooltipAlpha == 1)
                                menuTooltipState = 0;
                        break;
-               case 2:
+               case 2: // fade out
+               case 3: // forced fade out
                        menuTooltipAlpha = bound(0, menuTooltipAlpha - 2 * frametime, 1);
                        if(menuTooltipAlpha == 0)
                        {
index 62b85269d48fe14ae7df8778dfb8567b61329ea9..8638ab14b7aacd642b5b914643c47f4ad354dc79 100644 (file)
@@ -50,7 +50,8 @@ void Join_Click(entity btn, entity me);
 #ifdef IMPLEMENTATION
 void XonoticServerInfoDialog_loadServerInfo(entity me, float i)
 {
-       float m, pure, freeslots, j, numh, maxp, numb, sflags;
+       bool pure_available;
+       float m, pure_violations, freeslots, j, numh, maxp, numb, sflags;
        string s, typestr, versionstr, k, v, modname;
 
        // ====================================
@@ -121,7 +122,8 @@ void XonoticServerInfoDialog_loadServerInfo(entity me, float i)
        me.currentServerCName = strzone(gethostcachestring(SLIST_FIELD_CNAME, i));
        me.cnameLabel.setText(me.cnameLabel, me.currentServerCName);
 
-       pure = -1;
+       pure_available = false;
+       pure_violations = -1;
        typestr = _("N/A");
        versionstr = _("N/A");
 
@@ -142,7 +144,10 @@ void XonoticServerInfoDialog_loadServerInfo(entity me, float i)
                k = substring(argv(j), 0, 1);
                v = substring(argv(j), 1, -1);
                if(k == "P")
-                       pure = stof(v);
+               {
+                       pure_available = true;
+                       pure_violations = stof(v);
+               }
                else if(k == "S")
                        freeslots = stof(v);
                else if(k == "F")
@@ -194,7 +199,7 @@ void XonoticServerInfoDialog_loadServerInfo(entity me, float i)
        me.currentServerVersion = strzone(versionstr);
        me.versionLabel.setText(me.versionLabel, me.currentServerVersion);
 
-       me.currentServerPure = ((pure < 0) ? _("N/A") : (pure == 0) ? _("Official") : sprintf(_("%d modified"), pure));
+       me.currentServerPure = ((!pure_available) ? _("N/A") : (pure_violations == 0) ? _("Official") : sprintf(_("%d modified"), pure_violations));
        me.currentServerPure = strzone(me.currentServerPure);
        me.pureLabel.setText(me.pureLabel, me.currentServerPure);
 
index 69ab6758226e19356fd8d9cd459c93dcd5f6ebe7..3c1503b29774472af5b256b37930c7736c454d81 100644 (file)
@@ -12,6 +12,13 @@ CLASS(SettingSource, DataSource)
         if (returns) returns(it.title, string_null);
         return it;
     }
+    METHOD(SettingSource, getEntryTooltip, entity(entity this, int i, void(string theTooltip) returns))
+    {
+        Lazy l = Settings[i];
+        entity it = l.m_get();
+        if (returns) returns(it.tooltip);
+        return it;
+    }
     METHOD(SettingSource, reload, int(entity this, string filter)) { return Settings_COUNT; }
 ENDCLASS(SettingSource)
 
@@ -30,15 +37,23 @@ CLASS(XonoticRegisteredSettingsList, XonoticListBox)
     ATTRIB(XonoticRegisteredSettingsList, source, DataSource, NULL)
        ATTRIB(XonoticRegisteredSettingsList, onChange, void(entity, entity), func_null)
        ATTRIB(XonoticRegisteredSettingsList, onChangeEntity, entity, NULL)
+       METHOD(XonoticRegisteredSettingsList, focusedItemChangeNotify, void(entity));
+
        string XonoticRegisteredSettingsList_cb_name;
-       void XonoticRegisteredSettingsList_cb(string _name, string _icon)
+       string XonoticRegisteredSettingsList_cb_tooltip;
+       void XonoticRegisteredSettingsList_getNameIcon_cb(string _name, string _icon)
        {
                XonoticRegisteredSettingsList_cb_name = _name;
        }
+       void XonoticRegisteredSettingsList_getTooltip_cb(string _tooltip)
+       {
+               XonoticRegisteredSettingsList_cb_tooltip = _tooltip;
+       }
+
        METHOD(XonoticRegisteredSettingsList, drawListBoxItem, void(entity this, int i, vector absSize, bool isSelected, bool isFocused))
        {
                if (!this.source) return;
-               if (!this.source.getEntry(this.source, i, XonoticRegisteredSettingsList_cb)) return;
+               if (!this.source.getEntry(this.source, i, XonoticRegisteredSettingsList_getNameIcon_cb)) return;
                string name = XonoticRegisteredSettingsList_cb_name;
                if (isSelected) {
                        draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
@@ -49,6 +64,26 @@ CLASS(XonoticRegisteredSettingsList, XonoticListBox)
                string s = draw_TextShortenToWidth(strdecolorize(name), 1, 0, this.realFontSize);
                draw_Text(this.realUpperMargin * eY + (0.5 * this.realFontSize.x) * eX, s, this.realFontSize, '1 1 1', SKINALPHA_TEXT, 0);
        }
+
+       METHOD(XonoticRegisteredSettingsList, focusedItemChangeNotify, void(entity this))
+       {
+               if (this.focusedItem == -1 || !this.source)
+               {
+                       clearTooltip(this);
+                       return;
+               }
+               if (!this.source.getEntryTooltip(this, this.focusedItem, XonoticRegisteredSettingsList_getTooltip_cb))
+               {
+                       clearTooltip(this);
+                       return;
+               }
+               string theTooltip = XonoticRegisteredSettingsList_cb_tooltip;
+               if(theTooltip != "")
+                       setZonedTooltip(this, theTooltip, string_null);
+               else
+                       clearTooltip(this);
+       }
+
        METHOD(XonoticRegisteredSettingsList, refilter, void(entity this))
        {
                if (!this.source) {
index 7b0794bdd782e671c84693eb6b60b715dbba2b48..45d7aee3048bd743f2cf018cd64d5643b3ec1859 100644 (file)
@@ -5,6 +5,7 @@ CLASS(XonoticGameModelSettingsTab, XonoticTab)
        METHOD(XonoticGameModelSettingsTab, fill, void(entity));
        METHOD(XonoticGameModelSettingsTab, showNotify, void(entity));
        ATTRIB(XonoticGameModelSettingsTab, title, string, _("Models"))
+       ATTRIB(XonoticGameModelSettingsTab, tooltip, string, _("Customize how players and items are displayed in game"))
        ATTRIB(XonoticGameModelSettingsTab, intendedWidth, float, 0.9)
        ATTRIB(XonoticGameModelSettingsTab, rows, float, 13)
        ATTRIB(XonoticGameModelSettingsTab, columns, float, 5)
index e2fdfa8e72b60e52881c621e77f57379080c5c99..5522e13c7f75f4fd81302e3af353c5f94e370a44 100644 (file)
@@ -11,6 +11,7 @@ CLASS(XonoticGametypeList, XonoticListBox)
        METHOD(XonoticGametypeList, saveCvars, void(entity));
        METHOD(XonoticGametypeList, keyDown, float(entity, float, float, float));
        METHOD(XonoticGametypeList, clickListBoxItem, void(entity, float, vector));
+       METHOD(XonoticGametypeList, focusedItemChangeNotify, void(entity));
 
        ATTRIB(XonoticGametypeList, realFontSize, vector, '0 0 0')
        ATTRIB(XonoticGametypeList, realUpperMargin, float, 0)
@@ -137,4 +138,11 @@ void XonoticGametypeList_clickListBoxItem(entity me, float i, vector where)
 {
        m_play_click_sound(MENU_SOUND_SELECT);
 }
+void XonoticGametypeList_focusedItemChangeNotify(entity me)
+{
+       if(me.focusedItem >= 0)
+               setZonedTooltip(me, MapInfo_Type_Description(GameType_GetID(me.focusedItem)), string_null);
+       else
+               clearTooltip(me);
+}
 #endif
index e2c6472092fe53d19068e426b1adbcff9a0f279a..2cee6162ff7a9d1d81e45677cd7bf1a1015dcc5d 100644 (file)
@@ -994,7 +994,7 @@ void XonoticServerList_drawListBoxItem(entity me, int i, vector absSize, bool is
        bool isv4, isv6;
        vector theColor;
        float theAlpha;
-       bool pure = false;
+       bool pure = false, pure_available = false;
        int freeslots = -1, sflags = -1, j, m;
        string s, typestr, versionstr, k, v, modname;
 
@@ -1065,7 +1065,10 @@ void XonoticServerList_drawListBoxItem(entity me, int i, vector absSize, bool is
                k = substring(argv(j), 0, 1);
                v = substring(argv(j), 1, -1);
                if(k == "P")
-                       pure = stob(v);
+               {
+                       pure = (stof(v) == 0);
+                       pure_available = true;
+               }
                else if(k == "S")
                        freeslots = stof(v);
                else if(k == "F")
@@ -1076,23 +1079,25 @@ void XonoticServerList_drawListBoxItem(entity me, int i, vector absSize, bool is
 
 #ifdef COMPAT_NO_MOD_IS_XONOTIC
        if(modname == "")
-               modname = "Xonotic";
+               modname = "xonotic";
 #endif
 
+       modname = strtolower(modname);
+
        /*
        SLIST_FIELD_MOD = gethostcacheindexforkey("mod");
        s = gethostcachestring(SLIST_FIELD_MOD, i);
        if(s != "data")
-               if(modname == "Xonotic")
+               if(modname == "xonotic")
                        modname = s;
        */
 
        // list the mods here on which the pure server check actually works
-       if(modname != "Xonotic")
-       if(modname != "InstaGib" || modname != "MinstaGib")
-       if(modname != "CTS")
-       if(modname != "NIX")
-       if(modname != "NewToys")
+       if(modname != "xonotic")
+       if(modname != "instagib" || modname != "minstagib")
+       if(modname != "cts")
+       if(modname != "nix")
+       if(modname != "newtoys")
                pure = false;
 
        if(gethostcachenumber(SLIST_FIELD_FREESLOTS, i) <= 0)
@@ -1201,9 +1206,11 @@ void XonoticServerList_drawListBoxItem(entity me, int i, vector absSize, bool is
        iconPos.x += iconSize.x;
 
        // Mod
-       if(modname == "Xonotic")
+       if(modname == "xonotic")
        {
-               if(pure == 0)
+               // Here, pure_available should always be set. If not, consider
+               // it an impurity.
+               if(pure_available && pure)
                        draw_Picture(iconPos, "icon_pure1", iconSize, '1 1 1', 1);
        }
        else
@@ -1212,10 +1219,13 @@ void XonoticServerList_drawListBoxItem(entity me, int i, vector absSize, bool is
                if(draw_PictureSize(icon) == '0 0 0')
                        icon = "icon_mod_";
 
-               if(pure == 0)
-                       draw_Picture(iconPos, icon, iconSize, '1 1 1', 1);
-               else
+               // In mods, pure_available not being present indicates
+               // non-support of the feature. Just show the mod icon as is
+               // then.
+               if(pure_available && !pure)
                        draw_Picture(iconPos, icon, iconSize, '1 1 1', SKINALPHA_SERVERLIST_ICON_NONPURE);
+               else
+                       draw_Picture(iconPos, icon, iconSize, '1 1 1', 1);
        }
 
        iconPos.x += iconSize.x;
index 7ecd7a9d0a4e6a03ead4ee4e262ddaea22136813..2b0bd6ce0ac6343140b40783b3ee4e6f7f62a9b6 100644 (file)
@@ -4,6 +4,7 @@
 CLASS(XonoticSlider, Slider)
        METHOD(XonoticSlider, configureXonoticSlider, void(entity, float, float, float, string, string));
        METHOD(XonoticSlider, setValue, void(entity, float));
+       METHOD(XonoticSlider, setValue_noAnim, void(entity, float));
        ATTRIB(XonoticSlider, fontSize, float, SKINFONTSIZE_NORMAL)
        ATTRIB(XonoticSlider, valueSpace, float, SKINWIDTH_SLIDERTEXT)
        ATTRIB(XonoticSlider, image, string, SKINGFX_SLIDER)
@@ -66,6 +67,14 @@ void XonoticSlider_setValue(entity me, float val)
                me.saveCvars(me);
        }
 }
+void XonoticSlider_setValue_noAnim(entity me, float val)
+{
+       if(val != me.value)
+       {
+               SUPER(XonoticSlider).setValue_noAnim(me, val);
+               me.saveCvars(me);
+       }
+}
 void XonoticSlider_loadCvars(entity me)
 {
        if (!me.cvarName)
index 8c4682ee0ffbf9a25d5692bdd18ed1c267014777..c21b07734fcd8c10749969a1972e2a8017d44a1b 100644 (file)
@@ -4,6 +4,7 @@
 CLASS(XonoticTextSlider, TextSlider)
        METHOD(XonoticTextSlider, configureXonoticTextSlider, void(entity, string, string));
        METHOD(XonoticTextSlider, setValue, void(entity, float));
+       METHOD(XonoticTextSlider, setValue_noAnim, void(entity, float));
        METHOD(XonoticTextSlider, configureXonoticTextSliderValues, void(entity));
        ATTRIB(XonoticTextSlider, fontSize, float, SKINFONTSIZE_NORMAL)
        ATTRIB(XonoticTextSlider, valueSpace, float, SKINWIDTH_SLIDERTEXT)
@@ -55,6 +56,14 @@ void XonoticTextSlider_setValue(entity me, float val)
                me.saveCvars(me);
        }
 }
+void XonoticTextSlider_setValue_noAnim(entity me, float val)
+{
+       if(val != me.value)
+       {
+               SUPER(XonoticTextSlider).setValue_noAnim(me, val);
+               me.saveCvars(me);
+       }
+}
 void XonoticTextSlider_loadCvars(entity me)
 {
        if (!me.cvarName)
index affd9437ed279b83675d7fdd3d9ab9b12d3cda6a..d3c9007f33c5896b2ab8360e3ae786ad56e44d75 100644 (file)
@@ -120,31 +120,8 @@ float autocvar_g_balance_health_regenstable;
 float autocvar_g_balance_health_rot;
 float autocvar_g_balance_health_rotlinear;
 float autocvar_g_balance_health_rotstable;
-float autocvar_g_balance_keyhunt_damageforcescale;
-float autocvar_g_balance_keyhunt_delay_collect;
-float autocvar_g_balance_keyhunt_delay_return;
-float autocvar_g_balance_keyhunt_delay_round;
-float autocvar_g_balance_keyhunt_delay_tracking;
-float autocvar_g_balance_keyhunt_dropvelocity;
-float autocvar_g_balance_keyhunt_maxdist;
-float autocvar_g_balance_keyhunt_protecttime;
-int autocvar_g_balance_keyhunt_score_capture;
-int autocvar_g_balance_keyhunt_score_carrierfrag;
-int autocvar_g_balance_keyhunt_score_collect;
-int autocvar_g_balance_keyhunt_score_destroyed;
-int autocvar_g_balance_keyhunt_score_destroyed_ownfactor;
-int autocvar_g_balance_keyhunt_score_push;
-float autocvar_g_balance_keyhunt_throwvelocity;
 float autocvar_g_balance_kill_delay;
 float autocvar_g_balance_kill_antispam;
-float autocvar_g_balance_nexball_primary_animtime;
-float autocvar_g_balance_nexball_primary_refire;
-float autocvar_g_balance_nexball_primary_speed;
-float autocvar_g_balance_nexball_secondary_animtime;
-float autocvar_g_balance_nexball_secondary_force;
-float autocvar_g_balance_nexball_secondary_lifetime;
-float autocvar_g_balance_nexball_secondary_refire;
-float autocvar_g_balance_nexball_secondary_speed;
 int autocvar_g_balance_nix_ammo_cells;
 int autocvar_g_balance_nix_ammo_plasma;
 int autocvar_g_balance_nix_ammo_fuel;
@@ -196,15 +173,6 @@ string autocvar_g_banned_list;
 bool autocvar_g_banned_list_idmode;
 bool autocvar_g_botclip_collisions;
 bool autocvar_g_bugrigs;
-float autocvar_g_ca_damage2score_multiplier;
-int autocvar_g_ca_point_leadlimit;
-int autocvar_g_ca_point_limit;
-float autocvar_g_ca_round_timelimit;
-bool autocvar_g_ca_spectate_enemies;
-int autocvar_g_ca_teams;
-int autocvar_g_ca_teams_override;
-bool autocvar_g_ca_team_spawns;
-float autocvar_g_ca_warmup;
 bool autocvar_g_campaign;
 #define autocvar_g_campaign_forceteam cvar("g_campaign_forceteam")
 int autocvar_g_campaign_skill;
@@ -223,112 +191,13 @@ float autocvar_g_chat_flood_spl_tell;
 int autocvar_g_chat_nospectators;
 bool autocvar_g_chat_teamcolors;
 bool autocvar_g_chat_tellprivacy;
-bool autocvar_g_ctf_allow_vehicle_carry;
-bool autocvar_g_ctf_allow_vehicle_touch;
-bool autocvar_g_ctf_allow_monster_touch;
-bool autocvar_g_ctf_throw;
-float autocvar_g_ctf_throw_angle_max;
-float autocvar_g_ctf_throw_angle_min;
-int autocvar_g_ctf_throw_punish_count;
-float autocvar_g_ctf_throw_punish_delay;
-float autocvar_g_ctf_throw_punish_time;
-float autocvar_g_ctf_throw_strengthmultiplier;
-float autocvar_g_ctf_throw_velocity_forward;
-float autocvar_g_ctf_throw_velocity_up;
-float autocvar_g_ctf_drop_velocity_up;
-float autocvar_g_ctf_drop_velocity_side;
-bool autocvar_g_ctf_oneflag_reverse;
-bool autocvar_g_ctf_portalteleport;
-bool autocvar_g_ctf_pass;
-float autocvar_g_ctf_pass_arc;
-float autocvar_g_ctf_pass_arc_max;
-float autocvar_g_ctf_pass_directional_max;
-float autocvar_g_ctf_pass_directional_min;
-float autocvar_g_ctf_pass_radius;
-float autocvar_g_ctf_pass_wait;
-bool autocvar_g_ctf_pass_request;
-float autocvar_g_ctf_pass_turnrate;
-float autocvar_g_ctf_pass_timelimit;
-float autocvar_g_ctf_pass_velocity;
-bool autocvar_g_ctf_dynamiclights;
-float autocvar_g_ctf_flag_collect_delay;
-float autocvar_g_ctf_flag_damageforcescale;
-bool autocvar_g_ctf_flag_dropped_waypoint;
-bool autocvar_g_ctf_flag_dropped_floatinwater;
-bool autocvar_g_ctf_flag_glowtrails;
-int autocvar_g_ctf_flag_health;
-bool autocvar_g_ctf_flag_return;
-float autocvar_g_ctf_flag_return_carried_radius;
-float autocvar_g_ctf_flag_return_time;
-bool autocvar_g_ctf_flag_return_when_unreachable;
-float autocvar_g_ctf_flag_return_damage;
-float autocvar_g_ctf_flag_return_damage_delay;
-float autocvar_g_ctf_flag_return_dropped;
-float autocvar_g_ctf_flagcarrier_auto_helpme_damage;
-float autocvar_g_ctf_flagcarrier_auto_helpme_time;
-float autocvar_g_ctf_flagcarrier_selfdamagefactor;
-float autocvar_g_ctf_flagcarrier_selfforcefactor;
-float autocvar_g_ctf_flagcarrier_damagefactor;
-float autocvar_g_ctf_flagcarrier_forcefactor;
-//float autocvar_g_ctf_flagcarrier_waypointforenemy_spotting;
-bool autocvar_g_ctf_fullbrightflags;
-bool autocvar_g_ctf_ignore_frags;
-int autocvar_g_ctf_score_capture;
-int autocvar_g_ctf_score_capture_assist;
-int autocvar_g_ctf_score_kill;
-int autocvar_g_ctf_score_penalty_drop;
-int autocvar_g_ctf_score_penalty_returned;
-int autocvar_g_ctf_score_pickup_base;
-int autocvar_g_ctf_score_pickup_dropped_early;
-int autocvar_g_ctf_score_pickup_dropped_late;
-int autocvar_g_ctf_score_return;
-float autocvar_g_ctf_shield_force;
-float autocvar_g_ctf_shield_max_ratio;
-int autocvar_g_ctf_shield_min_negscore;
-bool autocvar_g_ctf_stalemate;
-int autocvar_g_ctf_stalemate_endcondition;
-float autocvar_g_ctf_stalemate_time;
-bool autocvar_g_ctf_reverse;
-float autocvar_g_ctf_dropped_capture_delay;
-float autocvar_g_ctf_dropped_capture_radius;
-float autocvar_g_cts_finish_kill_delay;
-bool autocvar_g_cts_selfdamage;
 bool autocvar_g_debug_bot_commands;
-int autocvar_g_domination_default_teams;
-bool autocvar_g_domination_disable_frags;
-int autocvar_g_domination_point_amt;
-bool autocvar_g_domination_point_fullbright;
-int autocvar_g_domination_point_leadlimit;
-bool autocvar_g_domination_roundbased;
-int 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;
-int autocvar_g_domination_teams_override;
 bool autocvar_g_forced_respawn;
 string autocvar_g_forced_team_blue;
 string autocvar_g_forced_team_otherwise;
 string autocvar_g_forced_team_pink;
 string autocvar_g_forced_team_red;
 string autocvar_g_forced_team_yellow;
-bool 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;
-bool autocvar_g_freezetag_revive_nade;
-float autocvar_g_freezetag_revive_nade_health;
-int autocvar_g_freezetag_point_leadlimit;
-int autocvar_g_freezetag_point_limit;
-float autocvar_g_freezetag_revive_extra_size;
-float autocvar_g_freezetag_revive_speed;
-float autocvar_g_freezetag_revive_clearspeed;
-float autocvar_g_freezetag_round_timelimit;
-int autocvar_g_freezetag_teams;
-int autocvar_g_freezetag_teams_override;
-bool autocvar_g_freezetag_team_spawns;
-float autocvar_g_freezetag_warmup;
 #define autocvar_g_friendlyfire cvar("g_friendlyfire")
 #define autocvar_g_friendlyfire_virtual cvar("g_friendlyfire_virtual")
 #define autocvar_g_friendlyfire_virtual_force cvar("g_friendlyfire_virtual_force")
@@ -347,35 +216,6 @@ float autocvar_g_jetpack_antigravity;
 int autocvar_g_jetpack_fuel;
 float autocvar_g_jetpack_maxspeed_side;
 float autocvar_g_jetpack_maxspeed_up;
-int autocvar_g_keepaway_ballcarrier_effects;
-float autocvar_g_keepaway_ballcarrier_damage;
-float autocvar_g_keepaway_ballcarrier_force;
-float autocvar_g_keepaway_ballcarrier_highspeed;
-float autocvar_g_keepaway_ballcarrier_selfdamage;
-float autocvar_g_keepaway_ballcarrier_selfforce;
-float autocvar_g_keepaway_noncarrier_damage;
-float autocvar_g_keepaway_noncarrier_force;
-float autocvar_g_keepaway_noncarrier_selfdamage;
-float autocvar_g_keepaway_noncarrier_selfforce;
-bool autocvar_g_keepaway_noncarrier_warn;
-int autocvar_g_keepaway_score_bckill;
-int autocvar_g_keepaway_score_killac;
-int autocvar_g_keepaway_score_timepoints;
-float autocvar_g_keepaway_score_timeinterval;
-float autocvar_g_keepawayball_damageforcescale;
-int autocvar_g_keepawayball_effects;
-float autocvar_g_keepawayball_respawntime;
-int autocvar_g_keepawayball_trail_color;
-int autocvar_g_keyhunt_point_leadlimit;
-bool autocvar_g_keyhunt_team_spawns;
-#define autocvar_g_keyhunt_point_limit cvar("g_keyhunt_point_limit")
-int autocvar_g_keyhunt_teams;
-int autocvar_g_keyhunt_teams_override;
-int autocvar_g_lms_extra_lives;
-bool autocvar_g_lms_join_anytime;
-int autocvar_g_lms_last_join;
-#define autocvar_g_lms_lives_override cvar("g_lms_lives_override")
-bool autocvar_g_lms_regenerate;
 #define autocvar_g_maplist cvar_string("g_maplist")
 bool autocvar_g_maplist_check_waypoints;
 int autocvar_g_maplist_index;
@@ -414,8 +254,6 @@ float autocvar_g_multijump_speed;
 float autocvar_g_multijump_maxspeed;
 float autocvar_g_multijump_dodging = 1;
 string autocvar_g_mutatormsg;
-int autocvar_g_nexball_goalleadlimit;
-#define autocvar_g_nexball_goallimit cvar("g_nexball_goallimit")
 //float autocvar_g_nick_flood_penalty;
 int autocvar_g_nick_flood_penalty_red;
 int autocvar_g_nick_flood_penalty_yellow;
@@ -445,10 +283,6 @@ int autocvar_g_projectiles_newton_style;
 float autocvar_g_projectiles_newton_style_2_maxfactor;
 float autocvar_g_projectiles_newton_style_2_minfactor;
 int autocvar_g_projectiles_spread_style;
-#define autocvar_g_race_laps_limit cvar("g_race_laps_limit")
-float autocvar_g_race_qualifying_timelimit;
-float autocvar_g_race_qualifying_timelimit_override;
-int autocvar_g_race_teams;
 float autocvar_g_respawn_delay_small;
 int autocvar_g_respawn_delay_small_count;
 float autocvar_g_respawn_delay_large;
@@ -461,7 +295,6 @@ float autocvar_g_respawn_ghosts_speed;
 int autocvar_g_respawn_waves;
 bool autocvar_g_running_guns;
 bool autocvar_g_shootfromcenter;
-int autocvar_g_shootfromclient;
 bool autocvar_g_shootfromeye;
 string autocvar_g_shootfromfixedorigin;
 int autocvar_g_showweaponspawns;
@@ -470,11 +303,6 @@ float autocvar_g_spawn_furthest;
 bool autocvar_g_spawn_useallspawns;
 bool autocvar_g_spawnpoints_auto_move_out_of_solid;
 #define autocvar_g_spawnshieldtime cvar("g_spawnshieldtime")
-bool autocvar_g_tdm_team_spawns;
-int autocvar_g_tdm_point_limit;
-int autocvar_g_tdm_point_leadlimit;
-int autocvar_g_tdm_teams;
-int autocvar_g_tdm_teams_override;
 float autocvar_g_teamdamage_resetspeed;
 float autocvar_g_teamdamage_threshold;
 bool autocvar_g_telefrags;
@@ -706,15 +534,6 @@ float autocvar_g_touchexplode_radius;
 float autocvar_g_touchexplode_damage;
 float autocvar_g_touchexplode_edgedamage;
 float autocvar_g_touchexplode_force;
-float autocvar_g_invasion_round_timelimit;
-int autocvar_g_invasion_teams;
-bool autocvar_g_invasion_team_spawns;
-float autocvar_g_invasion_spawnpoint_spawn_delay;
-#define autocvar_g_invasion_point_limit cvar("g_invasion_point_limit")
-float autocvar_g_invasion_warmup;
-int autocvar_g_invasion_monster_count;
-bool autocvar_g_invasion_zombies_only;
-float autocvar_g_invasion_spawn_delay;
 #define autocvar_g_bloodloss cvar("g_bloodloss")
 float autocvar_g_random_gravity_negative_chance;
 float autocvar_g_random_gravity_min;
@@ -792,30 +611,6 @@ float autocvar_g_spawn_near_teammate_distance;
 int autocvar_g_spawn_near_teammate_ignore_spawnpoint;
 float autocvar_g_spawn_near_teammate_ignore_spawnpoint_delay;
 float autocvar_g_spawn_near_teammate_ignore_spawnpoint_delay_death;
-float autocvar_g_onslaught_debug;
-float autocvar_g_onslaught_teleport_wait;
-bool autocvar_g_onslaught_spawn_at_controlpoints;
-bool autocvar_g_onslaught_spawn_at_generator;
-float autocvar_g_onslaught_cp_proxydecap;
-float autocvar_g_onslaught_cp_proxydecap_distance = 512;
-float autocvar_g_onslaught_cp_proxydecap_dps = 100;
-float autocvar_g_onslaught_spawn_at_controlpoints_chance = 0.5;
-float autocvar_g_onslaught_spawn_at_controlpoints_random;
-float autocvar_g_onslaught_spawn_at_generator_chance;
-float autocvar_g_onslaught_spawn_at_generator_random;
-float autocvar_g_onslaught_cp_buildhealth;
-float autocvar_g_onslaught_cp_buildtime;
-float autocvar_g_onslaught_cp_health;
-float autocvar_g_onslaught_cp_regen;
-float autocvar_g_onslaught_gen_health;
-float autocvar_g_onslaught_shield_force = 100;
-float autocvar_g_onslaught_allow_vehicle_touch;
-float autocvar_g_onslaught_round_timelimit;
-float autocvar_g_onslaught_point_limit;
-float autocvar_g_onslaught_warmup;
-float autocvar_g_onslaught_teleport_radius;
-float autocvar_g_onslaught_spawn_choose;
-float autocvar_g_onslaught_click_radius;
 int autocvar_g_spawn_near_teammate_ignore_spawnpoint_check_health;
 bool autocvar_g_spawn_near_teammate_ignore_spawnpoint_closetodeath;
 bool autocvar_g_physics_clientselect;
@@ -881,4 +676,8 @@ float autocvar_g_rm_laser_rapid_refire;
 float autocvar_g_rm_laser_rapid_delay;
 float autocvar_g_rm_laser_radius;
 float autocvar_g_rm_laser_force;
+float autocvar_g_frozen_revive_falldamage;
+int autocvar_g_frozen_revive_falldamage_health;
+bool autocvar_g_frozen_damage_trigger;
+float autocvar_g_frozen_force;
 #endif
index 07ea9091dc3f605f0bb56b7c759285480a432aeb..50e1d456f56e497720c5d153958518c48fac39f5 100644 (file)
@@ -4,7 +4,7 @@
 
 #include "../weapons/weaponsystem.qh"
 
-#include "../mutators/mutators_include.qh"
+#include "../mutators/all.qh"
 
 // traces multiple trajectories to find one that will impact the target
 // 'end' vector is the place it aims for,
index 3b2af5d92c41141ed4f08cab410c20d6324b6abb..c607de4f485988b24d9a310e34849881ed18a3f4 100644 (file)
@@ -19,7 +19,7 @@
 #include "../race.qh"
 #include "../t_items.qh"
 
-#include "../mutators/mutators_include.qh"
+#include "../mutators/all.qh"
 
 #include "../weapons/accuracy.qh"
 
@@ -566,19 +566,22 @@ void bot_calculate_stepheightvec(void)
 
 float bot_fixcount()
 {
-       entity head;
-       float realplayers, bots, activerealplayers;
-
-       activerealplayers = 0;
-       realplayers = 0;
-
-       FOR_EACH_REALCLIENT(head)
-       {
-               if(IS_PLAYER(head) || g_lms || head.caplayer == 1)
-                       ++activerealplayers;
-               ++realplayers;
+       int activerealplayers = 0;
+       int realplayers = 0;
+       if (MUTATOR_CALLHOOK(Bot_FixCount, activerealplayers, realplayers)) {
+               activerealplayers = bot_activerealplayers;
+               realplayers = bot_realplayers;
+       } else {
+               entity head;
+               FOR_EACH_REALCLIENT(head)
+               {
+                       if(IS_PLAYER(head))
+                               ++activerealplayers;
+                       ++realplayers;
+               }
        }
 
+       int bots;
        // add/remove bots if needed to make sure there are at least
        // minplayers+bot_number, or remove all bots if no one is playing
        // But don't remove bots immediately on level change, as the real players
index fb73954a1427109d13229a832daac7964fe812c5..2dd8c74b6250b8a660ab71a231b15864934e7e1a 100644 (file)
@@ -1,3 +1,2 @@
 #include "havocbot.qc"
-#include "role_keyhunt.qc"
 #include "roles.qc"
diff --git a/qcsrc/server/bot/havocbot/role_keyhunt.qc b/qcsrc/server/bot/havocbot/role_keyhunt.qc
deleted file mode 100644 (file)
index 0059dc9..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-#include "role_keyhunt.qh"
-
-#include "havocbot.qh"
-
-#include "../bot.qh"
-#include "../navigation.qh"
-
-#include "../../mutators/mutators_include.qh"
-
-void() havocbot_role_kh_carrier;
-void() havocbot_role_kh_defense;
-void() havocbot_role_kh_offense;
-void() havocbot_role_kh_freelancer;
-
-
-void havocbot_goalrating_kh(float ratingscale_team, float ratingscale_dropped, float ratingscale_enemy)
-{SELFPARAM();
-       entity head;
-       for (head = kh_worldkeylist; head; head = head.kh_worldkeynext)
-       {
-               if(head.owner == self)
-                       continue;
-               if(!kh_tracking_enabled)
-               {
-                       // if it's carried by our team we know about it
-                       // otherwise we have to see it to know about it
-                       if(!head.owner || head.team != self.team)
-                       {
-                               traceline(self.origin + self.view_ofs, head.origin, MOVE_NOMONSTERS, self);
-                               if (trace_fraction < 1 && trace_ent != head)
-                                       continue; // skip what I can't see
-                       }
-               }
-               if(!head.owner)
-                       navigation_routerating(head, ratingscale_dropped * BOT_PICKUP_RATING_HIGH, 100000);
-               else if(head.team == self.team)
-                       navigation_routerating(head.owner, ratingscale_team * BOT_PICKUP_RATING_HIGH, 100000);
-               else
-                       navigation_routerating(head.owner, ratingscale_enemy * BOT_PICKUP_RATING_HIGH, 100000);
-       }
-
-       havocbot_goalrating_items(1, self.origin, 10000);
-}
-
-void havocbot_role_kh_carrier()
-{SELFPARAM();
-       if(self.deadflag != DEAD_NO)
-               return;
-
-       if (!(self.kh_next))
-       {
-               LOG_TRACE("changing role to freelancer\n");
-               self.havocbot_role = havocbot_role_kh_freelancer;
-               self.havocbot_role_timeout = 0;
-               return;
-       }
-
-       if (self.bot_strategytime < time)
-       {
-               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
-               navigation_goalrating_start();
-
-               if(kh_Key_AllOwnedByWhichTeam() == self.team)
-                       havocbot_goalrating_kh(10, 0.1, 0.1); // bring home
-               else
-                       havocbot_goalrating_kh(4, 4, 1); // play defensively
-
-               navigation_goalrating_end();
-       }
-}
-
-void havocbot_role_kh_defense()
-{SELFPARAM();
-       if(self.deadflag != DEAD_NO)
-               return;
-
-       if (self.kh_next)
-       {
-               LOG_TRACE("changing role to carrier\n");
-               self.havocbot_role = havocbot_role_kh_carrier;
-               self.havocbot_role_timeout = 0;
-               return;
-       }
-
-       if (!self.havocbot_role_timeout)
-               self.havocbot_role_timeout = time + random() * 10 + 20;
-       if (time > self.havocbot_role_timeout)
-       {
-               LOG_TRACE("changing role to freelancer\n");
-               self.havocbot_role = havocbot_role_kh_freelancer;
-               self.havocbot_role_timeout = 0;
-               return;
-       }
-
-       if (self.bot_strategytime < time)
-       {
-               float key_owner_team;
-               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
-               navigation_goalrating_start();
-
-               key_owner_team = kh_Key_AllOwnedByWhichTeam();
-               if(key_owner_team == self.team)
-                       havocbot_goalrating_kh(10, 0.1, 0.1); // defend key carriers
-               else if(key_owner_team == -1)
-                       havocbot_goalrating_kh(4, 1, 0.1); // play defensively
-               else
-                       havocbot_goalrating_kh(0.1, 0.1, 10); // ATTACK ANYWAY
-
-               navigation_goalrating_end();
-       }
-}
-
-void havocbot_role_kh_offense()
-{SELFPARAM();
-       if(self.deadflag != DEAD_NO)
-               return;
-
-       if (self.kh_next)
-       {
-               LOG_TRACE("changing role to carrier\n");
-               self.havocbot_role = havocbot_role_kh_carrier;
-               self.havocbot_role_timeout = 0;
-               return;
-       }
-
-       if (!self.havocbot_role_timeout)
-               self.havocbot_role_timeout = time + random() * 10 + 20;
-       if (time > self.havocbot_role_timeout)
-       {
-               LOG_TRACE("changing role to freelancer\n");
-               self.havocbot_role = havocbot_role_kh_freelancer;
-               self.havocbot_role_timeout = 0;
-               return;
-       }
-
-       if (self.bot_strategytime < time)
-       {
-               float key_owner_team;
-
-               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
-               navigation_goalrating_start();
-
-               key_owner_team = kh_Key_AllOwnedByWhichTeam();
-               if(key_owner_team == self.team)
-                       havocbot_goalrating_kh(10, 0.1, 0.1); // defend anyway
-               else if(key_owner_team == -1)
-                       havocbot_goalrating_kh(0.1, 1, 4); // play offensively
-               else
-                       havocbot_goalrating_kh(0.1, 0.1, 10); // ATTACK! EMERGENCY!
-
-               navigation_goalrating_end();
-       }
-}
-
-void havocbot_role_kh_freelancer()
-{SELFPARAM();
-       if(self.deadflag != DEAD_NO)
-               return;
-
-       if (self.kh_next)
-       {
-               LOG_TRACE("changing role to carrier\n");
-               self.havocbot_role = havocbot_role_kh_carrier;
-               self.havocbot_role_timeout = 0;
-               return;
-       }
-
-       if (!self.havocbot_role_timeout)
-               self.havocbot_role_timeout = time + random() * 10 + 10;
-       if (time > self.havocbot_role_timeout)
-       {
-               if (random() < 0.5)
-               {
-                       LOG_TRACE("changing role to offense\n");
-                       self.havocbot_role = havocbot_role_kh_offense;
-               }
-               else
-               {
-                       LOG_TRACE("changing role to defense\n");
-                       self.havocbot_role = havocbot_role_kh_defense;
-               }
-               self.havocbot_role_timeout = 0;
-               return;
-       }
-
-       if (self.bot_strategytime < time)
-       {
-               float key_owner_team;
-
-               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
-               navigation_goalrating_start();
-
-               key_owner_team = kh_Key_AllOwnedByWhichTeam();
-               if(key_owner_team == self.team)
-                       havocbot_goalrating_kh(10, 0.1, 0.1); // defend anyway
-               else if(key_owner_team == -1)
-                       havocbot_goalrating_kh(1, 10, 4); // prefer dropped keys
-               else
-                       havocbot_goalrating_kh(0.1, 0.1, 10); // ATTACK ANYWAY
-
-               navigation_goalrating_end();
-       }
-}
-
-void havocbot_chooserole_kh()
-{SELFPARAM();
-       float r;
-
-       if(self.deadflag != DEAD_NO)
-               return;
-
-       r = random() * 3;
-       if (r < 1)
-               self.havocbot_role = havocbot_role_kh_offense;
-       else if (r < 2)
-               self.havocbot_role = havocbot_role_kh_defense;
-       else
-               self.havocbot_role = havocbot_role_kh_freelancer;
-}
diff --git a/qcsrc/server/bot/havocbot/role_keyhunt.qh b/qcsrc/server/bot/havocbot/role_keyhunt.qh
deleted file mode 100644 (file)
index f3136c6..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef ROLE_KEYHUNT_H
-#define ROLE_KEYHUNT_H
-
-entity kh_worldkeylist;
-.entity kh_worldkeynext;
-
-void havocbot_chooserole_kh();
-#endif
index a4357628eee88d6ae646e450f733e64f9363bd9c..acb24f51706a499bd0eaddf08ad340d98f072525 100644 (file)
@@ -1,6 +1,5 @@
 
 #include "havocbot.qh"
-#include "role_keyhunt.qh"
 
 #include "../bot.qh"
 #include "../navigation.qh"
@@ -237,10 +236,6 @@ void havocbot_chooserole()
 {SELFPARAM();
        LOG_TRACE("choosing a role...\n");
        self.bot_strategytime = 0;
-       if (MUTATOR_CALLHOOK(HavocBot_ChooseRole, self))
-               return;
-       else if (g_keyhunt)
-               havocbot_chooserole_kh();
-       else
+       if(!MUTATOR_CALLHOOK(HavocBot_ChooseRole, self))
                havocbot_chooserole_generic();
 }
index 64c7cec19e17ea2627faf89f40ca8d91bd95710a..8f34a7798b7fa90ceec7aeab4b0f3c1f74742f5d 100644 (file)
@@ -4,7 +4,7 @@
 #include "race.qh"
 #include "../common/triggers/teleporters.qh"
 
-#include "mutators/mutators_include.qh"
+#include "mutators/all.qh"
 
 #include "weapons/tracing.qh"
 
index c608c5b2c74a78325a2343556b1a679ff4137fd8..c4b078e14888a82fc1311584f3be5bd064bc7e0f 100644 (file)
@@ -208,7 +208,7 @@ void PutObserverInServer (void)
        self.frags = FRAGS_SPECTATOR;
        self.bot_attack = false;
 
-       MUTATOR_CALLHOOK(MakePlayerObserver);
+       bool mutator_returnvalue = MUTATOR_CALLHOOK(MakePlayerObserver);
 
        Portal_ClearAll(self);
 
@@ -226,7 +226,7 @@ void PutObserverInServer (void)
 
        WaypointSprite_PlayerDead();
 
-       if (!g_ca)  // don't reset teams when moving a ca player to the spectators
+       if(!mutator_returnvalue)  // mutator prevents resetting teams
                self.team = -1;  // move this as it is needed to log the player spectating in eventlog
 
        if(self.killcount != -666)
@@ -749,6 +749,8 @@ void SetNewParms (void)
 {
        // initialize parms for a new player
        parm1 = -(86400 * 366);
+
+       MUTATOR_CALLHOOK(SetNewParms);
 }
 
 /*
@@ -760,6 +762,8 @@ void SetChangeParms (void)
 {SELFPARAM();
        // save parms for level change
        parm1 = self.parm_idlesince - time;
+
+       MUTATOR_CALLHOOK(SetChangeParms);
 }
 
 /*
@@ -776,6 +780,8 @@ void DecodeLevelParms (void)
 
        // whatever happens, allow 60 seconds of idling directly after connect for map loading
        self.parm_idlesince = max(self.parm_idlesince, time - sv_maxidle + 60);
+
+       MUTATOR_CALLHOOK(DecodeLevelParms);
 }
 
 /*
@@ -884,14 +890,8 @@ void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto, -2
        if(g_race_qualifying || g_cts)
                killtime = 0;
 
-    if(g_cts && self.killindicator && self.killindicator.health == 1) // self.killindicator.health == 1 means that the kill indicator was spawned by CTS_ClientKill
-    {
-               remove(self.killindicator);
-               self.killindicator = world;
-
-        ClientKill_Now(); // allow instant kill in this case
-        return;
-    }
+    if(MUTATOR_CALLHOOK(ClientKill, self, killtime))
+       return;
 
        self.killindicator_teamchange = targetteam;
 
@@ -983,23 +983,10 @@ void ClientKill (void)
        ClientKill_TeamChange(0);
 }
 
-void CTS_ClientKill (entity e) // silent version of ClientKill, used when player finishes a CTS run. Useful to prevent cheating by running back to the start line and starting out with more speed
-{
-    e.killindicator = spawn();
-    e.killindicator.owner = e;
-    e.killindicator.think = KillIndicator_Think;
-    e.killindicator.nextthink = time + (e.lip) * 0.05;
-    e.killindicator.cnt = ceil(autocvar_g_cts_finish_kill_delay);
-    e.killindicator.health = 1; // this is used to indicate that it should be silent
-    e.lip = 0;
-}
-
 void FixClientCvars(entity e)
 {
        // send prediction settings to the client
        stuffcmd(e, "\nin_bindmap 0 0\n");
-       if(g_race || g_cts)
-               stuffcmd(e, "cl_cmd settemp cl_movecliptokeyboard 2\n");
        if(autocvar_g_antilag == 3) // client side hitscan
                stuffcmd(e, "cl_cmd settemp cl_prydoncursor_notrace 0\n");
        if(autocvar_sv_gentle)
@@ -1829,49 +1816,23 @@ void SetSpectator(entity player, entity spectatee)
 
 bool Spectate(entity pl)
 {SELFPARAM();
-       if(g_ca && !autocvar_g_ca_spectate_enemies && self.caplayer)
-       if(DIFF_TEAM(pl, self))
+       if(MUTATOR_CALLHOOK(SpectateSet, self, pl))
                return false;
+       pl = spec_player;
 
        SetSpectator(self, pl);
        return SpectateSet();
 }
 
-// Returns next available player to spectate if g_ca_spectate_enemies == 0
-entity CA_SpectateNext(entity start)
-{SELFPARAM();
-       if(SAME_TEAM(start, self))
-               return start;
-
-       other = start;
-       // continue from current player
-       while(other && DIFF_TEAM(other, self))
-               other = find(other, classname, "player");
-
-       if (!other)
-       {
-               // restart from begining
-               other = find(other, classname, "player");
-               while(other && DIFF_TEAM(other, self))
-                       other = find(other, classname, "player");
-       }
-
-       return other;
-}
-
 bool SpectateNext()
 {SELFPARAM();
        other = find(self.enemy, classname, "player");
 
-       if (g_ca && !autocvar_g_ca_spectate_enemies && self.caplayer)
-               // CA and ca players when spectating enemies is forbidden
-               other = CA_SpectateNext(other);
-       else
-       {
-               // other modes and ca spectators or spectating enemies is allowed
-               if (!other)
-                       other = find(other, classname, "player");
-       }
+       bool mutator_returnvalue = MUTATOR_CALLHOOK(SpectateNext, self, other);
+       other = spec_player;
+
+       if(!mutator_returnvalue && !other)
+               other = find(other, classname, "player");
 
        if(other) { SetSpectator(self, other); }
 
@@ -1891,27 +1852,24 @@ bool SpectatePrev()
        while(other && other != self.enemy)
                other = other.chain;
 
-       if (g_ca && !autocvar_g_ca_spectate_enemies && self.caplayer)
-       {
-               do { other = other.chain; }
-               while(other && DIFF_TEAM(other, self));
+       int mutator_returnvalue = MUTATOR_CALLHOOK(SpectatePrev, self, other, first);
+       other = spec_player;
 
-               if (!other)
+       switch(mutator_returnvalue)
+       {
+               case MUT_SPECPREV_FOUND: break;
+               case MUT_SPECPREV_RETURN: return true;
+               case MUT_SPECPREV_CONTINUE:
+               default:
                {
-                       other = first;
-                       while(other && DIFF_TEAM(other, self))
+                       if(other.chain)
                                other = other.chain;
-                       if(other == self.enemy)
-                               return true;
+                       else
+                               other = first;
+                       break;
                }
        }
-       else
-       {
-               if(other.chain)
-                       other = other.chain;
-               else
-                       other = first;
-       }
+
        SetSpectator(self, other);
        return SpectateSet();
 }
index 213a02945905db6e2ff65ab856cc236e3807ad74..1b462a329538ab3c6527a43b187a08f416d28804 100644 (file)
@@ -8,6 +8,4 @@ float CalcRotRegen(float current, float regenstable, float regenfactor, float re
 
 float Spectate(entity pl);
 
-void CTS_ClientKill (entity e);
-
 #endif
index 1b770121e8a8904b18ffe87312d271a8a885d741..9ab358635b2e47bbbd22030c68da337b5b4a4689 100644 (file)
 
 #include "../common/animdecide.qh"
 
+void Drop_Special_Items(entity player)
+{
+       // called when the player has become stuck or frozen
+       // so objective items aren't stuck with the player
+
+       MUTATOR_CALLHOOK(DropSpecialItems, player);
+}
+
 void CopyBody_Think(void)
 {SELFPARAM();
        if(self.CopyBody_nextthink && time > self.CopyBody_nextthink)
index ddfbe57950a0f46ff66ff83532dd89d9c1059bbd..e4eee69834d4e53632952f8520d8649df34b7bb4 100644 (file)
@@ -12,7 +12,7 @@
 #include "../scores.qh"
 #include "../teamplay.qh"
 
-#include "../mutators/mutators_include.qh"
+#include "../mutators/all.qh"
 
 #ifdef SVQC
        #include "../../common/vehicles/all.qh"
@@ -465,29 +465,13 @@ void ClientCommand_spectate(float request)
                {
                        if(IS_CLIENT(self))
                        {
-                               if(g_lms)
-                               {
-                                       if(self.lms_spectate_warning)
-                                       {
-                                               // for the forfeit message...
-                                               self.lms_spectate_warning = 2;
-                                               // mark player as spectator
-                                               PlayerScore_Add(self, SP_LMS_RANK, 666 - PlayerScore_Add(self, SP_LMS_RANK, 0));
-                                       }
-                                       else
-                                       {
-                                               self.lms_spectate_warning = 1;
-                                               sprint(self, "WARNING: you won't be able to enter the game again after spectating in LMS. Use the same command again to spectate anyway.\n");
-                                               return;
-                                       }
-                               }
+                               int mutator_returnvalue = MUTATOR_CALLHOOK(ClientCommand_Spectate, self);
 
-                               if((IS_PLAYER(self) || self.caplayer) && autocvar_sv_spectate == 1)
-                               {
-                                       if(self.caplayer && (IS_SPEC(self) || IS_OBSERVER(self)))
-                                               Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_CA_LEAVE);
+                               if(mutator_returnvalue == MUT_SPECCMD_RETURN)
+                                       return;
+
+                               if((IS_PLAYER(self) || mutator_returnvalue == MUT_SPECCMD_FORCE) && autocvar_sv_spectate == 1)
                                        ClientKill_TeamChange(-2); // observe
-                               }
                        }
                        return; // never fall through to usage
                }
index fee82a7e4b5933a4263b191b4e3fb543b9e97e18..8d804587232bb57bc1d03f6423969662a57586b8 100644 (file)
@@ -425,7 +425,7 @@ void CommonCommand_editmob(int request, entity caller, int argc)
                                case "butcher":
                                {
                                        if(caller) { print_to(caller, "This command is not available to players"); return; }
-                                       if(g_invasion) { print_to(caller, "This command does not work during an invasion!"); return; }
+                                       if(MUTATOR_CALLHOOK(AllowMobButcher)) { LOG_INFO(ret_string, "\n"); return; }
 
                                        int tmp_remcount = 0;
                                        entity tmp_entity;
index b3eeb1a69bdf2627042ceacb8daf94e107f7d55f..fd312bff6174b840d0c808f2370d01ee5407dc46 100644 (file)
 
 // See common.qc for their proper commands
 
-string getrecords(float page) // 50 records per page
+string getrecords(int page) // 50 records per page
 {
-       float rec = 0, r, i;
-       string h, s;
+       string s = "";
 
-       s = "";
-
-       if (g_ctf)
-       {
-               for (i = page * 200; i < MapInfo_count && i < page * 200 + 200; ++i)
-               {
-                       if (MapInfo_Get_ByID(i))
-                       {
-                               r = stof(db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, "/captimerecord/time")));
-
-                               if (!r)
-                                       continue;
-
-                               // TODO: uid2name
-                               h = db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, "/captimerecord/netname"));
-                               s = strcat(s, strpad(32, MapInfo_Map_bspname), " ", strpad(-6, ftos_decimals(r, 2)), " ", h, "\n");
-                               ++rec;
-                       }
-               }
-       }
-
-       if (g_race)
-       {
-               for (i = page * 200; i < MapInfo_count && i < page * 200 + 200; ++i)
-               {
-                       if (MapInfo_Get_ByID(i))
-                       {
-                               r = race_readTime(MapInfo_Map_bspname, 1);
-
-                               if (!r)
-                                       continue;
-
-                               h = race_readName(MapInfo_Map_bspname, 1);
-                               s = strcat(s, strpad(32, MapInfo_Map_bspname), " ", strpad(-8, TIME_ENCODED_TOSTRING(r)), " ", h, "\n");
-                               ++rec;
-                       }
-               }
-       }
-
-       if (g_cts)
-       {
-               for (i = page * 200; i < MapInfo_count && i < page * 200 + 200; ++i)
-               {
-                       if (MapInfo_Get_ByID(i))
-                       {
-                               r = race_readTime(MapInfo_Map_bspname, 1);
-
-                               if (!r)
-                                       continue;
-
-                               h = race_readName(MapInfo_Map_bspname, 1);
-                               s = strcat(s, strpad(32, MapInfo_Map_bspname), " ", strpad(-8, TIME_ENCODED_TOSTRING(r)), " ", h, "\n");
-                               ++rec;
-                       }
-               }
-       }
+       MUTATOR_CALLHOOK(GetRecords, page, s);
+       s = ret_string;
 
        MapInfo_ClearTemps();
 
index 21255e5ddf50e91d4bc12f44168340fd56ad8e40..cde2d6c45209150c5c61a4380bc09efe1a9d3f96 100644 (file)
@@ -20,7 +20,7 @@
 #include "../bot/navigation.qh"
 #include "../bot/scripting.qh"
 
-#include "../mutators/mutators_include.qh"
+#include "../mutators/all.qh"
 
 #include "../../common/constants.qh"
 #include "../../common/mapinfo.qh"
index 60faeb3c254c709009966df0ebe13a3b8c725860..77c0a35600dd12cee1428f7ae7ec8f53e3f3767b 100644 (file)
@@ -9,7 +9,7 @@
 #include "../round_handler.qh"
 #include "../scores.qh"
 
-#include "../mutators/mutators_include.qh"
+#include "../mutators/all.qh"
 
 #include "../../common/constants.qh"
 #include "../../common/mapinfo.qh"
@@ -422,9 +422,6 @@ void reset_map(float dorespawn)
                }
        }
 
-       if(g_keyhunt)
-               kh_Controller_SetThink(autocvar_g_balance_keyhunt_delay_round + (game_starttime - time), kh_StartRound);
-
        setself(this);
 }
 
@@ -500,7 +497,7 @@ void ReadyRestart_force()
 
 void ReadyRestart()
 {
-       // no arena, assault support yet...
+       // no assault support yet...
        if(g_assault | gameover | intermission_running | race_completing)
                localcmd("restart\n");
        else
index 548c60429b709b3064eb12491f4585d2a2b388be..cf275c0f89aa1b8eb49dd4ec55af3d238fe528b9 100644 (file)
@@ -1,7 +1,5 @@
 #include "ent_cs.qh"
 
-#include "mutators/gamemode_ca.qh"
-
 float entcs_customize()
 {
        SELFPARAM();
index b005da47a24e48e7a5b70eaa7cd143273eb03f30..8354007aa0fc2b3ac463cb5416354109e33a08c0 100644 (file)
@@ -2,7 +2,7 @@
 
 #include "bot/bot.qh"
 #include "g_hook.qh"
-#include "mutators/mutators_include.qh"
+#include "mutators/all.qh"
 #include "scores.qh"
 #include "spawnpoints.qh"
 #include "t_items.qh"
@@ -748,22 +748,22 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, int d
                if(targ.frozen)
                if(deathtype != DEATH_HURTTRIGGER.m_id && deathtype != DEATH_TEAMCHANGE.m_id && deathtype != DEATH_AUTOTEAMCHANGE.m_id)
                {
-                       if(autocvar_g_freezetag_revive_falldamage > 0)
+                       if(autocvar_g_frozen_revive_falldamage > 0)
                        if(deathtype == DEATH_FALL.m_id)
-                       if(damage >= autocvar_g_freezetag_revive_falldamage)
+                       if(damage >= autocvar_g_frozen_revive_falldamage)
                        {
                                Unfreeze(targ);
-                               targ.health = autocvar_g_freezetag_revive_falldamage_health;
+                               targ.health = autocvar_g_frozen_revive_falldamage_health;
                                Send_Effect(EFFECT_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;
+                       force *= autocvar_g_frozen_force;
                }
 
-               if(targ.frozen && deathtype == DEATH_HURTTRIGGER.m_id && !autocvar_g_freezetag_frozen_damage_trigger)
+               if(targ.frozen && deathtype == DEATH_HURTTRIGGER.m_id && !autocvar_g_frozen_damage_trigger)
                {
                        Send_Effect(EFFECT_TELEPORT, targ.origin, '0 0 0', 1);
 
index 62a74be22d0289087b1fd1f45b6e689fb026e8a9..cee65e1643ad76bb00787468eeccb980d7115f14 100644 (file)
@@ -18,7 +18,7 @@
     #include "defs.qh"
     #include "../common/notifications.qh"
     #include "../common/deathtypes/all.qh"
-    #include "mutators/mutators_include.qh"
+    #include "mutators/all.qh"
     #include "../common/turrets/sv_turrets.qh"
     #include "../common/vehicles/all.qh"
     #include "../lib/csqcmodel/sv_model.qh"
index 7a77d4aff695a0a1fbfdb50ef10a838223c6d77c..f95115a2ca465a8f8fbe01679da18eed973229a6 100644 (file)
@@ -151,10 +151,7 @@ void GrapplingHookThink()
 
        self.nextthink = time;
 
-       int s = self.realowner.cvar_cl_gunalign;
-       if(s != 1 && s != 2 && s != 4)
-               s = 3; // default value
-       --s;
+       int s = W_GetGunAlignment(self.realowner);
        vs = hook_shotorigin[s];
 
        makevectors(self.realowner.v_angle);
@@ -353,10 +350,7 @@ void FireGrapplingHook (void)
 
        makevectors(self.v_angle);
 
-       int s = self.cvar_cl_gunalign;
-       if(s != 1 && s != 2 && s != 4)
-               s = 3; // default value
-       --s;
+       int s = W_GetGunAlignment(self);
        vs = hook_shotorigin[s];
 
        // UGLY WORKAROUND: play this on CH_WEAPON_B so it can't cut off fire sounds
index fc3eed45286cd110e4a697a050d40cbd0f3b63a3..c3932f3fb8062a3d254507537dfff60db4c30ff1 100644 (file)
@@ -13,7 +13,7 @@
 #include "g_hook.qh"
 #include "ipban.qh"
 #include "mapvoting.qh"
-#include "mutators/mutators_include.qh"
+#include "mutators/all.qh"
 #include "race.qh"
 #include "scores.qh"
 #include "teamplay.qh"
@@ -31,6 +31,7 @@
 #include "../common/stats.qh"
 #include "../common/teams.qh"
 #include "../common/triggers/trigger/secret.qh"
+#include "../common/triggers/target/music.qh"
 #include "../common/util.qh"
 #include "../common/items/all.qh"
 #include "../common/weapons/all.qh"
@@ -557,6 +558,7 @@ spawnfunc(__init_dedicated_server)
 
        // needs to be done so early because of the constants they create
        static_init();
+       static_init_late();
 
        MapInfo_Enumerate();
        MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
@@ -655,6 +657,7 @@ spawnfunc(worldspawn)
        PlayerStats_GameReport_Init(); // we need this to be initiated before InitGameplayMode
 
        InitGameplayMode();
+       static_init_late();
        readlevelcvars();
        GrappleHookInit();
 
@@ -1423,7 +1426,7 @@ void DumpStats(float final)
                {
                        s = strcat(":player:see-labels:", GetPlayerScoreString(other, 0), ":");
                        s = strcat(s, ftos(rint(time - other.jointime)), ":");
-                       if(IS_PLAYER(other) || other.caplayer == 1 || g_lms)
+                       if(IS_PLAYER(other) || MUTATOR_CALLHOOK(GetPlayerStatus, other, s))
                                s = strcat(s, ftos(other.team), ":");
                        else
                                s = strcat(s, "spectator:");
@@ -1546,6 +1549,10 @@ void NextLevel()
                        bprint(other.netname, " ^7wins.\n");
        }
 
+       entity oldself = self;
+       target_music_kill();
+       self = oldself;
+
        if(autocvar_g_campaign)
                CampaignPreIntermission();
 
@@ -2082,35 +2089,13 @@ void CheckRules_World()
                return;
        }
 
-       float checkrules_status;
-       checkrules_status = WinningCondition_RanOutOfSpawns();
+       int checkrules_status = WinningCondition_RanOutOfSpawns();
        if(checkrules_status == WINNING_YES)
-       {
                bprint("Hey! Someone ran out of spawns!\n");
-       }
-       else if(g_race && !g_race_qualifying && timelimit >= 0)
-       {
-               checkrules_status = WinningCondition_Race(fraglimit);
-               //print("WC_RACE yields ", ftos(checkrules_status), "\n");
-       }
-       else if(g_race && g_race_qualifying == 2 && timelimit >= 0)
-       {
-               checkrules_status = WinningCondition_QualifyingThenRace(fraglimit);
-               //print("WC_QUALIFYING_THEN_RACE yields ", ftos(checkrules_status), "\n");
-       }
-       else if(g_assault)
-       {
-               checkrules_status = WinningCondition_Assault(); // TODO remove this?
-       }
-       else if(g_lms)
-       {
-               checkrules_status = WinningCondition_LMS();
-       }
-       else
-       {
+       else if(!MUTATOR_CALLHOOK(CheckRules_World, checkrules_status, timelimit, fraglimit))
                checkrules_status = WinningCondition_Scores(fraglimit, leadlimit);
-               //print("WC_SCORES yields ", ftos(checkrules_status), "\n");
-       }
+
+       checkrules_status = ret_float;
 
        if(checkrules_status == WINNING_STARTSUDDENDEATHOVERTIME)
        {
index 43036b4099a64d0972097ca50d3d91dc5bdf80b9..3a4680ebb94366867b11d1c9c11829e055302eec 100644 (file)
@@ -4,7 +4,7 @@
 #include "constants.qh"
 #include "g_hook.qh"
 #include "ipban.qh"
-#include "mutators/mutators_include.qh"
+#include "mutators/all.qh"
 #include "t_items.qh"
 #include "weapons/accuracy.qh"
 #include "weapons/csqcprojectile.qh"
@@ -485,25 +485,27 @@ float want_weapon(entity weaponinfo, float allguns) // WEAPONTODO: what still ne
 {
        int i = weaponinfo.weapon;
        int d = 0;
+       bool allow_mutatorblocked = false;
 
-       if (!i)
+       if(!i)
                return 0;
 
-       if (g_lms || g_ca || allguns)
+       bool mutator_returnvalue = MUTATOR_CALLHOOK(WantWeapon, weaponinfo, d, allguns, allow_mutatorblocked);
+       d = ret_float;
+       allguns = want_allguns;
+       allow_mutatorblocked = false;
+
+       if(allguns)
        {
                if(weaponinfo.spawnflags & WEP_FLAG_NORMAL)
                        d = true;
                else
                        d = false;
        }
-       else if (g_cts)
-               d = (i == WEP_SHOTGUN.m_id);
-       else if (g_nexball)
-               d = 0; // weapon is set a few lines later
-       else
+       else if(!mutator_returnvalue)
                d = !(!weaponinfo.weaponstart);
 
-       if(!g_cts && (weaponinfo.spawnflags & WEP_FLAG_MUTATORBLOCKED)) // never default mutator blocked guns
+       if(!allow_mutatorblocked && (weaponinfo.spawnflags & WEP_FLAG_MUTATORBLOCKED)) // never default mutator blocked guns
                d = 0;
 
        float t = weaponinfo.weaponstartoverride;
@@ -545,11 +547,9 @@ void readplayerstartcvars()
        g_weaponarena_weapons = '0 0 0';
 
        s = cvar_string("g_weaponarena");
-       if (s == "0" || s == "")
-       {
-               if(g_ca || g_freezetag)
-                       s = "most";
-       }
+
+       MUTATOR_CALLHOOK(SetWeaponArena, s);
+       s = ret_string;
 
        if (s == "0" || s == "")
        {
@@ -1521,94 +1521,6 @@ void write_recordmarker(entity pl, float tstart, float dt)
                  " ", ftos(tstart), " ", ftos(dt), "\n"));
 }
 
-vector shotorg_adjustfromclient(vector vecs, float y_is_right, float allowcenter, float algn)
-{
-       switch(algn)
-       {
-               default:
-               case 3: // right
-                       break;
-
-               case 4: // left
-                       vecs.y = -vecs.y;
-                       break;
-
-               case 1:
-                       if(allowcenter) // 2: allow center handedness
-                       {
-                               // center
-                               vecs.y = 0;
-                               vecs.z -= 2;
-                       }
-                       else
-                       {
-                               // right
-                       }
-                       break;
-
-               case 2:
-                       if(allowcenter) // 2: allow center handedness
-                       {
-                               // center
-                               vecs.y = 0;
-                               vecs.z -= 2;
-                       }
-                       else
-                       {
-                               // left
-                               vecs.y = -vecs.y;
-                       }
-                       break;
-       }
-       return vecs;
-}
-
-vector shotorg_adjust_values(vector vecs, float y_is_right, float visual, float algn)
-{
-       string s;
-       vector v;
-
-       if (autocvar_g_shootfromeye)
-       {
-               if (visual)
-               {
-                       if (autocvar_g_shootfromclient) { vecs = shotorg_adjustfromclient(vecs, y_is_right, (autocvar_g_shootfromclient >= 2), algn); }
-                       else { vecs.y = 0; vecs.z -= 2; }
-               }
-               else
-               {
-                       vecs.y = 0;
-                       vecs.z = 0;
-               }
-       }
-       else if (autocvar_g_shootfromcenter)
-       {
-               vecs.y = 0;
-               vecs.z -= 2;
-       }
-       else if ((s = autocvar_g_shootfromfixedorigin) != "")
-       {
-               v = stov(s);
-               if (y_is_right)
-                       v.y = -v.y;
-               if (v.x != 0)
-                       vecs.x = v.x;
-               vecs.y = v.y;
-               vecs.z = v.z;
-       }
-       else if (autocvar_g_shootfromclient)
-       {
-               vecs = shotorg_adjustfromclient(vecs, y_is_right, (autocvar_g_shootfromclient >= 2), algn);
-       }
-       return vecs;
-}
-
-vector shotorg_adjust(vector vecs, float y_is_right, float visual)
-{SELFPARAM();
-       return shotorg_adjust_values(vecs, y_is_right, visual, self.owner.cvar_cl_gunalign);
-}
-
-
 void attach_sameorigin(entity e, entity to, string tag)
 {
     vector org, t_forward, t_left, t_up, e_forward, e_up;
index ca8c41e9bfc02de784a3de5db23bb483c79ce841..c61e505e91a4be949255b0decfa43d6c8f01b7f0 100644 (file)
@@ -4,7 +4,6 @@
 #include "t_items.qh"
 
 #include "mutators/events.qh"
-#include "mutators/gamemode_race.qh"
 
 #include "../common/constants.qh"
 #include "../common/mapinfo.qh"
@@ -65,8 +64,6 @@ void stopsoundto(float _dest, entity e, float chan);
 void soundtoat(float _dest, entity e, vector o, float chan, string samp, float vol, float _atten);
 float ExponentialFalloff(float mindist, float maxdist, float halflifedist, float d);
 
-vector shotorg_adjust(vector vecs, float y_is_right, float visual);
-
 float DistributeEvenly_amount;
 float DistributeEvenly_totalweight;
 void objerror(string s);
@@ -119,8 +116,6 @@ void remove_unsafely(entity e);
 
 void SetMovetypeFollow(entity ent, entity e);
 
-vector shotorg_adjust_values(vector vecs, float y_is_right, float visual, float algn);
-
 void soundto(float dest, entity e, float chan, string samp, float vol, float atten);
 
 void stopsound(entity e, float chan);
@@ -302,12 +297,8 @@ float sv_autotaunt;
 float sv_taunt;
 
 string GetGametype(); // g_world.qc
-void mutators_add(); // mutators.qc
 void readlevelcvars(void)
 {
-       // load mutators
-       mutators_add();
-
        if(cvar("sv_allow_fullbright"))
                serverflags |= SERVERFLAG_ALLOW_FULLBRIGHT;
 
@@ -344,8 +335,8 @@ void readlevelcvars(void)
        g_warmup_allguns = cvar("g_warmup_allguns");
        g_warmup_allow_timeout = cvar("g_warmup_allow_timeout");
 
-       if ((g_race && g_race_qualifying == 2) || g_assault || cvar("g_campaign"))
-               warmup_stage = 0; // these modes cannot work together, sorry
+       if(cvar("g_campaign"))
+               warmup_stage = 0; // no warmup during campaign
 
        g_pickup_respawntime_weapon = cvar("g_pickup_respawntime_weapon");
        g_pickup_respawntime_superweapon = cvar("g_pickup_respawntime_superweapon");
@@ -413,6 +404,8 @@ void readlevelcvars(void)
     if(!g_weapon_stay)
         g_weapon_stay = cvar("g_weapon_stay");
 
+    MUTATOR_CALLHOOK(ReadLevelCvars);
+
        if (!warmup_stage)
                game_starttime = time + cvar("g_start_delay");
 
diff --git a/qcsrc/server/mutators/all.inc b/qcsrc/server/mutators/all.inc
new file mode 100644 (file)
index 0000000..f67ceae
--- /dev/null
@@ -0,0 +1,41 @@
+#include "mutator/gamemode_assault.qc"
+#include "mutator/gamemode_ca.qc"
+#include "mutator/gamemode_ctf.qc"
+#include "mutator/gamemode_cts.qc"
+#include "mutator/gamemode_deathmatch.qc"
+#include "mutator/gamemode_domination.qc"
+#include "mutator/gamemode_freezetag.qc"
+#include "mutator/gamemode_invasion.qc"
+#include "mutator/gamemode_keepaway.qc"
+#include "mutator/gamemode_keyhunt.qc"
+#include "mutator/gamemode_lms.qc"
+#include "mutator/gamemode_onslaught.qc"
+#include "mutator/gamemode_race.qc"
+#include "mutator/gamemode_tdm.qc"
+
+#include "mutator/mutator_bloodloss.qc"
+#include "mutator/mutator_breakablehook.qc"
+#include "mutator/mutator_buffs.qc"
+#include "mutator/mutator_campcheck.qc"
+#include "mutator/mutator_dodging.qc"
+#include "mutator/mutator_hook.qc"
+#include "mutator/mutator_invincibleproj.qc"
+#include "mutator/mutator_melee_only.qc"
+#include "mutator/mutator_midair.qc"
+#include "mutator/mutator_multijump.qc"
+#include "mutator/mutator_nades.qc"
+#include "mutator/mutator_new_toys.qc"
+#include "mutator/mutator_nix.qc"
+#include "mutator/mutator_overkill.qc"
+#include "mutator/mutator_physical_items.qc"
+#include "mutator/mutator_pinata.qc"
+#include "mutator/mutator_random_gravity.qc"
+#include "mutator/mutator_rocketflying.qc"
+#include "mutator/mutator_rocketminsta.qc"
+#include "mutator/mutator_spawn_near_teammate.qc"
+#include "mutator/mutator_superspec.qc"
+#include "mutator/mutator_touchexplode.qc"
+#include "mutator/mutator_vampirehook.qc"
+#include "mutator/mutator_vampire.qc"
+
+#include "mutator/sandbox.qc"
diff --git a/qcsrc/server/mutators/all.qc b/qcsrc/server/mutators/all.qc
new file mode 100644 (file)
index 0000000..542763f
--- /dev/null
@@ -0,0 +1,89 @@
+#if defined(CSQC)
+#elif defined(MENUQC)
+#elif defined(SVQC)
+    #include "../../lib/warpzone/anglestransform.qh"
+    #include "../../lib/warpzone/common.qh"
+    #include "../../lib/warpzone/util_server.qh"
+    #include "../../lib/warpzone/server.qh"
+    #include "../../common/constants.qh"
+    #include "../../common/stats.qh"
+    #include "../../common/teams.qh"
+    #include "../../common/util.qh"
+    #include "../../common/nades/all.qh"
+    #include "../../common/buffs/all.qh"
+    #include "../../common/command/markup.qh"
+    #include "../../common/command/rpn.qh"
+    #include "../../common/command/generic.qh"
+    #include "../../common/command/command.qh"
+    #include "../../common/net_notice.qh"
+    #include "../../common/animdecide.qh"
+    #include "../../common/monsters/all.qh"
+    #include "../../common/monsters/sv_monsters.qh"
+    #include "../../common/monsters/spawn.qh"
+    #include "../../common/weapons/config.qh"
+    #include "../../common/weapons/all.qh"
+    #include "../weapons/accuracy.qh"
+    #include "../weapons/common.qh"
+    #include "../weapons/csqcprojectile.qh"
+    #include "../weapons/hitplot.qh"
+    #include "../weapons/selection.qh"
+    #include "../weapons/spawning.qh"
+    #include "../weapons/throwing.qh"
+    #include "../weapons/tracing.qh"
+    #include "../weapons/weaponstats.qh"
+    #include "../weapons/weaponsystem.qh"
+    #include "../t_items.qh"
+    #include "../autocvars.qh"
+    #include "../constants.qh"
+    #include "../defs.qh"
+    #include "../../common/notifications.qh"
+    #include "../../common/deathtypes/all.qh"
+    #include "all.qh"
+    #include "../../common/turrets/sv_turrets.qh"
+    #include "../../common/vehicles/all.qh"
+    #include "../campaign.qh"
+    #include "../../common/campaign_common.qh"
+    #include "../../common/mapinfo.qh"
+    #include "../command/common.qh"
+    #include "../command/banning.qh"
+    #include "../command/radarmap.qh"
+    #include "../command/vote.qh"
+    #include "../command/getreplies.qh"
+    #include "../command/cmd.qh"
+    #include "../command/sv_cmd.qh"
+    #include "../../common/csqcmodel_settings.qh"
+    #include "../../lib/csqcmodel/common.qh"
+    #include "../../lib/csqcmodel/sv_model.qh"
+    #include "../anticheat.qh"
+    #include "../cheats.qh"
+    #include "../../common/playerstats.qh"
+    #include "../portals.qh"
+    #include "../g_hook.qh"
+    #include "../scores.qh"
+    #include "../spawnpoints.qh"
+    #include "../mapvoting.qh"
+    #include "../ipban.qh"
+    #include "../race.qh"
+    #include "../antilag.qh"
+    #include "../playerdemo.qh"
+    #include "../round_handler.qh"
+    #include "../item_key.qh"
+    #include "../pathlib/pathlib.qh"
+    #include "../../common/vehicles/all.qh"
+#endif
+
+#include "all.qh"
+
+STATIC_INIT_LATE(Gametype) {
+    Gametype g = MapInfo_Type(MapInfo_CurrentGametype());
+    if (g) {
+        for (string _s = g.m_mutators; _s != ""; _s = cdr(_s)) {
+            string s = car(_s);
+            FOREACH(Mutators, it.m_name == s, LAMBDA(Mutator_Add(it); break));
+        }
+    }
+}
+
+#define IMPLEMENTATION
+#include "all.inc"
+#undef IMPLEMENTATION
diff --git a/qcsrc/server/mutators/all.qh b/qcsrc/server/mutators/all.qh
new file mode 100644 (file)
index 0000000..e586ec7
--- /dev/null
@@ -0,0 +1,9 @@
+#include "mutator.qh"
+#include "gamemode.qh"
+
+#ifndef SERVER_MUTATORS_H
+#define SERVER_MUTATORS_H
+
+#include "all.inc"
+
+#endif
index 1492b9f6af3d07a06aa8a782a8d4a846ea60bea0..d5a842a6ef301114723b687bbb8c636b0318a4c3 100644 (file)
@@ -122,6 +122,8 @@ MUTATOR_HOOKABLE(MatchEnd, EV_NO_ARGS);
 #define EV_GetTeamCount(i, o) \
     /**/ i(float, ret_float) \
     /**/ o(float, ret_float) \
+    /**/ i(string, ret_string) \
+    /**/ o(string, ret_string) \
     /**/
 float ret_float;
 MUTATOR_HOOKABLE(GetTeamCount, EV_GetTeamCount);
@@ -145,9 +147,12 @@ string format_replacement;
 string format_message;
 MUTATOR_HOOKABLE(FormatMessage, EV_FormatMessage);
 
-/** returns 1 if throwing the current weapon shall not be allowed */
+/** returns true if throwing the current weapon shall not be allowed */
 MUTATOR_HOOKABLE(ForbidThrowCurrentWeapon, EV_NO_ARGS);
 
+/** returns true if dropping the current weapon shall not be allowed at any time including death */
+MUTATOR_HOOKABLE(ForbidDropCurrentWeapon, EV_NO_ARGS);
+
 /** allows changing attack rate */
 #define EV_WeaponRateFactor(i, o) \
     /**/ i(float, weapon_rate) \
@@ -635,4 +640,174 @@ MUTATOR_HOOKABLE(BuffModel_Customize, EV_BuffModel_Customize);
     /** player */ i(entity, other) \
     /**/
 MUTATOR_HOOKABLE(BuffTouch, EV_BuffTouch);
+
+MUTATOR_HOOKABLE(SetNewParms, EV_NO_ARGS);
+
+MUTATOR_HOOKABLE(SetChangeParms, EV_NO_ARGS);
+
+MUTATOR_HOOKABLE(DecodeLevelParms, EV_NO_ARGS);
+
+#define EV_GetRecords(i, o) \
+    /**/ i(int, record_page) \
+    /**/ i(string, ret_string) \
+    /**/ o(string, ret_string) \
+    /**/
+int record_page;
+MUTATOR_HOOKABLE(GetRecords, EV_GetRecords);
+
+#define EV_Race_FinalCheckpoint(i, o) \
+    /**/ i(entity, race_player) \
+    /**/
+entity race_player;
+MUTATOR_HOOKABLE(Race_FinalCheckpoint, EV_Race_FinalCheckpoint);
+
+/** called when player triggered kill (or is changing teams), return error to not do anything */
+#define EV_ClientKill(i, o) \
+    /** player */ i(entity, __self) \
+    /* kill delay */ i(float, ret_float) \
+    /* kill delay */ o(float, ret_float) \
+    /**/
+MUTATOR_HOOKABLE(ClientKill, EV_ClientKill);
+
+#define EV_FixClientCvars(i, o) \
+    /**/ i(entity, fix_client) \
+    /**/
+entity fix_client;
+MUTATOR_HOOKABLE(FixClientCvars, EV_FixClientCvars);
+
+#define EV_SpectateSet(i, o) \
+    /**/ i(entity, __self) \
+    /**/ i(entity, spec_player) \
+    /**/
+entity spec_player;
+MUTATOR_HOOKABLE(SpectateSet, EV_SpectateSet);
+
+#define EV_SpectateNext(i, o) \
+    /**/ i(entity, __self) \
+    /**/ i(entity, spec_player) \
+    /**/
+MUTATOR_HOOKABLE(SpectateNext, EV_SpectateNext);
+
+#define EV_SpectatePrev(i, o) \
+    /**/ i(entity, __self) \
+    /**/ i(entity, spec_player) \
+    /**/ i(entity, spec_first) \
+    /**/
+entity spec_first;
+MUTATOR_HOOKABLE(SpectatePrev, EV_SpectatePrev);
+
+enum {
+    MUT_SPECPREV_CONTINUE, // return this flag to make the function continue as normal
+    MUT_SPECPREV_RETURN, // return this flag to make the function return (handled entirely by mutator)
+    MUT_SPECPREV_FOUND // return this flag to make the function continue without default functions (handled mostly by mutator)
+};
+
+/** called when player triggered kill (or is changing teams), return error to not do anything */
+#define EV_Bot_FixCount(i, o) \
+    /**/ i(int, bot_activerealplayers) \
+    /**/ o(int, bot_activerealplayers) \
+    /**/ i(int, bot_realplayers) \
+    /**/ o(int, bot_realplayers) \
+    /**/
+int bot_activerealplayers;
+int bot_realplayers;
+MUTATOR_HOOKABLE(Bot_FixCount, EV_Bot_FixCount);
+
+#define EV_ClientCommand_Spectate(i, o) \
+    /**/ i(entity, __self) \
+    /**/
+MUTATOR_HOOKABLE(ClientCommand_Spectate, EV_ClientCommand_Spectate);
+
+enum {
+    MUT_SPECCMD_CONTINUE, // return this flag to make the function continue as normal
+    MUT_SPECCMD_RETURN, // return this flag to make the function return (don't spectate)
+    MUT_SPECCMD_FORCE // return this flag to force the player to spectate, even if they're not a player
+};
+
+#define EV_CheckRules_World(i, o) \
+    /* status */ i(float, ret_float) \
+    /* status */ o(float, ret_float) \
+    /* time limit */ i(float, checkrules_timelimit) \
+    /* frag limit */ i(int, checkrules_fraglimit) \
+    /**/
+float checkrules_timelimit;
+int checkrules_fraglimit;
+MUTATOR_HOOKABLE(CheckRules_World, EV_CheckRules_World);
+
+#define EV_WantWeapon(i, o) \
+    /**/ i(entity, want_weaponinfo) \
+    /**/ i(float, ret_float) \
+    /**/ o(float, ret_float) \
+    /**/ i(bool, want_allguns) \
+    /**/ o(bool, want_allguns) \
+    /**/ i(bool, want_mutatorblocked) \
+    /**/ o(bool, want_mutatorblocked) \
+    /**/
+entity want_weaponinfo;
+bool want_allguns;
+bool want_mutatorblocked;
+MUTATOR_HOOKABLE(WantWeapon, EV_WantWeapon);
+
+#define EV_AddPlayerScore(i, o) \
+    /**/ i(int, score_field) \
+    /**/ i(float, ret_float) \
+    /**/ o(float, ret_float) \
+    /**/
+int score_field;
+MUTATOR_HOOKABLE(AddPlayerScore, EV_AddPlayerScore);
+
+#define EV_GetPlayerStatus(i, o) \
+    /**/ i(entity, set_player) \
+    /**/ i(string, ret_string) \
+    /**/ o(string, ret_string) \
+    /**/
+entity set_player;
+MUTATOR_HOOKABLE(GetPlayerStatus, EV_GetPlayerStatus);
+
+#define EV_SetWeaponArena(i, o) \
+    /**/ i(string, ret_string) \
+    /**/ o(string, ret_string) \
+    /**/
+MUTATOR_HOOKABLE(SetWeaponArena, EV_SetWeaponArena);
+
+#define EV_DropSpecialItems(i, o) \
+    /**/ i(entity, frag_target) \
+    /**/
+MUTATOR_HOOKABLE(DropSpecialItems, EV_DropSpecialItems);
+
+/**
+ * called when an admin tries to kill all monsters
+ * return 1 to prevent spawning
+ */
+MUTATOR_HOOKABLE(AllowMobButcher, EV_NO_ARGS);
+
+MUTATOR_HOOKABLE(ReadLevelCvars, EV_NO_ARGS);
+
+#define EV_SendWaypoint(i, o) \
+    /**/ i(entity, __self) \
+    /**/ i(entity, wp_sendto) \
+    /**/ i(int, wp_sendflags) \
+    /**/ o(int, wp_sendflags) \
+    /**/ i(int, wp_flag) \
+    /**/ o(int, wp_flag) \
+    /**/
+entity wp_sendto;
+int wp_sendflags;
+int wp_flag;
+MUTATOR_HOOKABLE(SendWaypoint, EV_SendWaypoint);
+
+#define EV_TurretValidateTarget(i, o) \
+    /**/ i(entity, turret_this) \
+    /**/ i(entity, turret_target) \
+    /**/ i(int, turret_vflags) \
+    /**/
+entity turret_this;
+entity turret_target;
+int turret_vflags;
+MUTATOR_HOOKABLE(TurretValidateTarget, EV_TurretValidateTarget);
+
+#define EV_TurretThink(i, o) \
+    /**/ i(entity, __self) \
+    /**/
+MUTATOR_HOOKABLE(TurretThink, EV_TurretThink);
 #endif
index da11aefeeb0fbad8b186f1650ae340caa09f5b01..5e2c4635734d27cdd3717ccfe1d76b4df39e37d5 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef GAMEMODE_H
 #define GAMEMODE_H
 
-#include "mutator_nades.qh"
-
 #include "../cl_client.qh"
 #include "../cl_player.qh"
 #include "../cl_impulse.qh"
@@ -17,7 +15,6 @@
 #include "../bot/navigation.qh"
 #include "../bot/waypoints.qh"
 #include "../bot/havocbot/roles.qh"
-#include "../bot/havocbot/role_keyhunt.qh"
 
 #include "../bot/havocbot/havocbot.qh"
 
diff --git a/qcsrc/server/mutators/gamemode_assault.qc b/qcsrc/server/mutators/gamemode_assault.qc
deleted file mode 100644 (file)
index 85d975f..0000000
+++ /dev/null
@@ -1,607 +0,0 @@
-#include "gamemode_assault.qh"
-
-#include "gamemode.qh"
-
-.entity sprite;
-
-// random functions
-void assault_objective_use()
-{SELFPARAM();
-       // activate objective
-       self.health = 100;
-       //print("^2Activated objective ", self.targetname, "=", etos(self), "\n");
-       //print("Activator is ", activator.classname, "\n");
-
-       for (entity e = world; (e = find(e, target, this.targetname)); )
-       {
-               if (e.classname == "target_objective_decrease")
-               {
-                       WITH(entity, self, e, target_objective_decrease_activate());
-               }
-       }
-
-       setself(this);
-}
-
-vector target_objective_spawn_evalfunc(entity player, entity spot, vector current)
-{SELFPARAM();
-       if(self.health < 0 || self.health >= ASSAULT_VALUE_INACTIVE)
-               return '-1 0 0';
-       return current;
-}
-
-// reset this objective. Used when spawning an objective
-// and when a new round starts
-void assault_objective_reset()
-{SELFPARAM();
-       self.health = ASSAULT_VALUE_INACTIVE;
-}
-
-// decrease the health of targeted objectives
-void assault_objective_decrease_use()
-{SELFPARAM();
-       if(activator.team != assault_attacker_team)
-       {
-               // wrong team triggered decrease
-               return;
-       }
-
-       if(other.assault_sprite)
-       {
-               WaypointSprite_Disown(other.assault_sprite, waypointsprite_deadlifetime);
-               if(other.classname == "func_assault_destructible")
-                       other.sprite = world;
-       }
-       else
-               return; // already activated! cannot activate again!
-
-       if(self.enemy.health < ASSAULT_VALUE_INACTIVE)
-       {
-               if(self.enemy.health - self.dmg > 0.5)
-               {
-                       PlayerTeamScore_Add(activator, SP_SCORE, ST_SCORE, self.dmg);
-                       self.enemy.health = self.enemy.health - self.dmg;
-               }
-               else
-               {
-                       PlayerTeamScore_Add(activator, SP_SCORE, ST_SCORE, self.enemy.health);
-                       PlayerTeamScore_Add(activator, SP_ASSAULT_OBJECTIVES, ST_ASSAULT_OBJECTIVES, 1);
-                       self.enemy.health = -1;
-
-                       entity oldactivator, head;
-
-                       setself(this.enemy);
-                       if(self.message)
-                       FOR_EACH_PLAYER(head)
-                               centerprint(head, self.message);
-
-                       oldactivator = activator;
-                       activator = this;
-                       SUB_UseTargets();
-                       activator = oldactivator;
-                       setself(this);
-               }
-       }
-}
-
-void assault_setenemytoobjective()
-{SELFPARAM();
-       entity objective;
-       for(objective = world; (objective = find(objective, targetname, self.target)); )
-       {
-               if(objective.classname == "target_objective")
-               {
-                       if(self.enemy == world)
-                               self.enemy = objective;
-                       else
-                               objerror("more than one objective as target - fix the map!");
-                       break;
-               }
-       }
-
-       if(self.enemy == world)
-               objerror("no objective as target - fix the map!");
-}
-
-float assault_decreaser_sprite_visible(entity e)
-{SELFPARAM();
-       entity decreaser;
-
-       decreaser = self.assault_decreaser;
-
-       if(decreaser.enemy.health >= ASSAULT_VALUE_INACTIVE)
-               return false;
-
-       return true;
-}
-
-void target_objective_decrease_activate()
-{SELFPARAM();
-       entity ent, spr;
-       self.owner = world;
-       for(ent = world; (ent = find(ent, target, self.targetname)); )
-       {
-               if(ent.assault_sprite != world)
-               {
-                       WaypointSprite_Disown(ent.assault_sprite, waypointsprite_deadlifetime);
-                       if(ent.classname == "func_assault_destructible")
-                               ent.sprite = world;
-               }
-
-               spr = WaypointSprite_SpawnFixed(WP_Assault, 0.5 * (ent.absmin + ent.absmax), ent, assault_sprite, RADARICON_OBJECTIVE);
-               spr.assault_decreaser = self;
-               spr.waypointsprite_visible_for_player = assault_decreaser_sprite_visible;
-               spr.classname = "sprite_waypoint";
-               WaypointSprite_UpdateRule(spr, assault_attacker_team, SPRITERULE_TEAMPLAY);
-               if(ent.classname == "func_assault_destructible")
-               {
-                       WaypointSprite_UpdateSprites(spr, WP_AssaultDefend, WP_AssaultDestroy, WP_AssaultDestroy);
-                       WaypointSprite_UpdateMaxHealth(spr, ent.max_health);
-                       WaypointSprite_UpdateHealth(spr, ent.health);
-                       ent.sprite = spr;
-               }
-               else
-                       WaypointSprite_UpdateSprites(spr, WP_AssaultDefend, WP_AssaultPush, WP_AssaultPush);
-       }
-}
-
-void target_objective_decrease_findtarget()
-{
-       assault_setenemytoobjective();
-}
-
-void target_assault_roundend_reset()
-{SELFPARAM();
-       //print("round end reset\n");
-       self.cnt = self.cnt + 1; // up round counter
-       self.winning = 0; // up round
-}
-
-void target_assault_roundend_use()
-{SELFPARAM();
-       self.winning = 1; // round has been won by attackers
-}
-
-void assault_roundstart_use()
-{SELFPARAM();
-       activator = self;
-       SUB_UseTargets();
-
-       //(Re)spawn all turrets
-       for(entity ent = NULL; (ent = find(ent, classname, "turret_main")); ) {
-               // Swap turret teams
-               if(ent.team == NUM_TEAM_1)
-                       ent.team = NUM_TEAM_2;
-               else
-                       ent.team = NUM_TEAM_1;
-
-               // Dubbles as teamchange
-               WITH(entity, self, ent, turret_respawn());
-       }
-}
-
-void assault_wall_think()
-{SELFPARAM();
-       if(self.enemy.health < 0)
-       {
-               self.model = "";
-               self.solid = SOLID_NOT;
-       }
-       else
-       {
-               self.model = self.mdl;
-               self.solid = SOLID_BSP;
-       }
-
-       self.nextthink = time + 0.2;
-}
-
-// trigger new round
-// reset objectives, toggle spawnpoints, reset triggers, ...
-void vehicles_clearreturn(entity veh);
-void vehicles_spawn();
-void assault_new_round()
-{SELFPARAM();
-       //bprint("ASSAULT: new round\n");
-
-       // Eject players from vehicles
-       entity e;
-    FOR_EACH_PLAYER(e)
-    {
-        if(e.vehicle)
-        {
-               WITH(entity, self, e, vehicles_exit(VHEF_RELEASE));
-        }
-    }
-
-    for (entity e_ = findchainflags(vehicle_flags, VHF_ISVEHICLE); e_; e_ = e_.chain)
-    {
-       setself(e_);
-        vehicles_clearreturn(self);
-        vehicles_spawn();
-    }
-
-    setself(this);
-
-       // up round counter
-       self.winning = self.winning + 1;
-
-       // swap attacker/defender roles
-       if(assault_attacker_team == NUM_TEAM_1)
-               assault_attacker_team = NUM_TEAM_2;
-       else
-               assault_attacker_team = NUM_TEAM_1;
-
-       entity ent;
-       for(ent = world; (ent = nextent(ent)); )
-       {
-               if(clienttype(ent) == CLIENTTYPE_NOTACLIENT)
-               {
-                       if(ent.team_saved == NUM_TEAM_1)
-                               ent.team_saved = NUM_TEAM_2;
-                       else if(ent.team_saved == NUM_TEAM_2)
-                               ent.team_saved = NUM_TEAM_1;
-               }
-       }
-
-       // reset the level with a countdown
-       cvar_set("timelimit", ftos(ceil(time - game_starttime) / 60));
-       ReadyRestart_force(); // sets game_starttime
-}
-
-// spawnfuncs
-spawnfunc(info_player_attacker)
-{
-       if (!g_assault) { remove(self); return; }
-
-       self.team = NUM_TEAM_1; // red, gets swapped every round
-       spawnfunc_info_player_deathmatch(this);
-}
-
-spawnfunc(info_player_defender)
-{
-       if (!g_assault) { remove(self); return; }
-
-       self.team = NUM_TEAM_2; // blue, gets swapped every round
-       spawnfunc_info_player_deathmatch(this);
-}
-
-spawnfunc(target_objective)
-{
-       if (!g_assault) { remove(self); return; }
-
-       self.classname = "target_objective";
-       self.use = assault_objective_use;
-       assault_objective_reset();
-       self.reset = assault_objective_reset;
-       self.spawn_evalfunc = target_objective_spawn_evalfunc;
-}
-
-spawnfunc(target_objective_decrease)
-{
-       if (!g_assault) { remove(self); return; }
-
-       self.classname = "target_objective_decrease";
-
-       if(!self.dmg)
-               self.dmg = 101;
-
-       self.use = assault_objective_decrease_use;
-       self.health = ASSAULT_VALUE_INACTIVE;
-       self.max_health = ASSAULT_VALUE_INACTIVE;
-       self.enemy = world;
-
-       InitializeEntity(self, target_objective_decrease_findtarget, INITPRIO_FINDTARGET);
-}
-
-// destructible walls that can be used to trigger target_objective_decrease
-spawnfunc(func_breakable);
-spawnfunc(func_assault_destructible)
-{
-       if (!g_assault) { remove(self); return; }
-
-       self.spawnflags = 3;
-       self.classname = "func_assault_destructible";
-
-       if(assault_attacker_team == NUM_TEAM_1)
-               self.team = NUM_TEAM_2;
-       else
-               self.team = NUM_TEAM_1;
-
-       spawnfunc_func_breakable(this);
-}
-
-spawnfunc(func_assault_wall)
-{
-       if (!g_assault) { remove(self); return; }
-
-       self.classname = "func_assault_wall";
-       self.mdl = self.model;
-       _setmodel(self, self.mdl);
-       self.solid = SOLID_BSP;
-       self.think = assault_wall_think;
-       self.nextthink = time;
-       InitializeEntity(self, assault_setenemytoobjective, INITPRIO_FINDTARGET);
-}
-
-spawnfunc(target_assault_roundend)
-{
-       if (!g_assault) { remove(self); return; }
-
-       self.winning = 0; // round not yet won by attackers
-       self.classname = "target_assault_roundend";
-       self.use = target_assault_roundend_use;
-       self.cnt = 0; // first round
-       self.reset = target_assault_roundend_reset;
-}
-
-spawnfunc(target_assault_roundstart)
-{
-       if (!g_assault) { remove(self); return; }
-
-       assault_attacker_team = NUM_TEAM_1;
-       self.classname = "target_assault_roundstart";
-       self.use = assault_roundstart_use;
-       self.reset2 = assault_roundstart_use;
-       InitializeEntity(self, assault_roundstart_use, INITPRIO_FINDTARGET);
-}
-
-// legacy bot code
-void havocbot_goalrating_ast_targets(float ratingscale)
-{SELFPARAM();
-       entity ad, best, wp, tod;
-       float radius, found, bestvalue;
-       vector p;
-
-       ad = findchain(classname, "func_assault_destructible");
-
-       for (; ad; ad = ad.chain)
-       {
-               if (ad.target == "")
-                       continue;
-
-               if (!ad.bot_attack)
-                       continue;
-
-               found = false;
-               for(tod = world; (tod = find(tod, targetname, ad.target)); )
-               {
-                       if(tod.classname == "target_objective_decrease")
-                       {
-                               if(tod.enemy.health > 0 && tod.enemy.health < ASSAULT_VALUE_INACTIVE)
-                               {
-                               //      dprint(etos(ad),"\n");
-                                       found = true;
-                                       break;
-                               }
-                       }
-               }
-
-               if(!found)
-               {
-               ///     dprint("target not found\n");
-                       continue;
-               }
-               /// dprint("target #", etos(ad), " found\n");
-
-
-               p = 0.5 * (ad.absmin + ad.absmax);
-       //      dprint(vtos(ad.origin), " ", vtos(ad.absmin), " ", vtos(ad.absmax),"\n");
-       //      te_knightspike(p);
-       //      te_lightning2(world, '0 0 0', p);
-
-               // Find and rate waypoints around it
-               found = false;
-               best = world;
-               bestvalue = 99999999999;
-               for(radius=0; radius<1500 && !found; radius+=500)
-               {
-                       for(wp=findradius(p, radius); wp; wp=wp.chain)
-                       {
-                               if(!(wp.wpflags & WAYPOINTFLAG_GENERATED))
-                               if(wp.classname=="waypoint")
-                               if(checkpvs(wp.origin, ad))
-                               {
-                                       found = true;
-                                       if(wp.cnt<bestvalue)
-                                       {
-                                               best = wp;
-                                               bestvalue = wp.cnt;
-                                       }
-                               }
-                       }
-               }
-
-               if(best)
-               {
-               ///     dprint("waypoints around target were found\n");
-               //      te_lightning2(world, '0 0 0', best.origin);
-               //      te_knightspike(best.origin);
-
-                       navigation_routerating(best, ratingscale, 4000);
-                       best.cnt += 1;
-
-                       self.havocbot_attack_time = 0;
-
-                       if(checkpvs(self.view_ofs,ad))
-                       if(checkpvs(self.view_ofs,best))
-                       {
-                       //      dprint("increasing attack time for this target\n");
-                               self.havocbot_attack_time = time + 2;
-                       }
-               }
-       }
-}
-
-void havocbot_role_ast_offense()
-{SELFPARAM();
-       if(self.deadflag != DEAD_NO)
-       {
-               self.havocbot_attack_time = 0;
-               havocbot_ast_reset_role(self);
-               return;
-       }
-
-       // Set the role timeout if necessary
-       if (!self.havocbot_role_timeout)
-               self.havocbot_role_timeout = time + 120;
-
-       if (time > self.havocbot_role_timeout)
-       {
-               havocbot_ast_reset_role(self);
-               return;
-       }
-
-       if(self.havocbot_attack_time>time)
-               return;
-
-       if (self.bot_strategytime < time)
-       {
-               navigation_goalrating_start();
-               havocbot_goalrating_enemyplayers(20000, self.origin, 650);
-               havocbot_goalrating_ast_targets(20000);
-               havocbot_goalrating_items(15000, self.origin, 10000);
-               navigation_goalrating_end();
-
-               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
-       }
-}
-
-void havocbot_role_ast_defense()
-{SELFPARAM();
-       if(self.deadflag != DEAD_NO)
-       {
-               self.havocbot_attack_time = 0;
-               havocbot_ast_reset_role(self);
-               return;
-       }
-
-       // Set the role timeout if necessary
-       if (!self.havocbot_role_timeout)
-               self.havocbot_role_timeout = time + 120;
-
-       if (time > self.havocbot_role_timeout)
-       {
-               havocbot_ast_reset_role(self);
-               return;
-       }
-
-       if(self.havocbot_attack_time>time)
-               return;
-
-       if (self.bot_strategytime < time)
-       {
-               navigation_goalrating_start();
-               havocbot_goalrating_enemyplayers(20000, self.origin, 3000);
-               havocbot_goalrating_ast_targets(20000);
-               havocbot_goalrating_items(15000, self.origin, 10000);
-               navigation_goalrating_end();
-
-               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
-       }
-}
-
-void havocbot_role_ast_setrole(entity bot, float role)
-{
-       switch(role)
-       {
-               case HAVOCBOT_AST_ROLE_DEFENSE:
-                       bot.havocbot_role = havocbot_role_ast_defense;
-                       bot.havocbot_role_flags = HAVOCBOT_AST_ROLE_DEFENSE;
-                       bot.havocbot_role_timeout = 0;
-                       break;
-               case HAVOCBOT_AST_ROLE_OFFENSE:
-                       bot.havocbot_role = havocbot_role_ast_offense;
-                       bot.havocbot_role_flags = HAVOCBOT_AST_ROLE_OFFENSE;
-                       bot.havocbot_role_timeout = 0;
-                       break;
-       }
-}
-
-void havocbot_ast_reset_role(entity bot)
-{SELFPARAM();
-       if(self.deadflag != DEAD_NO)
-               return;
-
-       if(bot.team == assault_attacker_team)
-               havocbot_role_ast_setrole(bot, HAVOCBOT_AST_ROLE_OFFENSE);
-       else
-               havocbot_role_ast_setrole(bot, HAVOCBOT_AST_ROLE_DEFENSE);
-}
-
-// mutator hooks
-MUTATOR_HOOKFUNCTION(assault_PlayerSpawn)
-{SELFPARAM();
-       if(self.team == assault_attacker_team)
-               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_ASSAULT_ATTACKING);
-       else
-               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_ASSAULT_DEFENDING);
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(assault_TurretSpawn)
-{SELFPARAM();
-       if(!self.team || self.team == MAX_SHOT_DISTANCE)
-               self.team = 5; // this gets reversed when match starts?
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(assault_VehicleSpawn)
-{SELFPARAM();
-       self.nextthink = time + 0.5;
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(assault_BotRoles)
-{SELFPARAM();
-       havocbot_ast_reset_role(self);
-       return true;
-}
-
-MUTATOR_HOOKFUNCTION(assault_PlayHitsound)
-{
-       return (frag_victim.classname == "func_assault_destructible");
-}
-
-// scoreboard setup
-void assault_ScoreRules()
-{
-       ScoreRules_basics(2, SFL_SORT_PRIO_SECONDARY, SFL_SORT_PRIO_SECONDARY, true);
-       ScoreInfo_SetLabel_TeamScore(  ST_ASSAULT_OBJECTIVES,    "objectives",      SFL_SORT_PRIO_PRIMARY);
-       ScoreInfo_SetLabel_PlayerScore(SP_ASSAULT_OBJECTIVES,    "objectives",      SFL_SORT_PRIO_PRIMARY);
-       ScoreRules_basics_end();
-}
-
-MUTATOR_DEFINITION(gamemode_assault)
-{
-       MUTATOR_HOOK(PlayerSpawn, assault_PlayerSpawn, CBC_ORDER_ANY);
-       MUTATOR_HOOK(TurretSpawn, assault_TurretSpawn, CBC_ORDER_ANY);
-       MUTATOR_HOOK(VehicleSpawn, assault_VehicleSpawn, CBC_ORDER_ANY);
-       MUTATOR_HOOK(HavocBot_ChooseRole, assault_BotRoles, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayHitsound, assault_PlayHitsound, 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.");
-               assault_ScoreRules();
-       }
-
-       MUTATOR_ONROLLBACK_OR_REMOVE
-       {
-               // we actually cannot roll back assault_Initialize here
-               // BUT: we don't need to! If this gets called, adding always
-               // succeeds.
-       }
-
-       MUTATOR_ONREMOVE
-       {
-               LOG_INFO("This is a game type and it cannot be removed at runtime.");
-               return -1;
-       }
-
-       return 0;
-}
diff --git a/qcsrc/server/mutators/gamemode_assault.qh b/qcsrc/server/mutators/gamemode_assault.qh
deleted file mode 100644 (file)
index 1266492..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef GAMEMODE_ASSAULT_H
-#define GAMEMODE_ASSAULT_H
-// sprites
-.entity assault_decreaser;
-.entity assault_sprite;
-
-// legacy bot defs
-const int HAVOCBOT_AST_ROLE_NONE = 0;
-const int HAVOCBOT_AST_ROLE_DEFENSE = 2;
-const int HAVOCBOT_AST_ROLE_OFFENSE = 4;
-
-.int havocbot_role_flags;
-.float havocbot_attack_time;
-
-.void() havocbot_role;
-.void() havocbot_previous_role;
-
-void() havocbot_role_ast_defense;
-void() havocbot_role_ast_offense;
-.entity havocbot_ast_target;
-
-void(entity bot) havocbot_ast_reset_role;
-
-void(float ratingscale, vector org, float sradius) havocbot_goalrating_items;
-void(float ratingscale, vector org, float sradius) havocbot_goalrating_enemyplayers;
-
-// scoreboard stuff
-const float ST_ASSAULT_OBJECTIVES = 1;
-const float SP_ASSAULT_OBJECTIVES = 4;
-
-// predefined spawnfuncs
-void target_objective_decrease_activate();
-#endif
diff --git a/qcsrc/server/mutators/gamemode_ca.qc b/qcsrc/server/mutators/gamemode_ca.qc
deleted file mode 100644 (file)
index 42aa4a2..0000000
+++ /dev/null
@@ -1,420 +0,0 @@
-#include "gamemode_ca.qh"
-
-#include "gamemode.qh"
-
-float ca_teams;
-float allowed_to_spawn;
-
-const float ST_CA_ROUNDS = 1;
-void ca_ScoreRules(float teams)
-{
-       ScoreRules_basics(teams, SFL_SORT_PRIO_PRIMARY, 0, true);
-       ScoreInfo_SetLabel_TeamScore(ST_CA_ROUNDS, "rounds", SFL_SORT_PRIO_PRIMARY);
-       ScoreRules_basics_end();
-}
-
-void CA_count_alive_players()
-{
-       entity e;
-       total_players = redalive = bluealive = yellowalive = pinkalive = 0;
-       FOR_EACH_PLAYER(e) {
-               if(e.team == NUM_TEAM_1)
-               {
-                       ++total_players;
-                       if (e.health >= 1) ++redalive;
-               }
-               else if(e.team == NUM_TEAM_2)
-               {
-                       ++total_players;
-                       if (e.health >= 1) ++bluealive;
-               }
-               else if(e.team == NUM_TEAM_3)
-               {
-                       ++total_players;
-                       if (e.health >= 1) ++yellowalive;
-               }
-               else if(e.team == NUM_TEAM_4)
-               {
-                       ++total_players;
-                       if (e.health >= 1) ++pinkalive;
-               }
-       }
-       FOR_EACH_REALCLIENT(e) {
-               e.redalive_stat = redalive;
-               e.bluealive_stat = bluealive;
-               e.yellowalive_stat = yellowalive;
-               e.pinkalive_stat = pinkalive;
-       }
-}
-
-float CA_GetWinnerTeam()
-{
-       float winner_team = 0;
-       if(redalive >= 1)
-               winner_team = NUM_TEAM_1;
-       if(bluealive >= 1)
-       {
-               if(winner_team) return 0;
-               winner_team = NUM_TEAM_2;
-       }
-       if(yellowalive >= 1)
-       {
-               if(winner_team) return 0;
-               winner_team = NUM_TEAM_3;
-       }
-       if(pinkalive >= 1)
-       {
-               if(winner_team) return 0;
-               winner_team = NUM_TEAM_4;
-       }
-       if(winner_team)
-               return winner_team;
-       return -1; // no player left
-}
-
-#define CA_ALIVE_TEAMS() ((redalive > 0) + (bluealive > 0) + (yellowalive > 0) + (pinkalive > 0))
-#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;
-       }
-
-       CA_count_alive_players();
-       if(CA_ALIVE_TEAMS() > 1)
-               return 0;
-
-       float winner_team = CA_GetWinnerTeam();
-       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_CA_ROUNDS, +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);
-       }
-
-       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;
-}
-
-void CA_RoundStart()
-{
-       if(warmup_stage)
-               allowed_to_spawn = true;
-       else
-               allowed_to_spawn = false;
-}
-
-float CA_CheckTeams()
-{
-       static float prev_missing_teams_mask;
-       allowed_to_spawn = true;
-       CA_count_alive_players();
-       if(CA_ALIVE_TEAMS_OK())
-       {
-               if(prev_missing_teams_mask > 0)
-                       Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_MISSING_TEAMS);
-               prev_missing_teams_mask = -1;
-               return 1;
-       }
-       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)
-       {
-               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)
-{SELFPARAM();
-       self.caplayer = 1;
-       if(!warmup_stage)
-               eliminatedPlayers.SendFlags |= 1;
-       return 1;
-}
-
-MUTATOR_HOOKFUNCTION(ca_PutClientInServer)
-{SELFPARAM();
-       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
-               if(!self.caplayer)
-               {
-                       self.caplayer = 0.5;
-                       if(IS_REAL_CLIENT(self))
-                               Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_CA_JOIN_LATE);
-               }
-       }
-       return 1;
-}
-
-MUTATOR_HOOKFUNCTION(ca_reset_map_players)
-{SELFPARAM();
-       entity e;
-       FOR_EACH_CLIENT(e)
-       {
-               setself(e);
-               self.killcount = 0;
-               if(!self.caplayer && IS_BOT_CLIENT(self))
-               {
-                       self.team = -1;
-                       self.caplayer = 1;
-               }
-               if(self.caplayer)
-               {
-                       self.classname = "player";
-                       self.caplayer = 1;
-                       PutClientInServer();
-               }
-       }
-       return 1;
-}
-
-MUTATOR_HOOKFUNCTION(ca_ClientConnect)
-{SELFPARAM();
-       self.classname = "observer";
-       return 1;
-}
-
-MUTATOR_HOOKFUNCTION(ca_reset_map_global)
-{
-       allowed_to_spawn = true;
-       return 1;
-}
-
-MUTATOR_HOOKFUNCTION(ca_GetTeamCount)
-{
-       ret_float = ca_teams;
-       return 0;
-}
-
-entity ca_LastPlayerForTeam()
-{SELFPARAM();
-       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)
-{SELFPARAM();
-       ca_LastPlayerForTeam_Notify();
-       if(!allowed_to_spawn)
-               self.respawn_flags =  RESPAWN_SILENT;
-       if(!warmup_stage)
-               eliminatedPlayers.SendFlags |= 1;
-       return 1;
-}
-
-MUTATOR_HOOKFUNCTION(ca_ClientDisconnect)
-{SELFPARAM();
-       if(self.caplayer == 1)
-               ca_LastPlayerForTeam_Notify();
-       return 1;
-}
-
-MUTATOR_HOOKFUNCTION(ca_ForbidPlayerScore_Clear)
-{
-       return 1;
-}
-
-MUTATOR_HOOKFUNCTION(ca_MakePlayerObserver)
-{SELFPARAM();
-       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;
-}
-
-MUTATOR_HOOKFUNCTION(ca_ForbidThrowCurrentWeapon)
-{
-       return 1;
-}
-
-MUTATOR_HOOKFUNCTION(ca_GiveFragsForKill)
-{
-       frag_score = 0; // score will be given to the winner team when the round ends
-       return 1;
-}
-
-MUTATOR_HOOKFUNCTION(ca_SetStartItems)
-{
-       start_items &= ~IT_UNLIMITED_AMMO;
-       start_health       = warmup_start_health       = cvar("g_lms_start_health");
-       start_armorvalue   = warmup_start_armorvalue   = cvar("g_lms_start_armor");
-       start_ammo_shells  = warmup_start_ammo_shells  = cvar("g_lms_start_ammo_shells");
-       start_ammo_nails   = warmup_start_ammo_nails   = cvar("g_lms_start_ammo_nails");
-       start_ammo_rockets = warmup_start_ammo_rockets = cvar("g_lms_start_ammo_rockets");
-       start_ammo_cells   = warmup_start_ammo_cells   = cvar("g_lms_start_ammo_cells");
-       start_ammo_plasma  = warmup_start_ammo_plasma  = cvar("g_lms_start_ammo_plasma");
-       start_ammo_fuel    = warmup_start_ammo_fuel    = cvar("g_lms_start_ammo_fuel");
-
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(ca_PlayerDamage)
-{
-       if(IS_PLAYER(frag_target))
-       if(frag_target.deadflag == DEAD_NO)
-       if(frag_target == frag_attacker || SAME_TEAM(frag_target, frag_attacker) || frag_deathtype == DEATH_FALL.m_id)
-               frag_damage = 0;
-
-       frag_mirrordamage = 0;
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ca_FilterItem)
-{SELFPARAM();
-       if(autocvar_g_powerups <= 0)
-       if(self.flags & FL_POWERUP)
-               return true;
-
-       if(autocvar_g_pickup_items <= 0)
-               return true;
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ca_PlayerDamage_SplitHealthArmor)
-{
-       float excess = max(0, frag_damage - damage_take - damage_save);
-
-       if(frag_target != frag_attacker && IS_PLAYER(frag_attacker))
-               PlayerTeamScore_Add(frag_attacker, SP_SCORE, ST_SCORE, (frag_damage - excess) * autocvar_g_ca_damage2score_multiplier);
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ca_PlayerRegen)
-{
-       // no regeneration in CA
-       return true;
-}
-
-MUTATOR_HOOKFUNCTION(ca_CountFrags)
-{
-       // announce remaining frags
-       return true;
-}
-
-void ca_Initialize()
-{
-       allowed_to_spawn = true;
-
-       ca_teams = autocvar_g_ca_teams_override;
-       if(ca_teams < 2)
-               ca_teams = autocvar_g_ca_teams;
-       ca_teams = bound(2, ca_teams, 4);
-       ret_float = ca_teams;
-       ca_ScoreRules(ca_teams);
-
-       round_handler_Spawn(CA_CheckTeams, CA_CheckWinner, CA_RoundStart);
-       round_handler_Init(5, autocvar_g_ca_warmup, autocvar_g_ca_round_timelimit);
-
-       addstat(STAT_REDALIVE, AS_INT, redalive_stat);
-       addstat(STAT_BLUEALIVE, AS_INT, bluealive_stat);
-       addstat(STAT_YELLOWALIVE, AS_INT, yellowalive_stat);
-       addstat(STAT_PINKALIVE, AS_INT, pinkalive_stat);
-
-       EliminatedPlayers_Init(ca_isEliminated);
-}
-
-MUTATOR_DEFINITION(gamemode_ca)
-{
-       MUTATOR_HOOK(PlayerSpawn, ca_PlayerSpawn, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PutClientInServer, ca_PutClientInServer, CBC_ORDER_ANY);
-       MUTATOR_HOOK(MakePlayerObserver, ca_MakePlayerObserver, CBC_ORDER_ANY);
-       MUTATOR_HOOK(ClientConnect, ca_ClientConnect, CBC_ORDER_ANY);
-       MUTATOR_HOOK(reset_map_global, ca_reset_map_global, CBC_ORDER_ANY);
-       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);
-       MUTATOR_HOOK(SetStartItems, ca_SetStartItems, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerDamage_Calculate, ca_PlayerDamage, CBC_ORDER_ANY);
-       MUTATOR_HOOK(FilterItem, ca_FilterItem, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerDamage_SplitHealthArmor, ca_PlayerDamage_SplitHealthArmor, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerRegen, ca_PlayerRegen, CBC_ORDER_ANY);
-       MUTATOR_HOOK(Scores_CountFragsRemaining, ca_CountFrags, 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.");
-               ca_Initialize();
-       }
-
-       MUTATOR_ONREMOVE
-       {
-               LOG_INFO("This is a game type and it cannot be removed at runtime.");
-               return -1;
-       }
-
-       return 0;
-}
diff --git a/qcsrc/server/mutators/gamemode_ca.qh b/qcsrc/server/mutators/gamemode_ca.qh
deleted file mode 100644 (file)
index bf6686d..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-#ifndef GAMEMODE_CA_H
-#define GAMEMODE_CA_H
-// should be removed in the future, as other code should not have to care
-.float caplayer; // 0.5 if scheduled to join the next round
-#endif
diff --git a/qcsrc/server/mutators/gamemode_ctf.qc b/qcsrc/server/mutators/gamemode_ctf.qc
deleted file mode 100644 (file)
index 0c68bbf..0000000
+++ /dev/null
@@ -1,2470 +0,0 @@
-#include "gamemode_ctf.qh"
-
-#include "gamemode.qh"
-
-#ifdef SVQC
-#include "../../common/vehicles/all.qh"
-#include "../teamplay.qh"
-#endif
-
-#include "../../lib/warpzone/common.qh"
-
-void ctf_FakeTimeLimit(entity e, float t)
-{
-       msg_entity = e;
-       WriteByte(MSG_ONE, 3); // svc_updatestat
-       WriteByte(MSG_ONE, 236); // STAT_TIMELIMIT
-       if(t < 0)
-               WriteCoord(MSG_ONE, autocvar_timelimit);
-       else
-               WriteCoord(MSG_ONE, (t + 1) / 60);
-}
-
-void ctf_EventLog(string mode, int flagteam, entity actor) // use an alias for easy changing and quick editing later
-{
-       if(autocvar_sv_eventlog)
-               GameLogEcho(sprintf(":ctf:%s:%d:%d:%s", mode, flagteam, actor.team, ((actor != world) ? ftos(actor.playerid) : "")));
-               //GameLogEcho(strcat(":ctf:", mode, ":", ftos(flagteam), ((actor != world) ? (strcat(":", ftos(actor.playerid))) : "")));
-}
-
-void ctf_CaptureRecord(entity flag, entity player)
-{
-       float cap_record = ctf_captimerecord;
-       float cap_time = (time - flag.ctf_pickuptime);
-       string refername = db_get(ServerProgsDB, strcat(GetMapname(), "/captimerecord/netname"));
-
-       // notify about shit
-       if(ctf_oneflag) { Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_CTF_CAPTURE_NEUTRAL, player.netname); }
-       else if(!ctf_captimerecord) { Send_Notification(NOTIF_ALL, world, MSG_CHOICE, APP_TEAM_ENT_4(flag, CHOICE_CTF_CAPTURE_TIME_), player.netname, (cap_time * 100)); }
-       else if(cap_time < cap_record) { Send_Notification(NOTIF_ALL, world, MSG_CHOICE, APP_TEAM_ENT_4(flag, CHOICE_CTF_CAPTURE_BROKEN_), player.netname, refername, (cap_time * 100), (cap_record * 100)); }
-       else { Send_Notification(NOTIF_ALL, world, MSG_CHOICE, APP_TEAM_ENT_4(flag, CHOICE_CTF_CAPTURE_UNBROKEN_), player.netname, refername, (cap_time * 100), (cap_record * 100)); }
-
-       // write that shit in the database
-       if(!ctf_oneflag) // but not in 1-flag mode
-       if((!ctf_captimerecord) || (cap_time < cap_record))
-       {
-               ctf_captimerecord = cap_time;
-               db_put(ServerProgsDB, strcat(GetMapname(), "/captimerecord/time"), ftos(cap_time));
-               db_put(ServerProgsDB, strcat(GetMapname(), "/captimerecord/netname"), player.netname);
-               write_recordmarker(player, (time - cap_time), cap_time);
-       }
-}
-
-void ctf_FlagcarrierWaypoints(entity player)
-{
-       WaypointSprite_Spawn(WP_FlagCarrier, 0, 0, player, FLAG_WAYPOINT_OFFSET, world, player.team, player, wps_flagcarrier, true, RADARICON_FLAG);
-       WaypointSprite_UpdateMaxHealth(player.wps_flagcarrier, '1 0 0' * healtharmor_maxdamage(start_health, start_armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id) * 2);
-       WaypointSprite_UpdateHealth(player.wps_flagcarrier, '1 0 0' * healtharmor_maxdamage(player.health, player.armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id));
-       WaypointSprite_UpdateTeamRadar(player.wps_flagcarrier, RADARICON_FLAGCARRIER, WPCOLOR_FLAGCARRIER(player.team));
-}
-
-void ctf_CalculatePassVelocity(entity flag, vector to, vector from, float turnrate)
-{
-       float current_distance = vlen((('1 0 0' * to.x) + ('0 1 0' * to.y)) - (('1 0 0' * from.x) + ('0 1 0' * from.y))); // for the sake of this check, exclude Z axis
-       float initial_height = min(autocvar_g_ctf_pass_arc_max, (flag.pass_distance * tanh(autocvar_g_ctf_pass_arc)));
-       float current_height = (initial_height * min(1, (current_distance / flag.pass_distance)));
-       //print("current_height = ", ftos(current_height), ", initial_height = ", ftos(initial_height), ".\n");
-
-       vector targpos;
-       if(current_height) // make sure we can actually do this arcing path
-       {
-               targpos = (to + ('0 0 1' * current_height));
-               WarpZone_TraceLine(flag.origin, targpos, MOVE_NOMONSTERS, flag);
-               if(trace_fraction < 1)
-               {
-                       //print("normal arc line failed, trying to find new pos...");
-                       WarpZone_TraceLine(to, targpos, MOVE_NOMONSTERS, flag);
-                       targpos = (trace_endpos + FLAG_PASS_ARC_OFFSET);
-                       WarpZone_TraceLine(flag.origin, targpos, MOVE_NOMONSTERS, flag);
-                       if(trace_fraction < 1) { targpos = to; /* print(" ^1FAILURE^7, reverting to original direction.\n"); */ }
-                       /*else { print(" ^3SUCCESS^7, using new arc line.\n"); } */
-               }
-       }
-       else { targpos = to; }
-
-       //flag.angles = normalize(('0 1 0' * to_y) - ('0 1 0' * from_y));
-
-       vector desired_direction = normalize(targpos - from);
-       if(turnrate) { flag.velocity = (normalize(normalize(flag.velocity) + (desired_direction * autocvar_g_ctf_pass_turnrate)) * autocvar_g_ctf_pass_velocity); }
-       else { flag.velocity = (desired_direction * autocvar_g_ctf_pass_velocity); }
-}
-
-bool ctf_CheckPassDirection(vector head_center, vector passer_center, vector passer_angle, vector nearest_to_passer)
-{
-       if(autocvar_g_ctf_pass_directional_max || autocvar_g_ctf_pass_directional_min)
-       {
-               // directional tracing only
-               float spreadlimit;
-               makevectors(passer_angle);
-
-               // find the closest point on the enemy to the center of the attack
-               float h; // hypotenuse, which is the distance between attacker to head
-               float a; // adjacent side, which is the distance between attacker and the point on w_shotdir that is closest to head.origin
-
-               h = vlen(head_center - passer_center);
-               a = h * (normalize(head_center - passer_center) * v_forward);
-
-               vector nearest_on_line = (passer_center + a * v_forward);
-               float distance_from_line = vlen(nearest_to_passer - nearest_on_line);
-
-               spreadlimit = (autocvar_g_ctf_pass_radius ? min(1, (vlen(passer_center - nearest_on_line) / autocvar_g_ctf_pass_radius)) : 1);
-               spreadlimit = (autocvar_g_ctf_pass_directional_min * (1 - spreadlimit) + autocvar_g_ctf_pass_directional_max * spreadlimit);
-
-               if(spreadlimit && (distance_from_line <= spreadlimit) && ((vlen(normalize(head_center - passer_center) - v_forward) * RAD2DEG) <= 90))
-                       { return true; }
-               else
-                       { return false; }
-       }
-       else { return true; }
-}
-
-
-// =======================
-// CaptureShield Functions
-// =======================
-
-bool ctf_CaptureShield_CheckStatus(entity p)
-{
-       int s, s2, s3, s4, se, se2, se3, se4, sr, ser;
-       entity e;
-       int players_worseeq, players_total;
-
-       if(ctf_captureshield_max_ratio <= 0)
-               return false;
-
-       s = PlayerScore_Add(p, SP_CTF_CAPS, 0);
-       s2 = PlayerScore_Add(p, SP_CTF_PICKUPS, 0);
-       s3 = PlayerScore_Add(p, SP_CTF_RETURNS, 0);
-       s4 = PlayerScore_Add(p, SP_CTF_FCKILLS, 0);
-
-       sr = ((s - s2) + (s3 + s4));
-
-       if(sr >= -ctf_captureshield_min_negscore)
-               return false;
-
-       players_total = players_worseeq = 0;
-       FOR_EACH_PLAYER(e)
-       {
-               if(DIFF_TEAM(e, p))
-                       continue;
-               se = PlayerScore_Add(e, SP_CTF_CAPS, 0);
-               se2 = PlayerScore_Add(e, SP_CTF_PICKUPS, 0);
-               se3 = PlayerScore_Add(e, SP_CTF_RETURNS, 0);
-               se4 = PlayerScore_Add(e, SP_CTF_FCKILLS, 0);
-
-               ser = ((se - se2) + (se3 + se4));
-
-               if(ser <= sr)
-                       ++players_worseeq;
-               ++players_total;
-       }
-
-       // player is in the worse half, if >= half the players are better than him, or consequently, if < half of the players are worse
-       // use this rule here
-
-       if(players_worseeq >= players_total * ctf_captureshield_max_ratio)
-               return false;
-
-       return true;
-}
-
-void ctf_CaptureShield_Update(entity player, bool wanted_status)
-{
-       bool updated_status = ctf_CaptureShield_CheckStatus(player);
-       if((wanted_status == player.ctf_captureshielded) && (updated_status != wanted_status)) // 0: shield only, 1: unshield only
-       {
-               Send_Notification(NOTIF_ONE, player, MSG_CENTER, ((updated_status) ? CENTER_CTF_CAPTURESHIELD_SHIELDED : CENTER_CTF_CAPTURESHIELD_FREE));
-               player.ctf_captureshielded = updated_status;
-       }
-}
-
-bool ctf_CaptureShield_Customize()
-{SELFPARAM();
-       if(!other.ctf_captureshielded) { return false; }
-       if(CTF_SAMETEAM(self, other)) { return false; }
-
-       return true;
-}
-
-void ctf_CaptureShield_Touch()
-{SELFPARAM();
-       if(!other.ctf_captureshielded) { return; }
-       if(CTF_SAMETEAM(self, other)) { return; }
-
-       vector mymid = (self.absmin + self.absmax) * 0.5;
-       vector othermid = (other.absmin + other.absmax) * 0.5;
-
-       Damage(other, self, self, 0, DEATH_HURTTRIGGER.m_id, mymid, normalize(othermid - mymid) * ctf_captureshield_force);
-       if(IS_REAL_CLIENT(other)) { Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_CTF_CAPTURESHIELD_SHIELDED); }
-}
-
-void ctf_CaptureShield_Spawn(entity flag)
-{SELFPARAM();
-       entity shield = spawn();
-
-       shield.enemy = self;
-       shield.team = self.team;
-       shield.touch = ctf_CaptureShield_Touch;
-       shield.customizeentityforclient = ctf_CaptureShield_Customize;
-       shield.classname = "ctf_captureshield";
-       shield.effects = EF_ADDITIVE;
-       shield.movetype = MOVETYPE_NOCLIP;
-       shield.solid = SOLID_TRIGGER;
-       shield.avelocity = '7 0 11';
-       shield.scale = 0.5;
-
-       setorigin(shield, self.origin);
-       setmodel(shield, MDL_CTF_SHIELD);
-       setsize(shield, shield.scale * shield.mins, shield.scale * shield.maxs);
-}
-
-
-// ====================
-// Drop/Pass/Throw Code
-// ====================
-
-void ctf_Handle_Drop(entity flag, entity player, int droptype)
-{
-       // declarations
-       player = (player ? player : flag.pass_sender);
-
-       // main
-       flag.movetype = MOVETYPE_TOSS;
-       flag.takedamage = DAMAGE_YES;
-       flag.angles = '0 0 0';
-       flag.health = flag.max_flag_health;
-       flag.ctf_droptime = time;
-       flag.ctf_dropper = player;
-       flag.ctf_status = FLAG_DROPPED;
-
-       // messages and sounds
-       Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_LOST_) : INFO_CTF_LOST_NEUTRAL), player.netname);
-       _sound(flag, CH_TRIGGER, flag.snd_flag_dropped, VOL_BASE, ATTEN_NONE);
-       ctf_EventLog("dropped", player.team, player);
-
-       // scoring
-       PlayerTeamScore_AddScore(player, -autocvar_g_ctf_score_penalty_drop);
-       PlayerScore_Add(player, SP_CTF_DROPS, 1);
-
-       // waypoints
-       if(autocvar_g_ctf_flag_dropped_waypoint) {
-               entity wp = WaypointSprite_Spawn(WP_FlagDropped, 0, 0, flag, FLAG_WAYPOINT_OFFSET, world, ((autocvar_g_ctf_flag_dropped_waypoint == 2) ? 0 : player.team), flag, wps_flagdropped, true, RADARICON_FLAG);
-               wp.colormod = WPCOLOR_DROPPEDFLAG(flag.team);
-       }
-
-       if(autocvar_g_ctf_flag_return_time || (autocvar_g_ctf_flag_return_damage && autocvar_g_ctf_flag_health))
-       {
-               WaypointSprite_UpdateMaxHealth(flag.wps_flagdropped, flag.max_flag_health);
-               WaypointSprite_UpdateHealth(flag.wps_flagdropped, flag.health);
-       }
-
-       player.throw_antispam = time + autocvar_g_ctf_pass_wait;
-
-       if(droptype == DROP_PASS)
-       {
-               flag.pass_distance = 0;
-               flag.pass_sender = world;
-               flag.pass_target = world;
-       }
-}
-
-void ctf_Handle_Retrieve(entity flag, entity player)
-{
-       entity tmp_player; // temporary entity which the FOR_EACH_PLAYER loop uses to scan players
-       entity sender = flag.pass_sender;
-
-       // transfer flag to player
-       flag.owner = player;
-       flag.owner.flagcarried = flag;
-
-       // reset flag
-       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;
-       flag.angles = '0 0 0';
-       flag.ctf_status = FLAG_CARRY;
-
-       // messages and sounds
-       _sound(player, CH_TRIGGER, flag.snd_flag_pass, VOL_BASE, ATTEN_NORM);
-       ctf_EventLog("receive", flag.team, player);
-
-       FOR_EACH_REALPLAYER(tmp_player)
-       {
-               if(tmp_player == sender)
-                       Send_Notification(NOTIF_ONE, tmp_player, MSG_CENTER, ((flag.team) ? APP_TEAM_ENT_4(flag, CENTER_CTF_PASS_SENT_) : CENTER_CTF_PASS_SENT_NEUTRAL), player.netname);
-               else if(tmp_player == player)
-                       Send_Notification(NOTIF_ONE, tmp_player, MSG_CENTER, ((flag.team) ? APP_TEAM_ENT_4(flag, CENTER_CTF_PASS_RECEIVED_) : CENTER_CTF_PASS_RECEIVED_NEUTRAL), sender.netname);
-               else if(SAME_TEAM(tmp_player, sender))
-                       Send_Notification(NOTIF_ONE, tmp_player, MSG_CENTER, ((flag.team) ? APP_TEAM_ENT_4(flag, CENTER_CTF_PASS_OTHER_) : CENTER_CTF_PASS_OTHER_NEUTRAL), sender.netname, player.netname);
-       }
-
-       // create new waypoint
-       ctf_FlagcarrierWaypoints(player);
-
-       sender.throw_antispam = time + autocvar_g_ctf_pass_wait;
-       player.throw_antispam = sender.throw_antispam;
-
-       flag.pass_distance = 0;
-       flag.pass_sender = world;
-       flag.pass_target = world;
-}
-
-void ctf_Handle_Throw(entity player, entity receiver, int droptype)
-{
-       entity flag = player.flagcarried;
-       vector targ_origin, flag_velocity;
-
-       if(!flag) { return; }
-       if((droptype == DROP_PASS) && !receiver) { return; }
-
-       if(flag.speedrunning) { ctf_RespawnFlag(flag); return; }
-
-       // reset the flag
-       setattachment(flag, world, "");
-       setorigin(flag, player.origin + FLAG_DROP_OFFSET);
-       flag.owner.flagcarried = world;
-       flag.owner = world;
-       flag.solid = SOLID_TRIGGER;
-       flag.ctf_dropper = player;
-       flag.ctf_droptime = time;
-
-       flag.flags = FL_ITEM | FL_NOTARGET; // clear FL_ONGROUND for MOVETYPE_TOSS
-
-       switch(droptype)
-       {
-               case DROP_PASS:
-               {
-                       // warpzone support:
-                       // for the examples, we assume player -> wz1 -> ... -> wzn -> receiver
-                       // findradius has already put wzn ... wz1 into receiver's warpzone parameters!
-                       WarpZone_RefSys_Copy(flag, receiver);
-                       WarpZone_RefSys_AddInverse(flag, receiver); // wz1^-1 ... wzn^-1 receiver
-                       targ_origin = WarpZone_RefSys_TransformOrigin(receiver, flag, (0.5 * (receiver.absmin + receiver.absmax))); // this is target origin as seen by the flag
-
-                       flag.pass_distance = vlen((('1 0 0' * targ_origin.x) + ('0 1 0' * targ_origin.y)) - (('1 0 0' *  player.origin.x) + ('0 1 0' *  player.origin.y))); // for the sake of this check, exclude Z axis
-                       ctf_CalculatePassVelocity(flag, targ_origin, player.origin, false);
-
-                       // main
-                       flag.movetype = MOVETYPE_FLY;
-                       flag.takedamage = DAMAGE_NO;
-                       flag.pass_sender = player;
-                       flag.pass_target = receiver;
-                       flag.ctf_status = FLAG_PASSING;
-
-                       // other
-                       _sound(player, CH_TRIGGER, flag.snd_flag_touch, VOL_BASE, ATTEN_NORM);
-                       WarpZone_TrailParticles(world, _particleeffectnum(flag.passeffect), player.origin, targ_origin);
-                       ctf_EventLog("pass", flag.team, player);
-                       break;
-               }
-
-               case DROP_THROW:
-               {
-                       makevectors((player.v_angle.y * '0 1 0') + (bound(autocvar_g_ctf_throw_angle_min, player.v_angle.x, autocvar_g_ctf_throw_angle_max) * '1 0 0'));
-
-                       flag_velocity = (('0 0 1' * autocvar_g_ctf_throw_velocity_up) + ((v_forward * autocvar_g_ctf_throw_velocity_forward) * ((player.items & ITEM_Strength.m_itemid) ? autocvar_g_ctf_throw_strengthmultiplier : 1)));
-                       flag.velocity = W_CalculateProjectileVelocity(player.velocity, flag_velocity, false);
-                       ctf_Handle_Drop(flag, player, droptype);
-                       break;
-               }
-
-               case DROP_RESET:
-               {
-                       flag.velocity = '0 0 0'; // do nothing
-                       break;
-               }
-
-               default:
-               case DROP_NORMAL:
-               {
-                       flag.velocity = W_CalculateProjectileVelocity(player.velocity, (('0 0 1' * autocvar_g_ctf_drop_velocity_up) + ((('0 1 0' * crandom()) + ('1 0 0' * crandom())) * autocvar_g_ctf_drop_velocity_side)), false);
-                       ctf_Handle_Drop(flag, player, droptype);
-                       break;
-               }
-       }
-
-       // kill old waypointsprite
-       WaypointSprite_Ping(player.wps_flagcarrier);
-       WaypointSprite_Kill(player.wps_flagcarrier);
-
-       if(player.wps_enemyflagcarrier)
-               WaypointSprite_Kill(player.wps_enemyflagcarrier);
-
-       // captureshield
-       ctf_CaptureShield_Update(player, 0); // shield player from picking up flag
-}
-
-
-// ==============
-// Event Handlers
-// ==============
-
-void ctf_Handle_Capture(entity flag, entity toucher, int capturetype)
-{
-       entity enemy_flag = ((capturetype == CAPTURE_NORMAL) ? toucher.flagcarried : toucher);
-       entity player = ((capturetype == CAPTURE_NORMAL) ? toucher : enemy_flag.ctf_dropper);
-       entity player_team_flag = world, tmp_entity;
-       float old_time, new_time;
-
-       if(!player) { return; } // without someone to give the reward to, we can't possibly cap
-       if(CTF_DIFFTEAM(player, flag)) { return; }
-
-       if(ctf_oneflag)
-       for(tmp_entity = ctf_worldflaglist; tmp_entity; tmp_entity = tmp_entity.ctf_worldflagnext)
-       if(SAME_TEAM(tmp_entity, player))
-       {
-               player_team_flag = tmp_entity;
-               break;
-       }
-
-       nades_GiveBonus(player, autocvar_g_nades_bonus_score_high );
-
-       player.throw_prevtime = time;
-       player.throw_count = 0;
-
-       // messages and sounds
-       Send_Notification(NOTIF_ONE, player, MSG_CENTER, ((enemy_flag.team) ? APP_TEAM_ENT_4(enemy_flag, CENTER_CTF_CAPTURE_) : CENTER_CTF_CAPTURE_NEUTRAL));
-       ctf_CaptureRecord(enemy_flag, player);
-       _sound(player, CH_TRIGGER, ((ctf_oneflag) ? player_team_flag.snd_flag_capture : ((DIFF_TEAM(player, flag)) ? enemy_flag.snd_flag_capture : flag.snd_flag_capture)), VOL_BASE, ATTEN_NONE);
-
-       switch(capturetype)
-       {
-               case CAPTURE_NORMAL: ctf_EventLog("capture", enemy_flag.team, player); break;
-               case CAPTURE_DROPPED: ctf_EventLog("droppedcapture", enemy_flag.team, player); break;
-               default: break;
-       }
-
-       // scoring
-       PlayerTeamScore_AddScore(player, autocvar_g_ctf_score_capture);
-       PlayerTeamScore_Add(player, SP_CTF_CAPS, ST_CTF_CAPS, 1);
-
-       old_time = PlayerScore_Add(player, SP_CTF_CAPTIME, 0);
-       new_time = TIME_ENCODE(time - enemy_flag.ctf_pickuptime);
-       if(!old_time || new_time < old_time)
-               PlayerScore_Add(player, SP_CTF_CAPTIME, new_time - old_time);
-
-       // effects
-       Send_Effect_(flag.capeffect, flag.origin, '0 0 0', 1);
-       //shockwave_spawn("models/ctf/shockwavetransring.md3", flag.origin - '0 0 15', -0.8, 0, 1);
-
-       // other
-       if(capturetype == CAPTURE_NORMAL)
-       {
-               WaypointSprite_Kill(player.wps_flagcarrier);
-               if(flag.speedrunning) { ctf_FakeTimeLimit(player, -1); }
-
-               if((enemy_flag.ctf_dropper) && (player != enemy_flag.ctf_dropper))
-                       { PlayerTeamScore_AddScore(enemy_flag.ctf_dropper, autocvar_g_ctf_score_capture_assist); }
-       }
-
-       // reset the flag
-       player.next_take_time = time + autocvar_g_ctf_flag_collect_delay;
-       ctf_RespawnFlag(enemy_flag);
-}
-
-void ctf_Handle_Return(entity flag, entity player)
-{
-       // messages and sounds
-       if(IS_MONSTER(player))
-       {
-               Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(flag, INFO_CTF_RETURN_MONSTER_), player.monster_name);
-       }
-       else if(flag.team)
-       {
-               Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT_4(flag, CENTER_CTF_RETURN_));
-               Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(flag, INFO_CTF_RETURN_), player.netname);
-       }
-       _sound(player, CH_TRIGGER, flag.snd_flag_returned, VOL_BASE, ATTEN_NONE);
-       ctf_EventLog("return", flag.team, player);
-
-       // scoring
-       if(IS_PLAYER(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
-
-       if(flag.ctf_dropper)
-       {
-               PlayerScore_Add(flag.ctf_dropper, SP_SCORE, -autocvar_g_ctf_score_penalty_returned); // punish the player who dropped the flag
-               ctf_CaptureShield_Update(flag.ctf_dropper, 0); // shield player from picking up flag
-               flag.ctf_dropper.next_take_time = time + autocvar_g_ctf_flag_collect_delay; // set next take time
-       }
-
-       // other
-       if(player.flagcarried == flag)
-               WaypointSprite_Kill(player.wps_flagcarrier);
-
-       // reset the flag
-       ctf_RespawnFlag(flag);
-}
-
-void ctf_Handle_Pickup(entity flag, entity player, int pickuptype)
-{
-       // declarations
-       float pickup_dropped_score; // used to calculate dropped pickup score
-       entity tmp_entity; // temporary entity
-
-       // attach the flag to the player
-       flag.owner = player;
-       player.flagcarried = flag;
-       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;
-       flag.takedamage = DAMAGE_NO;
-       flag.solid = SOLID_NOT;
-       flag.angles = '0 0 0';
-       flag.ctf_status = FLAG_CARRY;
-
-       switch(pickuptype)
-       {
-               case PICKUP_BASE: flag.ctf_pickuptime = time; break; // used for timing runs
-               case PICKUP_DROPPED: flag.health = flag.max_flag_health; break; // reset health/return timelimit
-               default: break;
-       }
-
-       // messages and sounds
-       Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_PICKUP_) : INFO_CTF_PICKUP_NEUTRAL), player.netname);
-       if(ctf_stalemate) { Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_STALEMATE_CARRIER); }
-       if(!flag.team) { Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_PICKUP_NEUTRAL); }
-       else if(CTF_DIFFTEAM(player, flag)) { Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT_4(flag, CENTER_CTF_PICKUP_)); }
-       else { Send_Notification(NOTIF_ONE, player, MSG_CENTER, ((SAME_TEAM(player, flag)) ? CENTER_CTF_PICKUP_TEAM : CENTER_CTF_PICKUP_TEAM_ENEMY), Team_ColorCode(flag.team)); }
-
-       Send_Notification(NOTIF_TEAM_EXCEPT, player, MSG_CHOICE, ((flag.team) ? APP_TEAM_ENT_4(flag, CHOICE_CTF_PICKUP_TEAM_) : CHOICE_CTF_PICKUP_TEAM_NEUTRAL), Team_ColorCode(player.team), player.netname);
-
-       if(!flag.team)
-       FOR_EACH_PLAYER(tmp_entity)
-       if(tmp_entity != player)
-       if(DIFF_TEAM(player, tmp_entity))
-               Send_Notification(NOTIF_ONE, tmp_entity, MSG_CHOICE, CHOICE_CTF_PICKUP_ENEMY_NEUTRAL, Team_ColorCode(player.team), player.netname);
-
-       if(flag.team)
-       FOR_EACH_PLAYER(tmp_entity)
-       if(tmp_entity != player)
-       if(CTF_SAMETEAM(flag, tmp_entity))
-       if(SAME_TEAM(player, tmp_entity))
-               Send_Notification(NOTIF_ONE, tmp_entity, MSG_CHOICE, APP_TEAM_ENT_4(flag, CHOICE_CTF_PICKUP_TEAM_), Team_ColorCode(player.team), player.netname);
-       else
-               Send_Notification(NOTIF_ONE, tmp_entity, MSG_CHOICE, ((SAME_TEAM(flag, player)) ? CHOICE_CTF_PICKUP_ENEMY_TEAM : CHOICE_CTF_PICKUP_ENEMY), Team_ColorCode(player.team), player.netname);
-
-       _sound(player, CH_TRIGGER, flag.snd_flag_taken, VOL_BASE, ATTEN_NONE);
-
-       // scoring
-       PlayerScore_Add(player, SP_CTF_PICKUPS, 1);
-       nades_GiveBonus(player, autocvar_g_nades_bonus_score_minor);
-       switch(pickuptype)
-       {
-               case PICKUP_BASE:
-               {
-                       PlayerTeamScore_AddScore(player, autocvar_g_ctf_score_pickup_base);
-                       ctf_EventLog("steal", flag.team, player);
-                       break;
-               }
-
-               case PICKUP_DROPPED:
-               {
-                       pickup_dropped_score = (autocvar_g_ctf_flag_return_time ? bound(0, ((flag.ctf_droptime + autocvar_g_ctf_flag_return_time) - time) / autocvar_g_ctf_flag_return_time, 1) : 1);
-                       pickup_dropped_score = floor((autocvar_g_ctf_score_pickup_dropped_late * (1 - pickup_dropped_score) + autocvar_g_ctf_score_pickup_dropped_early * pickup_dropped_score) + 0.5);
-                       LOG_TRACE("pickup_dropped_score is ", ftos(pickup_dropped_score), "\n");
-                       PlayerTeamScore_AddScore(player, pickup_dropped_score);
-                       ctf_EventLog("pickup", flag.team, player);
-                       break;
-               }
-
-               default: break;
-       }
-
-       // speedrunning
-       if(pickuptype == PICKUP_BASE)
-       {
-               flag.speedrunning = player.speedrunning; // if speedrunning, flag will flag-return and teleport the owner back after the record
-               if((player.speedrunning) && (ctf_captimerecord))
-                       ctf_FakeTimeLimit(player, time + ctf_captimerecord);
-       }
-
-       // effects
-       Send_Effect_(flag.toucheffect, player.origin, '0 0 0', 1);
-
-       // waypoints
-       if(pickuptype == PICKUP_DROPPED) { WaypointSprite_Kill(flag.wps_flagdropped); }
-       ctf_FlagcarrierWaypoints(player);
-       WaypointSprite_Ping(player.wps_flagcarrier);
-}
-
-
-// ===================
-// Main Flag Functions
-// ===================
-
-void ctf_CheckFlagReturn(entity flag, int returntype)
-{
-       if((flag.ctf_status == FLAG_DROPPED) || (flag.ctf_status == FLAG_PASSING))
-       {
-               if(flag.wps_flagdropped) { WaypointSprite_UpdateHealth(flag.wps_flagdropped, flag.health); }
-
-               if((flag.health <= 0) || (time >= flag.ctf_droptime + autocvar_g_ctf_flag_return_time))
-               {
-                       switch(returntype)
-                       {
-                               case RETURN_DROPPED: Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_DROPPED_) : INFO_CTF_FLAGRETURN_DROPPED_NEUTRAL)); break;
-                               case RETURN_DAMAGE: Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_DAMAGED_) : INFO_CTF_FLAGRETURN_DAMAGED_NEUTRAL)); break;
-                               case RETURN_SPEEDRUN: Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_SPEEDRUN_) : INFO_CTF_FLAGRETURN_SPEEDRUN_NEUTRAL), ctf_captimerecord); break;
-                               case RETURN_NEEDKILL: Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_NEEDKILL_) : INFO_CTF_FLAGRETURN_NEEDKILL_NEUTRAL)); break;
-
-                               default:
-                               case RETURN_TIMEOUT:
-                                       { Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_TIMEOUT_) : INFO_CTF_FLAGRETURN_TIMEOUT_NEUTRAL)); break; }
-                       }
-                       _sound(flag, CH_TRIGGER, flag.snd_flag_respawn, VOL_BASE, ATTEN_NONE);
-                       ctf_EventLog("returned", flag.team, world);
-                       ctf_RespawnFlag(flag);
-               }
-       }
-}
-
-bool ctf_Stalemate_Customize()
-{SELFPARAM();
-       // make spectators see what the player would see
-       entity e, wp_owner;
-       e = WaypointSprite_getviewentity(other);
-       wp_owner = self.owner;
-
-       // team waypoints
-       if(CTF_SAMETEAM(wp_owner.flagcarried, wp_owner)) { return false; }
-       if(SAME_TEAM(wp_owner, e)) { return false; }
-       if(!IS_PLAYER(e)) { return false; }
-
-       return true;
-}
-
-void ctf_CheckStalemate(void)
-{
-       // declarations
-       int stale_flags = 0, stale_red_flags = 0, stale_blue_flags = 0, stale_yellow_flags = 0, stale_pink_flags = 0, stale_neutral_flags = 0;
-       entity tmp_entity;
-
-       entity ctf_staleflaglist = world; // reset the list, we need to build the list each time this function runs
-
-       // build list of stale flags
-       for(tmp_entity = ctf_worldflaglist; tmp_entity; tmp_entity = tmp_entity.ctf_worldflagnext)
-       {
-               if(autocvar_g_ctf_stalemate)
-               if(tmp_entity.ctf_status != FLAG_BASE)
-               if(time >= tmp_entity.ctf_pickuptime + autocvar_g_ctf_stalemate_time || !tmp_entity.team) // instant stalemate in oneflag
-               {
-                       tmp_entity.ctf_staleflagnext = ctf_staleflaglist; // link flag into staleflaglist
-                       ctf_staleflaglist = tmp_entity;
-
-                       switch(tmp_entity.team)
-                       {
-                               case NUM_TEAM_1: ++stale_red_flags; break;
-                               case NUM_TEAM_2: ++stale_blue_flags; break;
-                               case NUM_TEAM_3: ++stale_yellow_flags; break;
-                               case NUM_TEAM_4: ++stale_pink_flags; break;
-                               default: ++stale_neutral_flags; break;
-                       }
-               }
-       }
-
-       if(ctf_oneflag)
-               stale_flags = (stale_neutral_flags >= 1);
-       else
-               stale_flags = (stale_red_flags >= 1) + (stale_blue_flags >= 1) + (stale_yellow_flags >= 1) + (stale_pink_flags >= 1);
-
-       if(ctf_oneflag && stale_flags == 1)
-               ctf_stalemate = true;
-       else if(stale_flags >= 2)
-               ctf_stalemate = true;
-       else if(stale_flags == 0 && autocvar_g_ctf_stalemate_endcondition == 2)
-               { ctf_stalemate = false; wpforenemy_announced = false; }
-       else if(stale_flags < 2 && autocvar_g_ctf_stalemate_endcondition == 1)
-               { ctf_stalemate = false; wpforenemy_announced = false; }
-
-       // if sufficient stalemate, then set up the waypointsprite and announce the stalemate if necessary
-       if(ctf_stalemate)
-       {
-               for(tmp_entity = ctf_staleflaglist; tmp_entity; tmp_entity = tmp_entity.ctf_staleflagnext)
-               {
-                       if((tmp_entity.owner) && (!tmp_entity.owner.wps_enemyflagcarrier))
-                       {
-                               entity wp = WaypointSprite_Spawn(((ctf_oneflag) ? WP_FlagCarrier : WP_FlagCarrierEnemy), 0, 0, tmp_entity.owner, FLAG_WAYPOINT_OFFSET, world, 0, tmp_entity.owner, wps_enemyflagcarrier, true, RADARICON_FLAG);
-                               wp.colormod = WPCOLOR_ENEMYFC(tmp_entity.owner.team);
-                               tmp_entity.owner.wps_enemyflagcarrier.customizeentityforclient = ctf_Stalemate_Customize;
-                       }
-               }
-
-               if (!wpforenemy_announced)
-               {
-                       FOR_EACH_REALPLAYER(tmp_entity)
-                               Send_Notification(NOTIF_ONE, tmp_entity, MSG_CENTER, ((tmp_entity.flagcarried) ? CENTER_CTF_STALEMATE_CARRIER : CENTER_CTF_STALEMATE_OTHER));
-
-                       wpforenemy_announced = true;
-               }
-       }
-}
-
-void ctf_FlagDamage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
-{SELFPARAM();
-       if(ITEM_DAMAGE_NEEDKILL(deathtype))
-       {
-               if(autocvar_g_ctf_flag_return_damage_delay)
-               {
-                       self.ctf_flagdamaged = true;
-               }
-               else
-               {
-                       self.health = 0;
-                       ctf_CheckFlagReturn(self, RETURN_NEEDKILL);
-               }
-               return;
-       }
-       if(autocvar_g_ctf_flag_return_damage)
-       {
-               // reduce health and check if it should be returned
-               self.health = self.health - damage;
-               ctf_CheckFlagReturn(self, RETURN_DAMAGE);
-               return;
-       }
-}
-
-void ctf_FlagThink()
-{SELFPARAM();
-       // declarations
-       entity tmp_entity;
-
-       self.nextthink = time + FLAG_THINKRATE; // only 5 fps, more is unnecessary.
-
-       // captureshield
-       if(self == ctf_worldflaglist) // only for the first flag
-               FOR_EACH_CLIENT(tmp_entity)
-                       ctf_CaptureShield_Update(tmp_entity, 1); // release shield only
-
-       // sanity checks
-       if(self.mins != FLAG_MIN || self.maxs != FLAG_MAX) { // reset the flag boundaries in case it got squished
-               LOG_TRACE("wtf the flag got squashed?\n");
-               tracebox(self.origin, FLAG_MIN, FLAG_MAX, self.origin, MOVE_NOMONSTERS, self);
-               if(!trace_startsolid || self.noalign) // can we resize it without getting stuck?
-                       setsize(self, FLAG_MIN, FLAG_MAX); }
-
-       switch(self.ctf_status) // reset flag angles in case warpzones adjust it
-       {
-               case FLAG_DROPPED:
-               {
-                       self.angles = '0 0 0';
-                       break;
-               }
-
-               default: break;
-       }
-
-       // main think method
-       switch(self.ctf_status)
-       {
-               case FLAG_BASE:
-               {
-                       if(autocvar_g_ctf_dropped_capture_radius)
-                       {
-                               for(tmp_entity = ctf_worldflaglist; tmp_entity; tmp_entity = tmp_entity.ctf_worldflagnext)
-                                       if(tmp_entity.ctf_status == FLAG_DROPPED)
-                                       if(vlen(self.origin - tmp_entity.origin) < autocvar_g_ctf_dropped_capture_radius)
-                                       if(time > tmp_entity.ctf_droptime + autocvar_g_ctf_dropped_capture_delay)
-                                               ctf_Handle_Capture(self, tmp_entity, CAPTURE_DROPPED);
-                       }
-                       return;
-               }
-
-               case FLAG_DROPPED:
-               {
-                       if(autocvar_g_ctf_flag_dropped_floatinwater)
-                       {
-                               vector midpoint = ((self.absmin + self.absmax) * 0.5);
-                               if(pointcontents(midpoint) == CONTENT_WATER)
-                               {
-                                       self.velocity = self.velocity * 0.5;
-
-                                       if(pointcontents(midpoint + FLAG_FLOAT_OFFSET) == CONTENT_WATER)
-                                               { self.velocity_z = autocvar_g_ctf_flag_dropped_floatinwater; }
-                                       else
-                                               { self.movetype = MOVETYPE_FLY; }
-                               }
-                               else if(self.movetype == MOVETYPE_FLY) { self.movetype = MOVETYPE_TOSS; }
-                       }
-                       if(autocvar_g_ctf_flag_return_dropped)
-                       {
-                               if((vlen(self.origin - self.ctf_spawnorigin) <= autocvar_g_ctf_flag_return_dropped) || (autocvar_g_ctf_flag_return_dropped == -1))
-                               {
-                                       self.health = 0;
-                                       ctf_CheckFlagReturn(self, RETURN_DROPPED);
-                                       return;
-                               }
-                       }
-                       if(self.ctf_flagdamaged)
-                       {
-                               self.health -= ((self.max_flag_health / autocvar_g_ctf_flag_return_damage_delay) * FLAG_THINKRATE);
-                               ctf_CheckFlagReturn(self, RETURN_NEEDKILL);
-                               return;
-                       }
-                       else if(autocvar_g_ctf_flag_return_time)
-                       {
-                               self.health -= ((self.max_flag_health / autocvar_g_ctf_flag_return_time) * FLAG_THINKRATE);
-                               ctf_CheckFlagReturn(self, RETURN_TIMEOUT);
-                               return;
-                       }
-                       return;
-               }
-
-               case FLAG_CARRY:
-               {
-                       if(self.speedrunning && ctf_captimerecord && (time >= self.ctf_pickuptime + ctf_captimerecord))
-                       {
-                               self.health = 0;
-                               ctf_CheckFlagReturn(self, RETURN_SPEEDRUN);
-
-                               setself(self.owner);
-                               self.impulse = CHIMPULSE_SPEEDRUN; // move the player back to the waypoint they set
-                               ImpulseCommands();
-                               setself(this);
-                       }
-                       if(autocvar_g_ctf_stalemate)
-                       {
-                               if(time >= wpforenemy_nextthink)
-                               {
-                                       ctf_CheckStalemate();
-                                       wpforenemy_nextthink = time + WPFE_THINKRATE; // waypoint for enemy think rate (to reduce unnecessary spam of this check)
-                               }
-                       }
-                       if(CTF_SAMETEAM(self, self.owner) && self.team)
-                       {
-                               if(autocvar_g_ctf_flag_return) // drop the flag if reverse status has changed
-                                       ctf_Handle_Throw(self.owner, world, DROP_THROW);
-                               else if(vlen(self.owner.origin - self.ctf_spawnorigin) <= autocvar_g_ctf_flag_return_carried_radius)
-                                       ctf_Handle_Return(self, self.owner);
-                       }
-                       return;
-               }
-
-               case FLAG_PASSING:
-               {
-                       vector targ_origin = ((self.pass_target.absmin + self.pass_target.absmax) * 0.5);
-                       targ_origin = WarpZone_RefSys_TransformOrigin(self.pass_target, self, targ_origin); // origin of target as seen by the flag (us)
-                       WarpZone_TraceLine(self.origin, targ_origin, MOVE_NOMONSTERS, self);
-
-                       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))
-                       {
-                               // give up, pass failed
-                               ctf_Handle_Drop(self, world, DROP_PASS);
-                       }
-                       else
-                       {
-                               // still a viable target, go for it
-                               ctf_CalculatePassVelocity(self, targ_origin, self.origin, true);
-                       }
-                       return;
-               }
-
-               default: // this should never happen
-               {
-                       LOG_TRACE("ctf_FlagThink(): Flag exists with no status?\n");
-                       return;
-               }
-       }
-}
-
-void ctf_FlagTouch()
-{SELFPARAM();
-       if(gameover) { return; }
-       if(trace_dphitcontents & (DPCONTENTS_PLAYERCLIP | DPCONTENTS_MONSTERCLIP)) { return; }
-
-       entity toucher = other, tmp_entity;
-       bool is_not_monster = (!IS_MONSTER(toucher)), num_perteam = 0;
-
-       // automatically kill the flag and return it if it touched lava/slime/nodrop surfaces
-       if(ITEM_TOUCH_NEEDKILL())
-       {
-               if(!autocvar_g_ctf_flag_return_damage_delay)
-               {
-                       self.health = 0;
-                       ctf_CheckFlagReturn(self, RETURN_NEEDKILL);
-               }
-               if(!self.ctf_flagdamaged) { return; }
-       }
-
-       FOR_EACH_PLAYER(tmp_entity) if(SAME_TEAM(toucher, tmp_entity)) { ++num_perteam; }
-
-       // special touch behaviors
-       if(toucher.frozen) { return; }
-       else if(IS_VEHICLE(toucher))
-       {
-               if(autocvar_g_ctf_allow_vehicle_touch && toucher.owner)
-                       toucher = toucher.owner; // the player is actually the vehicle owner, not other
-               else
-                       return; // do nothing
-       }
-       else if(IS_MONSTER(toucher))
-       {
-               if(!autocvar_g_ctf_allow_monster_touch)
-                       return; // do nothing
-       }
-       else if (!IS_PLAYER(toucher)) // The flag just touched an object, most likely the world
-       {
-               if(time > self.wait) // if we haven't in a while, play a sound/effect
-               {
-                       Send_Effect_(self.toucheffect, self.origin, '0 0 0', 1);
-                       _sound(self, CH_TRIGGER, self.snd_flag_touch, VOL_BASE, ATTEN_NORM);
-                       self.wait = time + FLAG_TOUCHRATE;
-               }
-               return;
-       }
-       else if(toucher.deadflag != DEAD_NO) { return; }
-
-       switch(self.ctf_status)
-       {
-               case FLAG_BASE:
-               {
-                       if(ctf_oneflag)
-                       {
-                               if(CTF_SAMETEAM(toucher, self) && (toucher.flagcarried) && !toucher.flagcarried.team && is_not_monster)
-                                       ctf_Handle_Capture(self, toucher, CAPTURE_NORMAL); // toucher just captured the neutral flag to enemy base
-                               else if(!self.team && (!toucher.flagcarried) && (!toucher.ctf_captureshielded) && (time > toucher.next_take_time) && is_not_monster)
-                                       ctf_Handle_Pickup(self, toucher, PICKUP_BASE); // toucher just stole the neutral flag
-                       }
-                       else if(CTF_SAMETEAM(toucher, self) && (toucher.flagcarried) && DIFF_TEAM(toucher.flagcarried, self) && is_not_monster)
-                               ctf_Handle_Capture(self, toucher, CAPTURE_NORMAL); // toucher just captured the enemies flag to his base
-                       else if(CTF_DIFFTEAM(toucher, self) && (!toucher.flagcarried) && (!toucher.ctf_captureshielded) && (time > toucher.next_take_time) && is_not_monster)
-                               ctf_Handle_Pickup(self, toucher, PICKUP_BASE); // toucher just stole the enemies flag
-                       break;
-               }
-
-               case FLAG_DROPPED:
-               {
-                       if(CTF_SAMETEAM(toucher, self) && (autocvar_g_ctf_flag_return || num_perteam <= 1) && self.team) // automatically return if there's only 1 player on the team
-                               ctf_Handle_Return(self, toucher); // toucher just returned his own flag
-                       else if(is_not_monster && (!toucher.flagcarried) && ((toucher != self.ctf_dropper) || (time > self.ctf_droptime + autocvar_g_ctf_flag_collect_delay)))
-                               ctf_Handle_Pickup(self, toucher, PICKUP_DROPPED); // toucher just picked up a dropped enemy flag
-                       break;
-               }
-
-               case FLAG_CARRY:
-               {
-                       LOG_TRACE("Someone touched a flag even though it was being carried?\n");
-                       break;
-               }
-
-               case FLAG_PASSING:
-               {
-                       if((IS_PLAYER(toucher)) && (toucher.deadflag == DEAD_NO) && (toucher != self.pass_sender))
-                       {
-                               if(DIFF_TEAM(toucher, self.pass_sender))
-                                       ctf_Handle_Return(self, toucher);
-                               else
-                                       ctf_Handle_Retrieve(self, toucher);
-                       }
-                       break;
-               }
-       }
-}
-
-.float last_respawn;
-void ctf_RespawnFlag(entity flag)
-{
-       // check for flag respawn being called twice in a row
-       if(flag.last_respawn > time - 0.5)
-               { backtrace("flag respawn called twice quickly! please notify Samual about this..."); }
-
-       flag.last_respawn = time;
-
-       // reset the player (if there is one)
-       if((flag.owner) && (flag.owner.flagcarried == flag))
-       {
-               WaypointSprite_Kill(flag.owner.wps_enemyflagcarrier);
-               WaypointSprite_Kill(flag.wps_flagcarrier);
-
-               flag.owner.flagcarried = world;
-
-               if(flag.speedrunning)
-                       ctf_FakeTimeLimit(flag.owner, -1);
-       }
-
-       if((flag.owner) && (flag.owner.vehicle))
-               flag.scale = FLAG_SCALE;
-
-       if(flag.ctf_status == FLAG_DROPPED)
-               { WaypointSprite_Kill(flag.wps_flagdropped); }
-
-       // reset the flag
-       setattachment(flag, world, "");
-       setorigin(flag, flag.ctf_spawnorigin);
-
-       flag.movetype = ((flag.noalign) ? MOVETYPE_NONE : MOVETYPE_TOSS);
-       flag.takedamage = DAMAGE_NO;
-       flag.health = flag.max_flag_health;
-       flag.solid = SOLID_TRIGGER;
-       flag.velocity = '0 0 0';
-       flag.angles = flag.mangle;
-       flag.flags = FL_ITEM | FL_NOTARGET;
-
-       flag.ctf_status = FLAG_BASE;
-       flag.owner = world;
-       flag.pass_distance = 0;
-       flag.pass_sender = world;
-       flag.pass_target = world;
-       flag.ctf_dropper = world;
-       flag.ctf_pickuptime = 0;
-       flag.ctf_droptime = 0;
-       flag.ctf_flagdamaged = 0;
-
-       ctf_CheckStalemate();
-}
-
-void ctf_Reset()
-{SELFPARAM();
-       if(self.owner)
-               if(IS_PLAYER(self.owner))
-                       ctf_Handle_Throw(self.owner, world, DROP_RESET);
-
-       ctf_RespawnFlag(self);
-}
-
-void ctf_DelayedFlagSetup(void) // called after a flag is placed on a map by ctf_FlagSetup()
-{SELFPARAM();
-       // bot waypoints
-       waypoint_spawnforitem_force(self, self.origin);
-       self.nearestwaypointtimeout = 0; // activate waypointing again
-       self.bot_basewaypoint = self.nearestwaypoint;
-
-       // waypointsprites
-       entity basename;
-       switch (self.team)
-       {
-               case NUM_TEAM_1: basename = WP_FlagBaseRed; break;
-               case NUM_TEAM_2: basename = WP_FlagBaseBlue; break;
-               case NUM_TEAM_3: basename = WP_FlagBaseYellow; break;
-               case NUM_TEAM_4: basename = WP_FlagBasePink; break;
-               default: basename = WP_FlagBaseNeutral; break;
-       }
-
-       entity wp = WaypointSprite_SpawnFixed(basename, self.origin + FLAG_WAYPOINT_OFFSET, self, wps_flagbase, RADARICON_FLAG);
-       wp.colormod = ((self.team) ? Team_ColorRGB(self.team) : '1 1 1');
-       WaypointSprite_UpdateTeamRadar(self.wps_flagbase, RADARICON_FLAG, ((self.team) ? colormapPaletteColor(self.team - 1, false) : '1 1 1'));
-
-       // captureshield setup
-       ctf_CaptureShield_Spawn(self);
-}
-
-void set_flag_string(entity flag, .string field, string value, string teamname)
-{
-       if(flag.(field) == "")
-               flag.(field) = strzone(sprintf(value,teamname));
-}
-
-void ctf_FlagSetup(int teamnumber, entity flag) // called when spawning a flag entity on the map as a spawnfunc
-{SELFPARAM();
-       // declarations
-       setself(flag); // for later usage with droptofloor()
-
-       // main setup
-       flag.ctf_worldflagnext = ctf_worldflaglist; // link flag into ctf_worldflaglist
-       ctf_worldflaglist = flag;
-
-       setattachment(flag, world, "");
-
-       flag.netname = strzone(sprintf("%s%s^7 flag", Team_ColorCode(teamnumber), Team_ColorName_Upper(teamnumber)));
-       flag.team = teamnumber;
-       flag.classname = "item_flag_team";
-       flag.target = "###item###"; // wut?
-       flag.flags = FL_ITEM | FL_NOTARGET;
-       flag.solid = SOLID_TRIGGER;
-       flag.takedamage = DAMAGE_NO;
-       flag.damageforcescale = autocvar_g_ctf_flag_damageforcescale;
-       flag.max_flag_health = ((autocvar_g_ctf_flag_return_damage && autocvar_g_ctf_flag_health) ? autocvar_g_ctf_flag_health : 100);
-       flag.health = flag.max_flag_health;
-       flag.event_damage = ctf_FlagDamage;
-       flag.pushable = true;
-       flag.teleportable = TELEPORT_NORMAL;
-       flag.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
-       flag.damagedbytriggers = autocvar_g_ctf_flag_return_when_unreachable;
-       flag.damagedbycontents = autocvar_g_ctf_flag_return_when_unreachable;
-       flag.velocity = '0 0 0';
-       flag.mangle = flag.angles;
-       flag.reset = ctf_Reset;
-       flag.touch = ctf_FlagTouch;
-       flag.think = ctf_FlagThink;
-       flag.nextthink = time + FLAG_THINKRATE;
-       flag.ctf_status = FLAG_BASE;
-
-       string teamname = Static_Team_ColorName_Lower(teamnumber);
-       // appearence
-       if(!flag.scale)                         { flag.scale = FLAG_SCALE; }
-       if(flag.skin == 0)                      { flag.skin = cvar(sprintf("g_ctf_flag_%s_skin", teamname)); }
-       if(flag.model == "")            { flag.model = cvar_string(sprintf("g_ctf_flag_%s_model", teamname)); }
-       set_flag_string(flag, toucheffect,      "%sflag_touch", teamname);
-       set_flag_string(flag, passeffect,       "%s_pass",              teamname);
-       set_flag_string(flag, capeffect,        "%s_cap",               teamname);
-
-       // sounds
-       flag.snd_flag_taken = SND(CTF_TAKEN(teamnumber));
-       flag.snd_flag_returned = SND(CTF_RETURNED(teamnumber));
-       flag.snd_flag_capture = SND(CTF_CAPTURE(teamnumber));
-       flag.snd_flag_dropped = SND(CTF_DROPPED(teamnumber));
-       if (flag.snd_flag_respawn == "") flag.snd_flag_respawn = SND(CTF_RESPAWN); // if there is ever a team-based sound for this, update the code to match.
-       precache_sound(flag.snd_flag_respawn);
-       if (flag.snd_flag_touch == "") flag.snd_flag_touch = SND(CTF_TOUCH); // again has no team-based sound
-       precache_sound(flag.snd_flag_touch);
-       if (flag.snd_flag_pass == "") flag.snd_flag_pass = SND(CTF_PASS); // same story here
-       precache_sound(flag.snd_flag_pass);
-
-       // precache
-       precache_model(flag.model);
-
-       // appearence
-       _setmodel(flag, flag.model); // precision set below
-       setsize(flag, FLAG_MIN, FLAG_MAX);
-       setorigin(flag, (flag.origin + FLAG_SPAWN_OFFSET));
-
-       if(autocvar_g_ctf_flag_glowtrails)
-       {
-               switch(teamnumber)
-               {
-                       case NUM_TEAM_1: flag.glow_color = 251; break;
-                       case NUM_TEAM_2: flag.glow_color = 210; break;
-                       case NUM_TEAM_3: flag.glow_color = 110; break;
-                       case NUM_TEAM_4: flag.glow_color = 145; break;
-                       default:                 flag.glow_color = 254; break;
-               }
-               flag.glow_size = 25;
-               flag.glow_trail = 1;
-       }
-
-       flag.effects |= EF_LOWPRECISION;
-       if(autocvar_g_ctf_fullbrightflags) { flag.effects |= EF_FULLBRIGHT; }
-       if(autocvar_g_ctf_dynamiclights)
-       {
-               switch(teamnumber)
-               {
-                       case NUM_TEAM_1: flag.effects |= EF_RED; break;
-                       case NUM_TEAM_2: flag.effects |= EF_BLUE; break;
-                       case NUM_TEAM_3: flag.effects |= EF_DIMLIGHT; break;
-                       case NUM_TEAM_4: flag.effects |= EF_RED; break;
-                       default:                 flag.effects |= EF_DIMLIGHT; break;
-               }
-       }
-
-       // flag placement
-       if((flag.spawnflags & 1) || flag.noalign) // don't drop to floor, just stay at fixed location
-       {
-               flag.dropped_origin = flag.origin;
-               flag.noalign = true;
-               flag.movetype = MOVETYPE_NONE;
-       }
-       else // drop to floor, automatically find a platform and set that as spawn origin
-       {
-               flag.noalign = false;
-               setself(flag);
-               droptofloor();
-               flag.movetype = MOVETYPE_TOSS;
-       }
-
-       InitializeEntity(flag, ctf_DelayedFlagSetup, INITPRIO_SETLOCATION);
-}
-
-
-// ================
-// Bot player logic
-// ================
-
-// NOTE: LEGACY CODE, needs to be re-written!
-
-void havocbot_calculate_middlepoint()
-{
-       entity f;
-       vector s = '0 0 0';
-       vector fo = '0 0 0';
-       float n = 0;
-
-       f = ctf_worldflaglist;
-       while (f)
-       {
-               fo = f.origin;
-               s = s + fo;
-               f = f.ctf_worldflagnext;
-       }
-       if(!n)
-               return;
-       havocbot_ctf_middlepoint = s * (1.0 / n);
-       havocbot_ctf_middlepoint_radius  = vlen(fo - havocbot_ctf_middlepoint);
-}
-
-
-entity havocbot_ctf_find_flag(entity bot)
-{
-       entity f;
-       f = ctf_worldflaglist;
-       while (f)
-       {
-               if (CTF_SAMETEAM(bot, f))
-                       return f;
-               f = f.ctf_worldflagnext;
-       }
-       return world;
-}
-
-entity havocbot_ctf_find_enemy_flag(entity bot)
-{
-       entity f;
-       f = ctf_worldflaglist;
-       while (f)
-       {
-               if(ctf_oneflag)
-               {
-                       if(CTF_DIFFTEAM(bot, f))
-                       {
-                               if(f.team)
-                               {
-                                       if(bot.flagcarried)
-                                               return f;
-                               }
-                               else if(!bot.flagcarried)
-                                       return f;
-                       }
-               }
-               else if (CTF_DIFFTEAM(bot, f))
-                       return f;
-               f = f.ctf_worldflagnext;
-       }
-       return world;
-}
-
-int havocbot_ctf_teamcount(entity bot, vector org, float tc_radius)
-{
-       if (!teamplay)
-               return 0;
-
-       int c = 0;
-       entity head;
-
-       FOR_EACH_PLAYER(head)
-       {
-               if(DIFF_TEAM(head, bot) || head.deadflag != DEAD_NO || head == bot)
-                       continue;
-
-               if(vlen(head.origin - org) < tc_radius)
-                       ++c;
-       }
-
-       return c;
-}
-
-void havocbot_goalrating_ctf_ourflag(float ratingscale)
-{SELFPARAM();
-       entity head;
-       head = ctf_worldflaglist;
-       while (head)
-       {
-               if (CTF_SAMETEAM(self, head))
-                       break;
-               head = head.ctf_worldflagnext;
-       }
-       if (head)
-               navigation_routerating(head, ratingscale, 10000);
-}
-
-void havocbot_goalrating_ctf_ourbase(float ratingscale)
-{SELFPARAM();
-       entity head;
-       head = ctf_worldflaglist;
-       while (head)
-       {
-               if (CTF_SAMETEAM(self, head))
-                       break;
-               head = head.ctf_worldflagnext;
-       }
-       if (!head)
-               return;
-
-       navigation_routerating(head.bot_basewaypoint, ratingscale, 10000);
-}
-
-void havocbot_goalrating_ctf_enemyflag(float ratingscale)
-{SELFPARAM();
-       entity head;
-       head = ctf_worldflaglist;
-       while (head)
-       {
-               if(ctf_oneflag)
-               {
-                       if(CTF_DIFFTEAM(self, head))
-                       {
-                               if(head.team)
-                               {
-                                       if(self.flagcarried)
-                                               break;
-                               }
-                               else if(!self.flagcarried)
-                                       break;
-                       }
-               }
-               else if(CTF_DIFFTEAM(self, head))
-                       break;
-               head = head.ctf_worldflagnext;
-       }
-       if (head)
-               navigation_routerating(head, ratingscale, 10000);
-}
-
-void havocbot_goalrating_ctf_enemybase(float ratingscale)
-{SELFPARAM();
-       if (!bot_waypoints_for_items)
-       {
-               havocbot_goalrating_ctf_enemyflag(ratingscale);
-               return;
-       }
-
-       entity head;
-
-       head = havocbot_ctf_find_enemy_flag(self);
-
-       if (!head)
-               return;
-
-       navigation_routerating(head.bot_basewaypoint, ratingscale, 10000);
-}
-
-void havocbot_goalrating_ctf_ourstolenflag(float ratingscale)
-{SELFPARAM();
-       entity mf;
-
-       mf = havocbot_ctf_find_flag(self);
-
-       if(mf.ctf_status == FLAG_BASE)
-               return;
-
-       if(mf.tag_entity)
-               navigation_routerating(mf.tag_entity, ratingscale, 10000);
-}
-
-void havocbot_goalrating_ctf_droppedflags(float ratingscale, vector org, float df_radius)
-{
-       entity head;
-       head = ctf_worldflaglist;
-       while (head)
-       {
-               // flag is out in the field
-               if(head.ctf_status != FLAG_BASE)
-               if(head.tag_entity==world)      // dropped
-               {
-                       if(df_radius)
-                       {
-                               if(vlen(org-head.origin)<df_radius)
-                                       navigation_routerating(head, ratingscale, 10000);
-                       }
-                       else
-                               navigation_routerating(head, ratingscale, 10000);
-               }
-
-               head = head.ctf_worldflagnext;
-       }
-}
-
-void havocbot_goalrating_ctf_carrieritems(float ratingscale, vector org, float sradius)
-{SELFPARAM();
-       entity head;
-       float t;
-       head = findchainfloat(bot_pickup, true);
-       while (head)
-       {
-               // gather health and armor only
-               if (head.solid)
-               if (head.health || head.armorvalue)
-               if (vlen(head.origin - org) < sradius)
-               {
-                       // get the value of the item
-                       t = head.bot_pickupevalfunc(self, head) * 0.0001;
-                       if (t > 0)
-                               navigation_routerating(head, t * ratingscale, 500);
-               }
-               head = head.chain;
-       }
-}
-
-void havocbot_ctf_reset_role(entity bot)
-{
-       float cdefense, cmiddle, coffense;
-       entity mf, ef, head;
-       float c;
-
-       if(bot.deadflag != DEAD_NO)
-               return;
-
-       if(vlen(havocbot_ctf_middlepoint)==0)
-               havocbot_calculate_middlepoint();
-
-       // Check ctf flags
-       if (bot.flagcarried)
-       {
-               havocbot_role_ctf_setrole(bot, HAVOCBOT_CTF_ROLE_CARRIER);
-               return;
-       }
-
-       mf = havocbot_ctf_find_flag(bot);
-       ef = havocbot_ctf_find_enemy_flag(bot);
-
-       // Retrieve stolen flag
-       if(mf.ctf_status!=FLAG_BASE)
-       {
-               havocbot_role_ctf_setrole(bot, HAVOCBOT_CTF_ROLE_RETRIEVER);
-               return;
-       }
-
-       // If enemy flag is taken go to the middle to intercept pursuers
-       if(ef.ctf_status!=FLAG_BASE)
-       {
-               havocbot_role_ctf_setrole(bot, HAVOCBOT_CTF_ROLE_MIDDLE);
-               return;
-       }
-
-       // if there is only me on the team switch to offense
-       c = 0;
-       FOR_EACH_PLAYER(head)
-       if(SAME_TEAM(head, bot))
-               ++c;
-
-       if(c==1)
-       {
-               havocbot_role_ctf_setrole(bot, HAVOCBOT_CTF_ROLE_OFFENSE);
-               return;
-       }
-
-       // Evaluate best position to take
-       // Count mates on middle position
-       cmiddle = havocbot_ctf_teamcount(bot, havocbot_ctf_middlepoint, havocbot_ctf_middlepoint_radius * 0.5);
-
-       // Count mates on defense position
-       cdefense = havocbot_ctf_teamcount(bot, mf.dropped_origin, havocbot_ctf_middlepoint_radius * 0.5);
-
-       // Count mates on offense position
-       coffense = havocbot_ctf_teamcount(bot, ef.dropped_origin, havocbot_ctf_middlepoint_radius);
-
-       if(cdefense<=coffense)
-               havocbot_role_ctf_setrole(bot, HAVOCBOT_CTF_ROLE_DEFENSE);
-       else if(coffense<=cmiddle)
-               havocbot_role_ctf_setrole(bot, HAVOCBOT_CTF_ROLE_OFFENSE);
-       else
-               havocbot_role_ctf_setrole(bot, HAVOCBOT_CTF_ROLE_MIDDLE);
-}
-
-void havocbot_role_ctf_carrier()
-{SELFPARAM();
-       if(self.deadflag != DEAD_NO)
-       {
-               havocbot_ctf_reset_role(self);
-               return;
-       }
-
-       if (self.flagcarried == world)
-       {
-               havocbot_ctf_reset_role(self);
-               return;
-       }
-
-       if (self.bot_strategytime < time)
-       {
-               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
-
-               navigation_goalrating_start();
-               if(ctf_oneflag)
-                       havocbot_goalrating_ctf_enemybase(50000);
-               else
-                       havocbot_goalrating_ctf_ourbase(50000);
-
-               if(self.health<100)
-                       havocbot_goalrating_ctf_carrieritems(1000, self.origin, 1000);
-
-               navigation_goalrating_end();
-
-               if (self.navigation_hasgoals)
-                       self.havocbot_cantfindflag = time + 10;
-               else if (time > self.havocbot_cantfindflag)
-               {
-                       // Can't navigate to my own base, suicide!
-                       // TODO: drop it and wander around
-                       Damage(self, self, self, 100000, DEATH_KILL.m_id, self.origin, '0 0 0');
-                       return;
-               }
-       }
-}
-
-void havocbot_role_ctf_escort()
-{SELFPARAM();
-       entity mf, ef;
-
-       if(self.deadflag != DEAD_NO)
-       {
-               havocbot_ctf_reset_role(self);
-               return;
-       }
-
-       if (self.flagcarried)
-       {
-               havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_CARRIER);
-               return;
-       }
-
-       // If enemy flag is back on the base switch to previous role
-       ef = havocbot_ctf_find_enemy_flag(self);
-       if(ef.ctf_status==FLAG_BASE)
-       {
-               self.havocbot_role = self.havocbot_previous_role;
-               self.havocbot_role_timeout = 0;
-               return;
-       }
-
-       // If the flag carrier reached the base switch to defense
-       mf = havocbot_ctf_find_flag(self);
-       if(mf.ctf_status!=FLAG_BASE)
-       if(vlen(ef.origin - mf.dropped_origin) < 300)
-       {
-               havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_DEFENSE);
-               return;
-       }
-
-       // Set the role timeout if necessary
-       if (!self.havocbot_role_timeout)
-       {
-               self.havocbot_role_timeout = time + random() * 30 + 60;
-       }
-
-       // If nothing happened just switch to previous role
-       if (time > self.havocbot_role_timeout)
-       {
-               self.havocbot_role = self.havocbot_previous_role;
-               self.havocbot_role_timeout = 0;
-               return;
-       }
-
-       // Chase the flag carrier
-       if (self.bot_strategytime < time)
-       {
-               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
-               navigation_goalrating_start();
-               havocbot_goalrating_ctf_enemyflag(30000);
-               havocbot_goalrating_ctf_ourstolenflag(40000);
-               havocbot_goalrating_items(10000, self.origin, 10000);
-               navigation_goalrating_end();
-       }
-}
-
-void havocbot_role_ctf_offense()
-{SELFPARAM();
-       entity mf, ef;
-       vector pos;
-
-       if(self.deadflag != DEAD_NO)
-       {
-               havocbot_ctf_reset_role(self);
-               return;
-       }
-
-       if (self.flagcarried)
-       {
-               havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_CARRIER);
-               return;
-       }
-
-       // Check flags
-       mf = havocbot_ctf_find_flag(self);
-       ef = havocbot_ctf_find_enemy_flag(self);
-
-       // Own flag stolen
-       if(mf.ctf_status!=FLAG_BASE)
-       {
-               if(mf.tag_entity)
-                       pos = mf.tag_entity.origin;
-               else
-                       pos = mf.origin;
-
-               // Try to get it if closer than the enemy base
-               if(vlen(self.origin-ef.dropped_origin)>vlen(self.origin-pos))
-               {
-                       havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_RETRIEVER);
-                       return;
-               }
-       }
-
-       // Escort flag carrier
-       if(ef.ctf_status!=FLAG_BASE)
-       {
-               if(ef.tag_entity)
-                       pos = ef.tag_entity.origin;
-               else
-                       pos = ef.origin;
-
-               if(vlen(pos-mf.dropped_origin)>700)
-               {
-                       havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_ESCORT);
-                       return;
-               }
-       }
-
-       // About to fail, switch to middlefield
-       if(self.health<50)
-       {
-               havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_MIDDLE);
-               return;
-       }
-
-       // Set the role timeout if necessary
-       if (!self.havocbot_role_timeout)
-               self.havocbot_role_timeout = time + 120;
-
-       if (time > self.havocbot_role_timeout)
-       {
-               havocbot_ctf_reset_role(self);
-               return;
-       }
-
-       if (self.bot_strategytime < time)
-       {
-               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
-               navigation_goalrating_start();
-               havocbot_goalrating_ctf_ourstolenflag(50000);
-               havocbot_goalrating_ctf_enemybase(20000);
-               havocbot_goalrating_items(5000, self.origin, 1000);
-               havocbot_goalrating_items(1000, self.origin, 10000);
-               navigation_goalrating_end();
-       }
-}
-
-// Retriever (temporary role):
-void havocbot_role_ctf_retriever()
-{SELFPARAM();
-       entity mf;
-
-       if(self.deadflag != DEAD_NO)
-       {
-               havocbot_ctf_reset_role(self);
-               return;
-       }
-
-       if (self.flagcarried)
-       {
-               havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_CARRIER);
-               return;
-       }
-
-       // If flag is back on the base switch to previous role
-       mf = havocbot_ctf_find_flag(self);
-       if(mf.ctf_status==FLAG_BASE)
-       {
-               havocbot_ctf_reset_role(self);
-               return;
-       }
-
-       if (!self.havocbot_role_timeout)
-               self.havocbot_role_timeout = time + 20;
-
-       if (time > self.havocbot_role_timeout)
-       {
-               havocbot_ctf_reset_role(self);
-               return;
-       }
-
-       if (self.bot_strategytime < time)
-       {
-               float rt_radius;
-               rt_radius = 10000;
-
-               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
-               navigation_goalrating_start();
-               havocbot_goalrating_ctf_ourstolenflag(50000);
-               havocbot_goalrating_ctf_droppedflags(40000, self.origin, rt_radius);
-               havocbot_goalrating_ctf_enemybase(30000);
-               havocbot_goalrating_items(500, self.origin, rt_radius);
-               navigation_goalrating_end();
-       }
-}
-
-void havocbot_role_ctf_middle()
-{SELFPARAM();
-       entity mf;
-
-       if(self.deadflag != DEAD_NO)
-       {
-               havocbot_ctf_reset_role(self);
-               return;
-       }
-
-       if (self.flagcarried)
-       {
-               havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_CARRIER);
-               return;
-       }
-
-       mf = havocbot_ctf_find_flag(self);
-       if(mf.ctf_status!=FLAG_BASE)
-       {
-               havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_RETRIEVER);
-               return;
-       }
-
-       if (!self.havocbot_role_timeout)
-               self.havocbot_role_timeout = time + 10;
-
-       if (time > self.havocbot_role_timeout)
-       {
-               havocbot_ctf_reset_role(self);
-               return;
-       }
-
-       if (self.bot_strategytime < time)
-       {
-               vector org;
-
-               org = havocbot_ctf_middlepoint;
-               org.z = self.origin.z;
-
-               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
-               navigation_goalrating_start();
-               havocbot_goalrating_ctf_ourstolenflag(50000);
-               havocbot_goalrating_ctf_droppedflags(30000, self.origin, 10000);
-               havocbot_goalrating_enemyplayers(10000, org, havocbot_ctf_middlepoint_radius * 0.5);
-               havocbot_goalrating_items(5000, org, havocbot_ctf_middlepoint_radius * 0.5);
-               havocbot_goalrating_items(2500, self.origin, 10000);
-               havocbot_goalrating_ctf_enemybase(2500);
-               navigation_goalrating_end();
-       }
-}
-
-void havocbot_role_ctf_defense()
-{SELFPARAM();
-       entity mf;
-
-       if(self.deadflag != DEAD_NO)
-       {
-               havocbot_ctf_reset_role(self);
-               return;
-       }
-
-       if (self.flagcarried)
-       {
-               havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_CARRIER);
-               return;
-       }
-
-       // If own flag was captured
-       mf = havocbot_ctf_find_flag(self);
-       if(mf.ctf_status!=FLAG_BASE)
-       {
-               havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_RETRIEVER);
-               return;
-       }
-
-       if (!self.havocbot_role_timeout)
-               self.havocbot_role_timeout = time + 30;
-
-       if (time > self.havocbot_role_timeout)
-       {
-               havocbot_ctf_reset_role(self);
-               return;
-       }
-       if (self.bot_strategytime < time)
-       {
-               float mp_radius;
-               vector org;
-
-               org = mf.dropped_origin;
-               mp_radius = havocbot_ctf_middlepoint_radius;
-
-               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
-               navigation_goalrating_start();
-
-               // if enemies are closer to our base, go there
-               entity head, closestplayer = world;
-               float distance, bestdistance = 10000;
-               FOR_EACH_PLAYER(head)
-               {
-                       if(head.deadflag!=DEAD_NO)
-                               continue;
-
-                       distance = vlen(org - head.origin);
-                       if(distance<bestdistance)
-                       {
-                               closestplayer = head;
-                               bestdistance = distance;
-                       }
-               }
-
-               if(closestplayer)
-               if(DIFF_TEAM(closestplayer, self))
-               if(vlen(org - self.origin)>1000)
-               if(checkpvs(self.origin,closestplayer)||random()<0.5)
-                       havocbot_goalrating_ctf_ourbase(30000);
-
-               havocbot_goalrating_ctf_ourstolenflag(20000);
-               havocbot_goalrating_ctf_droppedflags(20000, org, mp_radius);
-               havocbot_goalrating_enemyplayers(15000, org, mp_radius);
-               havocbot_goalrating_items(10000, org, mp_radius);
-               havocbot_goalrating_items(5000, self.origin, 10000);
-               navigation_goalrating_end();
-       }
-}
-
-void havocbot_role_ctf_setrole(entity bot, int role)
-{
-       LOG_TRACE(strcat(bot.netname," switched to "));
-       switch(role)
-       {
-               case HAVOCBOT_CTF_ROLE_CARRIER:
-                       LOG_TRACE("carrier");
-                       bot.havocbot_role = havocbot_role_ctf_carrier;
-                       bot.havocbot_role_timeout = 0;
-                       bot.havocbot_cantfindflag = time + 10;
-                       bot.bot_strategytime = 0;
-                       break;
-               case HAVOCBOT_CTF_ROLE_DEFENSE:
-                       LOG_TRACE("defense");
-                       bot.havocbot_role = havocbot_role_ctf_defense;
-                       bot.havocbot_role_timeout = 0;
-                       break;
-               case HAVOCBOT_CTF_ROLE_MIDDLE:
-                       LOG_TRACE("middle");
-                       bot.havocbot_role = havocbot_role_ctf_middle;
-                       bot.havocbot_role_timeout = 0;
-                       break;
-               case HAVOCBOT_CTF_ROLE_OFFENSE:
-                       LOG_TRACE("offense");
-                       bot.havocbot_role = havocbot_role_ctf_offense;
-                       bot.havocbot_role_timeout = 0;
-                       break;
-               case HAVOCBOT_CTF_ROLE_RETRIEVER:
-                       LOG_TRACE("retriever");
-                       bot.havocbot_previous_role = bot.havocbot_role;
-                       bot.havocbot_role = havocbot_role_ctf_retriever;
-                       bot.havocbot_role_timeout = time + 10;
-                       bot.bot_strategytime = 0;
-                       break;
-               case HAVOCBOT_CTF_ROLE_ESCORT:
-                       LOG_TRACE("escort");
-                       bot.havocbot_previous_role = bot.havocbot_role;
-                       bot.havocbot_role = havocbot_role_ctf_escort;
-                       bot.havocbot_role_timeout = time + 30;
-                       bot.bot_strategytime = 0;
-                       break;
-       }
-       LOG_TRACE("\n");
-}
-
-
-// ==============
-// Hook Functions
-// ==============
-
-MUTATOR_HOOKFUNCTION(ctf_PlayerPreThink)
-{SELFPARAM();
-       entity flag;
-       int t = 0, t2 = 0, t3 = 0;
-
-       // initially clear items so they can be set as necessary later.
-       self.ctf_flagstatus &= ~(CTF_RED_FLAG_CARRYING          | CTF_RED_FLAG_TAKEN            | CTF_RED_FLAG_LOST
-                                                  | CTF_BLUE_FLAG_CARRYING             | CTF_BLUE_FLAG_TAKEN           | CTF_BLUE_FLAG_LOST
-                                                  | CTF_YELLOW_FLAG_CARRYING   | CTF_YELLOW_FLAG_TAKEN         | CTF_YELLOW_FLAG_LOST
-                                                  | CTF_PINK_FLAG_CARRYING     | CTF_PINK_FLAG_TAKEN           | CTF_PINK_FLAG_LOST
-                                                  | CTF_NEUTRAL_FLAG_CARRYING  | CTF_NEUTRAL_FLAG_TAKEN        | CTF_NEUTRAL_FLAG_LOST
-                                                  | CTF_FLAG_NEUTRAL | CTF_SHIELDED);
-
-       // scan through all the flags and notify the client about them
-       for(flag = ctf_worldflaglist; flag; flag = flag.ctf_worldflagnext)
-       {
-               if(flag.team == NUM_TEAM_1) { t = CTF_RED_FLAG_CARRYING;                t2 = CTF_RED_FLAG_TAKEN;                t3 = CTF_RED_FLAG_LOST; }
-               if(flag.team == NUM_TEAM_2) { t = CTF_BLUE_FLAG_CARRYING;               t2 = CTF_BLUE_FLAG_TAKEN;               t3 = CTF_BLUE_FLAG_LOST; }
-               if(flag.team == NUM_TEAM_3) { t = CTF_YELLOW_FLAG_CARRYING;     t2 = CTF_YELLOW_FLAG_TAKEN;             t3 = CTF_YELLOW_FLAG_LOST; }
-               if(flag.team == NUM_TEAM_4) { t = CTF_PINK_FLAG_CARRYING;               t2 = CTF_PINK_FLAG_TAKEN;               t3 = CTF_PINK_FLAG_LOST; }
-               if(flag.team == 0)                      { t = CTF_NEUTRAL_FLAG_CARRYING;        t2 = CTF_NEUTRAL_FLAG_TAKEN;    t3 = CTF_NEUTRAL_FLAG_LOST; self.ctf_flagstatus |= CTF_FLAG_NEUTRAL; }
-
-               switch(flag.ctf_status)
-               {
-                       case FLAG_PASSING:
-                       case FLAG_CARRY:
-                       {
-                               if((flag.owner == self) || (flag.pass_sender == self))
-                                       self.ctf_flagstatus |= t; // carrying: self is currently carrying the flag
-                               else
-                                       self.ctf_flagstatus |= t2; // taken: someone else is carrying the flag
-                               break;
-                       }
-                       case FLAG_DROPPED:
-                       {
-                               self.ctf_flagstatus |= t3; // lost: the flag is dropped somewhere on the map
-                               break;
-                       }
-               }
-       }
-
-       // item for stopping players from capturing the flag too often
-       if(self.ctf_captureshielded)
-               self.ctf_flagstatus |= CTF_SHIELDED;
-
-       // update the health of the flag carrier waypointsprite
-       if(self.wps_flagcarrier)
-               WaypointSprite_UpdateHealth(self.wps_flagcarrier, '1 0 0' * healtharmor_maxdamage(self.health, self.armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id));
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ctf_PlayerDamage) // for changing damage and force values that are applied to players in g_damage.qc
-{
-       if(frag_attacker.flagcarried) // if the attacker is a flagcarrier
-       {
-               if(frag_target == frag_attacker) // damage done to yourself
-               {
-                       frag_damage *= autocvar_g_ctf_flagcarrier_selfdamagefactor;
-                       frag_force *= autocvar_g_ctf_flagcarrier_selfforcefactor;
-               }
-               else // damage done to everyone else
-               {
-                       frag_damage *= autocvar_g_ctf_flagcarrier_damagefactor;
-                       frag_force *= autocvar_g_ctf_flagcarrier_forcefactor;
-               }
-       }
-       else if(frag_target.flagcarried && (frag_target.deadflag == DEAD_NO) && CTF_DIFFTEAM(frag_target, frag_attacker)) // if the target is a flagcarrier
-       {
-               if(autocvar_g_ctf_flagcarrier_auto_helpme_damage > ('1 0 0' * healtharmor_maxdamage(frag_target.health, frag_target.armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id)))
-               if(time > frag_target.wps_helpme_time + autocvar_g_ctf_flagcarrier_auto_helpme_time)
-               {
-                       frag_target.wps_helpme_time = time;
-                       WaypointSprite_HelpMePing(frag_target.wps_flagcarrier);
-               }
-               // todo: add notification for when flag carrier needs help?
-       }
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ctf_PlayerDies)
-{
-       if((frag_attacker != frag_target) && (IS_PLAYER(frag_attacker)) && (frag_target.flagcarried))
-       {
-               PlayerTeamScore_AddScore(frag_attacker, autocvar_g_ctf_score_kill);
-               PlayerScore_Add(frag_attacker, SP_CTF_FCKILLS, 1);
-       }
-
-       if(frag_target.flagcarried)
-       {
-               entity tmp_entity = frag_target.flagcarried;
-               ctf_Handle_Throw(frag_target, world, DROP_NORMAL);
-               tmp_entity.ctf_dropper = world;
-       }
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ctf_GiveFragsForKill)
-{
-       frag_score = 0;
-       return (autocvar_g_ctf_ignore_frags); // no frags counted in ctf if this is true
-}
-
-MUTATOR_HOOKFUNCTION(ctf_RemovePlayer)
-{SELFPARAM();
-       entity flag; // temporary entity for the search method
-
-       if(self.flagcarried)
-               { ctf_Handle_Throw(self, world, DROP_NORMAL); }
-
-       for(flag = ctf_worldflaglist; flag; flag = flag.ctf_worldflagnext)
-       {
-               if(flag.pass_sender == self) { flag.pass_sender = world; }
-               if(flag.pass_target == self) { flag.pass_target = world; }
-               if(flag.ctf_dropper == self) { flag.ctf_dropper = world; }
-       }
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ctf_PortalTeleport)
-{SELFPARAM();
-       if(self.flagcarried)
-       if(!autocvar_g_ctf_portalteleport)
-               { ctf_Handle_Throw(self, world, DROP_NORMAL); }
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ctf_PlayerUseKey)
-{SELFPARAM();
-       if(MUTATOR_RETURNVALUE || gameover) { return false; }
-
-       entity player = self;
-
-       if((time > player.throw_antispam) && (player.deadflag == DEAD_NO) && !player.speedrunning && (!player.vehicle || autocvar_g_ctf_allow_vehicle_touch))
-       {
-               // pass the flag to a team mate
-               if(autocvar_g_ctf_pass)
-               {
-                       entity head, closest_target = world;
-                       head = WarpZone_FindRadius(player.origin, autocvar_g_ctf_pass_radius, true);
-
-                       while(head) // find the closest acceptable target to pass to
-                       {
-                               if(IS_PLAYER(head) && head.deadflag == DEAD_NO)
-                               if(head != player && SAME_TEAM(head, player))
-                               if(!head.speedrunning && !head.vehicle)
-                               {
-                                       // if it's a player, use the view origin as reference (stolen from RadiusDamage functions in g_damage.qc)
-                                       vector head_center = WarpZone_UnTransformOrigin(head, CENTER_OR_VIEWOFS(head));
-                                       vector passer_center = CENTER_OR_VIEWOFS(player);
-
-                                       if(ctf_CheckPassDirection(head_center, passer_center, player.v_angle, head.WarpZone_findradius_nearest))
-                                       {
-                                               if(autocvar_g_ctf_pass_request && !player.flagcarried && head.flagcarried)
-                                               {
-                                                       if(IS_BOT_CLIENT(head))
-                                                       {
-                                                               Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_PASS_REQUESTING, head.netname);
-                                                               ctf_Handle_Throw(head, player, DROP_PASS);
-                                                       }
-                                                       else
-                                                       {
-                                                               Send_Notification(NOTIF_ONE, head, MSG_CENTER, CENTER_CTF_PASS_REQUESTED, player.netname);
-                                                               Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_PASS_REQUESTING, head.netname);
-                                                       }
-                                                       player.throw_antispam = time + autocvar_g_ctf_pass_wait;
-                                                       return true;
-                                               }
-                                               else if(player.flagcarried)
-                                               {
-                                                       if(closest_target)
-                                                       {
-                                                               vector closest_target_center = WarpZone_UnTransformOrigin(closest_target, CENTER_OR_VIEWOFS(closest_target));
-                                                               if(vlen(passer_center - head_center) < vlen(passer_center - closest_target_center))
-                                                                       { closest_target = head; }
-                                                       }
-                                                       else { closest_target = head; }
-                                               }
-                                       }
-                               }
-                               head = head.chain;
-                       }
-
-                       if(closest_target) { ctf_Handle_Throw(player, closest_target, DROP_PASS); return true; }
-               }
-
-               // throw the flag in front of you
-               if(autocvar_g_ctf_throw && player.flagcarried)
-               {
-                       if(player.throw_count == -1)
-                       {
-                               if(time > player.throw_prevtime + autocvar_g_ctf_throw_punish_delay)
-                               {
-                                       player.throw_prevtime = time;
-                                       player.throw_count = 1;
-                                       ctf_Handle_Throw(player, world, DROP_THROW);
-                                       return true;
-                               }
-                               else
-                               {
-                                       Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_FLAG_THROW_PUNISH, rint((player.throw_prevtime + autocvar_g_ctf_throw_punish_delay) - time));
-                                       return false;
-                               }
-                       }
-                       else
-                       {
-                               if(time > player.throw_prevtime + autocvar_g_ctf_throw_punish_time) { player.throw_count = 1; }
-                               else { player.throw_count += 1; }
-                               if(player.throw_count >= autocvar_g_ctf_throw_punish_count) { player.throw_count = -1; }
-
-                               player.throw_prevtime = time;
-                               ctf_Handle_Throw(player, world, DROP_THROW);
-                               return true;
-                       }
-               }
-       }
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ctf_HelpMePing)
-{SELFPARAM();
-       if(self.wps_flagcarrier) // update the flagcarrier waypointsprite with "NEEDING HELP" notification
-       {
-               self.wps_helpme_time = time;
-               WaypointSprite_HelpMePing(self.wps_flagcarrier);
-       }
-       else // create a normal help me waypointsprite
-       {
-               WaypointSprite_Spawn(WP_Helpme, waypointsprite_deployed_lifetime, waypointsprite_limitedrange, self, FLAG_WAYPOINT_OFFSET, world, self.team, self, wps_helpme, false, RADARICON_HELPME);
-               WaypointSprite_Ping(self.wps_helpme);
-       }
-
-       return true;
-}
-
-MUTATOR_HOOKFUNCTION(ctf_VehicleEnter)
-{
-       if(vh_player.flagcarried)
-       {
-               vh_player.flagcarried.nodrawtoclient = vh_player; // hide the flag from the driver
-
-               if(!autocvar_g_ctf_allow_vehicle_carry && !autocvar_g_ctf_allow_vehicle_touch)
-               {
-                       ctf_Handle_Throw(vh_player, world, DROP_NORMAL);
-               }
-               else
-               {
-                       setattachment(vh_player.flagcarried, vh_vehicle, "");
-                       setorigin(vh_player.flagcarried, VEHICLE_FLAG_OFFSET);
-                       vh_player.flagcarried.scale = VEHICLE_FLAG_SCALE;
-                       //vh_player.flagcarried.angles = '0 0 0';
-               }
-               return true;
-       }
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ctf_VehicleExit)
-{
-       if(vh_player.flagcarried)
-       {
-               setattachment(vh_player.flagcarried, vh_player, "");
-               setorigin(vh_player.flagcarried, FLAG_CARRY_OFFSET);
-               vh_player.flagcarried.scale = FLAG_SCALE;
-               vh_player.flagcarried.angles = '0 0 0';
-               vh_player.flagcarried.nodrawtoclient = world;
-               return true;
-       }
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ctf_AbortSpeedrun)
-{SELFPARAM();
-       if(self.flagcarried)
-       {
-               Send_Notification(NOTIF_ALL, world, MSG_INFO, ((self.flagcarried.team) ? APP_TEAM_ENT_4(self.flagcarried, INFO_CTF_FLAGRETURN_ABORTRUN_) : INFO_CTF_FLAGRETURN_ABORTRUN_NEUTRAL));
-               ctf_RespawnFlag(self.flagcarried);
-               return true;
-       }
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ctf_MatchEnd)
-{
-       entity flag; // temporary entity for the search method
-
-       for(flag = ctf_worldflaglist; flag; flag = flag.ctf_worldflagnext)
-       {
-               switch(flag.ctf_status)
-               {
-                       case FLAG_DROPPED:
-                       case FLAG_PASSING:
-                       {
-                               // lock the flag, game is over
-                               flag.movetype = MOVETYPE_NONE;
-                               flag.takedamage = DAMAGE_NO;
-                               flag.solid = SOLID_NOT;
-                               flag.nextthink = false; // stop thinking
-
-                               //dprint("stopping the ", flag.netname, " from moving.\n");
-                               break;
-                       }
-
-                       default:
-                       case FLAG_BASE:
-                       case FLAG_CARRY:
-                       {
-                               // do nothing for these flags
-                               break;
-                       }
-               }
-       }
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ctf_BotRoles)
-{SELFPARAM();
-       havocbot_ctf_reset_role(self);
-       return true;
-}
-
-MUTATOR_HOOKFUNCTION(ctf_GetTeamCount)
-{
-       //ret_float = ctf_teams;
-       ret_string = "ctf_team";
-       return true;
-}
-
-MUTATOR_HOOKFUNCTION(ctf_SpectateCopy)
-{SELFPARAM();
-       self.ctf_flagstatus = other.ctf_flagstatus;
-       return false;
-}
-
-
-// ==========
-// Spawnfuncs
-// ==========
-
-/*QUAKED spawnfunc_item_flag_team1 (0 0.5 0.8) (-48 -48 -37) (48 48 37)
-CTF flag for team one (Red).
-Keys:
-"angle" Angle the flag will point (minus 90 degrees)...
-"model" model to use, note this needs red and blue as skins 0 and 1...
-"noise" sound played when flag is picked up...
-"noise1" sound played when flag is returned by a teammate...
-"noise2" sound played when flag is captured...
-"noise3" sound played when flag is lost in the field and respawns itself...
-"noise4" sound played when flag is dropped by a player...
-"noise5" sound played when flag touches the ground... */
-spawnfunc(item_flag_team1)
-{
-       if(!g_ctf) { remove(self); return; }
-
-       ctf_FlagSetup(NUM_TEAM_1, self);
-}
-
-/*QUAKED spawnfunc_item_flag_team2 (0 0.5 0.8) (-48 -48 -37) (48 48 37)
-CTF flag for team two (Blue).
-Keys:
-"angle" Angle the flag will point (minus 90 degrees)...
-"model" model to use, note this needs red and blue as skins 0 and 1...
-"noise" sound played when flag is picked up...
-"noise1" sound played when flag is returned by a teammate...
-"noise2" sound played when flag is captured...
-"noise3" sound played when flag is lost in the field and respawns itself...
-"noise4" sound played when flag is dropped by a player...
-"noise5" sound played when flag touches the ground... */
-spawnfunc(item_flag_team2)
-{
-       if(!g_ctf) { remove(self); return; }
-
-       ctf_FlagSetup(NUM_TEAM_2, self);
-}
-
-/*QUAKED spawnfunc_item_flag_team3 (0 0.5 0.8) (-48 -48 -37) (48 48 37)
-CTF flag for team three (Yellow).
-Keys:
-"angle" Angle the flag will point (minus 90 degrees)...
-"model" model to use, note this needs red, blue yellow and pink as skins 0, 1, 2 and 3...
-"noise" sound played when flag is picked up...
-"noise1" sound played when flag is returned by a teammate...
-"noise2" sound played when flag is captured...
-"noise3" sound played when flag is lost in the field and respawns itself...
-"noise4" sound played when flag is dropped by a player...
-"noise5" sound played when flag touches the ground... */
-spawnfunc(item_flag_team3)
-{
-       if(!g_ctf) { remove(self); return; }
-
-       ctf_FlagSetup(NUM_TEAM_3, self);
-}
-
-/*QUAKED spawnfunc_item_flag_team4 (0 0.5 0.8) (-48 -48 -37) (48 48 37)
-CTF flag for team four (Pink).
-Keys:
-"angle" Angle the flag will point (minus 90 degrees)...
-"model" model to use, note this needs red, blue yellow and pink as skins 0, 1, 2 and 3...
-"noise" sound played when flag is picked up...
-"noise1" sound played when flag is returned by a teammate...
-"noise2" sound played when flag is captured...
-"noise3" sound played when flag is lost in the field and respawns itself...
-"noise4" sound played when flag is dropped by a player...
-"noise5" sound played when flag touches the ground... */
-spawnfunc(item_flag_team4)
-{
-       if(!g_ctf) { remove(self); return; }
-
-       ctf_FlagSetup(NUM_TEAM_4, self);
-}
-
-/*QUAKED spawnfunc_item_flag_neutral (0 0.5 0.8) (-48 -48 -37) (48 48 37)
-CTF flag (Neutral).
-Keys:
-"angle" Angle the flag will point (minus 90 degrees)...
-"model" model to use, note this needs red, blue yellow and pink as skins 0, 1, 2 and 3...
-"noise" sound played when flag is picked up...
-"noise1" sound played when flag is returned by a teammate...
-"noise2" sound played when flag is captured...
-"noise3" sound played when flag is lost in the field and respawns itself...
-"noise4" sound played when flag is dropped by a player...
-"noise5" sound played when flag touches the ground... */
-spawnfunc(item_flag_neutral)
-{
-       if(!g_ctf) { remove(self); return; }
-       if(!cvar("g_ctf_oneflag")) { remove(self); return; }
-
-       ctf_FlagSetup(0, self);
-}
-
-/*QUAKED spawnfunc_ctf_team (0 .5 .8) (-16 -16 -24) (16 16 32)
-Team declaration for CTF gameplay, this allows you to decide what team names and control point models are used in your map.
-Note: If you use spawnfunc_ctf_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)... */
-spawnfunc(ctf_team)
-{
-       if(!g_ctf) { remove(self); return; }
-
-       self.classname = "ctf_team";
-       self.team = self.cnt + 1;
-}
-
-// compatibility for quake maps
-spawnfunc(team_CTF_redflag)    { spawnfunc_item_flag_team1(this);    }
-spawnfunc(team_CTF_blueflag)   { spawnfunc_item_flag_team2(this);    }
-spawnfunc(info_player_team1);
-spawnfunc(team_CTF_redplayer)  { spawnfunc_info_player_team1(this);  }
-spawnfunc(team_CTF_redspawn)   { spawnfunc_info_player_team1(this);  }
-spawnfunc(info_player_team2);
-spawnfunc(team_CTF_blueplayer) { spawnfunc_info_player_team2(this);  }
-spawnfunc(team_CTF_bluespawn)  { spawnfunc_info_player_team2(this);  }
-
-void team_CTF_neutralflag()                     { SELFPARAM(); spawnfunc_item_flag_neutral(self);  }
-void team_neutralobelisk()                      { SELFPARAM(); spawnfunc_item_flag_neutral(self);  }
-
-
-// ==============
-// Initialization
-// ==============
-
-// scoreboard setup
-void ctf_ScoreRules(int teams)
-{
-       CheckAllowedTeams(world);
-       ScoreRules_basics(teams, SFL_SORT_PRIO_PRIMARY, 0, true);
-       ScoreInfo_SetLabel_TeamScore  (ST_CTF_CAPS,     "caps",      SFL_SORT_PRIO_PRIMARY);
-       ScoreInfo_SetLabel_PlayerScore(SP_CTF_CAPS,     "caps",      SFL_SORT_PRIO_SECONDARY);
-       ScoreInfo_SetLabel_PlayerScore(SP_CTF_CAPTIME,  "captime",   SFL_LOWER_IS_BETTER | SFL_TIME);
-       ScoreInfo_SetLabel_PlayerScore(SP_CTF_PICKUPS,  "pickups",   0);
-       ScoreInfo_SetLabel_PlayerScore(SP_CTF_FCKILLS,  "fckills",   0);
-       ScoreInfo_SetLabel_PlayerScore(SP_CTF_RETURNS,  "returns",   0);
-       ScoreInfo_SetLabel_PlayerScore(SP_CTF_DROPS,    "drops",     SFL_LOWER_IS_BETTER);
-       ScoreRules_basics_end();
-}
-
-// code from here on is just to support maps that don't have flag and team entities
-void ctf_SpawnTeam (string teamname, int teamcolor)
-{
-       entity this = new(ctf_team);
-       this.netname = teamname;
-       this.cnt = teamcolor;
-       this.spawnfunc_checked = true;
-       WITH(entity, self, this, spawnfunc_ctf_team(this));
-}
-
-void ctf_DelayedInit() // Do this check with a delay so we can wait for teams to be set up.
-{
-       ctf_teams = 2;
-
-       entity tmp_entity;
-       for(tmp_entity = ctf_worldflaglist; tmp_entity; tmp_entity = tmp_entity.ctf_worldflagnext)
-       {
-               if(tmp_entity.team == NUM_TEAM_3) { ctf_teams = max(3, ctf_teams); }
-               if(tmp_entity.team == NUM_TEAM_4) { ctf_teams = max(4, ctf_teams); }
-               if(tmp_entity.team == 0) { ctf_oneflag = true; }
-       }
-
-       ctf_teams = bound(2, ctf_teams, 4);
-
-       // if no teams are found, spawn defaults
-       if(find(world, classname, "ctf_team") == world)
-       {
-               LOG_INFO("No ""ctf_team"" entities found on this map, creating them anyway.\n");
-               ctf_SpawnTeam("Red", NUM_TEAM_1 - 1);
-               ctf_SpawnTeam("Blue", NUM_TEAM_2 - 1);
-               if(ctf_teams >= 3)
-                       ctf_SpawnTeam("Yellow", NUM_TEAM_3 - 1);
-               if(ctf_teams >= 4)
-                       ctf_SpawnTeam("Pink", NUM_TEAM_4 - 1);
-       }
-
-       ctf_ScoreRules(ctf_teams);
-}
-
-void ctf_Initialize()
-{
-       ctf_captimerecord = stof(db_get(ServerProgsDB, strcat(GetMapname(), "/captimerecord/time")));
-
-       ctf_captureshield_min_negscore = autocvar_g_ctf_shield_min_negscore;
-       ctf_captureshield_max_ratio = autocvar_g_ctf_shield_max_ratio;
-       ctf_captureshield_force = autocvar_g_ctf_shield_force;
-
-       addstat(STAT_CTF_FLAGSTATUS, AS_INT, ctf_flagstatus);
-
-       InitializeEntity(world, ctf_DelayedInit, INITPRIO_GAMETYPE);
-}
-
-
-MUTATOR_DEFINITION(gamemode_ctf)
-{
-       MUTATOR_HOOK(MakePlayerObserver, ctf_RemovePlayer, CBC_ORDER_ANY);
-       MUTATOR_HOOK(ClientDisconnect, ctf_RemovePlayer, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerDies, ctf_PlayerDies, CBC_ORDER_ANY);
-       MUTATOR_HOOK(MatchEnd, ctf_MatchEnd, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PortalTeleport, ctf_PortalTeleport, CBC_ORDER_ANY);
-       MUTATOR_HOOK(GiveFragsForKill, ctf_GiveFragsForKill, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerPreThink, ctf_PlayerPreThink, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerDamage_Calculate, ctf_PlayerDamage, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerUseKey, ctf_PlayerUseKey, CBC_ORDER_ANY);
-       MUTATOR_HOOK(HelpMePing, ctf_HelpMePing, CBC_ORDER_ANY);
-       MUTATOR_HOOK(VehicleEnter, ctf_VehicleEnter, CBC_ORDER_ANY);
-       MUTATOR_HOOK(VehicleExit, ctf_VehicleExit, CBC_ORDER_ANY);
-       MUTATOR_HOOK(AbortSpeedrun, ctf_AbortSpeedrun, CBC_ORDER_ANY);
-       MUTATOR_HOOK(HavocBot_ChooseRole, ctf_BotRoles, CBC_ORDER_ANY);
-       MUTATOR_HOOK(GetTeamCount, ctf_GetTeamCount, CBC_ORDER_ANY);
-       MUTATOR_HOOK(SpectateCopy, ctf_SpectateCopy, 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.");
-               ctf_Initialize();
-       }
-
-       MUTATOR_ONROLLBACK_OR_REMOVE
-       {
-               // we actually cannot roll back ctf_Initialize here
-               // BUT: we don't need to! If this gets called, adding always
-               // succeeds.
-       }
-
-       MUTATOR_ONREMOVE
-       {
-               LOG_INFO("This is a game type and it cannot be removed at runtime.");
-               return -1;
-       }
-
-       return 0;
-}
diff --git a/qcsrc/server/mutators/gamemode_ctf.qh b/qcsrc/server/mutators/gamemode_ctf.qh
deleted file mode 100644 (file)
index b5ff177..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-#ifndef GAMEMODE_CTF_H
-#define GAMEMODE_CTF_H
-// these are needed since mutators are compiled last
-
-#ifdef SVQC
-// used in cheats.qc
-void ctf_RespawnFlag(entity flag);
-
-// score rule declarations
-const int ST_CTF_CAPS = 1;
-const int SP_CTF_CAPS = 4;
-const int SP_CTF_CAPTIME = 5;
-const int SP_CTF_PICKUPS = 6;
-const int SP_CTF_DROPS = 7;
-const int SP_CTF_FCKILLS = 8;
-const int SP_CTF_RETURNS = 9;
-
-// flag constants // for most of these, there is just one question to be asked: WHYYYYY?
-#define FLAG_MIN (PL_MIN_CONST + '0 0 -13')
-#define FLAG_MAX (PL_MAX_CONST + '0 0 -13')
-
-const float FLAG_SCALE = 0.6;
-
-const float FLAG_THINKRATE = 0.2;
-const float FLAG_TOUCHRATE = 0.5;
-const float WPFE_THINKRATE = 0.5;
-
-const vector FLAG_DROP_OFFSET = ('0 0 32');
-const vector FLAG_CARRY_OFFSET = ('-16 0 8');
-#define FLAG_SPAWN_OFFSET ('0 0 1' * (PL_MAX_CONST.z - 13))
-const vector FLAG_WAYPOINT_OFFSET = ('0 0 64');
-const vector FLAG_FLOAT_OFFSET = ('0 0 32');
-const vector FLAG_PASS_ARC_OFFSET = ('0 0 -10');
-
-const vector VEHICLE_FLAG_OFFSET = ('0 0 96');
-const float VEHICLE_FLAG_SCALE = 1.0;
-
-// waypoint colors
-#define WPCOLOR_ENEMYFC(t) ((t) ? colormapPaletteColor(t - 1, false) * 0.75 : '1 1 1')
-#define WPCOLOR_FLAGCARRIER(t) (WP_FlagCarrier.m_color)
-#define WPCOLOR_DROPPEDFLAG(t) ((t) ? ('0.25 0.25 0.25' + colormapPaletteColor(t - 1, false)) * 0.5 : '1 1 1')
-
-// sounds
-#define snd_flag_taken noise
-#define snd_flag_returned noise1
-#define snd_flag_capture noise2
-#define snd_flag_respawn noise3
-.string snd_flag_dropped;
-.string snd_flag_touch;
-.string snd_flag_pass;
-
-// effects
-.string toucheffect;
-.string passeffect;
-.string capeffect;
-
-// list of flags on the map
-entity ctf_worldflaglist;
-.entity ctf_worldflagnext;
-.entity ctf_staleflagnext;
-
-// waypoint sprites
-.entity bot_basewaypoint; // flag waypointsprite
-.entity wps_helpme;
-.entity wps_flagbase;
-.entity wps_flagcarrier;
-.entity wps_flagdropped;
-.entity wps_enemyflagcarrier;
-.float wps_helpme_time;
-bool wpforenemy_announced;
-float wpforenemy_nextthink;
-
-// statuses
-const int FLAG_BASE = 1;
-const int FLAG_DROPPED = 2;
-const int FLAG_CARRY = 3;
-const int FLAG_PASSING = 4;
-
-const int DROP_NORMAL = 1;
-const int DROP_THROW = 2;
-const int DROP_PASS = 3;
-const int DROP_RESET = 4;
-
-const int PICKUP_BASE = 1;
-const int PICKUP_DROPPED = 2;
-
-const int CAPTURE_NORMAL = 1;
-const int CAPTURE_DROPPED = 2;
-
-const int RETURN_TIMEOUT = 1;
-const int RETURN_DROPPED = 2;
-const int RETURN_DAMAGE = 3;
-const int RETURN_SPEEDRUN = 4;
-const int RETURN_NEEDKILL = 5;
-
-void ctf_Handle_Throw(entity player, entity receiver, float droptype);
-
-// flag properties
-#define ctf_spawnorigin dropped_origin
-bool ctf_stalemate; // indicates that a stalemate is active
-float ctf_captimerecord; // record time for capturing the flag
-.float ctf_pickuptime;
-.float ctf_droptime;
-.int ctf_status; // status of the flag (FLAG_BASE, FLAG_DROPPED, FLAG_CARRY declared globally)
-.entity ctf_dropper; // don't allow spam of dropping the flag
-.int max_flag_health;
-.float next_take_time;
-.bool ctf_flagdamaged;
-int ctf_teams;
-
-// passing/throwing properties
-.float pass_distance;
-.entity pass_sender;
-.entity pass_target;
-.float throw_antispam;
-.float throw_prevtime;
-.int throw_count;
-
-// CaptureShield: If the player is too bad to be allowed to capture, shield them from taking the flag.
-.bool ctf_captureshielded; // set to 1 if the player is too bad to be allowed to capture
-float ctf_captureshield_min_negscore; // punish at -20 points
-float ctf_captureshield_max_ratio; // punish at most 30% of each team
-float ctf_captureshield_force; // push force of the shield
-
-// 1 flag ctf
-bool ctf_oneflag; // indicates whether or not a neutral flag has been found
-
-// bot player logic
-const int HAVOCBOT_CTF_ROLE_NONE = 0;
-const int HAVOCBOT_CTF_ROLE_DEFENSE = 2;
-const int HAVOCBOT_CTF_ROLE_MIDDLE = 4;
-const int HAVOCBOT_CTF_ROLE_OFFENSE = 8;
-const int HAVOCBOT_CTF_ROLE_CARRIER = 16;
-const int HAVOCBOT_CTF_ROLE_RETRIEVER = 32;
-const int HAVOCBOT_CTF_ROLE_ESCORT = 64;
-
-.bool havocbot_cantfindflag;
-
-vector havocbot_ctf_middlepoint;
-float havocbot_ctf_middlepoint_radius;
-
-void havocbot_role_ctf_setrole(entity bot, int role);
-
-// team checking
-#define CTF_SAMETEAM(a,b) ((autocvar_g_ctf_reverse || (ctf_oneflag && autocvar_g_ctf_oneflag_reverse)) ? DIFF_TEAM(a,b) : SAME_TEAM(a,b))
-#define CTF_DIFFTEAM(a,b) ((autocvar_g_ctf_reverse || (ctf_oneflag && autocvar_g_ctf_oneflag_reverse)) ? SAME_TEAM(a,b) : DIFF_TEAM(a,b))
-
-// networked flag statuses
-.int ctf_flagstatus;
-#endif
-
-const int CTF_RED_FLAG_TAKEN                   = 1;
-const int CTF_RED_FLAG_LOST                            = 2;
-const int CTF_RED_FLAG_CARRYING                        = 3;
-const int CTF_BLUE_FLAG_TAKEN                  = 4;
-const int CTF_BLUE_FLAG_LOST                   = 8;
-const int CTF_BLUE_FLAG_CARRYING               = 12;
-const int CTF_YELLOW_FLAG_TAKEN                        = 16;
-const int CTF_YELLOW_FLAG_LOST                 = 32;
-const int CTF_YELLOW_FLAG_CARRYING             = 48;
-const int CTF_PINK_FLAG_TAKEN                  = 64;
-const int CTF_PINK_FLAG_LOST                   = 128;
-const int CTF_PINK_FLAG_CARRYING               = 192;
-const int CTF_NEUTRAL_FLAG_TAKEN               = 256;
-const int CTF_NEUTRAL_FLAG_LOST                        = 512;
-const int CTF_NEUTRAL_FLAG_CARRYING            = 768;
-const int CTF_FLAG_NEUTRAL                             = 2048;
-const int CTF_SHIELDED                                 = 4096;
-
-#endif
diff --git a/qcsrc/server/mutators/gamemode_cts.qc b/qcsrc/server/mutators/gamemode_cts.qc
deleted file mode 100644 (file)
index 06e2ca3..0000000
+++ /dev/null
@@ -1,332 +0,0 @@
-#include "gamemode_cts.qh"
-
-#include "gamemode.qh"
-
-#include "../race.qh"
-
-// legacy bot roles
-.float race_checkpoint;
-void havocbot_role_cts()
-{SELFPARAM();
-       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)
-{SELFPARAM();
-       // 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)
-{SELFPARAM();
-       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)
-{SELFPARAM();
-       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)
-{SELFPARAM();
-       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)
-{SELFPARAM();
-       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)
-{SELFPARAM();
-       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)
-{SELFPARAM();
-       self.respawn_flags |= RESPAWN_FORCE;
-       race_AbandonRaceCheck(self);
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(cts_BotRoles)
-{SELFPARAM();
-       self.havocbot_role = havocbot_role_cts;
-       return true;
-}
-
-MUTATOR_HOOKFUNCTION(cts_PlayerPostThink)
-{SELFPARAM();
-       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)
-{SELFPARAM();
-       if(self.classname == "droppedweapon")
-               return true;
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(cts_PlayerDamage)
-{
-       if(frag_target == frag_attacker || frag_deathtype == DEATH_FALL.m_id)
-       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
-       {
-               LOG_INFO("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
deleted file mode 100644 (file)
index fa27fe4..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef GAMEMODE_CTS_H
-#define GAMEMODE_CTS_H
-//float g_race_qualifying;
-
-// scores
-const float ST_CTS_LAPS = 1;
-const float SP_CTS_LAPS = 4;
-const float SP_CTS_TIME = 5;
-const float SP_CTS_FASTEST = 6;
-#endif
diff --git a/qcsrc/server/mutators/gamemode_deathmatch.qc b/qcsrc/server/mutators/gamemode_deathmatch.qc
deleted file mode 100644 (file)
index c3c8b0d..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-#include "gamemode.qh"
-
-MUTATOR_HOOKFUNCTION(dm_CountFrags)
-{
-       // announce remaining frags
-       return true;
-}
-
-MUTATOR_DEFINITION(gamemode_deathmatch)
-{
-       MUTATOR_HOOK(Scores_CountFragsRemaining, dm_CountFrags, 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.");
-       }
-
-       MUTATOR_ONROLLBACK_OR_REMOVE
-       {
-               // we actually cannot roll back dm_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_domination.qc b/qcsrc/server/mutators/gamemode_domination.qc
deleted file mode 100644 (file)
index 9e309f6..0000000
+++ /dev/null
@@ -1,653 +0,0 @@
-#include "gamemode_domination.qh"
-
-#include "gamemode.qh"
-
-#include "../teamplay.qh"
-
-void dom_EventLog(string mode, float team_before, entity actor) // use an alias for easy changing and quick editing later
-{
-       if(autocvar_sv_eventlog)
-               GameLogEcho(strcat(":dom:", mode, ":", ftos(team_before), ((actor != world) ? (strcat(":", ftos(actor.playerid))) : "")));
-}
-
-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(domination_teams >= 3)
-               e.dom_pps_yellow = pps_yellow;
-       if(domination_teams >= 4)
-               e.dom_pps_pink = pps_pink;
-}
-
-void dompoint_captured ()
-{SELFPARAM();
-       entity head;
-       float old_delay, old_team, real_team;
-
-       // now that the delay has expired, switch to the latest team to lay claim to this point
-       head = self.owner;
-
-       real_team = self.cnt;
-       self.cnt = -1;
-
-       dom_EventLog("taken", self.team, self.dmg_inflictor);
-       self.dmg_inflictor = world;
-
-       self.goalentity = head;
-       self.model = head.mdl;
-       self.modelindex = head.dmg;
-       self.skin = head.skin;
-
-       float points, wait_time;
-       if (autocvar_g_domination_point_amt)
-               points = autocvar_g_domination_point_amt;
-       else
-               points = self.frags;
-       if (autocvar_g_domination_point_rate)
-               wait_time = autocvar_g_domination_point_rate;
-       else
-               wait_time = self.wait;
-
-       if(domination_roundbased)
-               bprint(sprintf("^3%s^3%s\n", head.netname, self.message));
-       else
-               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);
-       else
-               self.enemy = world;
-
-       if (head.noise != "")
-               if(self.enemy)
-                       _sound(self.enemy, CH_TRIGGER, head.noise, VOL_BASE, ATTEN_NORM);
-               else
-                       _sound(self, CH_TRIGGER, head.noise, VOL_BASE, ATTEN_NORM);
-       if (head.noise1 != "")
-               play2all(head.noise1);
-
-       self.delay = time + wait_time;
-
-       // do trigger work
-       old_delay = self.delay;
-       old_team = self.team;
-       self.team = real_team;
-       self.delay = 0;
-       activator = self;
-       SUB_UseTargets ();
-       self.delay = old_delay;
-       self.team = old_team;
-
-       entity msg = WP_DomNeut;
-       switch(self.team)
-       {
-               case NUM_TEAM_1: msg = WP_DomRed; break;
-               case NUM_TEAM_2: msg = WP_DomBlue; break;
-               case NUM_TEAM_3: msg = WP_DomYellow; break;
-               case NUM_TEAM_4: msg = WP_DomPink; break;
-       }
-
-       WaypointSprite_UpdateSprites(self.sprite, msg, WP_Null, WP_Null);
-
-       total_pps = 0, pps_red = 0, pps_blue = 0, pps_yellow = 0, pps_pink = 0;
-       for(head = world; (head = find(head, classname, "dom_controlpoint")) != world; )
-       {
-               if (autocvar_g_domination_point_amt)
-                       points = autocvar_g_domination_point_amt;
-               else
-                       points = head.frags;
-               if (autocvar_g_domination_point_rate)
-                       wait_time = autocvar_g_domination_point_rate;
-               else
-                       wait_time = head.wait;
-               switch(head.goalentity.team)
-               {
-                       case NUM_TEAM_1:
-                               pps_red += points/wait_time;
-                               break;
-                       case NUM_TEAM_2:
-                               pps_blue += points/wait_time;
-                               break;
-                       case NUM_TEAM_3:
-                               pps_yellow += points/wait_time;
-                               break;
-                       case NUM_TEAM_4:
-                               pps_pink += points/wait_time;
-                               break;
-               }
-               total_pps += points/wait_time;
-       }
-
-       WaypointSprite_UpdateTeamRadar(self.sprite, RADARICON_DOMPOINT, colormapPaletteColor(self.goalentity.team - 1, 0));
-       WaypointSprite_Ping(self.sprite);
-
-       self.captime = time;
-
-       FOR_EACH_REALCLIENT(head)
-               set_dom_state(head);
-}
-
-void AnimateDomPoint()
-{SELFPARAM();
-       if(self.pain_finished > time)
-               return;
-       self.pain_finished = time + self.t_width;
-       if(self.nextthink > self.pain_finished)
-               self.nextthink = self.pain_finished;
-
-       self.frame = self.frame + 1;
-       if(self.frame > self.t_length)
-               self.frame = 0;
-}
-
-void dompointthink()
-{SELFPARAM();
-       float fragamt;
-
-       self.nextthink = time + 0.1;
-
-       //self.frame = self.frame + 1;
-       //if(self.frame > 119)
-       //      self.frame = 0;
-       AnimateDomPoint();
-
-       // give points
-
-       if (gameover || self.delay > time || time < game_starttime)     // game has ended, don't keep giving points
-               return;
-
-       if(autocvar_g_domination_point_rate)
-               self.delay = time + autocvar_g_domination_point_rate;
-       else
-               self.delay = time + self.wait;
-
-       // give credit to the team
-       // NOTE: this defaults to 0
-       if (!domination_roundbased)
-       if (self.goalentity.netname != "")
-       {
-               if(autocvar_g_domination_point_amt)
-                       fragamt = autocvar_g_domination_point_amt;
-               else
-                       fragamt = self.frags;
-               TeamScore_AddToTeam(self.goalentity.team, ST_SCORE, fragamt);
-               TeamScore_AddToTeam(self.goalentity.team, ST_DOM_TICKS, fragamt);
-
-               // give credit to the individual player, if he is still there
-               if (self.enemy.playerid == self.enemy_playerid)
-               {
-                       PlayerScore_Add(self.enemy, SP_SCORE, fragamt);
-                       PlayerScore_Add(self.enemy, SP_DOM_TICKS, fragamt);
-               }
-               else
-                       self.enemy = world;
-       }
-}
-
-void dompointtouch()
-{SELFPARAM();
-       entity head;
-       if (!IS_PLAYER(other))
-               return;
-       if (other.health < 1)
-               return;
-
-       if(round_handler_IsActive() && !round_handler_IsRoundStarted())
-               return;
-
-       if(time < self.captime + 0.3)
-               return;
-
-       // only valid teams can claim it
-       head = find(world, classname, "dom_team");
-       while (head && head.team != other.team)
-               head = find(head, classname, "dom_team");
-       if (!head || head.netname == "" || head == self.goalentity)
-               return;
-
-       // delay capture
-
-       self.team = self.goalentity.team; // this stores the PREVIOUS team!
-
-       self.cnt = other.team;
-       self.owner = head; // team to switch to after the delay
-       self.dmg_inflictor = other;
-
-       // self.state = 1;
-       // self.delay = time + cvar("g_domination_point_capturetime");
-       //self.nextthink = time + cvar("g_domination_point_capturetime");
-       //self.think = dompoint_captured;
-
-       // go to neutral team in the mean time
-       head = find(world, classname, "dom_team");
-       while (head && head.netname != "")
-               head = find(head, classname, "dom_team");
-       if(head == world)
-               return;
-
-       WaypointSprite_UpdateSprites(self.sprite, WP_DomNeut, WP_Null, WP_Null);
-       WaypointSprite_UpdateTeamRadar(self.sprite, RADARICON_DOMPOINT, '0 1 1');
-       WaypointSprite_Ping(self.sprite);
-
-       self.goalentity = head;
-       self.model = head.mdl;
-       self.modelindex = head.dmg;
-       self.skin = head.skin;
-
-       self.enemy = other; // individual player scoring
-       self.enemy_playerid = other.playerid;
-       dompoint_captured();
-}
-
-void dom_controlpoint_setup()
-{SELFPARAM();
-       entity head;
-       // find the spawnfunc_dom_team representing unclaimed points
-       head = find(world, classname, "dom_team");
-       while(head && head.netname != "")
-               head = find(head, classname, "dom_team");
-       if (!head)
-               objerror("no spawnfunc_dom_team with netname \"\" found\n");
-
-       // copy important properties from spawnfunc_dom_team entity
-       self.goalentity = head;
-       _setmodel(self, head.mdl); // precision already set
-       self.skin = head.skin;
-
-       self.cnt = -1;
-
-       if(self.message == "")
-               self.message = " has captured a control point";
-
-       if(self.frags <= 0)
-               self.frags = 1;
-       if(self.wait <= 0)
-               self.wait = 5;
-
-       float points, waittime;
-       if (autocvar_g_domination_point_amt)
-               points = autocvar_g_domination_point_amt;
-       else
-               points = self.frags;
-       if (autocvar_g_domination_point_rate)
-               waittime = autocvar_g_domination_point_rate;
-       else
-               waittime = self.wait;
-
-       total_pps += points/waittime;
-
-       if(!self.t_width)
-               self.t_width = 0.02; // frame animation rate
-       if(!self.t_length)
-               self.t_length = 239; // maximum frame
-
-       self.think = dompointthink;
-       self.nextthink = time;
-       self.touch = dompointtouch;
-       self.solid = SOLID_TRIGGER;
-       self.flags = FL_ITEM;
-       setsize(self, '-32 -32 -32', '32 32 32');
-       setorigin(self, self.origin + '0 0 20');
-       droptofloor();
-
-       waypoint_spawnforitem(self);
-       WaypointSprite_SpawnFixed(WP_DomNeut, self.origin + '0 0 32', self, sprite, RADARICON_DOMPOINT);
-}
-
-float total_controlpoints;
-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()
-{SELFPARAM();
-       if(self.deadflag != DEAD_NO)
-               return;
-
-       if (self.bot_strategytime < time)
-       {
-               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
-               navigation_goalrating_start();
-               havocbot_goalrating_controlpoints(10000, self.origin, 15000);
-               havocbot_goalrating_items(8000, self.origin, 8000);
-               //havocbot_goalrating_enemyplayers(3000, self.origin, 2000);
-               //havocbot_goalrating_waypoints(1, self.origin, 1000);
-               navigation_goalrating_end();
-       }
-}
-
-MUTATOR_HOOKFUNCTION(dom_GetTeamCount)
-{
-       ret_float = domination_teams;
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(dom_ResetMap)
-{SELFPARAM();
-       total_pps = 0, pps_red = 0, pps_blue = 0, pps_yellow = 0, pps_pink = 0;
-       entity e;
-       FOR_EACH_PLAYER(e)
-       {
-               setself(e);
-               PutClientInServer();
-               self.player_blocked = 1;
-               if(IS_REAL_CLIENT(self))
-                       set_dom_state(self);
-       }
-       return 1;
-}
-
-MUTATOR_HOOKFUNCTION(dom_PlayerSpawn)
-{SELFPARAM();
-       if(domination_roundbased)
-       if(!round_handler_IsRoundStarted())
-               self.player_blocked = 1;
-       else
-               self.player_blocked = 0;
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(dom_ClientConnect)
-{SELFPARAM();
-       set_dom_state(self);
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(dom_BotRoles)
-{SELFPARAM();
-       self.havocbot_role = havocbot_role_dom;
-       return true;
-}
-
-/*QUAKED spawnfunc_dom_controlpoint (0 .5 .8) (-16 -16 -24) (16 16 32)
-Control point for Domination gameplay.
-*/
-spawnfunc(dom_controlpoint)
-{
-       if(!g_domination)
-       {
-               remove(self);
-               return;
-       }
-       self.think = dom_controlpoint_setup;
-       self.nextthink = time + 0.1;
-       self.reset = dom_controlpoint_setup;
-
-       if(!self.scale)
-               self.scale = 0.6;
-
-       self.effects = self.effects | EF_LOWPRECISION;
-       if (autocvar_g_domination_point_fullbright)
-               self.effects |= EF_FULLBRIGHT;
-}
-
-/*QUAKED spawnfunc_dom_team (0 .5 .8) (-32 -32 -24) (32 32 32)
-Team declaration for Domination gameplay, this allows you to decide what team
-names and control point models are used in your map.
-
-Note: If you use spawnfunc_dom_team entities you must define at least 3 and only two
-can have netname set!  The nameless team owns all control points at start.
-
-Keys:
-"netname"
- Name of the team (for example Red Team, Blue Team, Green Team, Yellow Team, Life, Death, etc)
-"cnt"
- Scoreboard color of the team (for example 4 is red and 13 is blue)
-"model"
- Model to use for control points owned by this team (for example
- "progs/b_g_key.mdl" is a gold keycard, and "progs/b_s_key.mdl" is a silver
- keycard)
-"skin"
- Skin of the model to use (for team skins on a single model)
-"noise"
- Sound to play when this team captures a point.
- (this is a localized sound, like a small alarm or other effect)
-"noise1"
- Narrator speech to play when this team captures a point.
- (this is a global sound, like "Red team has captured a control point")
-*/
-
-spawnfunc(dom_team)
-{
-       if(!g_domination || autocvar_g_domination_teams_override >= 2)
-       {
-               remove(self);
-               return;
-       }
-       precache_model(self.model);
-       if (self.noise != "")
-               precache_sound(self.noise);
-       if (self.noise1 != "")
-               precache_sound(self.noise1);
-       self.classname = "dom_team";
-       _setmodel(self, self.model); // precision not needed
-       self.mdl = self.model;
-       self.dmg = self.modelindex;
-       self.model = "";
-       self.modelindex = 0;
-       // this would have to be changed if used in quakeworld
-       if(self.cnt)
-               self.team = self.cnt + 1; // WHY are these different anyway?
-}
-
-// scoreboard setup
-void ScoreRules_dom(float teams)
-{
-       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
-       {
-               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
-void dom_spawnteam (string teamname, float teamcolor, string pointmodel, float pointskin, string capsound, string capnarration, string capmessage)
-{SELFPARAM();
-       setself(spawn());
-       self.classname = "dom_team";
-       self.netname = teamname;
-       self.cnt = teamcolor;
-       self.model = pointmodel;
-       self.skin = pointskin;
-       self.noise = capsound;
-       self.noise1 = capnarration;
-       self.message = capmessage;
-
-       // this code is identical to spawnfunc_dom_team
-       _setmodel(self, self.model); // precision not needed
-       self.mdl = self.model;
-       self.dmg = self.modelindex;
-       self.model = "";
-       self.modelindex = 0;
-       // this would have to be changed if used in quakeworld
-       self.team = self.cnt + 1;
-
-       //eprint(self);
-       setself(this);
-}
-
-void _spawnfunc_dom_controlpoint() { SELFPARAM(); spawnfunc_dom_controlpoint(self); }
-void dom_spawnpoint(vector org)
-{SELFPARAM();
-       setself(spawn());
-       self.classname = "dom_controlpoint";
-       self.think = _spawnfunc_dom_controlpoint;
-       self.nextthink = time;
-       setorigin(self, org);
-       spawnfunc_dom_controlpoint(this);
-       setself(this);
-}
-
-// spawn some default teams if the map is not set up for domination
-void dom_spawnteams(float teams)
-{
-       dom_spawnteam("Red", NUM_TEAM_1-1, "models/domination/dom_red.md3", 0, SND(DOM_CLAIM), "", "Red team has captured a control point");
-       dom_spawnteam("Blue", NUM_TEAM_2-1, "models/domination/dom_blue.md3", 0, SND(DOM_CLAIM), "", "Blue team has captured a control point");
-       if(teams >= 3)
-               dom_spawnteam("Yellow", NUM_TEAM_3-1, "models/domination/dom_yellow.md3", 0, SND(DOM_CLAIM), "", "Yellow team has captured a control point");
-       if(teams >= 4)
-               dom_spawnteam("Pink", NUM_TEAM_4-1, "models/domination/dom_pink.md3", 0, SND(DOM_CLAIM), "", "Pink team has captured a control point");
-       dom_spawnteam("", 0, "models/domination/dom_unclaimed.md3", 0, "", "", "");
-}
-
-void dom_DelayedInit() // Do this check with a delay so we can wait for teams to be set up.
-{
-       // if no teams are found, spawn defaults
-       if(find(world, classname, "dom_team") == world || autocvar_g_domination_teams_override >= 2)
-       {
-               LOG_INFO("No ""dom_team"" entities found on this map, creating them anyway.\n");
-               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);
-
-       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()
-{
-       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);
-
-       MUTATOR_ONADD
-       {
-               if(time > 1) // game loads at time 1
-                       error("This is a game type and it cannot be added at runtime.");
-               dom_Initialize();
-       }
-
-       MUTATOR_ONREMOVE
-       {
-               LOG_INFO("This is a game type and it cannot be removed at runtime.");
-               return -1;
-       }
-
-       return 0;
-}
diff --git a/qcsrc/server/mutators/gamemode_domination.qh b/qcsrc/server/mutators/gamemode_domination.qh
deleted file mode 100644 (file)
index d017b62..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef GAMEMODE_DOMINATION_H
-#define GAMEMODE_DOMINATION_H
-// these are needed since mutators are compiled last
-
-// score rule declarations
-const float ST_DOM_TICKS = 1;
-const float SP_DOM_TICKS = 4;
-const float SP_DOM_TAKES = 5;
-const float ST_DOM_CAPS = 1;
-const float SP_DOM_CAPS = 4;
-
-// pps: points per second
-.float dom_total_pps;
-.float dom_pps_red;
-.float dom_pps_blue;
-.float dom_pps_yellow;
-.float dom_pps_pink;
-float total_pps;
-float pps_red;
-float pps_blue;
-float pps_yellow;
-float pps_pink;
-
-// capture declarations
-.float enemy_playerid;
-.entity sprite;
-.float captime;
-
-// misc globals
-float domination_roundbased;
-float domination_teams;
-#endif
diff --git a/qcsrc/server/mutators/gamemode_freezetag.qc b/qcsrc/server/mutators/gamemode_freezetag.qc
deleted file mode 100644 (file)
index 6eb2128..0000000
+++ /dev/null
@@ -1,615 +0,0 @@
-#include "gamemode_freezetag.qh"
-
-#include "gamemode.qh"
-
-const float SP_FREEZETAG_REVIVALS = 4;
-void freezetag_ScoreRules(float teams)
-{
-       ScoreRules_basics(teams, SFL_SORT_PRIO_PRIMARY, SFL_SORT_PRIO_PRIMARY, true); // SFL_SORT_PRIO_PRIMARY
-       ScoreInfo_SetLabel_PlayerScore(SP_FREEZETAG_REVIVALS, "revivals", 0);
-       ScoreRules_basics_end();
-}
-
-void freezetag_count_alive_players()
-{
-       entity e;
-       total_players = redalive = bluealive = yellowalive = pinkalive = 0;
-       FOR_EACH_PLAYER(e)
-       {
-               switch(e.team)
-               {
-                       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)
-       {
-               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 freezetag_CheckTeams()
-{
-       static float prev_missing_teams_mask;
-       if(FREEZETAG_ALIVE_TEAMS_OK())
-       {
-               if(prev_missing_teams_mask > 0)
-                       Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_MISSING_TEAMS);
-               prev_missing_teams_mask = -1;
-               return 1;
-       }
-       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)
-       {
-               Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_MISSING_TEAMS, missing_teams_mask);
-               prev_missing_teams_mask = missing_teams_mask;
-       }
-       return 0;
-}
-
-float freezetag_getWinnerTeam()
-{
-       float winner_team = 0;
-       if(redalive >= 1)
-               winner_team = NUM_TEAM_1;
-       if(bluealive >= 1)
-       {
-               if(winner_team) return 0;
-               winner_team = NUM_TEAM_2;
-       }
-       if(yellowalive >= 1)
-       {
-               if(winner_team) return 0;
-               winner_team = NUM_TEAM_3;
-       }
-       if(pinkalive >= 1)
-       {
-               if(winner_team) return 0;
-               winner_team = NUM_TEAM_4;
-       }
-       if(winner_team)
-               return winner_team;
-       return -1; // no player left
-}
-
-float freezetag_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);
-               FOR_EACH_PLAYER(e)
-               {
-                       e.freezetag_frozen_timeout = 0;
-                       nades_Clear(e);
-               }
-               round_handler_Init(5, autocvar_g_freezetag_warmup, autocvar_g_freezetag_round_timelimit);
-               return 1;
-       }
-
-       if(FREEZETAG_ALIVE_TEAMS() > 1)
-               return 0;
-
-       float winner_team;
-       winner_team = freezetag_getWinnerTeam();
-       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_SCORE, +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);
-       }
-
-       FOR_EACH_PLAYER(e)
-       {
-               e.freezetag_frozen_timeout = 0;
-               nades_Clear(e);
-       }
-       round_handler_Init(5, autocvar_g_freezetag_warmup, autocvar_g_freezetag_round_timelimit);
-       return 1;
-}
-
-entity freezetag_LastPlayerForTeam()
-{SELFPARAM();
-       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)
-{SELFPARAM();
-       if(attacker == self)
-       {
-               // you froze your own dumb self
-               // counted as "suicide" already
-               PlayerScore_Add(self, SP_SCORE, -1);
-       }
-       else if(IS_PLAYER(attacker))
-       {
-               // got frozen by an enemy
-               // counted as "kill" and "death" already
-               PlayerScore_Add(self, SP_SCORE, -1);
-               PlayerScore_Add(attacker, SP_SCORE, +1);
-       }
-       // else nothing - got frozen by the game type rules themselves
-}
-
-void freezetag_Freeze(entity attacker)
-{SELFPARAM();
-       if(self.frozen)
-               return;
-
-       if(autocvar_g_freezetag_frozen_maxtime > 0)
-               self.freezetag_frozen_timeout = time + autocvar_g_freezetag_frozen_maxtime;
-
-       Freeze(self, 0, 1, true);
-
-       freezetag_count_alive_players();
-
-       freezetag_Add_Score(attacker);
-}
-
-void freezetag_Unfreeze(entity attacker)
-{SELFPARAM();
-       self.freezetag_frozen_time = 0;
-       self.freezetag_frozen_timeout = 0;
-
-       Unfreeze(self);
-}
-
-float freezetag_isEliminated(entity e)
-{
-       if(IS_PLAYER(e) && (e.frozen == 1 || e.deadflag != DEAD_NO))
-               return true;
-       return false;
-}
-
-
-// ================
-// Bot player logic
-// ================
-
-void() havocbot_role_ft_freeing;
-void() havocbot_role_ft_offense;
-
-void havocbot_goalrating_freeplayers(float ratingscale, vector org, float sradius)
-{SELFPARAM();
-       entity head;
-       float distance;
-
-       FOR_EACH_PLAYER(head)
-       {
-               if ((head != self) && (head.team == self.team))
-               {
-                       if (head.frozen == 1)
-                       {
-                               distance = vlen(head.origin - org);
-                               if (distance > sradius)
-                                       continue;
-                               navigation_routerating(head, ratingscale, 2000);
-                       }
-                       else
-                       {
-                               // If teamate is not frozen still seek them out as fight better
-                               // in a group.
-                               navigation_routerating(head, ratingscale/3, 2000);
-                       }
-               }
-       }
-}
-
-void havocbot_role_ft_offense()
-{SELFPARAM();
-       entity head;
-       float unfrozen;
-
-       if(self.deadflag != DEAD_NO)
-               return;
-
-       if (!self.havocbot_role_timeout)
-               self.havocbot_role_timeout = time + random() * 10 + 20;
-
-       // Count how many players on team are unfrozen.
-       unfrozen = 0;
-       FOR_EACH_PLAYER(head)
-       {
-               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.frozen)) || (time > self.havocbot_role_timeout))
-       {
-               LOG_TRACE("changing role to freeing\n");
-               self.havocbot_role = havocbot_role_ft_freeing;
-               self.havocbot_role_timeout = 0;
-               return;
-       }
-
-       if (time > self.bot_strategytime)
-       {
-               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
-
-               navigation_goalrating_start();
-               havocbot_goalrating_items(10000, self.origin, 10000);
-               havocbot_goalrating_enemyplayers(20000, self.origin, 10000);
-               havocbot_goalrating_freeplayers(9000, self.origin, 10000);
-               //havocbot_goalrating_waypoints(1, self.origin, 1000);
-               navigation_goalrating_end();
-       }
-}
-
-void havocbot_role_ft_freeing()
-{SELFPARAM();
-       if(self.deadflag != DEAD_NO)
-               return;
-
-       if (!self.havocbot_role_timeout)
-               self.havocbot_role_timeout = time + random() * 10 + 20;
-
-       if (time > self.havocbot_role_timeout)
-       {
-               LOG_TRACE("changing role to offense\n");
-               self.havocbot_role = havocbot_role_ft_offense;
-               self.havocbot_role_timeout = 0;
-               return;
-       }
-
-       if (time > self.bot_strategytime)
-       {
-               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
-
-               navigation_goalrating_start();
-               havocbot_goalrating_items(8000, self.origin, 10000);
-               havocbot_goalrating_enemyplayers(10000, self.origin, 10000);
-               havocbot_goalrating_freeplayers(20000, self.origin, 10000);
-               //havocbot_goalrating_waypoints(1, self.origin, 1000);
-               navigation_goalrating_end();
-       }
-}
-
-
-// ==============
-// Hook Functions
-// ==============
-
-MUTATOR_HOOKFUNCTION(freezetag_RemovePlayer)
-{SELFPARAM();
-       self.health = 0; // neccessary to update correctly alive stats
-       if(!self.frozen)
-               freezetag_LastPlayerForTeam_Notify();
-       freezetag_Unfreeze(world);
-       freezetag_count_alive_players();
-       return 1;
-}
-
-MUTATOR_HOOKFUNCTION(freezetag_PlayerDies)
-{SELFPARAM();
-       if(round_handler_IsActive())
-       if(round_handler_CountdownRunning())
-       {
-               if(self.frozen)
-                       freezetag_Unfreeze(world);
-               freezetag_count_alive_players();
-               return 1; // let the player die so that he can respawn whenever he wants
-       }
-
-       // Cases DEATH_TEAMCHANGE and DEATH_AUTOTEAMCHANGE are needed to fix a bug whe
-       // you succeed changing team through the menu: you both really die (gibbing) and get frozen
-       if(ITEM_DAMAGE_NEEDKILL(frag_deathtype)
-               || frag_deathtype == DEATH_TEAMCHANGE.m_id || frag_deathtype == DEATH_AUTOTEAMCHANGE.m_id)
-       {
-               // let the player die, he will be automatically frozen when he respawns
-               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.frozen)
-               return 1;
-
-       freezetag_Freeze(frag_attacker);
-       freezetag_LastPlayerForTeam_Notify();
-
-       if(frag_attacker == frag_target || frag_attacker == world)
-       {
-               if(IS_PLAYER(frag_target))
-                       Send_Notification(NOTIF_ONE, frag_target, MSG_CENTER, CENTER_FREEZETAG_SELF);
-               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_FREEZETAG_SELF, frag_target.netname);
-       }
-       else
-       {
-               if(IS_PLAYER(frag_target))
-                       Send_Notification(NOTIF_ONE, frag_target, MSG_CENTER, CENTER_FREEZETAG_FROZEN, frag_attacker.netname);
-               if(IS_PLAYER(frag_attacker))
-                       Send_Notification(NOTIF_ONE, frag_attacker, MSG_CENTER, CENTER_FREEZETAG_FREEZE, frag_target.netname);
-               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_FREEZETAG_FREEZE, frag_target.netname, frag_attacker.netname);
-       }
-
-       return 1;
-}
-
-MUTATOR_HOOKFUNCTION(freezetag_PlayerSpawn)
-{SELFPARAM();
-       if(self.freezetag_frozen_timeout == -1) // if PlayerSpawn is called by reset_map_players
-               return 1; // do nothing, round is starting right now
-
-       if(self.freezetag_frozen_timeout == -2) // player was dead
-       {
-               freezetag_Freeze(world);
-               return 1;
-       }
-
-       freezetag_count_alive_players();
-
-       if(round_handler_IsActive())
-       if(round_handler_IsRoundStarted())
-       {
-               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_FREEZETAG_SPAWN_LATE);
-               freezetag_Freeze(world);
-       }
-
-       return 1;
-}
-
-MUTATOR_HOOKFUNCTION(freezetag_reset_map_players)
-{SELFPARAM();
-       entity e;
-       FOR_EACH_PLAYER(e)
-       {
-               e.killcount = 0;
-               e.freezetag_frozen_timeout = -1;
-               setself(e);
-               PutClientInServer();
-               e.freezetag_frozen_timeout = 0;
-       }
-       freezetag_count_alive_players();
-       return 1;
-}
-
-MUTATOR_HOOKFUNCTION(freezetag_GiveFragsForKill)
-{
-       frag_score = 0; // no frags counted in Freeze Tag
-       return 1;
-}
-
-MUTATOR_HOOKFUNCTION(freezetag_PlayerPreThink)
-{SELFPARAM();
-       float n;
-
-       if(gameover)
-               return 1;
-
-       if(self.frozen == 1)
-       {
-               // keep health = 1
-               self.pauseregen_finished = time + autocvar_g_balance_pause_health_regen;
-       }
-
-       if(round_handler_IsActive())
-       if(!round_handler_IsRoundStarted())
-               return 1;
-
-       entity o;
-       o = world;
-       //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;
-       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.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(!o)
-                               o = other;
-                       if(self.frozen == 1)
-                               other.reviving = true;
-                       ++n;
-               }
-       }
-
-       if(n && self.frozen == 1) // 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 * ((warmup_stage) ? warmup_start_health : start_health));
-
-               if(self.revive_progress >= 1)
-               {
-                       freezetag_Unfreeze(self);
-                       freezetag_count_alive_players();
-
-                       if(n == -1)
-                       {
-                               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_FREEZETAG_AUTO_REVIVED, autocvar_g_freezetag_frozen_maxtime);
-                               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_FREEZETAG_AUTO_REVIVED, self.netname, autocvar_g_freezetag_frozen_maxtime);
-                               return 1;
-                       }
-
-                       // EVERY team mate nearby gets a point (even if multiple!)
-                       FOR_EACH_PLAYER(other)
-                       {
-                               if(other.reviving)
-                               {
-                                       PlayerScore_Add(other, SP_FREEZETAG_REVIVALS, +1);
-                                       PlayerScore_Add(other, SP_SCORE, +1);
-
-                                       nades_GiveBonus(other,autocvar_g_nades_bonus_score_low);
-                               }
-                       }
-
-                       Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_FREEZETAG_REVIVED, o.netname);
-                       Send_Notification(NOTIF_ONE, o, MSG_CENTER, CENTER_FREEZETAG_REVIVE, self.netname);
-                       Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_FREEZETAG_REVIVED, self.netname, o.netname);
-               }
-
-               FOR_EACH_PLAYER(other)
-               {
-                       if(other.reviving)
-                       {
-                               other.revive_progress = self.revive_progress;
-                               other.reviving = false;
-                       }
-               }
-       }
-       else if(!n && self.frozen == 1) // only if no teammate is nearby will we reset
-       {
-               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));
-       }
-       else if(!n && !self.frozen)
-       {
-               self.revive_progress = 0; // thawing nobody
-       }
-
-       return 1;
-}
-
-MUTATOR_HOOKFUNCTION(freezetag_SetStartItems)
-{
-       start_items &= ~IT_UNLIMITED_AMMO;
-       //start_health       = warmup_start_health       = cvar("g_lms_start_health");
-       //start_armorvalue   = warmup_start_armorvalue   = cvar("g_lms_start_armor");
-       start_ammo_shells  = warmup_start_ammo_shells  = cvar("g_lms_start_ammo_shells");
-       start_ammo_nails   = warmup_start_ammo_nails   = cvar("g_lms_start_ammo_nails");
-       start_ammo_rockets = warmup_start_ammo_rockets = cvar("g_lms_start_ammo_rockets");
-       start_ammo_cells   = warmup_start_ammo_cells   = cvar("g_lms_start_ammo_cells");
-       start_ammo_plasma  = warmup_start_ammo_plasma  = cvar("g_lms_start_ammo_plasma");
-       start_ammo_fuel    = warmup_start_ammo_fuel    = cvar("g_lms_start_ammo_fuel");
-
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(freezetag_BotRoles)
-{SELFPARAM();
-       if (!self.deadflag)
-       {
-               if (random() < 0.5)
-                       self.havocbot_role = havocbot_role_ft_freeing;
-               else
-                       self.havocbot_role = havocbot_role_ft_offense;
-       }
-
-       return true;
-}
-
-MUTATOR_HOOKFUNCTION(freezetag_GetTeamCount)
-{
-       ret_float = freezetag_teams;
-       return false;
-}
-
-void freezetag_Initialize()
-{
-       freezetag_teams = autocvar_g_freezetag_teams_override;
-       if(freezetag_teams < 2)
-               freezetag_teams = autocvar_g_freezetag_teams;
-       freezetag_teams = bound(2, freezetag_teams, 4);
-       freezetag_ScoreRules(freezetag_teams);
-
-       round_handler_Spawn(freezetag_CheckTeams, freezetag_CheckWinner, func_null);
-       round_handler_Init(5, autocvar_g_freezetag_warmup, autocvar_g_freezetag_round_timelimit);
-
-       addstat(STAT_REDALIVE, AS_INT, redalive_stat);
-       addstat(STAT_BLUEALIVE, AS_INT, bluealive_stat);
-       addstat(STAT_YELLOWALIVE, AS_INT, yellowalive_stat);
-       addstat(STAT_PINKALIVE, AS_INT, pinkalive_stat);
-
-       EliminatedPlayers_Init(freezetag_isEliminated);
-}
-
-MUTATOR_DEFINITION(gamemode_freezetag)
-{
-       MUTATOR_HOOK(MakePlayerObserver, freezetag_RemovePlayer, CBC_ORDER_ANY);
-       MUTATOR_HOOK(ClientDisconnect, freezetag_RemovePlayer, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerDies, freezetag_PlayerDies, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerSpawn, freezetag_PlayerSpawn, CBC_ORDER_ANY);
-       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(SetStartItems, freezetag_SetStartItems, CBC_ORDER_ANY);
-       MUTATOR_HOOK(HavocBot_ChooseRole, freezetag_BotRoles, CBC_ORDER_ANY);
-       MUTATOR_HOOK(GetTeamCount, freezetag_GetTeamCount, CBC_ORDER_EXCLUSIVE);
-
-       MUTATOR_ONADD
-       {
-               if(time > 1) // game loads at time 1
-                       error("This is a game type and it cannot be added at runtime.");
-               freezetag_Initialize();
-       }
-
-       MUTATOR_ONROLLBACK_OR_REMOVE
-       {
-               // we actually cannot roll back freezetag_Initialize here
-               // BUT: we don't need to! If this gets called, adding always
-               // succeeds.
-       }
-
-       MUTATOR_ONREMOVE
-       {
-               LOG_INFO("This is a game type and it cannot be removed at runtime.");
-               return -1;
-       }
-
-       return 0;
-}
diff --git a/qcsrc/server/mutators/gamemode_freezetag.qh b/qcsrc/server/mutators/gamemode_freezetag.qh
deleted file mode 100644 (file)
index 19489fc..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef GAMEMODE_FREEZETAG_H
-#define GAMEMODE_FREEZETAG_H
-.float freezetag_frozen_time;
-.float freezetag_frozen_timeout;
-const float ICE_MAX_ALPHA = 1;
-const float ICE_MIN_ALPHA = 0.1;
-float freezetag_teams;
-
-.float reviving; // temp var
-
-#endif
diff --git a/qcsrc/server/mutators/gamemode_invasion.qc b/qcsrc/server/mutators/gamemode_invasion.qc
deleted file mode 100644 (file)
index 0929d93..0000000
+++ /dev/null
@@ -1,495 +0,0 @@
-#include "gamemode_invasion.qh"
-
-#include "gamemode.qh"
-
-#include "../../common/monsters/spawn.qh"
-#include "../../common/monsters/sv_monsters.qh"
-
-#include "../teamplay.qh"
-
-spawnfunc(invasion_spawnpoint)
-{
-       if(!g_invasion) { remove(self); return; }
-
-       self.classname = "invasion_spawnpoint";
-
-       if(autocvar_g_invasion_zombies_only) // precache only if it hasn't been already
-       if(self.monsterid) {
-               Monster mon = get_monsterinfo(self.monsterid);
-               mon.mr_precache(mon);
-       }
-}
-
-float invasion_PickMonster(float supermonster_count)
-{
-       if(autocvar_g_invasion_zombies_only)
-               return MON_ZOMBIE.monsterid;
-
-       float i;
-       entity mon;
-
-       RandomSelection_Init();
-
-       for(i = MON_FIRST; i <= MON_LAST; ++i)
-       {
-               mon = get_monsterinfo(i);
-               if((mon.spawnflags & MONSTER_TYPE_FLY) || (mon.spawnflags & MONSTER_TYPE_SWIM) || ((mon.spawnflags & MON_FLAG_SUPERMONSTER) && supermonster_count >= 1))
-                       continue; // flying/swimming monsters not yet supported
-
-               RandomSelection_Add(world, i, string_null, 1, 1);
-       }
-
-       return RandomSelection_chosen_float;
-}
-
-entity invasion_PickSpawn()
-{
-       entity e;
-
-       RandomSelection_Init();
-
-       for(e = world;(e = find(e, classname, "invasion_spawnpoint")); )
-       {
-               RandomSelection_Add(e, 0, string_null, 1, ((time >= e.spawnshieldtime) ? 0.2 : 1)); // give recently used spawnpoints a very low rating
-               e.spawnshieldtime = time + autocvar_g_invasion_spawnpoint_spawn_delay;
-       }
-
-       return RandomSelection_chosen_ent;
-}
-
-void invasion_SpawnChosenMonster(float mon)
-{
-       entity spawn_point, monster;
-
-       spawn_point = invasion_PickSpawn();
-
-       if(spawn_point == world)
-       {
-               LOG_TRACE("Warning: couldn't find any invasion_spawnpoint spawnpoints, attempting to spawn monsters in random locations\n");
-               entity e = spawn();
-               setsize(e, (get_monsterinfo(mon)).mins, (get_monsterinfo(mon)).maxs);
-
-               if(MoveToRandomMapLocation(e, DPCONTENTS_SOLID | DPCONTENTS_CORPSE | DPCONTENTS_PLAYERCLIP, DPCONTENTS_SLIME | DPCONTENTS_LAVA | DPCONTENTS_SKY | DPCONTENTS_BODY | DPCONTENTS_DONOTENTER, Q3SURFACEFLAG_SKY, 10, 1024, 256))
-                       monster = spawnmonster("", mon, world, world, e.origin, false, false, 2);
-               else return;
-
-               e.think = SUB_Remove;
-               e.nextthink = time + 0.1;
-       }
-       else
-               monster = spawnmonster("", ((spawn_point.monsterid) ? spawn_point.monsterid : mon), spawn_point, spawn_point, spawn_point.origin, false, false, 2);
-
-       if(spawn_point) monster.target2 = spawn_point.target2;
-       monster.spawnshieldtime = time;
-       if(spawn_point && spawn_point.target_range) monster.target_range = spawn_point.target_range;
-
-       if(teamplay)
-       if(spawn_point && spawn_point.team && inv_monsters_perteam[spawn_point.team] > 0)
-               monster.team = spawn_point.team;
-       else
-       {
-               RandomSelection_Init();
-               if(inv_monsters_perteam[NUM_TEAM_1] > 0) RandomSelection_Add(world, NUM_TEAM_1, string_null, 1, 1);
-               if(inv_monsters_perteam[NUM_TEAM_2] > 0) RandomSelection_Add(world, NUM_TEAM_2, string_null, 1, 1);
-               if(invasion_teams >= 3) if(inv_monsters_perteam[NUM_TEAM_3] > 0) { RandomSelection_Add(world, NUM_TEAM_3, string_null, 1, 1); }
-               if(invasion_teams >= 4) if(inv_monsters_perteam[NUM_TEAM_4] > 0) { RandomSelection_Add(world, NUM_TEAM_4, string_null, 1, 1); }
-
-               monster.team = RandomSelection_chosen_float;
-       }
-
-       if(teamplay)
-       {
-               monster_setupcolors(monster);
-
-               if(monster.sprite)
-               {
-                       WaypointSprite_UpdateTeamRadar(monster.sprite, RADARICON_DANGER, ((monster.team) ? Team_ColorRGB(monster.team) : '1 0 0'));
-
-                       monster.sprite.team = 0;
-                       monster.sprite.SendFlags |= 1;
-               }
-       }
-
-       monster.monster_attack = false; // it's the player's job to kill all the monsters
-
-       if(inv_roundcnt >= inv_maxrounds)
-               monster.spawnflags |= MONSTERFLAG_MINIBOSS; // last round spawns minibosses
-}
-
-void invasion_SpawnMonsters(float supermonster_count)
-{
-       float chosen_monster = invasion_PickMonster(supermonster_count);
-
-       invasion_SpawnChosenMonster(chosen_monster);
-}
-
-float Invasion_CheckWinner()
-{
-       entity head;
-       if(round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0)
-       {
-               FOR_EACH_MONSTER(head)
-                       Monster_Remove(head);
-
-               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_invasion_warmup, autocvar_g_invasion_round_timelimit);
-               return 1;
-       }
-
-       float total_alive_monsters = 0, supermonster_count = 0, red_alive = 0, blue_alive = 0, yellow_alive = 0, pink_alive = 0;
-
-       FOR_EACH_MONSTER(head) if(head.health > 0)
-       {
-               if((get_monsterinfo(head.monsterid)).spawnflags & MON_FLAG_SUPERMONSTER)
-                       ++supermonster_count;
-               ++total_alive_monsters;
-
-               if(teamplay)
-               switch(head.team)
-               {
-                       case NUM_TEAM_1: ++red_alive; break;
-                       case NUM_TEAM_2: ++blue_alive; break;
-                       case NUM_TEAM_3: ++yellow_alive; break;
-                       case NUM_TEAM_4: ++pink_alive; break;
-               }
-       }
-
-       if((total_alive_monsters + inv_numkilled) < inv_maxspawned && inv_maxcurrent < inv_maxspawned)
-       {
-               if(time >= inv_lastcheck)
-               {
-                       invasion_SpawnMonsters(supermonster_count);
-                       inv_lastcheck = time + autocvar_g_invasion_spawn_delay;
-               }
-
-               return 0;
-       }
-
-       if(inv_numspawned < 1)
-               return 0; // nothing has spawned yet
-
-       if(teamplay)
-       {
-               if(((red_alive > 0) + (blue_alive > 0) + (yellow_alive > 0) + (pink_alive > 0)) > 1)
-                       return 0;
-       }
-       else if(inv_numkilled < inv_maxspawned)
-               return 0;
-
-       entity winner = world;
-       float winning_score = 0, winner_team = 0;
-
-
-       if(teamplay)
-       {
-               if(red_alive > 0) { winner_team = NUM_TEAM_1; }
-               if(blue_alive > 0)
-               if(winner_team) { winner_team = 0; }
-               else { winner_team = NUM_TEAM_2; }
-               if(yellow_alive > 0)
-               if(winner_team) { winner_team = 0; }
-               else { winner_team = NUM_TEAM_3; }
-               if(pink_alive > 0)
-               if(winner_team) { winner_team = 0; }
-               else { winner_team = NUM_TEAM_4; }
-       }
-       else
-       FOR_EACH_PLAYER(head)
-       {
-               float cs = PlayerScore_Add(head, SP_KILLS, 0);
-               if(cs > winning_score)
-               {
-                       winning_score = cs;
-                       winner = head;
-               }
-       }
-
-       FOR_EACH_MONSTER(head)
-               Monster_Remove(head);
-
-       if(teamplay)
-       {
-               if(winner_team)
-               {
-                       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_));
-               }
-       }
-       else if(winner)
-       {
-               Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_ROUND_PLAYER_WIN, winner.netname);
-               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_ROUND_PLAYER_WIN, winner.netname);
-       }
-
-       round_handler_Init(5, autocvar_g_invasion_warmup, autocvar_g_invasion_round_timelimit);
-
-       return 1;
-}
-
-float Invasion_CheckPlayers()
-{
-       return true;
-}
-
-void Invasion_RoundStart()
-{
-       entity e;
-       float numplayers = 0;
-       FOR_EACH_PLAYER(e)
-       {
-               e.player_blocked = 0;
-               ++numplayers;
-       }
-
-       if(inv_roundcnt < inv_maxrounds)
-               inv_roundcnt += 1; // a limiter to stop crazy counts
-
-       inv_monsterskill = inv_roundcnt + max(1, numplayers * 0.3);
-
-       inv_maxcurrent = 0;
-       inv_numspawned = 0;
-       inv_numkilled = 0;
-
-       inv_maxspawned = rint(max(autocvar_g_invasion_monster_count, autocvar_g_invasion_monster_count * (inv_roundcnt * 0.5)));
-
-       if(teamplay)
-       {
-               DistributeEvenly_Init(inv_maxspawned, invasion_teams);
-               inv_monsters_perteam[NUM_TEAM_1] = DistributeEvenly_Get(1);
-               inv_monsters_perteam[NUM_TEAM_2] = DistributeEvenly_Get(1);
-               if(invasion_teams >= 3) inv_monsters_perteam[NUM_TEAM_3] = DistributeEvenly_Get(1);
-               if(invasion_teams >= 4) inv_monsters_perteam[NUM_TEAM_4] = DistributeEvenly_Get(1);
-       }
-}
-
-MUTATOR_HOOKFUNCTION(invasion_MonsterDies)
-{SELFPARAM();
-       if(!(self.spawnflags & MONSTERFLAG_RESPAWNED))
-       {
-               inv_numkilled += 1;
-               inv_maxcurrent -= 1;
-               if(teamplay) { inv_monsters_perteam[self.team] -= 1; }
-
-               if(IS_PLAYER(frag_attacker))
-               if(SAME_TEAM(frag_attacker, self)) // in non-teamplay modes, same team = same player, so this works
-                       PlayerScore_Add(frag_attacker, SP_KILLS, -1);
-               else
-               {
-                       PlayerScore_Add(frag_attacker, SP_KILLS, +1);
-                       if(teamplay)
-                               TeamScore_AddToTeam(frag_attacker.team, ST_INV_KILLS, +1);
-               }
-       }
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(invasion_MonsterSpawn)
-{SELFPARAM();
-       if(!(self.spawnflags & MONSTERFLAG_SPAWNED))
-               return true;
-
-       if(!(self.spawnflags & MONSTERFLAG_RESPAWNED))
-       {
-               inv_numspawned += 1;
-               inv_maxcurrent += 1;
-       }
-
-       self.monster_skill = inv_monsterskill;
-
-       if((get_monsterinfo(self.monsterid)).spawnflags & MON_FLAG_SUPERMONSTER)
-               Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_INVASION_SUPERMONSTER, self.monster_name);
-
-       self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_BOTCLIP | DPCONTENTS_MONSTERCLIP;
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(invasion_OnEntityPreSpawn)
-{SELFPARAM();
-       if(startsWith(self.classname, "monster_"))
-       if(!(self.spawnflags & MONSTERFLAG_SPAWNED))
-               return true;
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(invasion_StartFrame)
-{
-       monsters_total = inv_maxspawned; // TODO: make sure numspawned never exceeds maxspawned
-       monsters_killed = inv_numkilled;
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(invasion_PlayerRegen)
-{
-       // no regeneration in invasion
-       return true;
-}
-
-MUTATOR_HOOKFUNCTION(invasion_PlayerSpawn)
-{SELFPARAM();
-       self.bot_attack = false;
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(invasion_PlayerDamage)
-{
-       if(IS_PLAYER(frag_attacker) && IS_PLAYER(frag_target) && frag_attacker != frag_target)
-       {
-               frag_damage = 0;
-               frag_force = '0 0 0';
-       }
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(invasion_PlayerCommand)
-{SELFPARAM();
-       if(MUTATOR_RETURNVALUE) // command was already handled?
-               return false;
-
-       if(cmd_name == "debuginvasion")
-       {
-               sprint(self, strcat("inv_maxspawned = ", ftos(inv_maxspawned), "\n"));
-               sprint(self, strcat("inv_numspawned = ", ftos(inv_numspawned), "\n"));
-               sprint(self, strcat("inv_numkilled = ", ftos(inv_numkilled), "\n"));
-               sprint(self, strcat("inv_roundcnt = ", ftos(inv_roundcnt), "\n"));
-               sprint(self, strcat("monsters_total = ", ftos(monsters_total), "\n"));
-               sprint(self, strcat("monsters_killed = ", ftos(monsters_killed), "\n"));
-               sprint(self, strcat("inv_monsterskill = ", ftos(inv_monsterskill), "\n"));
-
-               return true;
-       }
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(invasion_BotShouldAttack)
-{
-       if(!IS_MONSTER(checkentity))
-               return true;
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(invasion_SetStartItems)
-{
-       start_health = 200;
-       start_armorvalue = 200;
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(invasion_AccuracyTargetValid)
-{
-       if(IS_MONSTER(frag_target))
-               return MUT_ACCADD_INVALID;
-       return MUT_ACCADD_INDIFFERENT;
-}
-
-MUTATOR_HOOKFUNCTION(invasion_AllowMobSpawning)
-{
-       // monster spawning disabled during an invasion
-       return true;
-}
-
-MUTATOR_HOOKFUNCTION(invasion_GetTeamCount)
-{
-       ret_float = invasion_teams;
-       return false;
-}
-
-void invasion_ScoreRules(float inv_teams)
-{
-       if(inv_teams) { CheckAllowedTeams(world); }
-       ScoreRules_basics(inv_teams, 0, 0, false);
-       if(inv_teams) ScoreInfo_SetLabel_TeamScore(ST_INV_KILLS, "frags", SFL_SORT_PRIO_PRIMARY);
-       ScoreInfo_SetLabel_PlayerScore(SP_KILLS, "frags", ((inv_teams) ? SFL_SORT_PRIO_SECONDARY : SFL_SORT_PRIO_PRIMARY));
-       ScoreRules_basics_end();
-}
-
-void invasion_DelayedInit() // Do this check with a delay so we can wait for teams to be set up.
-{
-       if(autocvar_g_invasion_teams)
-               invasion_teams = bound(2, autocvar_g_invasion_teams, 4);
-       else
-               invasion_teams = 0;
-
-       independent_players = 1; // to disable extra useless scores
-
-       invasion_ScoreRules(invasion_teams);
-
-       independent_players = 0;
-
-       round_handler_Spawn(Invasion_CheckPlayers, Invasion_CheckWinner, Invasion_RoundStart);
-       round_handler_Init(5, autocvar_g_invasion_warmup, autocvar_g_invasion_round_timelimit);
-
-       inv_roundcnt = 0;
-       inv_maxrounds = 15; // 15?
-}
-
-void invasion_Initialize()
-{
-       if(autocvar_g_invasion_zombies_only) {
-               Monster mon = MON_ZOMBIE;
-               mon.mr_precache(mon);
-       } else
-       {
-               float i;
-               entity mon;
-               for(i = MON_FIRST; i <= MON_LAST; ++i)
-               {
-                       mon = get_monsterinfo(i);
-                       if((mon.spawnflags & MONSTER_TYPE_FLY) || (mon.spawnflags & MONSTER_TYPE_SWIM))
-                               continue; // flying/swimming monsters not yet supported
-
-                       mon.mr_precache(mon);
-               }
-       }
-
-       InitializeEntity(world, invasion_DelayedInit, INITPRIO_GAMETYPE);
-}
-
-MUTATOR_DEFINITION(gamemode_invasion)
-{
-       MUTATOR_HOOK(MonsterDies, invasion_MonsterDies, CBC_ORDER_ANY);
-       MUTATOR_HOOK(MonsterSpawn, invasion_MonsterSpawn, CBC_ORDER_ANY);
-       MUTATOR_HOOK(OnEntityPreSpawn, invasion_OnEntityPreSpawn, CBC_ORDER_ANY);
-       MUTATOR_HOOK(SV_StartFrame, invasion_StartFrame, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerRegen, invasion_PlayerRegen, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerSpawn, invasion_PlayerSpawn, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerDamage_Calculate, invasion_PlayerDamage, CBC_ORDER_ANY);
-       MUTATOR_HOOK(SV_ParseClientCommand, invasion_PlayerCommand, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BotShouldAttack, invasion_BotShouldAttack, CBC_ORDER_ANY);
-       MUTATOR_HOOK(SetStartItems, invasion_SetStartItems, CBC_ORDER_ANY);
-       MUTATOR_HOOK(AccuracyTargetValid, invasion_AccuracyTargetValid, CBC_ORDER_ANY);
-       MUTATOR_HOOK(AllowMobSpawning, invasion_AllowMobSpawning, CBC_ORDER_ANY);
-       MUTATOR_HOOK(GetTeamCount, invasion_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.");
-               invasion_Initialize();
-
-               cvar_settemp("g_monsters", "1");
-       }
-
-       MUTATOR_ONROLLBACK_OR_REMOVE
-       {
-               // we actually cannot roll back invasion_Initialize here
-               // BUT: we don't need to! If this gets called, adding always
-               // succeeds.
-       }
-
-       MUTATOR_ONREMOVE
-       {
-               LOG_INFO("This is a game type and it cannot be removed at runtime.");
-               return -1;
-       }
-
-       return 0;
-}
diff --git a/qcsrc/server/mutators/gamemode_invasion.qh b/qcsrc/server/mutators/gamemode_invasion.qh
deleted file mode 100644 (file)
index 191aef9..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef GAMEMODE_INVASION_H
-#define GAMEMODE_INVASION_H
-
-float inv_numspawned;
-float inv_maxspawned;
-float inv_roundcnt;
-float inv_maxrounds;
-float inv_numkilled;
-float inv_lastcheck;
-float inv_maxcurrent;
-
-float invasion_teams;
-float inv_monsters_perteam[17];
-
-float inv_monsterskill;
-
-const float ST_INV_KILLS = 1;
-#endif
diff --git a/qcsrc/server/mutators/gamemode_keepaway.qc b/qcsrc/server/mutators/gamemode_keepaway.qc
deleted file mode 100644 (file)
index b4951c6..0000000
+++ /dev/null
@@ -1,473 +0,0 @@
-#include "gamemode_keepaway.qh"
-
-#include "gamemode.qh"
-
-// ===========================================================
-//  Keepaway game mode coding, written by Samual and Diabolik
-//  Last updated: September, 2012
-// ===========================================================
-
-float ka_ballcarrier_waypointsprite_visible_for_player(entity e) // runs on waypoints which are attached to ballcarriers, updates once per frame
-{
-       if(e.ballcarried)
-               if(IS_SPEC(other))
-                       return false; // we don't want spectators of the ballcarrier to see the attached waypoint on the top of their screen
-
-       // TODO: Make the ballcarrier lack a waypointsprite whenever they have the invisibility powerup
-
-       return true;
-}
-
-void ka_EventLog(string mode, entity actor) // use an alias for easy changing and quick editing later
-{
-       if(autocvar_sv_eventlog)
-               GameLogEcho(strcat(":ka:", mode, ((actor != world) ? (strcat(":", ftos(actor.playerid))) : "")));
-}
-
-void ka_TouchEvent();
-void ka_RespawnBall() // runs whenever the ball needs to be relocated
-{SELFPARAM();
-       if(gameover) { return; }
-       vector oldballorigin = self.origin;
-
-       if(!MoveToRandomMapLocation(self, DPCONTENTS_SOLID | DPCONTENTS_CORPSE | DPCONTENTS_PLAYERCLIP, DPCONTENTS_SLIME | DPCONTENTS_LAVA | DPCONTENTS_SKY | DPCONTENTS_BODY | DPCONTENTS_DONOTENTER, Q3SURFACEFLAG_SKY, 10, 1024, 256))
-       {
-               entity spot = SelectSpawnPoint(true);
-               setorigin(self, spot.origin);
-               self.angles = spot.angles;
-       }
-
-       makevectors(self.angles);
-       self.movetype = MOVETYPE_BOUNCE;
-       self.velocity = '0 0 200';
-       self.angles = '0 0 0';
-       self.effects = autocvar_g_keepawayball_effects;
-       self.touch = ka_TouchEvent;
-       self.think = ka_RespawnBall;
-       self.nextthink = time + autocvar_g_keepawayball_respawntime;
-
-       Send_Effect(EFFECT_ELECTRO_COMBO, oldballorigin, '0 0 0', 1);
-       Send_Effect(EFFECT_ELECTRO_COMBO, self.origin, '0 0 0', 1);
-
-       WaypointSprite_Spawn(WP_KaBall, 0, 0, self, '0 0 64', world, self.team, self, waypointsprite_attachedforcarrier, false, RADARICON_FLAGCARRIER);
-       WaypointSprite_Ping(self.waypointsprite_attachedforcarrier);
-
-       sound(self, CH_TRIGGER, SND_KA_RESPAWN, VOL_BASE, ATTEN_NONE); // ATTEN_NONE (it's a sound intended to be heard anywhere)
-}
-
-void ka_TimeScoring()
-{SELFPARAM();
-       if(self.owner.ballcarried)
-       { // add points for holding the ball after a certain amount of time
-               if(autocvar_g_keepaway_score_timepoints)
-                       PlayerScore_Add(self.owner, SP_SCORE, autocvar_g_keepaway_score_timepoints);
-
-               PlayerScore_Add(self.owner, SP_KEEPAWAY_BCTIME, (autocvar_g_keepaway_score_timeinterval / 1)); // interval is divided by 1 so that time always shows "seconds"
-               self.nextthink = time + autocvar_g_keepaway_score_timeinterval;
-       }
-}
-
-void ka_TouchEvent() // runs any time that the ball comes in contact with something
-{SELFPARAM();
-       if(gameover) { return; }
-       if(!self) { return; }
-       if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
-       { // The ball fell off the map, respawn it since players can't get to it
-               ka_RespawnBall();
-               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
-               Send_Effect(EFFECT_BALL_SPARKS, self.origin, '0 0 0', 1);
-               sound(self, CH_TRIGGER, SND_KA_TOUCH, VOL_BASE, ATTEN_NORM);
-               return;
-       }
-       else if(self.wait > time) { return; }
-
-       // attach the ball to the player
-       self.owner = other;
-       other.ballcarried = self;
-       setattachment(self, other, "");
-       setorigin(self, '0 0 0');
-
-       // make the ball invisible/unable to do anything/set up time scoring
-       self.velocity = '0 0 0';
-       self.movetype = MOVETYPE_NONE;
-       self.effects |= EF_NODRAW;
-       self.touch = func_null;
-       self.think = ka_TimeScoring;
-       self.nextthink = time + autocvar_g_keepaway_score_timeinterval;
-       self.takedamage = DAMAGE_NO;
-
-       // apply effects to player
-       other.glow_color = autocvar_g_keepawayball_trail_color;
-       other.glow_trail = true;
-       other.effects |= autocvar_g_keepaway_ballcarrier_effects;
-
-       // messages and sounds
-       ka_EventLog("pickup", other);
-       Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_KEEPAWAY_PICKUP, other.netname);
-       Send_Notification(NOTIF_ALL_EXCEPT, other, MSG_CENTER, CENTER_KEEPAWAY_PICKUP, other.netname);
-       Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_KEEPAWAY_PICKUP_SELF);
-       sound(self.owner, CH_TRIGGER, SND_KA_PICKEDUP, VOL_BASE, ATTEN_NONE); // ATTEN_NONE (it's a sound intended to be heard anywhere)
-
-       // scoring
-       PlayerScore_Add(other, SP_KEEPAWAY_PICKUPS, 1);
-
-       // waypoints
-       WaypointSprite_AttachCarrier(WP_KaBallCarrier, other, RADARICON_FLAGCARRIER);
-       other.waypointsprite_attachedforcarrier.waypointsprite_visible_for_player = ka_ballcarrier_waypointsprite_visible_for_player;
-       WaypointSprite_UpdateRule(other.waypointsprite_attachedforcarrier, 0, SPRITERULE_DEFAULT);
-       WaypointSprite_Ping(other.waypointsprite_attachedforcarrier);
-       WaypointSprite_Kill(self.waypointsprite_attachedforcarrier);
-}
-
-void ka_DropEvent(entity plyr) // runs any time that a player is supposed to lose the ball
-{
-       entity ball;
-       ball = plyr.ballcarried;
-
-       if(!ball) { return; }
-
-       // reset the ball
-       setattachment(ball, world, "");
-       ball.movetype = MOVETYPE_BOUNCE;
-       ball.wait = time + 1;
-       ball.touch = ka_TouchEvent;
-       ball.think = ka_RespawnBall;
-       ball.nextthink = time + autocvar_g_keepawayball_respawntime;
-       ball.takedamage = DAMAGE_YES;
-       ball.effects &= ~EF_NODRAW;
-       setorigin(ball, plyr.origin + '0 0 10');
-       ball.velocity = '0 0 200' + '0 100 0'*crandom() + '100 0 0'*crandom();
-       ball.owner.ballcarried = world; // I hope nothing checks to see if the world has the ball in the rest of my code :P
-       ball.owner = world;
-
-       // reset the player effects
-       plyr.glow_trail = false;
-       plyr.effects &= ~autocvar_g_keepaway_ballcarrier_effects;
-
-       // messages and sounds
-       ka_EventLog("dropped", plyr);
-       Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_KEEPAWAY_DROPPED, plyr.netname);
-       Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_KEEPAWAY_DROPPED, plyr.netname);
-       sound(other, CH_TRIGGER, SND_KA_DROPPED, VOL_BASE, ATTEN_NONE); // ATTEN_NONE (it's a sound intended to be heard anywhere)
-
-       // scoring
-       // PlayerScore_Add(plyr, SP_KEEPAWAY_DROPS, 1); Not anymore, this is 100% the same as pickups and is useless.
-
-       // waypoints
-       WaypointSprite_Spawn(WP_KaBall, 0, 0, ball, '0 0 64', world, ball.team, ball, waypointsprite_attachedforcarrier, false, RADARICON_FLAGCARRIER);
-       WaypointSprite_UpdateRule(ball.waypointsprite_attachedforcarrier, 0, SPRITERULE_DEFAULT);
-       WaypointSprite_Ping(ball.waypointsprite_attachedforcarrier);
-       WaypointSprite_Kill(plyr.waypointsprite_attachedforcarrier);
-}
-
-void ka_Reset() // used to clear the ballcarrier whenever the match switches from warmup to normal
-{SELFPARAM();
-       if((self.owner) && (IS_PLAYER(self.owner)))
-               ka_DropEvent(self.owner);
-
-       if(time < game_starttime)
-       {
-               self.think = ka_RespawnBall;
-               self.touch = func_null;
-               self.nextthink = game_starttime;
-       }
-       else
-               ka_RespawnBall();
-}
-
-
-// ================
-// Bot player logic
-// ================
-
-void havocbot_goalrating_ball(float ratingscale, vector org)
-{SELFPARAM();
-       float t;
-       entity ball_owner;
-       ball_owner = ka_ball.owner;
-
-       if (ball_owner == self)
-               return;
-
-       // If ball is carried by player then hunt them down.
-       if (ball_owner)
-       {
-               t = (self.health + self.armorvalue) / (ball_owner.health + ball_owner.armorvalue);
-               navigation_routerating(ball_owner, t * ratingscale, 2000);
-       }
-       else // Ball has been dropped so collect.
-               navigation_routerating(ka_ball, ratingscale, 2000);
-}
-
-void havocbot_role_ka_carrier()
-{SELFPARAM();
-       if (self.deadflag != DEAD_NO)
-               return;
-
-       if (time > self.bot_strategytime)
-       {
-               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
-
-               navigation_goalrating_start();
-               havocbot_goalrating_items(10000, self.origin, 10000);
-               havocbot_goalrating_enemyplayers(20000, self.origin, 10000);
-               //havocbot_goalrating_waypoints(1, self.origin, 1000);
-               navigation_goalrating_end();
-       }
-
-       if (!self.ballcarried)
-       {
-               self.havocbot_role = havocbot_role_ka_collector;
-               self.bot_strategytime = 0;
-       }
-}
-
-void havocbot_role_ka_collector()
-{SELFPARAM();
-       if (self.deadflag != DEAD_NO)
-               return;
-
-       if (time > self.bot_strategytime)
-       {
-               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
-
-               navigation_goalrating_start();
-               havocbot_goalrating_items(10000, self.origin, 10000);
-               havocbot_goalrating_enemyplayers(1000, self.origin, 10000);
-               havocbot_goalrating_ball(20000, self.origin);
-               navigation_goalrating_end();
-       }
-
-       if (self.ballcarried)
-       {
-               self.havocbot_role = havocbot_role_ka_carrier;
-               self.bot_strategytime = 0;
-       }
-}
-
-
-// ==============
-// Hook Functions
-// ==============
-
-MUTATOR_HOOKFUNCTION(ka_Scoring)
-{SELFPARAM();
-       if((frag_attacker != frag_target) && (IS_PLAYER(frag_attacker)))
-       {
-               if(frag_target.ballcarried) { // add to amount of times killing carrier
-                       PlayerScore_Add(frag_attacker, SP_KEEPAWAY_CARRIERKILLS, 1);
-                       if(autocvar_g_keepaway_score_bckill) // add bckills to the score
-                               PlayerScore_Add(frag_attacker, SP_SCORE, autocvar_g_keepaway_score_bckill);
-               }
-               else if(!frag_attacker.ballcarried)
-                       if(autocvar_g_keepaway_noncarrier_warn)
-                               Send_Notification(NOTIF_ONE_ONLY, frag_attacker, MSG_CENTER, CENTER_KEEPAWAY_WARN);
-
-               if(frag_attacker.ballcarried) // add to amount of kills while ballcarrier
-                       PlayerScore_Add(frag_attacker, SP_SCORE, autocvar_g_keepaway_score_killac);
-       }
-
-       if(self.ballcarried) { ka_DropEvent(self); } // a player with the ball has died, drop it
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(ka_GiveFragsForKill)
-{
-       frag_score = 0; // no frags counted in keepaway
-       return 1; // you deceptive little bugger ;3 This needs to be true in order for this function to even count.
-}
-
-MUTATOR_HOOKFUNCTION(ka_PlayerPreThink)
-{SELFPARAM();
-       // clear the item used for the ball in keepaway
-       self.items &= ~IT_KEY1;
-
-       // if the player has the ball, make sure they have the item for it (Used for HUD primarily)
-       if(self.ballcarried)
-               self.items |= IT_KEY1;
-
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(ka_PlayerUseKey)
-{SELFPARAM();
-       if(MUTATOR_RETURNVALUE == 0)
-       if(self.ballcarried)
-       {
-               ka_DropEvent(self);
-               return 1;
-       }
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(ka_PlayerDamage) // for changing damage and force values that are applied to players in g_damage.qc
-{
-       if(frag_attacker.ballcarried) // if the attacker is a ballcarrier
-       {
-               if(frag_target == frag_attacker) // damage done to yourself
-               {
-                       frag_damage *= autocvar_g_keepaway_ballcarrier_selfdamage;
-                       frag_force *= autocvar_g_keepaway_ballcarrier_selfforce;
-               }
-               else // damage done to noncarriers
-               {
-                       frag_damage *= autocvar_g_keepaway_ballcarrier_damage;
-                       frag_force *= autocvar_g_keepaway_ballcarrier_force;
-               }
-       }
-       else if (!frag_target.ballcarried) // if the target is a noncarrier
-       {
-               if(frag_target == frag_attacker) // damage done to yourself
-               {
-                       frag_damage *= autocvar_g_keepaway_noncarrier_selfdamage;
-                       frag_force *= autocvar_g_keepaway_noncarrier_selfforce;
-               }
-               else // damage done to other noncarriers
-               {
-                       frag_damage *= autocvar_g_keepaway_noncarrier_damage;
-                       frag_force *= autocvar_g_keepaway_noncarrier_force;
-               }
-       }
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(ka_RemovePlayer)
-{SELFPARAM();
-       if(self.ballcarried) { ka_DropEvent(self); } // a player with the ball has left the match, drop it
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(ka_PlayerPowerups)
-{SELFPARAM();
-       // In the future this hook is supposed to allow me to do some extra stuff with waypointsprites and invisibility powerup
-       // So bare with me until I can fix a certain bug with ka_ballcarrier_waypointsprite_visible_for_player()
-
-       self.effects &= ~autocvar_g_keepaway_ballcarrier_effects;
-
-       if(self.ballcarried)
-               self.effects |= autocvar_g_keepaway_ballcarrier_effects;
-
-       return 0;
-}
-
-.float stat_sv_airspeedlimit_nonqw;
-.float stat_sv_maxspeed;
-
-MUTATOR_HOOKFUNCTION(ka_PlayerPhysics)
-{SELFPARAM();
-       if(self.ballcarried)
-       {
-               self.stat_sv_airspeedlimit_nonqw *= autocvar_g_keepaway_ballcarrier_highspeed;
-               self.stat_sv_maxspeed *= autocvar_g_keepaway_ballcarrier_highspeed;
-       }
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ka_BotShouldAttack)
-{SELFPARAM();
-       // if neither player has ball then don't attack unless the ball is on the ground
-       if(!checkentity.ballcarried && !self.ballcarried && ka_ball.owner)
-               return true;
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ka_BotRoles)
-{SELFPARAM();
-       if (self.ballcarried)
-               self.havocbot_role = havocbot_role_ka_carrier;
-       else
-               self.havocbot_role = havocbot_role_ka_collector;
-       return true;
-}
-
-
-// ==============
-// Initialization
-// ==============
-
-void ka_SpawnBall() // loads various values for the ball, runs only once at start of match
-{
-       if(!g_keepaway) { return; }
-
-       entity e;
-       e = spawn();
-       e.model = "models/orbs/orbblue.md3";
-       precache_model(e.model);
-       _setmodel(e, e.model);
-       setsize(e, '-16 -16 -20', '16 16 20'); // 20 20 20 was too big, player is only 16 16 24... gotta cheat with the Z (20) axis so that the particle isn't cut off
-       e.classname = "keepawayball";
-       e.damageforcescale = autocvar_g_keepawayball_damageforcescale;
-       e.takedamage = DAMAGE_YES;
-       e.solid = SOLID_TRIGGER;
-       e.movetype = MOVETYPE_BOUNCE;
-       e.glow_color = autocvar_g_keepawayball_trail_color;
-       e.glow_trail = true;
-       e.flags = FL_ITEM;
-       e.reset = ka_Reset;
-       e.touch = ka_TouchEvent;
-       e.owner = world;
-       ka_ball = e;
-
-       InitializeEntity(e, ka_RespawnBall, INITPRIO_SETLOCATION); // is this the right priority? Neh, I have no idea.. Well-- it works! So.
-}
-
-void ka_ScoreRules()
-{
-       ScoreRules_basics(0, SFL_SORT_PRIO_PRIMARY, 0, true); // SFL_SORT_PRIO_PRIMARY
-       ScoreInfo_SetLabel_PlayerScore(SP_KEEPAWAY_PICKUPS,                     "pickups",              0);
-       ScoreInfo_SetLabel_PlayerScore(SP_KEEPAWAY_CARRIERKILLS,        "bckills",              0);
-       ScoreInfo_SetLabel_PlayerScore(SP_KEEPAWAY_BCTIME,                      "bctime",               SFL_SORT_PRIO_SECONDARY);
-       ScoreRules_basics_end();
-}
-
-void ka_Initialize() // run at the start of a match, initiates game mode
-{
-       if(!g_keepaway)
-               return;
-
-       ka_ScoreRules();
-       ka_SpawnBall();
-}
-
-
-MUTATOR_DEFINITION(gamemode_keepaway)
-{
-       MUTATOR_HOOK(MakePlayerObserver, ka_RemovePlayer, CBC_ORDER_ANY);
-       MUTATOR_HOOK(ClientDisconnect, ka_RemovePlayer, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerDies, ka_Scoring, CBC_ORDER_ANY);
-       MUTATOR_HOOK(GiveFragsForKill, ka_GiveFragsForKill, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerPreThink, ka_PlayerPreThink, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerDamage_Calculate, ka_PlayerDamage, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerPowerups, ka_PlayerPowerups, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerUseKey, ka_PlayerUseKey, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerPhysics, ka_PlayerPhysics, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BotShouldAttack, ka_BotShouldAttack, CBC_ORDER_ANY);
-       MUTATOR_HOOK(HavocBot_ChooseRole, ka_BotRoles, 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.");
-               ka_Initialize();
-       }
-
-       MUTATOR_ONROLLBACK_OR_REMOVE
-       {
-               // we actually cannot roll back ka_Initialize here
-               // BUT: we don't need to! If this gets called, adding always
-               // succeeds.
-       }
-
-       MUTATOR_ONREMOVE
-       {
-               LOG_INFO("This is a game type and it cannot be removed at runtime.");
-               return -1;
-       }
-
-       return 0;
-}
diff --git a/qcsrc/server/mutators/gamemode_keepaway.qh b/qcsrc/server/mutators/gamemode_keepaway.qh
deleted file mode 100644 (file)
index 250f2fb..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef GAMEMODE_KEEPAWAY_H
-#define GAMEMODE_KEEPAWAY_H
-
-// these are needed since mutators are compiled last
-
-entity ka_ball;
-
-const float SP_KEEPAWAY_PICKUPS = 4;
-const float SP_KEEPAWAY_CARRIERKILLS = 5;
-const float SP_KEEPAWAY_BCTIME = 6;
-
-void() havocbot_role_ka_carrier;
-void() havocbot_role_ka_collector;
-
-void ka_DropEvent(entity plyr);
-
-#endif
diff --git a/qcsrc/server/mutators/gamemode_keyhunt.qc b/qcsrc/server/mutators/gamemode_keyhunt.qc
deleted file mode 100644 (file)
index 6809775..0000000
+++ /dev/null
@@ -1,1130 +0,0 @@
-#include "gamemode_keyhunt.qh"
-
-#include "gamemode.qh"
-
-
-// #define KH_PLAYER_USE_ATTACHMENT
-// #define KH_PLAYER_USE_CARRIEDMODEL
-
-#ifdef KH_PLAYER_USE_ATTACHMENT
-const vector KH_PLAYER_ATTACHMENT_DIST_ROTATED = '0 -4 0';
-const vector KH_PLAYER_ATTACHMENT_DIST = '4 0 0';
-const vector KH_PLAYER_ATTACHMENT = '0 0 0';
-const vector KH_PLAYER_ATTACHMENT_ANGLES = '0 0 0';
-const string KH_PLAYER_ATTACHMENT_BONE = "";
-#else
-const float KH_KEY_ZSHIFT = 22;
-const float KH_KEY_XYDIST = 24;
-const float KH_KEY_XYSPEED = 45;
-#endif
-const float KH_KEY_WP_ZSHIFT = 20;
-
-const vector KH_KEY_MIN = '-10 -10 -46';
-const vector KH_KEY_MAX = '10 10 3';
-const float KH_KEY_BRIGHTNESS = 2;
-
-float kh_no_radar_circles;
-
-// kh_state
-//     bits  0- 4: team of key 1, or 0 for no such key, or 30 for dropped, or 31 for self
-//     bits  5- 9: team of key 2, or 0 for no such key, or 30 for dropped, or 31 for self
-//     bits 10-14: team of key 3, or 0 for no such key, or 30 for dropped, or 31 for self
-//     bits 15-19: team of key 4, or 0 for no such key, or 30 for dropped, or 31 for self
-.float kh_state;
-.float siren_time;  //  time delay the siren
-//.float stuff_time;  //  time delay to stuffcmd a cvar
-
-float kh_keystatus[17];
-//kh_keystatus[0] = status of dropped keys, kh_keystatus[1 - 16] = player #
-//replace 17 with cvar("maxplayers") or similar !!!!!!!!!
-//for(i = 0; i < maxplayers; ++i)
-//     kh_keystatus[i] = "0";
-
-float kh_Team_ByID(float t)
-{
-       if(t == 0) return NUM_TEAM_1;
-       if(t == 1) return NUM_TEAM_2;
-       if(t == 2) return NUM_TEAM_3;
-       if(t == 3) return NUM_TEAM_4;
-       return 0;
-}
-
-//entity kh_worldkeylist;
-.entity kh_worldkeynext;
-entity kh_controller;
-//float kh_tracking_enabled;
-float kh_teams;
-float kh_interferemsg_time, kh_interferemsg_team;
-.entity kh_next, kh_prev; // linked list
-.float kh_droptime;
-.float kh_dropperteam;
-.entity kh_previous_owner;
-.float kh_previous_owner_playerid;
-.float kh_cp_duration;
-
-float kh_key_dropped, kh_key_carried;
-
-const float ST_KH_CAPS = 1;
-const float SP_KH_CAPS = 4;
-const float SP_KH_PUSHES = 5;
-const float SP_KH_DESTROYS = 6;
-const float SP_KH_PICKUPS = 7;
-const float SP_KH_KCKILLS = 8;
-const float SP_KH_LOSSES = 9;
-void kh_ScoreRules(float teams)
-{
-       ScoreRules_basics(teams, SFL_SORT_PRIO_PRIMARY, SFL_SORT_PRIO_PRIMARY, true);
-       ScoreInfo_SetLabel_TeamScore(  ST_KH_CAPS,      "caps",      SFL_SORT_PRIO_SECONDARY);
-       ScoreInfo_SetLabel_PlayerScore(SP_KH_CAPS,      "caps",      SFL_SORT_PRIO_SECONDARY);
-       ScoreInfo_SetLabel_PlayerScore(SP_KH_PUSHES,    "pushes",    0);
-       ScoreInfo_SetLabel_PlayerScore(SP_KH_DESTROYS,  "destroyed", SFL_LOWER_IS_BETTER);
-       ScoreInfo_SetLabel_PlayerScore(SP_KH_PICKUPS,   "pickups",   0);
-       ScoreInfo_SetLabel_PlayerScore(SP_KH_KCKILLS,   "kckills",   0);
-       ScoreInfo_SetLabel_PlayerScore(SP_KH_LOSSES,    "losses",    SFL_LOWER_IS_BETTER);
-       ScoreRules_basics_end();
-}
-
-float kh_KeyCarrier_waypointsprite_visible_for_player(entity e)  // runs all the time
-{SELFPARAM();
-       if(!IS_PLAYER(e) || self.team != e.team)
-               if(!kh_tracking_enabled)
-                       return false;
-
-       return true;
-}
-
-float kh_Key_waypointsprite_visible_for_player(entity e) // ??
-{SELFPARAM();
-       if(!kh_tracking_enabled)
-               return false;
-       if(!self.owner)
-               return true;
-       if(!self.owner.owner)
-               return true;
-       return false;  // draw only when key is not owned
-}
-
-void kh_update_state()
-{
-       entity player;
-       entity key;
-       float s;
-       float f;
-
-       s = 0;
-       FOR_EACH_KH_KEY(key)
-       {
-               if(key.owner)
-                       f = key.team;
-               else
-                       f = 30;
-               s |= pow(32, key.count) * f;
-       }
-
-       FOR_EACH_CLIENT(player)
-       {
-               player.kh_state = s;
-       }
-
-       FOR_EACH_KH_KEY(key)
-       {
-               if(key.owner)
-                       key.owner.kh_state |= pow(32, key.count) * 31;
-       }
-       //print(ftos((nextent(world)).kh_state), "\n");
-}
-
-
-
-
-var kh_Think_t kh_Controller_Thinkfunc;
-void kh_Controller_SetThink(float t, kh_Think_t func)  // runs occasionaly
-{
-       kh_Controller_Thinkfunc = func;
-       kh_controller.cnt = ceil(t);
-       if(t == 0)
-               kh_controller.nextthink = time; // force
-}
-void kh_WaitForPlayers();
-void kh_Controller_Think()  // called a lot
-{SELFPARAM();
-       if(intermission_running)
-               return;
-       if(self.cnt > 0)
-       { if(self.think != kh_WaitForPlayers) { self.cnt -= 1; } }
-       else if(self.cnt == 0)
-       {
-               self.cnt -= 1;
-               kh_Controller_Thinkfunc();
-       }
-       self.nextthink = time + 1;
-}
-
-// frags f: take from cvar * f
-// frags 0: no frags
-void kh_Scores_Event(entity player, entity key, string what, float frags_player, float frags_owner)  // update the score when a key is captured
-{
-       string s;
-       if(intermission_running)
-               return;
-
-       if(frags_player)
-               UpdateFrags(player, frags_player);
-
-       if(key && key.owner && frags_owner)
-               UpdateFrags(key.owner, frags_owner);
-
-       if(!autocvar_sv_eventlog)  //output extra info to the console or text file
-               return;
-
-       s = strcat(":keyhunt:", what, ":", ftos(player.playerid), ":", ftos(frags_player));
-
-       if(key && key.owner)
-               s = strcat(s, ":", ftos(key.owner.playerid));
-       else
-               s = strcat(s, ":0");
-
-       s = strcat(s, ":", ftos(frags_owner), ":");
-
-       if(key)
-               s = strcat(s, key.netname);
-
-       GameLogEcho(s);
-}
-
-vector kh_AttachedOrigin(entity e)  // runs when a team captures the flag, it can run 2 or 3 times.
-{
-       if(e.tag_entity)
-       {
-               makevectors(e.tag_entity.angles);
-               return e.tag_entity.origin + e.origin.x * v_forward - e.origin.y * v_right + e.origin.z * v_up;
-       }
-       else
-               return e.origin;
-}
-
-void kh_Key_Attach(entity key)  // runs when a player picks up a key and several times when a key is assigned to a player at the start of a round
-{
-#ifdef KH_PLAYER_USE_ATTACHMENT
-       entity first;
-       first = key.owner.kh_next;
-       if(key == first)
-       {
-               setattachment(key, key.owner, KH_PLAYER_ATTACHMENT_BONE);
-               if(key.kh_next)
-               {
-                       setattachment(key.kh_next, key, "");
-                       setorigin(key, key.kh_next.origin - 0.5 * KH_PLAYER_ATTACHMENT_DIST);
-                       setorigin(key.kh_next, KH_PLAYER_ATTACHMENT_DIST_ROTATED);
-                       key.kh_next.angles = '0 0 0';
-               }
-               else
-                       setorigin(key, KH_PLAYER_ATTACHMENT);
-               key.angles = KH_PLAYER_ATTACHMENT_ANGLES;
-       }
-       else
-       {
-               setattachment(key, key.kh_prev, "");
-               if(key.kh_next)
-                       setattachment(key.kh_next, key, "");
-               setorigin(key, KH_PLAYER_ATTACHMENT_DIST_ROTATED);
-               setorigin(first, first.origin - 0.5 * KH_PLAYER_ATTACHMENT_DIST);
-               key.angles = '0 0 0';
-       }
-#else
-       setattachment(key, key.owner, "");
-       setorigin(key, '0 0 1' * KH_KEY_ZSHIFT);  // fixing x, y in think
-       key.angles_y -= key.owner.angles.y;
-#endif
-       key.flags = 0;
-       key.solid = SOLID_NOT;
-       key.movetype = MOVETYPE_NONE;
-       key.team = key.owner.team;
-       key.nextthink = time;
-       key.damageforcescale = 0;
-       key.takedamage = DAMAGE_NO;
-       key.modelindex = kh_key_carried;
-}
-
-void kh_Key_Detach(entity key) // runs every time a key is dropped or lost. Runs several times times when all the keys are captured
-{
-#ifdef KH_PLAYER_USE_ATTACHMENT
-       entity first;
-       first = key.owner.kh_next;
-       if(key == first)
-       {
-               if(key.kh_next)
-               {
-                       setattachment(key.kh_next, key.owner, KH_PLAYER_ATTACHMENT_BONE);
-                       setorigin(key.kh_next, key.origin + 0.5 * KH_PLAYER_ATTACHMENT_DIST);
-                       key.kh_next.angles = KH_PLAYER_ATTACHMENT_ANGLES;
-               }
-       }
-       else
-       {
-               if(key.kh_next)
-                       setattachment(key.kh_next, key.kh_prev, "");
-               setorigin(first, first.origin + 0.5 * KH_PLAYER_ATTACHMENT_DIST);
-       }
-       // in any case:
-       setattachment(key, world, "");
-       setorigin(key, key.owner.origin + '0 0 1' * (PL_MIN.z - KH_KEY_MIN_z));
-       key.angles = key.owner.angles;
-#else
-       setorigin(key, key.owner.origin + key.origin.z * '0 0 1');
-       setattachment(key, world, "");
-       key.angles_y += key.owner.angles.y;
-#endif
-       key.flags = FL_ITEM;
-       key.solid = SOLID_TRIGGER;
-       key.movetype = MOVETYPE_TOSS;
-       key.pain_finished = time + autocvar_g_balance_keyhunt_delay_return;
-       key.damageforcescale = autocvar_g_balance_keyhunt_damageforcescale;
-       key.takedamage = DAMAGE_YES;
-       // let key.team stay
-       key.modelindex = kh_key_dropped;
-       key.kh_previous_owner = key.owner;
-       key.kh_previous_owner_playerid = key.owner.playerid;
-}
-
-void kh_Key_AssignTo(entity key, entity player)  // runs every time a key is picked up or assigned. Runs prior to kh_key_attach
-{
-       entity k;
-       float ownerteam0, ownerteam;
-       if(key.owner == player)
-               return;
-
-       ownerteam0 = kh_Key_AllOwnedByWhichTeam();
-
-       if(key.owner)
-       {
-               kh_Key_Detach(key);
-
-               // remove from linked list
-               if(key.kh_next)
-                       key.kh_next.kh_prev = key.kh_prev;
-               key.kh_prev.kh_next = key.kh_next;
-               key.kh_next = world;
-               key.kh_prev = world;
-
-               if(key.owner.kh_next == world)
-               {
-                       // No longer a key carrier
-                       if(!kh_no_radar_circles)
-                               WaypointSprite_Ping(key.owner.waypointsprite_attachedforcarrier);
-                       WaypointSprite_DetachCarrier(key.owner);
-               }
-       }
-
-       key.owner = player;
-
-       if(player)
-       {
-               // insert into linked list
-               key.kh_next = player.kh_next;
-               key.kh_prev = player;
-               player.kh_next = key;
-               if(key.kh_next)
-                       key.kh_next.kh_prev = key;
-
-               float i;
-               i = kh_keystatus[key.owner.playerid];
-                       if(key.netname == "^1red key")
-                               i += 1;
-                       if(key.netname == "^4blue key")
-                               i += 2;
-                       if(key.netname == "^3yellow key")
-                               i += 4;
-                       if(key.netname == "^6pink key")
-                               i += 8;
-               kh_keystatus[key.owner.playerid] = i;
-
-               kh_Key_Attach(key);
-
-               if(key.kh_next == world)
-               {
-                       // player is now a key carrier
-                       entity wp = WaypointSprite_AttachCarrier(WP_Null, player, RADARICON_FLAGCARRIER);
-                       wp.colormod = colormapPaletteColor(player.team - 1, 0);
-                       player.waypointsprite_attachedforcarrier.waypointsprite_visible_for_player = kh_KeyCarrier_waypointsprite_visible_for_player;
-                       WaypointSprite_UpdateRule(player.waypointsprite_attachedforcarrier, player.team, SPRITERULE_TEAMPLAY);
-                       if(player.team == NUM_TEAM_1)
-                               WaypointSprite_UpdateSprites(player.waypointsprite_attachedforcarrier, WP_KeyCarrierRed, WP_KeyCarrierFriend, WP_KeyCarrierRed);
-                       else if(player.team == NUM_TEAM_2)
-                               WaypointSprite_UpdateSprites(player.waypointsprite_attachedforcarrier, WP_KeyCarrierBlue, WP_KeyCarrierFriend, WP_KeyCarrierBlue);
-                       else if(player.team == NUM_TEAM_3)
-                               WaypointSprite_UpdateSprites(player.waypointsprite_attachedforcarrier, WP_KeyCarrierYellow, WP_KeyCarrierFriend, WP_KeyCarrierYellow);
-                       else if(player.team == NUM_TEAM_4)
-                               WaypointSprite_UpdateSprites(player.waypointsprite_attachedforcarrier, WP_KeyCarrierPink, WP_KeyCarrierFriend, WP_KeyCarrierPink);
-                       if(!kh_no_radar_circles)
-                               WaypointSprite_Ping(player.waypointsprite_attachedforcarrier);
-               }
-       }
-
-       // moved that here, also update if there's no player
-       kh_update_state();
-
-       key.pusher = world;
-
-       ownerteam = kh_Key_AllOwnedByWhichTeam();
-       if(ownerteam != ownerteam0)
-       {
-               if(ownerteam != -1)
-               {
-                       kh_interferemsg_time = time + 0.2;
-                       kh_interferemsg_team = player.team;
-
-                       // audit all key carrier sprites, update them to RUN HERE
-                       FOR_EACH_KH_KEY(k)
-                       {
-                               if (!k.owner) continue;
-                               entity first = WP_Null;
-                               FOREACH(Waypoints, it.netname == k.owner.waypointsprite_attachedforcarrier.model1, LAMBDA(first = it; break));
-                               entity third = WP_Null;
-                               FOREACH(Waypoints, it.netname == k.owner.waypointsprite_attachedforcarrier.model3, LAMBDA(third = it; break));
-                               WaypointSprite_UpdateSprites(k.owner.waypointsprite_attachedforcarrier, first, WP_KeyCarrierFinish, third);
-                       }
-               }
-               else
-               {
-                       kh_interferemsg_time = 0;
-
-                       // audit all key carrier sprites, update them to RUN HERE
-                       FOR_EACH_KH_KEY(k)
-                       {
-                               if (!k.owner) continue;
-                               entity first = WP_Null;
-                               FOREACH(Waypoints, it.netname == k.owner.waypointsprite_attachedforcarrier.model1, LAMBDA(first = it; break));
-                               entity third = WP_Null;
-                               FOREACH(Waypoints, it.netname == k.owner.waypointsprite_attachedforcarrier.model3, LAMBDA(third = it; break));
-                               WaypointSprite_UpdateSprites(k.owner.waypointsprite_attachedforcarrier, first, WP_KeyCarrierFriend, third);
-                       }
-               }
-       }
-}
-
-void kh_Key_Damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
-{SELFPARAM();
-       if(self.owner)
-               return;
-       if(ITEM_DAMAGE_NEEDKILL(deathtype))
-       {
-               // touching lava, or hurt trigger
-               // what shall we do?
-               // immediately return is bad
-               // maybe start a shorter countdown?
-       }
-       if(vlen(force) <= 0)
-               return;
-       if(time > self.pushltime)
-               if(IS_PLAYER(attacker))
-                       self.team = attacker.team;
-}
-
-void kh_Key_Collect(entity key, entity player)  //a player picks up a dropped key
-{
-       sound(player, CH_TRIGGER, SND_KH_COLLECT, VOL_BASE, ATTEN_NORM);
-
-       if(key.kh_dropperteam != player.team)
-       {
-               kh_Scores_Event(player, key, "collect", autocvar_g_balance_keyhunt_score_collect, 0);
-               PlayerScore_Add(player, SP_KH_PICKUPS, 1);
-       }
-       key.kh_dropperteam = 0;
-       Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(key, INFO_KEYHUNT_PICKUP_), player.netname);
-
-       kh_Key_AssignTo(key, player); // this also updates .kh_state
-}
-
-void kh_Key_Touch()  // runs many, many times when a key has been dropped and can be picked up
-{SELFPARAM();
-       if(intermission_running)
-               return;
-
-       if(self.owner) // already carried
-               return;
-
-       if(ITEM_TOUCH_NEEDKILL())
-       {
-               // touching sky, or nodrop
-               // what shall we do?
-               // immediately return is bad
-               // maybe start a shorter countdown?
-       }
-
-       if (!IS_PLAYER(other))
-               return;
-       if(other.deadflag != DEAD_NO)
-               return;
-       if(other == self.enemy)
-               if(time < self.kh_droptime + autocvar_g_balance_keyhunt_delay_collect)
-                       return;  // you just dropped it!
-       kh_Key_Collect(self, other);
-}
-
-void kh_Key_Remove(entity key)  // runs after when all the keys have been collected or when a key has been dropped for more than X seconds
-{
-       entity o;
-       o = key.owner;
-       kh_Key_AssignTo(key, world);
-       if(o) // it was attached
-               WaypointSprite_Kill(key.waypointsprite_attachedforcarrier);
-       else // it was dropped
-               WaypointSprite_DetachCarrier(key);
-
-       // remove key from key list
-       if (kh_worldkeylist == key)
-               kh_worldkeylist = kh_worldkeylist.kh_worldkeynext;
-       else
-       {
-               o = kh_worldkeylist;
-               while (o)
-               {
-                       if (o.kh_worldkeynext == key)
-                       {
-                               o.kh_worldkeynext = o.kh_worldkeynext.kh_worldkeynext;
-                               break;
-                       }
-                       o = o.kh_worldkeynext;
-               }
-       }
-
-       remove(key);
-
-       kh_update_state();
-}
-
-void kh_FinishRound()  // runs when a team captures the keys
-{
-       // prepare next round
-       kh_interferemsg_time = 0;
-       entity key;
-
-       kh_no_radar_circles = true;
-       FOR_EACH_KH_KEY(key)
-               kh_Key_Remove(key);
-       kh_no_radar_circles = false;
-
-       Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_KEYHUNT_ROUNDSTART, autocvar_g_balance_keyhunt_delay_round);
-       kh_Controller_SetThink(autocvar_g_balance_keyhunt_delay_round, kh_StartRound);
-}
-
-void kh_WinnerTeam(float teem)  // runs when a team wins // Samual: Teem?.... TEEM?!?! what the fuck is wrong with you people
-{
-       // all key carriers get some points
-       vector firstorigin, lastorigin, midpoint;
-       float first;
-       entity key;
-       float score;
-       score = (kh_teams - 1) * autocvar_g_balance_keyhunt_score_capture;
-       DistributeEvenly_Init(score, kh_teams);
-       // twice the score for 3 team games, three times the score for 4 team games!
-       // note: for a win by destroying the key, this should NOT be applied
-       FOR_EACH_KH_KEY(key)
-       {
-               float f;
-               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;
-       string keyowner = "";
-       FOR_EACH_KH_KEY(key)
-               if(key.owner.kh_next == key)
-               {
-                       if(!first)
-                               keyowner = strcat(keyowner, ", ");
-                       keyowner = key.owner.netname;
-                       first = false;
-               }
-
-       Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(teem, INFO_KEYHUNT_CAPTURE_), keyowner);
-
-       first = true;
-       midpoint = '0 0 0';
-       firstorigin = '0 0 0';
-       lastorigin = '0 0 0';
-       FOR_EACH_KH_KEY(key)
-       {
-               vector thisorigin;
-
-               thisorigin = kh_AttachedOrigin(key);
-               //dprint("Key origin: ", vtos(thisorigin), "\n");
-               midpoint += thisorigin;
-
-               if(!first)
-                       te_lightning2(world, lastorigin, thisorigin);
-               lastorigin = thisorigin;
-               if(first)
-                       firstorigin = thisorigin;
-               first = false;
-       }
-       if(kh_teams > 2)
-       {
-               te_lightning2(world, lastorigin, firstorigin);
-       }
-       midpoint = midpoint * (1 / kh_teams);
-       te_customflash(midpoint, 1000, 1, Team_ColorRGB(teem) * 0.5 + '0.5 0.5 0.5');  // make the color >=0.5 in each component
-
-       play2all(SND(KH_CAPTURE));
-       kh_FinishRound();
-}
-
-void kh_LoserTeam(float teem, entity lostkey)  // runs when a player pushes a flag carrier off the map
-{
-       entity player, key, attacker;
-       float players;
-       float keys;
-       float f;
-
-       attacker = world;
-       if(lostkey.pusher)
-               if(lostkey.pusher.team != teem)
-                       if(IS_PLAYER(lostkey.pusher))
-                               attacker = lostkey.pusher;
-
-       players = keys = 0;
-
-       if(attacker)
-       {
-               if(lostkey.kh_previous_owner)
-                       kh_Scores_Event(lostkey.kh_previous_owner, world, "pushed", 0, -autocvar_g_balance_keyhunt_score_push);
-                       // don't actually GIVE him the -nn points, just log
-               kh_Scores_Event(attacker, world, "push", autocvar_g_balance_keyhunt_score_push, 0);
-               PlayerScore_Add(attacker, SP_KH_PUSHES, 1);
-               //centerprint(attacker, "Your push is the best!"); // does this really need to exist?
-       }
-       else
-       {
-               float of, fragsleft, i, j, thisteam;
-               of = autocvar_g_balance_keyhunt_score_destroyed_ownfactor;
-
-               FOR_EACH_PLAYER(player)
-                       if(player.team != teem)
-                               ++players;
-
-               FOR_EACH_KH_KEY(key)
-                       if(key.owner && key.team != teem)
-                               ++keys;
-
-               if(lostkey.kh_previous_owner)
-                       kh_Scores_Event(lostkey.kh_previous_owner, world, "destroyed", 0, -autocvar_g_balance_keyhunt_score_destroyed);
-                       // don't actually GIVE him the -nn points, just log
-
-               if(lostkey.kh_previous_owner.playerid == lostkey.kh_previous_owner_playerid)
-                       PlayerScore_Add(lostkey.kh_previous_owner, SP_KH_DESTROYS, 1);
-
-               DistributeEvenly_Init(autocvar_g_balance_keyhunt_score_destroyed, keys * of + players);
-
-               FOR_EACH_KH_KEY(key)
-                       if(key.owner && key.team != teem)
-                       {
-                               f = DistributeEvenly_Get(of);
-                               kh_Scores_Event(key.owner, world, "destroyed_holdingkey", f, 0);
-                       }
-
-               fragsleft = DistributeEvenly_Get(players);
-
-               // Now distribute these among all other teams...
-               j = kh_teams - 1;
-               for(i = 0; i < kh_teams; ++i)
-               {
-                       thisteam = kh_Team_ByID(i);
-                       if(thisteam == teem) // bad boy, no cookie - this WILL happen
-                               continue;
-
-                       players = 0;
-                       FOR_EACH_PLAYER(player)
-                               if(player.team == thisteam)
-                                       ++players;
-
-                       DistributeEvenly_Init(fragsleft, j);
-                       fragsleft = DistributeEvenly_Get(j - 1);
-                       DistributeEvenly_Init(DistributeEvenly_Get(1), players);
-
-                       FOR_EACH_PLAYER(player)
-                               if(player.team == thisteam)
-                               {
-                                       f = DistributeEvenly_Get(1);
-                                       kh_Scores_Event(player, world, "destroyed", f, 0);
-                               }
-
-                       --j;
-               }
-       }
-
-       Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(lostkey, INFO_KEYHUNT_LOST_), lostkey.kh_previous_owner.netname);
-
-       play2all(SND(KH_DESTROY));
-       te_tarexplosion(lostkey.origin);
-
-       kh_FinishRound();
-}
-
-void kh_Key_Think()  // runs all the time
-{SELFPARAM();
-       entity head;
-       //entity player;  // needed by FOR_EACH_PLAYER
-
-       if(intermission_running)
-               return;
-
-       if(self.owner)
-       {
-#ifndef KH_PLAYER_USE_ATTACHMENT
-               makevectors('0 1 0' * (self.cnt + (time % 360) * KH_KEY_XYSPEED));
-               setorigin(self, v_forward * KH_KEY_XYDIST + '0 0 1' * self.origin.z);
-#endif
-       }
-
-       // if in nodrop or time over, end the round
-       if(!self.owner)
-               if(time > self.pain_finished)
-                       kh_LoserTeam(self.team, self);
-
-       if(self.owner)
-       if(kh_Key_AllOwnedByWhichTeam() != -1)
-       {
-               if(self.siren_time < time)
-               {
-                       sound(self.owner, CH_TRIGGER, SND_KH_ALARM, VOL_BASE, ATTEN_NORM);  // play a simple alarm
-                       self.siren_time = time + 2.5;  // repeat every 2.5 seconds
-               }
-
-               entity key;
-               vector p;
-               p = self.owner.origin;
-               FOR_EACH_KH_KEY(key)
-                       if(vlen(key.owner.origin - p) > autocvar_g_balance_keyhunt_maxdist)
-                               goto not_winning;
-               kh_WinnerTeam(self.team);
-:not_winning
-       }
-
-       if(kh_interferemsg_time && time > kh_interferemsg_time)
-       {
-               kh_interferemsg_time = 0;
-               FOR_EACH_PLAYER(head)
-               {
-                       if(head.team == kh_interferemsg_team)
-                               if(head.kh_next)
-                                       Send_Notification(NOTIF_ONE, head, MSG_CENTER, CENTER_KEYHUNT_MEET);
-                               else
-                                       Send_Notification(NOTIF_ONE, head, MSG_CENTER, CENTER_KEYHUNT_HELP);
-                       else
-                               Send_Notification(NOTIF_ONE, head, MSG_CENTER, APP_TEAM_NUM_4(kh_interferemsg_team, CENTER_KEYHUNT_INTERFERE_));
-               }
-       }
-
-       self.nextthink = time + 0.05;
-}
-
-void key_reset()
-{SELFPARAM();
-       kh_Key_AssignTo(self, world);
-       kh_Key_Remove(self);
-}
-
-const string STR_ITEM_KH_KEY = "item_kh_key";
-void kh_Key_Spawn(entity initial_owner, float angle, float i)  // runs every time a new flag is created, ie after all the keys have been collected
-{
-       entity key;
-       key = spawn();
-       key.count = i;
-       key.classname = STR_ITEM_KH_KEY;
-       key.touch = kh_Key_Touch;
-       key.think = kh_Key_Think;
-       key.nextthink = time;
-       key.items = IT_KEY1 | IT_KEY2;
-       key.cnt = angle;
-       key.angles = '0 360 0' * random();
-       key.event_damage = kh_Key_Damage;
-       key.takedamage = DAMAGE_YES;
-       key.modelindex = kh_key_dropped;
-       key.model = "key";
-       key.kh_dropperteam = 0;
-       key.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
-       setsize(key, KH_KEY_MIN, KH_KEY_MAX);
-       key.colormod = Team_ColorRGB(initial_owner.team) * KH_KEY_BRIGHTNESS;
-       key.reset = key_reset;
-
-       switch(initial_owner.team)
-       {
-               case NUM_TEAM_1:
-                       key.netname = "^1red key";
-                       break;
-               case NUM_TEAM_2:
-                       key.netname = "^4blue key";
-                       break;
-               case NUM_TEAM_3:
-                       key.netname = "^3yellow key";
-                       break;
-               case NUM_TEAM_4:
-                       key.netname = "^6pink key";
-                       break;
-               default:
-                       key.netname = "NETGIER key";
-                       break;
-       }
-
-       // link into key list
-       key.kh_worldkeynext = kh_worldkeylist;
-       kh_worldkeylist = key;
-
-       Send_Notification(NOTIF_ONE, initial_owner, MSG_CENTER, APP_TEAM_NUM_4(initial_owner.team, CENTER_KEYHUNT_START_));
-
-       WaypointSprite_Spawn(WP_KeyDropped, 0, 0, key, '0 0 1' * KH_KEY_WP_ZSHIFT, world, key.team, key, waypointsprite_attachedforcarrier, false, RADARICON_FLAG);
-       key.waypointsprite_attachedforcarrier.waypointsprite_visible_for_player = kh_Key_waypointsprite_visible_for_player;
-
-       kh_Key_AssignTo(key, initial_owner);
-}
-
-// -1 when no team completely owns all keys yet
-float kh_Key_AllOwnedByWhichTeam()  // constantly called. check to see if all the keys are owned by the same team
-{
-       entity key;
-       float teem;
-       float keys;
-
-       teem = -1;
-       keys = kh_teams;
-       FOR_EACH_KH_KEY(key)
-       {
-               if(!key.owner)
-                       return -1;
-               if(teem == -1)
-                       teem = key.team;
-               else if(teem != key.team)
-                       return -1;
-               --keys;
-       }
-       if(keys != 0)
-               return -1;
-       return teem;
-}
-
-void kh_Key_DropOne(entity key)
-{
-       // prevent collecting this one for some time
-       entity player;
-       player = key.owner;
-
-       key.kh_droptime = time;
-       key.enemy = player;
-
-       kh_Scores_Event(player, key, "dropkey", 0, 0);
-       PlayerScore_Add(player, SP_KH_LOSSES, 1);
-       Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(key, INFO_KEYHUNT_DROP_), player.netname);
-
-       kh_Key_AssignTo(key, world);
-       makevectors(player.v_angle);
-       key.velocity = W_CalculateProjectileVelocity(player.velocity, autocvar_g_balance_keyhunt_throwvelocity * v_forward, false);
-       key.pusher = world;
-       key.pushltime = time + autocvar_g_balance_keyhunt_protecttime;
-       key.kh_dropperteam = key.team;
-
-       sound(player, CH_TRIGGER, SND_KH_DROP, VOL_BASE, ATTEN_NORM);
-}
-
-void kh_Key_DropAll(entity player, float suicide) // runs whenever a player dies
-{
-       entity key;
-       entity mypusher;
-       if(player.kh_next)
-       {
-               mypusher = world;
-               if(player.pusher)
-                       if(time < player.pushltime)
-                               mypusher = player.pusher;
-               while((key = player.kh_next))
-               {
-                       kh_Scores_Event(player, key, "losekey", 0, 0);
-                       PlayerScore_Add(player, SP_KH_LOSSES, 1);
-                       Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(key, INFO_KEYHUNT_LOST_), player.netname);
-                       kh_Key_AssignTo(key, world);
-                       makevectors('-1 0 0' * (45 + 45 * random()) + '0 360 0' * random());
-                       key.velocity = W_CalculateProjectileVelocity(player.velocity, autocvar_g_balance_keyhunt_dropvelocity * v_forward, false);
-                       key.pusher = mypusher;
-                       key.pushltime = time + autocvar_g_balance_keyhunt_protecttime;
-                       if(suicide)
-                               key.kh_dropperteam = player.team;
-               }
-               sound(player, CH_TRIGGER, SND_KH_DROP, VOL_BASE, ATTEN_NORM);
-       }
-}
-
-float kh_CheckPlayers(float num)
-{
-       if(num < kh_teams)
-       {
-               float t_team = kh_Team_ByID(num);
-               float players = 0;
-               entity tmp_player;
-               FOR_EACH_PLAYER(tmp_player)
-                       if(tmp_player.deadflag == DEAD_NO)
-                               if(!tmp_player.BUTTON_CHAT)
-                                       if(tmp_player.team == t_team)
-                                               ++players;
-
-               if (!players) { return t_team; }
-       }
-       return 0;
-}
-
-#define KH_READY_TEAMS() (!p1 + !p2 + ((kh_teams >= 3) ? !p3 : p3) + ((kh_teams >= 4) ? !p4 : p4))
-#define KH_READY_TEAMS_OK() (KH_READY_TEAMS() == kh_teams)
-void kh_WaitForPlayers()  // delay start of the round until enough players are present
-{
-       if(time < game_starttime)
-       {
-               kh_Controller_SetThink(game_starttime - time + 0.1, kh_WaitForPlayers);
-               return;
-       }
-
-       static float prev_missing_teams_mask;
-       float p1 = kh_CheckPlayers(0), p2 = kh_CheckPlayers(1), p3 = kh_CheckPlayers(2), p4 = kh_CheckPlayers(3);
-       if(KH_READY_TEAMS_OK())
-       {
-               if(prev_missing_teams_mask > 0)
-                       Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_MISSING_TEAMS);
-               prev_missing_teams_mask = -1;
-               Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_KEYHUNT_ROUNDSTART, autocvar_g_balance_keyhunt_delay_round);
-               kh_Controller_SetThink(autocvar_g_balance_keyhunt_delay_round, kh_StartRound);
-       }
-       else
-       {
-               if(player_count == 0)
-               {
-                       if(prev_missing_teams_mask > 0)
-                               Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_MISSING_TEAMS);
-                       prev_missing_teams_mask = -1;
-               }
-               else
-               {
-                       float missing_teams_mask = (!!p1) + (!!p2) * 2;
-                       if(kh_teams >= 3) missing_teams_mask += (!!p3) * 4;
-                       if(kh_teams >= 4) missing_teams_mask += (!!p4) * 8;
-                       if(prev_missing_teams_mask != missing_teams_mask)
-                       {
-                               Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_MISSING_TEAMS, missing_teams_mask);
-                               prev_missing_teams_mask = missing_teams_mask;
-                       }
-               }
-               kh_Controller_SetThink(1, kh_WaitForPlayers);
-       }
-}
-
-void kh_EnableTrackingDevice()  // runs after each round
-{
-       Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_KEYHUNT);
-       Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_KEYHUNT_OTHER);
-
-       kh_tracking_enabled = true;
-}
-
-void kh_StartRound()  // runs at the start of each round
-{
-       float i, players, teem;
-       entity player;
-
-       if(time < game_starttime)
-       {
-               kh_Controller_SetThink(game_starttime - time + 0.1, kh_WaitForPlayers);
-               return;
-       }
-
-       float p1 = kh_CheckPlayers(0), p2 = kh_CheckPlayers(1), p3 = kh_CheckPlayers(2), p4 = kh_CheckPlayers(3);
-       if(!KH_READY_TEAMS_OK())
-       {
-               kh_Controller_SetThink(1, kh_WaitForPlayers);
-               return;
-       }
-
-       Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_KEYHUNT);
-       Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_KEYHUNT_OTHER);
-
-       for(i = 0; i < kh_teams; ++i)
-       {
-               teem = kh_Team_ByID(i);
-               players = 0;
-               entity my_player = world;
-               FOR_EACH_PLAYER(player)
-                       if(player.deadflag == DEAD_NO)
-                               if(!player.BUTTON_CHAT)
-                                       if(player.team == teem)
-                                       {
-                                               ++players;
-                                               if(random() * players <= 1)
-                                                       my_player = player;
-                                       }
-               kh_Key_Spawn(my_player, 360 * i / kh_teams, i);
-       }
-
-       kh_tracking_enabled = false;
-       Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_KEYHUNT_SCAN, autocvar_g_balance_keyhunt_delay_tracking);
-       kh_Controller_SetThink(autocvar_g_balance_keyhunt_delay_tracking, kh_EnableTrackingDevice);
-}
-
-float kh_HandleFrags(entity attacker, entity targ, float f)  // adds to the player score
-{
-       if(attacker == targ)
-               return f;
-
-       if(targ.kh_next)
-       {
-               if(attacker.team == targ.team)
-               {
-                       entity k;
-                       float nk;
-                       nk = 0;
-                       for(k = targ.kh_next; k != world; k = k.kh_next)
-                               ++nk;
-                       kh_Scores_Event(attacker, targ.kh_next, "carrierfrag", -nk * autocvar_g_balance_keyhunt_score_collect, 0);
-               }
-               else
-               {
-                       kh_Scores_Event(attacker, targ.kh_next, "carrierfrag", autocvar_g_balance_keyhunt_score_carrierfrag-1, 0);
-                       PlayerScore_Add(attacker, SP_KH_KCKILLS, 1);
-                       // the frag gets added later
-               }
-       }
-
-       return f;
-}
-
-void kh_Initialize()  // sets up th KH environment
-{
-       // setup variables
-       kh_teams = autocvar_g_keyhunt_teams_override;
-       if(kh_teams < 2)
-               kh_teams = autocvar_g_keyhunt_teams;
-       kh_teams = bound(2, kh_teams, 4);
-
-       // make a KH entity for controlling the game
-       kh_controller = spawn();
-       kh_controller.think = kh_Controller_Think;
-       kh_Controller_SetThink(0, kh_WaitForPlayers);
-
-       setmodel(kh_controller, MDL_KH_KEY);
-       kh_key_dropped = kh_controller.modelindex;
-       /*
-       dprint(vtos(kh_controller.mins));
-       dprint(vtos(kh_controller.maxs));
-       dprint("\n");
-       */
-#ifdef KH_PLAYER_USE_CARRIEDMODEL
-       setmodel(kh_controller, MDL_KH_KEY_CARRIED);
-       kh_key_carried = kh_controller.modelindex;
-#else
-       kh_key_carried = kh_key_dropped;
-#endif
-
-       kh_controller.model = "";
-       kh_controller.modelindex = 0;
-
-       addstat(STAT_KH_KEYS, AS_INT, kh_state);
-
-       kh_ScoreRules(kh_teams);
-}
-
-void kh_finalize()
-{
-       // to be called before intermission
-       kh_FinishRound();
-       remove(kh_controller);
-       kh_controller = world;
-}
-
-// register this as a mutator
-
-MUTATOR_HOOKFUNCTION(kh_Key_DropAll)
-{SELFPARAM();
-       kh_Key_DropAll(self, true);
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(kh_PlayerDies)
-{SELFPARAM();
-       if(self == other)
-               kh_Key_DropAll(self, true);
-       else if(IS_PLAYER(other))
-               kh_Key_DropAll(self, false);
-       else
-               kh_Key_DropAll(self, true);
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(kh_GiveFragsForKill)
-{
-       frag_score = kh_HandleFrags(frag_attacker, frag_target, frag_score);
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(kh_finalize)
-{
-       kh_finalize();
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(kh_GetTeamCount)
-{
-       ret_float = kh_teams;
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(kh_SpectateCopy)
-{SELFPARAM();
-       self.kh_state = other.kh_state;
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(kh_PlayerUseKey)
-{SELFPARAM();
-       if(MUTATOR_RETURNVALUE == 0)
-       {
-               entity k;
-               k = self.kh_next;
-               if(k)
-               {
-                       kh_Key_DropOne(k);
-                       return 1;
-               }
-       }
-       return 0;
-}
-
-MUTATOR_DEFINITION(gamemode_keyhunt)
-{
-       MUTATOR_HOOK(MakePlayerObserver, kh_Key_DropAll, CBC_ORDER_ANY);
-       MUTATOR_HOOK(ClientDisconnect, kh_Key_DropAll, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerDies, kh_PlayerDies, CBC_ORDER_ANY);
-       MUTATOR_HOOK(GiveFragsForKill, kh_GiveFragsForKill, CBC_ORDER_FIRST);
-       MUTATOR_HOOK(MatchEnd, kh_finalize, CBC_ORDER_ANY);
-       MUTATOR_HOOK(GetTeamCount, kh_GetTeamCount, CBC_ORDER_EXCLUSIVE);
-       MUTATOR_HOOK(SpectateCopy, kh_SpectateCopy, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerUseKey, kh_PlayerUseKey, 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.");
-               kh_Initialize();
-       }
-
-       MUTATOR_ONROLLBACK_OR_REMOVE
-       {
-               // we actually cannot roll back kh_Initialize here
-               // BUT: we don't need to! If this gets called, adding always
-               // succeeds.
-       }
-
-       MUTATOR_ONREMOVE
-       {
-               LOG_INFO("This is a game type and it cannot be removed at runtime.");
-               return -1;
-       }
-
-       return 0;
-}
diff --git a/qcsrc/server/mutators/gamemode_keyhunt.qh b/qcsrc/server/mutators/gamemode_keyhunt.qh
deleted file mode 100644 (file)
index 4d1645d..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef GAMEMODE_KEYHUNT_H
-#define GAMEMODE_KEYHUNT_H
-
-#define FOR_EACH_KH_KEY(v) for(v = kh_worldkeylist; v; v = v.kh_worldkeynext )
-
-// ALL OF THESE should be removed in the future, as other code should not have to care
-
-// used by bots:
-float kh_tracking_enabled;
-.entity kh_next;
-float kh_Key_AllOwnedByWhichTeam();
-
-typedef void(void) kh_Think_t;
-void kh_StartRound();
-void kh_Controller_SetThink(float t, kh_Think_t func);
-
-void kh_Key_DropAll(entity player, float suicide);
-
-#endif
diff --git a/qcsrc/server/mutators/gamemode_lms.qc b/qcsrc/server/mutators/gamemode_lms.qc
deleted file mode 100644 (file)
index b3cf0db..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-#include "gamemode_lms.qh"
-
-#include "gamemode.qh"
-
-#include "../campaign.qh"
-#include "../command/cmd.qh"
-
-// main functions
-float LMS_NewPlayerLives()
-{
-       float fl;
-       fl = autocvar_fraglimit;
-       if(fl == 0)
-               fl = 999;
-
-       // first player has left the game for dying too much? Nobody else can get in.
-       if(lms_lowest_lives < 1)
-               return 0;
-
-       if(!autocvar_g_lms_join_anytime)
-               if(lms_lowest_lives < fl - autocvar_g_lms_last_join)
-                       return 0;
-
-       return bound(1, lms_lowest_lives, fl);
-}
-
-// mutator hooks
-MUTATOR_HOOKFUNCTION(lms_ResetMap)
-{
-       lms_lowest_lives = 999;
-       lms_next_place = player_count;
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(lms_ResetPlayers)
-{SELFPARAM();
-       entity e;
-       if(restart_mapalreadyrestarted || (time < game_starttime))
-       FOR_EACH_CLIENT(e)
-       if(IS_PLAYER(e))
-       {
-               WITH(entity, self, e, PlayerScore_Add(e, SP_LMS_LIVES, LMS_NewPlayerLives()));
-       }
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(lms_PlayerPreSpawn)
-{SELFPARAM();
-       // player is dead and becomes observer
-       // FIXME fix LMS scoring for new system
-       if(PlayerScore_Add(self, SP_LMS_RANK, 0) > 0)
-       {
-               self.classname = "observer";
-               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_LMS_NOLIVES);
-       }
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(lms_PlayerDies)
-{SELFPARAM();
-       self.respawn_flags |= RESPAWN_FORCE;
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(lms_RemovePlayer)
-{SELFPARAM();
-       // Only if the player cannot play at all
-       if(PlayerScore_Add(self, SP_LMS_RANK, 0) == 666)
-               self.frags = FRAGS_SPECTATOR;
-       else
-               self.frags = FRAGS_LMS_LOSER;
-
-       if(self.killcount != -666)
-               if(PlayerScore_Add(self, SP_LMS_RANK, 0) > 0 && self.lms_spectate_warning != 2)
-                       Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_LMS_NOLIVES, self.netname);
-               else
-                       Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_LMS_FORFEIT, self.netname);
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(lms_ClientConnect)
-{SELFPARAM();
-       self.classname = "player";
-       campaign_bots_may_start = 1;
-
-       if(PlayerScore_Add(self, SP_LMS_LIVES, LMS_NewPlayerLives()) <= 0)
-       {
-               PlayerScore_Add(self, SP_LMS_RANK, 666);
-               self.frags = FRAGS_SPECTATOR;
-       }
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(lms_PlayerThink)
-{SELFPARAM();
-       if(self.deadflag == DEAD_DYING)
-               self.deadflag = DEAD_RESPAWNING;
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(lms_PlayerRegen)
-{
-       if(autocvar_g_lms_regenerate)
-               return false;
-       return true;
-}
-
-MUTATOR_HOOKFUNCTION(lms_ForbidThrowing)
-{
-       // forbode!
-       return true;
-}
-
-MUTATOR_HOOKFUNCTION(lms_GiveFragsForKill)
-{
-       // remove a life
-       float tl;
-       tl = PlayerScore_Add(frag_target, SP_LMS_LIVES, -1);
-       if(tl < lms_lowest_lives)
-               lms_lowest_lives = tl;
-       if(tl <= 0)
-       {
-               if(!lms_next_place)
-                       lms_next_place = player_count;
-               else
-                       lms_next_place = min(lms_next_place, player_count);
-               PlayerScore_Add(frag_target, SP_LMS_RANK, lms_next_place); // won't ever spawn again
-               --lms_next_place;
-       }
-       frag_score = 0;
-
-       return true;
-}
-
-MUTATOR_HOOKFUNCTION(lms_SetStartItems)
-{
-       start_items &= ~IT_UNLIMITED_AMMO;
-       start_health       = warmup_start_health       = cvar("g_lms_start_health");
-       start_armorvalue   = warmup_start_armorvalue   = cvar("g_lms_start_armor");
-       start_ammo_shells  = warmup_start_ammo_shells  = cvar("g_lms_start_ammo_shells");
-       start_ammo_nails   = warmup_start_ammo_nails   = cvar("g_lms_start_ammo_nails");
-       start_ammo_rockets = warmup_start_ammo_rockets = cvar("g_lms_start_ammo_rockets");
-       start_ammo_cells   = warmup_start_ammo_cells   = cvar("g_lms_start_ammo_cells");
-       start_ammo_plasma  = warmup_start_ammo_plasma  = cvar("g_lms_start_ammo_plasma");
-       start_ammo_fuel    = warmup_start_ammo_fuel    = cvar("g_lms_start_ammo_fuel");
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(lms_KeepScore)
-{
-       // don't clear player score
-       return true;
-}
-
-MUTATOR_HOOKFUNCTION(lms_FilterItem)
-{SELFPARAM();
-       if(autocvar_g_lms_extra_lives)
-       if(self.itemdef == ITEM_HealthMega)
-       {
-               self.max_health = 1;
-               return false;
-       }
-
-       return true;
-}
-
-MUTATOR_HOOKFUNCTION(lms_ItemTouch)
-{SELFPARAM();
-       // give extra lives for mega health
-       if (self.items & ITEM_HealthMega.m_itemid)
-       {
-               Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_EXTRALIVES);
-               PlayerScore_Add(other, SP_LMS_LIVES, autocvar_g_lms_extra_lives);
-       }
-
-       return MUT_ITEMTOUCH_CONTINUE;
-}
-
-// scoreboard stuff
-void lms_ScoreRules()
-{
-       ScoreRules_basics(0, 0, 0, false);
-       ScoreInfo_SetLabel_PlayerScore(SP_LMS_LIVES,    "lives",     SFL_SORT_PRIO_SECONDARY);
-       ScoreInfo_SetLabel_PlayerScore(SP_LMS_RANK,     "rank",      SFL_LOWER_IS_BETTER | SFL_RANK | SFL_SORT_PRIO_PRIMARY | SFL_ALLOW_HIDE);
-       ScoreRules_basics_end();
-}
-
-void lms_Initialize()
-{
-       lms_lowest_lives = 9999;
-       lms_next_place = 0;
-
-       lms_ScoreRules();
-}
-
-MUTATOR_DEFINITION(gamemode_lms)
-{
-       MUTATOR_HOOK(reset_map_global, lms_ResetMap, CBC_ORDER_ANY);
-       MUTATOR_HOOK(reset_map_players, lms_ResetPlayers, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PutClientInServer, lms_PlayerPreSpawn, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerDies, lms_PlayerDies, CBC_ORDER_ANY);
-       MUTATOR_HOOK(MakePlayerObserver, lms_RemovePlayer, CBC_ORDER_ANY);
-       MUTATOR_HOOK(ClientConnect, lms_ClientConnect, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerPreThink, lms_PlayerThink, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerRegen, lms_PlayerRegen, CBC_ORDER_ANY);
-       MUTATOR_HOOK(ForbidThrowCurrentWeapon, lms_ForbidThrowing, CBC_ORDER_ANY);
-       MUTATOR_HOOK(GiveFragsForKill, lms_GiveFragsForKill, CBC_ORDER_ANY);
-       MUTATOR_HOOK(SetStartItems, lms_SetStartItems, CBC_ORDER_ANY);
-       MUTATOR_HOOK(ForbidPlayerScore_Clear, lms_KeepScore, CBC_ORDER_ANY);
-       MUTATOR_HOOK(FilterItem, lms_FilterItem, CBC_ORDER_ANY);
-       MUTATOR_HOOK(ItemTouch, lms_ItemTouch, 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.");
-               lms_Initialize();
-       }
-
-       MUTATOR_ONROLLBACK_OR_REMOVE
-       {
-               // we actually cannot roll back lms_Initialize here
-               // BUT: we don't need to! If this gets called, adding always
-               // succeeds.
-       }
-
-       MUTATOR_ONREMOVE
-       {
-               LOG_INFO("This is a game type and it cannot be removed at runtime.");
-               return -1;
-       }
-
-       return 0;
-}
diff --git a/qcsrc/server/mutators/gamemode_lms.qh b/qcsrc/server/mutators/gamemode_lms.qh
deleted file mode 100644 (file)
index 474e3e1..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef GAMEMODE_LMS_H
-#define GAMEMODE_LMS_H
-
-// scoreboard stuff
-const float SP_LMS_LIVES = 4;
-const float SP_LMS_RANK = 5;
-
-// lives related defs
-float lms_lowest_lives;
-float lms_next_place;
-float LMS_NewPlayerLives();
-#endif
diff --git a/qcsrc/server/mutators/gamemode_onslaught.qc b/qcsrc/server/mutators/gamemode_onslaught.qc
deleted file mode 100644 (file)
index 19a7a5e..0000000
+++ /dev/null
@@ -1,2154 +0,0 @@
-
-#include "gamemode.qh"
-#include "../controlpoint.qh"
-#include "../generator.qh"
-
-void FixSize(entity e);
-
-// =======================
-// CaptureShield Functions
-// =======================
-
-bool ons_CaptureShield_Customize()
-{SELFPARAM();
-       entity e = WaypointSprite_getviewentity(other);
-
-       if(!self.enemy.isshielded && (ons_ControlPoint_Attackable(self.enemy, e.team) > 0 || self.enemy.classname != "onslaught_controlpoint")) { return false; }
-       if(SAME_TEAM(self, e)) { return false; }
-
-       return true;
-}
-
-void ons_CaptureShield_Touch()
-{SELFPARAM();
-       if(!self.enemy.isshielded && (ons_ControlPoint_Attackable(self.enemy, other.team) > 0 || self.enemy.classname != "onslaught_controlpoint")) { return; }
-       if(!IS_PLAYER(other)) { return; }
-       if(SAME_TEAM(other, self)) { return; }
-
-       vector mymid = (self.absmin + self.absmax) * 0.5;
-       vector othermid = (other.absmin + other.absmax) * 0.5;
-
-       Damage(other, self, self, 0, DEATH_HURTTRIGGER.m_id, mymid, normalize(othermid - mymid) * ons_captureshield_force);
-
-       if(IS_REAL_CLIENT(other))
-       {
-               play2(other, SND(ONS_DAMAGEBLOCKEDBYSHIELD));
-
-               if(self.enemy.classname == "onslaught_generator")
-                       Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_ONS_GENERATOR_SHIELDED);
-               else
-                       Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_ONS_CONTROLPOINT_SHIELDED);
-       }
-}
-
-void ons_CaptureShield_Reset()
-{SELFPARAM();
-       self.colormap = self.enemy.colormap;
-       self.team = self.enemy.team;
-}
-
-void ons_CaptureShield_Spawn(entity generator, bool is_generator)
-{
-       entity shield = spawn();
-
-       shield.enemy = generator;
-       shield.team = generator.team;
-       shield.colormap = generator.colormap;
-       shield.reset = ons_CaptureShield_Reset;
-       shield.touch = ons_CaptureShield_Touch;
-       shield.customizeentityforclient = ons_CaptureShield_Customize;
-       shield.classname = "ons_captureshield";
-       shield.effects = EF_ADDITIVE;
-       shield.movetype = MOVETYPE_NOCLIP;
-       shield.solid = SOLID_TRIGGER;
-       shield.avelocity = '7 0 11';
-       shield.scale = 1;
-       shield.model = ((is_generator) ? "models/onslaught/generator_shield.md3" : "models/onslaught/controlpoint_shield.md3");
-
-       precache_model(shield.model);
-       setorigin(shield, generator.origin);
-       _setmodel(shield, shield.model);
-       setsize(shield, shield.scale * shield.mins, shield.scale * shield.maxs);
-}
-
-
-// ==========
-// Junk Pile
-// ==========
-
-void ons_debug(string input)
-{
-       switch(autocvar_g_onslaught_debug)
-       {
-               case 1: LOG_TRACE(input); break;
-               case 2: LOG_INFO(input); break;
-       }
-}
-
-void setmodel_fixsize(entity e, Model m)
-{
-       setmodel(e, m);
-       FixSize(e);
-}
-
-void onslaught_updatelinks()
-{
-       entity l;
-       // first check if the game has ended
-       ons_debug("--- updatelinks ---\n");
-       // mark generators as being shielded and networked
-       for(l = ons_worldgeneratorlist; l; l = l.ons_worldgeneratornext)
-       {
-               if (l.iscaptured)
-                       ons_debug(strcat(etos(l), " (generator) belongs to team ", ftos(l.team), "\n"));
-               else
-                       ons_debug(strcat(etos(l), " (generator) is destroyed\n"));
-               l.islinked = l.iscaptured;
-               l.isshielded = l.iscaptured;
-               l.sprite.SendFlags |= 16;
-       }
-       // mark points as shielded and not networked
-       for(l = ons_worldcplist; l; l = l.ons_worldcpnext)
-       {
-               l.islinked = false;
-               l.isshielded = true;
-               int i;
-               for(i = 0; i < 17; ++i) { l.isgenneighbor[i] = false; l.iscpneighbor[i] = false; }
-               ons_debug(strcat(etos(l), " (point) belongs to team ", ftos(l.team), "\n"));
-               l.sprite.SendFlags |= 16;
-       }
-       // flow power outward from the generators through the network
-       bool stop = false;
-       while (!stop)
-       {
-               stop = true;
-               for(l = ons_worldlinklist; l; l = l.ons_worldlinknext)
-               {
-                       // if both points are captured by the same team, and only one of
-                       // them is powered, mark the other one as powered as well
-                       if (l.enemy.iscaptured && l.goalentity.iscaptured)
-                               if (l.enemy.islinked != l.goalentity.islinked)
-                                       if(SAME_TEAM(l.enemy, l.goalentity))
-                                       {
-                                               if (!l.goalentity.islinked)
-                                               {
-                                                       stop = false;
-                                                       l.goalentity.islinked = true;
-                                                       ons_debug(strcat(etos(l), " (link) is marking ", etos(l.goalentity), " (point) because its team matches ", etos(l.enemy), " (point)\n"));
-                                               }
-                                               else if (!l.enemy.islinked)
-                                               {
-                                                       stop = false;
-                                                       l.enemy.islinked = true;
-                                                       ons_debug(strcat(etos(l), " (link) is marking ", etos(l.enemy), " (point) because its team matches ", etos(l.goalentity), " (point)\n"));
-                                               }
-                                       }
-               }
-       }
-       // now that we know which points are powered we can mark their neighbors
-       // as unshielded if team differs
-       for(l = ons_worldlinklist; l; l = l.ons_worldlinknext)
-       {
-               if (l.goalentity.islinked)
-               {
-                       if(DIFF_TEAM(l.goalentity, l.enemy))
-                       {
-                               ons_debug(strcat(etos(l), " (link) is unshielding ", etos(l.enemy), " (point) because its team does not match ", etos(l.goalentity), " (point)\n"));
-                               l.enemy.isshielded = false;
-                       }
-                       if(l.goalentity.classname == "onslaught_generator")
-                               l.enemy.isgenneighbor[l.goalentity.team] = true;
-                       else
-                               l.enemy.iscpneighbor[l.goalentity.team] = true;
-               }
-               if (l.enemy.islinked)
-               {
-                       if(DIFF_TEAM(l.goalentity, l.enemy))
-                       {
-                               ons_debug(strcat(etos(l), " (link) is unshielding ", etos(l.goalentity), " (point) because its team does not match ", etos(l.enemy), " (point)\n"));
-                               l.goalentity.isshielded = false;
-                       }
-                       if(l.enemy.classname == "onslaught_generator")
-                               l.goalentity.isgenneighbor[l.enemy.team] = true;
-                       else
-                               l.goalentity.iscpneighbor[l.enemy.team] = true;
-               }
-       }
-       // now update the generators
-       for(l = ons_worldgeneratorlist; l; l = l.ons_worldgeneratornext)
-       {
-               if (l.isshielded)
-               {
-                       ons_debug(strcat(etos(l), " (generator) is shielded\n"));
-                       l.takedamage = DAMAGE_NO;
-                       l.bot_attack = false;
-               }
-               else
-               {
-                       ons_debug(strcat(etos(l), " (generator) is not shielded\n"));
-                       l.takedamage = DAMAGE_AIM;
-                       l.bot_attack = true;
-               }
-
-               ons_Generator_UpdateSprite(l);
-       }
-       // now update the takedamage and alpha variables on control point icons
-       for(l = ons_worldcplist; l; l = l.ons_worldcpnext)
-       {
-               if (l.isshielded)
-               {
-                       ons_debug(strcat(etos(l), " (point) is shielded\n"));
-                       if (l.goalentity)
-                       {
-                               l.goalentity.takedamage = DAMAGE_NO;
-                               l.goalentity.bot_attack = false;
-                       }
-               }
-               else
-               {
-                       ons_debug(strcat(etos(l), " (point) is not shielded\n"));
-                       if (l.goalentity)
-                       {
-                               l.goalentity.takedamage = DAMAGE_AIM;
-                               l.goalentity.bot_attack = true;
-                       }
-               }
-               ons_ControlPoint_UpdateSprite(l);
-       }
-       l = findchain(classname, "ons_captureshield");
-       while(l)
-       {
-               l.team = l.enemy.team;
-               l.colormap = l.enemy.colormap;
-               l = l.chain;
-       }
-}
-
-
-// ===================
-// Main Link Functions
-// ===================
-
-bool ons_Link_Send(entity this, entity to, int sendflags)
-{
-       WriteByte(MSG_ENTITY, ENT_CLIENT_RADARLINK);
-       WriteByte(MSG_ENTITY, sendflags);
-       if(sendflags & 1)
-       {
-               WriteCoord(MSG_ENTITY, self.goalentity.origin_x);
-               WriteCoord(MSG_ENTITY, self.goalentity.origin_y);
-               WriteCoord(MSG_ENTITY, self.goalentity.origin_z);
-       }
-       if(sendflags & 2)
-       {
-               WriteCoord(MSG_ENTITY, self.enemy.origin_x);
-               WriteCoord(MSG_ENTITY, self.enemy.origin_y);
-               WriteCoord(MSG_ENTITY, self.enemy.origin_z);
-       }
-       if(sendflags & 4)
-       {
-               WriteByte(MSG_ENTITY, self.clientcolors); // which is goalentity's color + enemy's color * 16
-       }
-       return true;
-}
-
-void ons_Link_CheckUpdate()
-{SELFPARAM();
-       // TODO check if the two sides have moved (currently they won't move anyway)
-       float cc = 0, cc1 = 0, cc2 = 0;
-
-       if(self.goalentity.islinked || self.goalentity.iscaptured) { cc1 = (self.goalentity.team - 1) * 0x01; }
-       if(self.enemy.islinked || self.enemy.iscaptured) { cc2 = (self.enemy.team - 1) * 0x10; }
-
-       cc = cc1 + cc2;
-
-       if(cc != self.clientcolors)
-       {
-               self.clientcolors = cc;
-               self.SendFlags |= 4;
-       }
-
-       self.nextthink = time;
-}
-
-void ons_DelayedLinkSetup()
-{SELFPARAM();
-       self.goalentity = find(world, targetname, self.target);
-       self.enemy = find(world, targetname, self.target2);
-       if(!self.goalentity) { objerror("can not find target\n"); }
-       if(!self.enemy) { objerror("can not find target2\n"); }
-
-       ons_debug(strcat(etos(self.goalentity), " linked with ", etos(self.enemy), "\n"));
-       self.SendFlags |= 3;
-       self.think = ons_Link_CheckUpdate;
-       self.nextthink = time;
-}
-
-
-// =============================
-// Main Control Point Functions
-// =============================
-
-int ons_ControlPoint_CanBeLinked(entity cp, int teamnumber)
-{
-       if(cp.isgenneighbor[teamnumber]) { return 2; }
-       if(cp.iscpneighbor[teamnumber]) { return 1; }
-
-       return 0;
-}
-
-int ons_ControlPoint_Attackable(entity cp, int teamnumber)
-       // -2: SAME TEAM, attackable by enemy!
-       // -1: SAME TEAM!
-       // 0: off limits
-       // 1: attack it
-       // 2: touch it
-       // 3: attack it (HIGH PRIO)
-       // 4: touch it (HIGH PRIO)
-{
-       int a;
-
-       if(cp.isshielded)
-       {
-               return 0;
-       }
-       else if(cp.goalentity)
-       {
-               // if there's already an icon built, nothing happens
-               if(cp.team == teamnumber)
-               {
-                       a = ons_ControlPoint_CanBeLinked(cp, teamnumber);
-                       if(a) // attackable by enemy?
-                               return -2; // EMERGENCY!
-                       return -1;
-               }
-               // we know it can be linked, so no need to check
-               // but...
-               a = ons_ControlPoint_CanBeLinked(cp, teamnumber);
-               if(a == 2) // near our generator?
-                       return 3; // EMERGENCY!
-               return 1;
-       }
-       else
-       {
-               // free point
-               if(ons_ControlPoint_CanBeLinked(cp, teamnumber))
-               {
-                       a = ons_ControlPoint_CanBeLinked(cp, teamnumber); // why was this here NUM_TEAM_1 + NUM_TEAM_2 - t
-                       if(a == 2)
-                               return 4; // GET THIS ONE NOW!
-                       else
-                               return 2; // TOUCH ME
-               }
-       }
-       return 0;
-}
-
-void ons_ControlPoint_Icon_Damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
-{SELFPARAM();
-       if(damage <= 0) { return; }
-
-       if (self.owner.isshielded)
-       {
-               // this is protected by a shield, so ignore the damage
-               if (time > self.pain_finished)
-                       if (IS_PLAYER(attacker))
-                       {
-                               play2(attacker, SND(ONS_DAMAGEBLOCKEDBYSHIELD));
-                               self.pain_finished = time + 1;
-                               attacker.typehitsound += 1; // play both sounds (shield is way too quiet)
-                       }
-
-               return;
-       }
-
-       if(IS_PLAYER(attacker))
-       if(time - ons_notification_time[self.team] > 10)
-       {
-               play2team(self.team, SND(ONS_CONTROLPOINT_UNDERATTACK));
-               ons_notification_time[self.team] = time;
-       }
-
-       self.health = self.health - damage;
-       if(self.owner.iscaptured)
-               WaypointSprite_UpdateHealth(self.owner.sprite, self.health);
-       else
-               WaypointSprite_UpdateBuildFinished(self.owner.sprite, time + (self.max_health - self.health) / (self.count / ONS_CP_THINKRATE));
-       self.pain_finished = time + 1;
-       // particles on every hit
-       pointparticles(particleeffectnum(EFFECT_SPARKS), hitloc, force*-1, 1);
-       //sound on every hit
-       if (random() < 0.5)
-               sound(self, CH_TRIGGER, SND_ONS_HIT1, VOL_BASE+0.3, ATTEN_NORM);
-       else
-               sound(self, CH_TRIGGER, SND_ONS_HIT2, VOL_BASE+0.3, ATTEN_NORM);
-
-       if (self.health < 0)
-       {
-               sound(self, CH_TRIGGER, SND_GRENADE_IMPACT, VOL_BASE, ATTEN_NORM);
-               pointparticles(particleeffectnum(EFFECT_ROCKET_EXPLODE), self.origin, '0 0 0', 1);
-               Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(self.team, INFO_ONSLAUGHT_CPDESTROYED_), self.owner.message, attacker.netname);
-
-               PlayerScore_Add(attacker, SP_ONS_TAKES, 1);
-               PlayerScore_Add(attacker, SP_SCORE, 10);
-
-               self.owner.goalentity = world;
-               self.owner.islinked = false;
-               self.owner.iscaptured = false;
-               self.owner.team = 0;
-               self.owner.colormap = 1024;
-
-               WaypointSprite_UpdateMaxHealth(self.owner.sprite, 0);
-
-               onslaught_updatelinks();
-
-               // Use targets now (somebody make sure this is in the right place..)
-               setself(self.owner);
-               activator = self;
-               SUB_UseTargets ();
-               setself(this);
-
-               self.owner.waslinked = self.owner.islinked;
-               if(self.owner.model != "models/onslaught/controlpoint_pad.md3")
-                       setmodel_fixsize(self.owner, MDL_ONS_CP_PAD1);
-               //setsize(self, '-32 -32 0', '32 32 8');
-
-               remove(self);
-       }
-
-       self.SendFlags |= CPSF_STATUS;
-}
-
-void ons_ControlPoint_Icon_Think()
-{SELFPARAM();
-       self.nextthink = time + ONS_CP_THINKRATE;
-
-       if(autocvar_g_onslaught_cp_proxydecap)
-       {
-        int _enemy_count = 0;
-        int _friendly_count = 0;
-        float _dist;
-        entity _player;
-
-        FOR_EACH_PLAYER(_player)
-        {
-            if(!_player.deadflag)
-            {
-                _dist = vlen(_player.origin - self.origin);
-                if(_dist < autocvar_g_onslaught_cp_proxydecap_distance)
-                {
-                                       if(SAME_TEAM(_player, self))
-                        ++_friendly_count;
-                    else
-                        ++_enemy_count;
-                }
-            }
-        }
-
-        _friendly_count = _friendly_count * (autocvar_g_onslaught_cp_proxydecap_dps * ONS_CP_THINKRATE);
-        _enemy_count = _enemy_count * (autocvar_g_onslaught_cp_proxydecap_dps * ONS_CP_THINKRATE);
-
-        self.health = bound(0, self.health + (_friendly_count - _enemy_count), self.max_health);
-               self.SendFlags |= CPSF_STATUS;
-        if(self.health <= 0)
-        {
-            ons_ControlPoint_Icon_Damage(self, self, 1, 0, self.origin, '0 0 0');
-            return;
-        }
-    }
-
-       if (time > self.pain_finished + 5)
-       {
-               if(self.health < self.max_health)
-               {
-                       self.health = self.health + self.count;
-                       if (self.health >= self.max_health)
-                               self.health = self.max_health;
-                       WaypointSprite_UpdateHealth(self.owner.sprite, self.health);
-               }
-       }
-
-       if(self.owner.islinked != self.owner.waslinked)
-       {
-               // unteam the spawnpoint if needed
-               int t = self.owner.team;
-               if(!self.owner.islinked)
-                       self.owner.team = 0;
-
-               setself(self.owner);
-               activator = self;
-               SUB_UseTargets ();
-               setself(this);
-
-               self.owner.team = t;
-
-               self.owner.waslinked = self.owner.islinked;
-       }
-
-       // damaged fx
-       if(random() < 0.6 - self.health / self.max_health)
-       {
-               Send_Effect(EFFECT_ELECTRIC_SPARKS, self.origin + randompos('-10 -10 -20', '10 10 20'), '0 0 0', 1);
-
-               if(random() > 0.8)
-                       sound(self, CH_PAIN, SND_ONS_SPARK1, VOL_BASE, ATTEN_NORM);
-               else if (random() > 0.5)
-                       sound(self, CH_PAIN, SND_ONS_SPARK2, VOL_BASE, ATTEN_NORM);
-       }
-}
-
-void ons_ControlPoint_Icon_BuildThink()
-{SELFPARAM();
-       int a;
-
-       self.nextthink = time + ONS_CP_THINKRATE;
-
-       // only do this if there is power
-       a = ons_ControlPoint_CanBeLinked(self.owner, self.owner.team);
-       if(!a)
-               return;
-
-       self.health = self.health + self.count;
-
-       self.SendFlags |= CPSF_STATUS;
-
-       if (self.health >= self.max_health)
-       {
-               self.health = self.max_health;
-               self.count = autocvar_g_onslaught_cp_regen * ONS_CP_THINKRATE; // slow repair rate from now on
-               self.think = ons_ControlPoint_Icon_Think;
-               sound(self, CH_TRIGGER, SND_ONS_CONTROLPOINT_BUILT, VOL_BASE, ATTEN_NORM);
-               self.owner.iscaptured = true;
-               self.solid = SOLID_BBOX;
-
-               Send_Effect(EFFECT_CAP(self.owner.team), self.owner.origin, '0 0 0', 1);
-
-               WaypointSprite_UpdateMaxHealth(self.owner.sprite, self.max_health);
-               WaypointSprite_UpdateHealth(self.owner.sprite, self.health);
-
-               if(IS_PLAYER(self.owner.ons_toucher))
-               {
-                       Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_ONSLAUGHT_CAPTURE, self.owner.ons_toucher.netname, self.owner.message);
-                       Send_Notification(NOTIF_ALL_EXCEPT, self.owner.ons_toucher, MSG_CENTER, APP_TEAM_ENT_4(self.owner.ons_toucher, CENTER_ONS_CAPTURE_), self.owner.message);
-                       Send_Notification(NOTIF_ONE, self.owner.ons_toucher, MSG_CENTER, CENTER_ONS_CAPTURE, self.owner.message);
-                       PlayerScore_Add(self.owner.ons_toucher, SP_ONS_CAPS, 1);
-                       PlayerTeamScore_AddScore(self.owner.ons_toucher, 10);
-               }
-
-               self.owner.ons_toucher = world;
-
-               onslaught_updatelinks();
-
-               // Use targets now (somebody make sure this is in the right place..)
-               setself(self.owner);
-               activator = self;
-               SUB_UseTargets ();
-               setself(this);
-
-               self.SendFlags |= CPSF_SETUP;
-       }
-       if(self.owner.model != MDL_ONS_CP_PAD2.model_str())
-               setmodel_fixsize(self.owner, MDL_ONS_CP_PAD2);
-
-       if(random() < 0.9 - self.health / self.max_health)
-               Send_Effect(EFFECT_RAGE, self.origin + 10 * randomvec(), '0 0 -1', 1);
-}
-
-void onslaught_controlpoint_icon_link(entity e, void() spawnproc);
-
-void ons_ControlPoint_Icon_Spawn(entity cp, entity player)
-{
-       entity e = spawn();
-
-       setsize(e, CPICON_MIN, CPICON_MAX);
-       setorigin(e, cp.origin + CPICON_OFFSET);
-
-       e.classname = "onslaught_controlpoint_icon";
-       e.owner = cp;
-       e.max_health = autocvar_g_onslaught_cp_health;
-       e.health = autocvar_g_onslaught_cp_buildhealth;
-       e.solid = SOLID_NOT;
-       e.takedamage = DAMAGE_AIM;
-       e.bot_attack = true;
-       e.event_damage = ons_ControlPoint_Icon_Damage;
-       e.team = player.team;
-       e.colormap = 1024 + (e.team - 1) * 17;
-       e.count = (e.max_health - e.health) * ONS_CP_THINKRATE / autocvar_g_onslaught_cp_buildtime; // how long it takes to build
-
-       sound(e, CH_TRIGGER, SND_ONS_CONTROLPOINT_BUILD, VOL_BASE, ATTEN_NORM);
-
-       cp.goalentity = e;
-       cp.team = e.team;
-       cp.colormap = e.colormap;
-
-       Send_Effect(EFFECT_FLAG_TOUCH(player.team), e.origin, '0 0 0', 1);
-
-       WaypointSprite_UpdateBuildFinished(cp.sprite, time + (e.max_health - e.health) / (e.count / ONS_CP_THINKRATE));
-       WaypointSprite_UpdateRule(cp.sprite,cp.team,SPRITERULE_TEAMPLAY);
-       cp.sprite.SendFlags |= 16;
-
-       onslaught_controlpoint_icon_link(e, ons_ControlPoint_Icon_BuildThink);
-}
-
-entity ons_ControlPoint_Waypoint(entity e)
-{
-       if(e.team)
-       {
-               int a = ons_ControlPoint_Attackable(e, e.team);
-
-               if(a == -2) { return WP_OnsCPDefend; } // defend now
-               if(a == -1 || a == 1 || a == 2) { return WP_OnsCP; } // touch
-               if(a == 3 || a == 4) { return WP_OnsCPAttack; } // attack
-       }
-       else
-               return WP_OnsCP;
-
-       return WP_Null;
-}
-
-void ons_ControlPoint_UpdateSprite(entity e)
-{
-       entity s1 = ons_ControlPoint_Waypoint(e);
-       WaypointSprite_UpdateSprites(e.sprite, s1, s1, s1);
-
-       bool sh;
-       sh = !(ons_ControlPoint_CanBeLinked(e, NUM_TEAM_1) || ons_ControlPoint_CanBeLinked(e, NUM_TEAM_2) || ons_ControlPoint_CanBeLinked(e, NUM_TEAM_3) || ons_ControlPoint_CanBeLinked(e, NUM_TEAM_4));
-
-       if(e.lastteam != e.team + 2 || e.lastshielded != sh || e.iscaptured != e.lastcaptured)
-       {
-               if(e.iscaptured) // don't mess up build bars!
-               {
-                       if(sh)
-                       {
-                               WaypointSprite_UpdateMaxHealth(e.sprite, 0);
-                       }
-                       else
-                       {
-                               WaypointSprite_UpdateMaxHealth(e.sprite, e.goalentity.max_health);
-                               WaypointSprite_UpdateHealth(e.sprite, e.goalentity.health);
-                       }
-               }
-               if(e.lastshielded)
-               {
-                       if(e.team)
-                               WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_CONTROLPOINT, 0.5 * colormapPaletteColor(e.team - 1, false));
-                       else
-                               WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_CONTROLPOINT, '0.5 0.5 0.5');
-               }
-               else
-               {
-                       if(e.team)
-                               WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_CONTROLPOINT, colormapPaletteColor(e.team - 1, false));
-                       else
-                               WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_CONTROLPOINT, '0.75 0.75 0.75');
-               }
-               WaypointSprite_Ping(e.sprite);
-
-               e.lastteam = e.team + 2;
-               e.lastshielded = sh;
-               e.lastcaptured = e.iscaptured;
-       }
-}
-
-void ons_ControlPoint_Touch()
-{SELFPARAM();
-       entity toucher = other;
-       int attackable;
-
-       if(IS_VEHICLE(toucher) && toucher.owner)
-       if(autocvar_g_onslaught_allow_vehicle_touch)
-               toucher = toucher.owner;
-       else
-               return;
-
-       if(!IS_PLAYER(toucher)) { return; }
-       if(toucher.frozen) { return; }
-       if(toucher.deadflag != DEAD_NO) { return; }
-
-       if ( SAME_TEAM(self,toucher) )
-       if ( self.iscaptured )
-       {
-               if(time <= toucher.teleport_antispam)
-                       Send_Notification(NOTIF_ONE, toucher, MSG_CENTER, CENTER_ONS_TELEPORT_ANTISPAM, rint(toucher.teleport_antispam - time));
-               else
-                       Send_Notification(NOTIF_ONE, toucher, MSG_CENTER, CENTER_ONS_TELEPORT);
-       }
-
-       attackable = ons_ControlPoint_Attackable(self, toucher.team);
-       if(attackable != 2 && attackable != 4)
-               return;
-       // we've verified that this player has a legitimate claim to this point,
-       // so start building the captured point icon (which only captures this
-       // point if it successfully builds without being destroyed first)
-       ons_ControlPoint_Icon_Spawn(self, toucher);
-
-       self.ons_toucher = toucher;
-
-       onslaught_updatelinks();
-}
-
-void ons_ControlPoint_Think()
-{SELFPARAM();
-       self.nextthink = time + ONS_CP_THINKRATE;
-       CSQCMODEL_AUTOUPDATE(self);
-}
-
-void ons_ControlPoint_Reset()
-{SELFPARAM();
-       if(self.goalentity)
-               remove(self.goalentity);
-
-       self.goalentity = world;
-       self.team = 0;
-       self.colormap = 1024;
-       self.iscaptured = false;
-       self.islinked = false;
-       self.isshielded = true;
-       self.think = ons_ControlPoint_Think;
-       self.ons_toucher = world;
-       self.nextthink = time + ONS_CP_THINKRATE;
-       setmodel_fixsize(self, MDL_ONS_CP_PAD1);
-
-       WaypointSprite_UpdateMaxHealth(self.sprite, 0);
-       WaypointSprite_UpdateRule(self.sprite,self.team,SPRITERULE_TEAMPLAY);
-
-       onslaught_updatelinks();
-
-       activator = self;
-       SUB_UseTargets(); // to reset the structures, playerspawns etc.
-
-       CSQCMODEL_AUTOUPDATE(self);
-}
-
-void ons_DelayedControlPoint_Setup(void)
-{SELFPARAM();
-       onslaught_updatelinks();
-
-       // captureshield setup
-       ons_CaptureShield_Spawn(self, false);
-
-       CSQCMODEL_AUTOINIT(self);
-}
-
-void ons_ControlPoint_Setup(entity cp)
-{SELFPARAM();
-       // declarations
-       setself(cp); // for later usage with droptofloor()
-
-       // main setup
-       cp.ons_worldcpnext = ons_worldcplist; // link control point into ons_worldcplist
-       ons_worldcplist = cp;
-
-       cp.netname = "Control point";
-       cp.team = 0;
-       cp.solid = SOLID_BBOX;
-       cp.movetype = MOVETYPE_NONE;
-       cp.touch = ons_ControlPoint_Touch;
-       cp.think = ons_ControlPoint_Think;
-       cp.nextthink = time + ONS_CP_THINKRATE;
-       cp.reset = ons_ControlPoint_Reset;
-       cp.colormap = 1024;
-       cp.iscaptured = false;
-       cp.islinked = false;
-       cp.isshielded = true;
-
-       if(cp.message == "") { cp.message = "a"; }
-
-       // appearence
-       setmodel_fixsize(cp, MDL_ONS_CP_PAD1);
-
-       // control point placement
-       if((cp.spawnflags & 1) || cp.noalign) // don't drop to floor, just stay at fixed location
-       {
-               cp.noalign = true;
-               cp.movetype = MOVETYPE_NONE;
-       }
-       else // drop to floor, automatically find a platform and set that as spawn origin
-       {
-               setorigin(cp, cp.origin + '0 0 20');
-               cp.noalign = false;
-               setself(cp);
-               droptofloor();
-               cp.movetype = MOVETYPE_TOSS;
-       }
-
-       // waypointsprites
-       WaypointSprite_SpawnFixed(WP_Null, self.origin + CPGEN_WAYPOINT_OFFSET, self, sprite, RADARICON_NONE);
-       WaypointSprite_UpdateRule(self.sprite, self.team, SPRITERULE_TEAMPLAY);
-
-       InitializeEntity(cp, ons_DelayedControlPoint_Setup, INITPRIO_SETLOCATION);
-}
-
-
-// =========================
-// Main Generator Functions
-// =========================
-
-entity ons_Generator_Waypoint(entity e)
-{
-       if (e.isshielded)
-               return WP_OnsGenShielded;
-       return WP_OnsGen;
-}
-
-void ons_Generator_UpdateSprite(entity e)
-{
-       entity s1 = ons_Generator_Waypoint(e);
-       WaypointSprite_UpdateSprites(e.sprite, s1, s1, s1);
-
-       if(e.lastteam != e.team + 2 || e.lastshielded != e.isshielded)
-       {
-               e.lastteam = e.team + 2;
-               e.lastshielded = e.isshielded;
-               if(e.lastshielded)
-               {
-                       if(e.team)
-                               WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_GENERATOR, 0.5 * colormapPaletteColor(e.team - 1, false));
-                       else
-                               WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_GENERATOR, '0.5 0.5 0.5');
-               }
-               else
-               {
-                       if(e.team)
-                               WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_GENERATOR, colormapPaletteColor(e.team - 1, false));
-                       else
-                               WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_GENERATOR, '0.75 0.75 0.75');
-               }
-               WaypointSprite_Ping(e.sprite);
-       }
-}
-
-void ons_GeneratorDamage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
-{SELFPARAM();
-       if(damage <= 0) { return; }
-       if(warmup_stage || gameover) { return; }
-       if(!round_handler_IsRoundStarted()) { return; }
-
-       if (attacker != self)
-       {
-               if (self.isshielded)
-               {
-                       // this is protected by a shield, so ignore the damage
-                       if (time > self.pain_finished)
-                               if (IS_PLAYER(attacker))
-                               {
-                                       play2(attacker, SND(ONS_DAMAGEBLOCKEDBYSHIELD));
-                                       attacker.typehitsound += 1;
-                                       self.pain_finished = time + 1;
-                               }
-                       return;
-               }
-               if (time > self.pain_finished)
-               {
-                       self.pain_finished = time + 10;
-                       entity head;
-                       FOR_EACH_REALPLAYER(head) if(SAME_TEAM(head, self)) { Send_Notification(NOTIF_ONE, head, MSG_CENTER, CENTER_GENERATOR_UNDERATTACK); }
-                       play2team(self.team, SND(ONS_GENERATOR_UNDERATTACK));
-               }
-       }
-       self.health = self.health - damage;
-       WaypointSprite_UpdateHealth(self.sprite, self.health);
-       // choose an animation frame based on health
-       self.frame = 10 * bound(0, (1 - self.health / self.max_health), 1);
-       // see if the generator is still functional, or dying
-       if (self.health > 0)
-       {
-               self.lasthealth = self.health;
-       }
-       else
-       {
-               if (attacker == self)
-                       Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(self.team, INFO_ONSLAUGHT_GENDESTROYED_OVERTIME_));
-               else
-               {
-                       Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(self.team, INFO_ONSLAUGHT_GENDESTROYED_));
-                       PlayerScore_Add(attacker, SP_SCORE, 100);
-               }
-               self.iscaptured = false;
-               self.islinked = false;
-               self.isshielded = false;
-               self.takedamage = DAMAGE_NO; // can't be hurt anymore
-               self.event_damage = func_null; // won't do anything if hurt
-               self.count = 0; // reset counter
-               self.think = func_null;
-               self.nextthink = 0;
-               //self.think(); // do the first explosion now
-
-               WaypointSprite_UpdateMaxHealth(self.sprite, 0);
-               WaypointSprite_Ping(self.sprite);
-               //WaypointSprite_Kill(self.sprite); // can't do this yet, code too poor
-
-               onslaught_updatelinks();
-       }
-
-       // Throw some flaming gibs on damage, more damage = more chance for gib
-       if(random() < damage/220)
-       {
-               sound(self, CH_TRIGGER, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM);
-       }
-       else
-       {
-               // particles on every hit
-               Send_Effect(EFFECT_SPARKS, hitloc, force * -1, 1);
-
-               //sound on every hit
-               if (random() < 0.5)
-                       sound(self, CH_TRIGGER, SND_ONS_HIT1, VOL_BASE, ATTEN_NORM);
-               else
-                       sound(self, CH_TRIGGER, SND_ONS_HIT2, VOL_BASE, ATTEN_NORM);
-       }
-
-       self.SendFlags |= GSF_STATUS;
-}
-
-void ons_GeneratorThink()
-{SELFPARAM();
-       entity e;
-       self.nextthink = time + GEN_THINKRATE;
-       if (!gameover)
-       {
-        if(!self.isshielded && self.wait < time)
-        {
-            self.wait = time + 5;
-            FOR_EACH_REALPLAYER(e)
-            {
-                               if(SAME_TEAM(e, self))
-                               {
-                                       Send_Notification(NOTIF_ONE, e, MSG_CENTER, CENTER_ONS_NOTSHIELDED_TEAM);
-                    soundto(MSG_ONE, e, CHAN_AUTO, SND(KH_ALARM), VOL_BASE, ATTEN_NONE);    // FIXME: unique sound?
-                }
-                               else
-                                       Send_Notification(NOTIF_ONE, e, MSG_CENTER, APP_TEAM_NUM_4(self.team, CENTER_ONS_NOTSHIELDED_));
-            }
-        }
-       }
-}
-
-void ons_GeneratorReset()
-{SELFPARAM();
-       self.team = self.team_saved;
-       self.lasthealth = self.max_health = self.health = autocvar_g_onslaught_gen_health;
-       self.takedamage = DAMAGE_AIM;
-       self.bot_attack = true;
-       self.iscaptured = true;
-       self.islinked = true;
-       self.isshielded = true;
-       self.event_damage = ons_GeneratorDamage;
-       self.think = ons_GeneratorThink;
-       self.nextthink = time + GEN_THINKRATE;
-
-       Net_LinkEntity(self, false, 0, generator_send);
-
-       self.SendFlags = GSF_SETUP; // just incase
-       self.SendFlags |= GSF_STATUS;
-
-       WaypointSprite_UpdateMaxHealth(self.sprite, self.max_health);
-       WaypointSprite_UpdateHealth(self.sprite, self.health);
-       WaypointSprite_UpdateRule(self.sprite,self.team,SPRITERULE_TEAMPLAY);
-
-       onslaught_updatelinks();
-}
-
-void ons_DelayedGeneratorSetup()
-{SELFPARAM();
-       // bot waypoints
-       waypoint_spawnforitem_force(self, self.origin);
-       self.nearestwaypointtimeout = 0; // activate waypointing again
-       self.bot_basewaypoint = self.nearestwaypoint;
-
-       // captureshield setup
-       ons_CaptureShield_Spawn(self, true);
-
-       onslaught_updatelinks();
-
-       Net_LinkEntity(self, false, 0, generator_send);
-}
-
-
-void onslaught_generator_touch()
-{SELFPARAM();
-       if ( IS_PLAYER(other) )
-       if ( SAME_TEAM(self,other) )
-       if ( self.iscaptured )
-       {
-               Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_ONS_TELEPORT);
-       }
-}
-
-void ons_GeneratorSetup(entity gen) // called when spawning a generator entity on the map as a spawnfunc
-{SELFPARAM();
-       // declarations
-       int teamnumber = gen.team;
-       setself(gen); // for later usage with droptofloor()
-
-       // main setup
-       gen.ons_worldgeneratornext = ons_worldgeneratorlist; // link generator into ons_worldgeneratorlist
-       ons_worldgeneratorlist = gen;
-
-       gen.netname = sprintf("%s generator", Team_ColoredFullName(teamnumber));
-       gen.classname = "onslaught_generator";
-       gen.solid = SOLID_BBOX;
-       gen.team_saved = teamnumber;
-       gen.movetype = MOVETYPE_NONE;
-       gen.lasthealth = gen.max_health = gen.health = autocvar_g_onslaught_gen_health;
-       gen.takedamage = DAMAGE_AIM;
-       gen.bot_attack = true;
-       gen.event_damage = ons_GeneratorDamage;
-       gen.reset = ons_GeneratorReset;
-       gen.think = ons_GeneratorThink;
-       gen.nextthink = time + GEN_THINKRATE;
-       gen.iscaptured = true;
-       gen.islinked = true;
-       gen.isshielded = true;
-       gen.touch = onslaught_generator_touch;
-
-       // appearence
-       // model handled by CSQC
-       setsize(gen, GENERATOR_MIN, GENERATOR_MAX);
-       setorigin(gen, (gen.origin + CPGEN_SPAWN_OFFSET));
-       gen.colormap = 1024 + (teamnumber - 1) * 17;
-
-       // generator placement
-       setself(gen);
-       droptofloor();
-
-       // waypointsprites
-       WaypointSprite_SpawnFixed(WP_Null, self.origin + CPGEN_WAYPOINT_OFFSET, self, sprite, RADARICON_NONE);
-       WaypointSprite_UpdateRule(self.sprite, self.team, SPRITERULE_TEAMPLAY);
-       WaypointSprite_UpdateMaxHealth(self.sprite, self.max_health);
-       WaypointSprite_UpdateHealth(self.sprite, self.health);
-
-       InitializeEntity(gen, ons_DelayedGeneratorSetup, INITPRIO_SETLOCATION);
-}
-
-
-// ===============
-//  Round Handler
-// ===============
-
-int total_generators;
-void Onslaught_count_generators()
-{
-       entity e;
-       total_generators = redowned = blueowned = yellowowned = pinkowned = 0;
-       for(e = ons_worldgeneratorlist; e; e = e.ons_worldgeneratornext)
-       {
-               ++total_generators;
-               redowned += (e.team == NUM_TEAM_1 && e.health > 0);
-               blueowned += (e.team == NUM_TEAM_2 && e.health > 0);
-               yellowowned += (e.team == NUM_TEAM_3 && e.health > 0);
-               pinkowned += (e.team == NUM_TEAM_4 && e.health > 0);
-       }
-}
-
-int Onslaught_GetWinnerTeam()
-{
-       int winner_team = 0;
-       if(redowned > 0)
-               winner_team = NUM_TEAM_1;
-       if(blueowned > 0)
-       {
-               if(winner_team) return 0;
-               winner_team = NUM_TEAM_2;
-       }
-       if(yellowowned > 0)
-       {
-               if(winner_team) return 0;
-               winner_team = NUM_TEAM_3;
-       }
-       if(pinkowned > 0)
-       {
-               if(winner_team) return 0;
-               winner_team = NUM_TEAM_4;
-       }
-       if(winner_team)
-               return winner_team;
-       return -1; // no generators left?
-}
-
-#define ONS_OWNED_GENERATORS() ((redowned > 0) + (blueowned > 0) + (yellowowned > 0) + (pinkowned > 0))
-#define ONS_OWNED_GENERATORS_OK() (ONS_OWNED_GENERATORS() > 1)
-bool Onslaught_CheckWinner()
-{
-       entity e;
-
-       if ((autocvar_timelimit && time > game_starttime + autocvar_timelimit * 60) || (round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0))
-       {
-               ons_stalemate = true;
-
-               if (!wpforenemy_announced)
-               {
-                       Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_OVERTIME_CONTROLPOINT);
-                       sound(world, CH_INFO, SND_ONS_GENERATOR_DECAY, VOL_BASE, ATTEN_NONE);
-
-                       wpforenemy_announced = true;
-               }
-
-               entity tmp_entity; // temporary entity
-               float d;
-               for(tmp_entity = ons_worldgeneratorlist; tmp_entity; tmp_entity = tmp_entity.ons_worldgeneratornext) if(time >= tmp_entity.ons_overtime_damagedelay)
-               {
-                       // tmp_entity.max_health / 300 gives 5 minutes of overtime.
-                       // control points reduce the overtime duration.
-                       d = 1;
-                       for(e = ons_worldcplist; e; e = e.ons_worldcpnext)
-                       {
-                               if(DIFF_TEAM(e, tmp_entity))
-                               if(e.islinked)
-                                       d = d + 1;
-                       }
-
-                       if(autocvar_g_campaign && autocvar__campaign_testrun)
-                               d = d * tmp_entity.max_health;
-                       else
-                               d = d * tmp_entity.max_health / max(30, 60 * autocvar_timelimit_suddendeath);
-
-                       Damage(tmp_entity, tmp_entity, tmp_entity, d, DEATH_HURTTRIGGER.m_id, tmp_entity.origin, '0 0 0');
-
-                       tmp_entity.sprite.SendFlags |= 16;
-
-                       tmp_entity.ons_overtime_damagedelay = time + 1;
-               }
-       }
-       else { wpforenemy_announced = false; ons_stalemate = false; }
-
-       Onslaught_count_generators();
-
-       if(ONS_OWNED_GENERATORS_OK())
-               return 0;
-
-       int winner_team = Onslaught_GetWinnerTeam();
-
-       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_ONS_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);
-       }
-
-       ons_stalemate = false;
-
-       play2all(SND(CTF_CAPTURE(winner_team)));
-
-       round_handler_Init(7, autocvar_g_onslaught_warmup, autocvar_g_onslaught_round_timelimit);
-
-       FOR_EACH_PLAYER(e)
-       {
-               e.ons_roundlost = true;
-               e.player_blocked = true;
-
-               nades_Clear(e);
-       }
-
-       return 1;
-}
-
-bool Onslaught_CheckPlayers()
-{
-       return 1;
-}
-
-void Onslaught_RoundStart()
-{
-       entity tmp_entity;
-       FOR_EACH_PLAYER(tmp_entity) { tmp_entity.player_blocked = false; }
-
-       for(tmp_entity = ons_worldcplist; tmp_entity; tmp_entity = tmp_entity.ons_worldcpnext)
-               tmp_entity.sprite.SendFlags |= 16;
-
-       for(tmp_entity = ons_worldgeneratorlist; tmp_entity; tmp_entity = tmp_entity.ons_worldgeneratornext)
-               tmp_entity.sprite.SendFlags |= 16;
-}
-
-
-// ================
-// Bot player logic
-// ================
-
-// NOTE: LEGACY CODE, needs to be re-written!
-
-void havocbot_goalrating_ons_offenseitems(float ratingscale, vector org, float sradius)
-{SELFPARAM();
-       entity head;
-       float t, c;
-       int i;
-       bool needarmor = false, needweapons = false;
-
-       // Needs armor/health?
-       if(self.health<100)
-               needarmor = true;
-
-       // Needs weapons?
-       c = 0;
-       for(i = WEP_FIRST; i <= WEP_LAST ; ++i)
-       {
-               // Find weapon
-               if(self.weapons & WepSet_FromWeapon(i))
-               if(++c>=4)
-                       break;
-       }
-
-       if(c<4)
-               needweapons = true;
-
-       if(!needweapons && !needarmor)
-               return;
-
-       ons_debug(strcat(self.netname, " needs weapons ", ftos(needweapons) , "\n"));
-       ons_debug(strcat(self.netname, " needs armor ", ftos(needarmor) , "\n"));
-
-       // See what is around
-       head = findchainfloat(bot_pickup, true);
-       while (head)
-       {
-               // gather health and armor only
-               if (head.solid)
-               if ( ((head.health || head.armorvalue) && needarmor) || (head.weapons && needweapons ) )
-               if (vlen(head.origin - org) < sradius)
-               {
-                       t = head.bot_pickupevalfunc(self, head);
-                       if (t > 0)
-                               navigation_routerating(head, t * ratingscale, 500);
-               }
-               head = head.chain;
-       }
-}
-
-void havocbot_role_ons_setrole(entity bot, int role)
-{
-       ons_debug(strcat(bot.netname," switched to "));
-       switch(role)
-       {
-               case HAVOCBOT_ONS_ROLE_DEFENSE:
-                       ons_debug("defense");
-                       bot.havocbot_role = havocbot_role_ons_defense;
-                       bot.havocbot_role_flags = HAVOCBOT_ONS_ROLE_DEFENSE;
-                       bot.havocbot_role_timeout = 0;
-                       break;
-               case HAVOCBOT_ONS_ROLE_ASSISTANT:
-                       ons_debug("assistant");
-                       bot.havocbot_role = havocbot_role_ons_assistant;
-                       bot.havocbot_role_flags = HAVOCBOT_ONS_ROLE_ASSISTANT;
-                       bot.havocbot_role_timeout = 0;
-                       break;
-               case HAVOCBOT_ONS_ROLE_OFFENSE:
-                       ons_debug("offense");
-                       bot.havocbot_role = havocbot_role_ons_offense;
-                       bot.havocbot_role_flags = HAVOCBOT_ONS_ROLE_OFFENSE;
-                       bot.havocbot_role_timeout = 0;
-                       break;
-       }
-       ons_debug("\n");
-}
-
-int havocbot_ons_teamcount(entity bot, int role)
-{SELFPARAM();
-       int c = 0;
-       entity head;
-
-       FOR_EACH_PLAYER(head)
-       if(SAME_TEAM(head, self))
-       if(head.havocbot_role_flags & role)
-               ++c;
-
-       return c;
-}
-
-void havocbot_goalrating_ons_controlpoints_attack(float ratingscale)
-{SELFPARAM();
-       entity cp, cp1, cp2, best, pl, wp;
-       float radius, bestvalue;
-       int c;
-       bool found;
-
-       // Filter control points
-       for(cp2 = ons_worldcplist; cp2; cp2 = cp2.ons_worldcpnext)
-       {
-               cp2.wpcost = c = 0;
-               cp2.wpconsidered = false;
-
-               if(cp2.isshielded)
-                       continue;
-
-               // Ignore owned controlpoints
-               if(!(cp2.isgenneighbor[self.team] || cp2.iscpneighbor[self.team]))
-                       continue;
-
-               // Count team mates interested in this control point
-               // (easier and cleaner than keeping counters per cp and teams)
-               FOR_EACH_PLAYER(pl)
-               if(SAME_TEAM(pl, self))
-               if(pl.havocbot_role_flags & HAVOCBOT_ONS_ROLE_OFFENSE)
-               if(pl.havocbot_ons_target==cp2)
-                       ++c;
-
-               // NOTE: probably decrease the cost of attackable control points
-               cp2.wpcost = c;
-               cp2.wpconsidered = true;
-       }
-
-       // We'll consider only the best case
-       bestvalue = 99999999999;
-       cp = world;
-       for(cp1 = ons_worldcplist; cp1; cp1 = cp1.ons_worldcpnext)
-       {
-               if (!cp1.wpconsidered)
-                       continue;
-
-               if(cp1.wpcost<bestvalue)
-               {
-                       bestvalue = cp1.wpcost;
-                       cp = cp1;
-                       self.havocbot_ons_target = cp1;
-               }
-       }
-
-       if (!cp)
-               return;
-
-       ons_debug(strcat(self.netname, " chose cp ranked ", ftos(bestvalue), "\n"));
-
-       if(cp.goalentity)
-       {
-               // Should be attacked
-               // Rate waypoints near it
-               found = false;
-               best = world;
-               bestvalue = 99999999999;
-               for(radius=0; radius<1000 && !found; radius+=500)
-               {
-                       for(wp=findradius(cp.origin,radius); wp; wp=wp.chain)
-                       {
-                               if(!(wp.wpflags & WAYPOINTFLAG_GENERATED))
-                               if(wp.classname=="waypoint")
-                               if(checkpvs(wp.origin,cp))
-                               {
-                                       found = true;
-                                       if(wp.cnt<bestvalue)
-                                       {
-                                               best = wp;
-                                               bestvalue = wp.cnt;
-                                       }
-                               }
-                       }
-               }
-
-               if(best)
-               {
-                       navigation_routerating(best, ratingscale, 10000);
-                       best.cnt += 1;
-
-                       self.havocbot_attack_time = 0;
-                       if(checkpvs(self.view_ofs,cp))
-                       if(checkpvs(self.view_ofs,best))
-                               self.havocbot_attack_time = time + 2;
-               }
-               else
-               {
-                       navigation_routerating(cp, ratingscale, 10000);
-               }
-               ons_debug(strcat(self.netname, " found an attackable controlpoint at ", vtos(cp.origin) ,"\n"));
-       }
-       else
-       {
-               // Should be touched
-               ons_debug(strcat(self.netname, " found a touchable controlpoint at ", vtos(cp.origin) ,"\n"));
-               found = false;
-
-               // Look for auto generated waypoint
-               if (!bot_waypoints_for_items)
-               for (wp = findradius(cp.origin,100); wp; wp = wp.chain)
-               {
-                       if(wp.classname=="waypoint")
-                       {
-                               navigation_routerating(wp, ratingscale, 10000);
-                               found = true;
-                       }
-               }
-
-               // Nothing found, rate the controlpoint itself
-               if (!found)
-                       navigation_routerating(cp, ratingscale, 10000);
-       }
-}
-
-bool havocbot_goalrating_ons_generator_attack(float ratingscale)
-{SELFPARAM();
-       entity g, wp, bestwp;
-       bool found;
-       int best;
-
-       for(g = ons_worldgeneratorlist; g; g = g.ons_worldgeneratornext)
-       {
-               if(SAME_TEAM(g, self) || g.isshielded)
-                       continue;
-
-               // Should be attacked
-               // Rate waypoints near it
-               found = false;
-               bestwp = world;
-               best = 99999999999;
-
-               for(wp=findradius(g.origin,400); wp; wp=wp.chain)
-               {
-                       if(wp.classname=="waypoint")
-                       if(checkpvs(wp.origin,g))
-                       {
-                               found = true;
-                               if(wp.cnt<best)
-                               {
-                                       bestwp = wp;
-                                       best = wp.cnt;
-                               }
-                       }
-               }
-
-               if(bestwp)
-               {
-                       ons_debug("waypoints found around generator\n");
-                       navigation_routerating(bestwp, ratingscale, 10000);
-                       bestwp.cnt += 1;
-
-                       self.havocbot_attack_time = 0;
-                       if(checkpvs(self.view_ofs,g))
-                       if(checkpvs(self.view_ofs,bestwp))
-                               self.havocbot_attack_time = time + 5;
-
-                       return true;
-               }
-               else
-               {
-                       ons_debug("generator found without waypoints around\n");
-                       // if there aren't waypoints near the generator go straight to it
-                       navigation_routerating(g, ratingscale, 10000);
-                       self.havocbot_attack_time = 0;
-                       return true;
-               }
-       }
-       return false;
-}
-
-void havocbot_role_ons_offense()
-{SELFPARAM();
-       if(self.deadflag != DEAD_NO)
-       {
-               self.havocbot_attack_time = 0;
-               havocbot_ons_reset_role(self);
-               return;
-       }
-
-       // Set the role timeout if necessary
-       if (!self.havocbot_role_timeout)
-               self.havocbot_role_timeout = time + 120;
-
-       if (time > self.havocbot_role_timeout)
-       {
-               havocbot_ons_reset_role(self);
-               return;
-       }
-
-       if(self.havocbot_attack_time>time)
-               return;
-
-       if (self.bot_strategytime < time)
-       {
-               navigation_goalrating_start();
-               havocbot_goalrating_enemyplayers(20000, self.origin, 650);
-               if(!havocbot_goalrating_ons_generator_attack(20000))
-                       havocbot_goalrating_ons_controlpoints_attack(20000);
-               havocbot_goalrating_ons_offenseitems(10000, self.origin, 10000);
-               navigation_goalrating_end();
-
-               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
-       }
-}
-
-void havocbot_role_ons_assistant()
-{SELFPARAM();
-       havocbot_ons_reset_role(self);
-}
-
-void havocbot_role_ons_defense()
-{SELFPARAM();
-       havocbot_ons_reset_role(self);
-}
-
-void havocbot_ons_reset_role(entity bot)
-{SELFPARAM();
-       entity head;
-       int c = 0;
-
-       if(self.deadflag != DEAD_NO)
-               return;
-
-       bot.havocbot_ons_target = world;
-
-       // TODO: Defend control points or generator if necessary
-
-       // if there is only me on the team switch to offense
-       c = 0;
-       FOR_EACH_PLAYER(head)
-       if(SAME_TEAM(head, self))
-               ++c;
-
-       if(c==1)
-       {
-               havocbot_role_ons_setrole(bot, HAVOCBOT_ONS_ROLE_OFFENSE);
-               return;
-       }
-
-       havocbot_role_ons_setrole(bot, HAVOCBOT_ONS_ROLE_OFFENSE);
-}
-
-
-/*
- * Find control point or generator owned by the same team self which is nearest to pos
- * if max_dist is positive, only control points within this range will be considered
- */
-entity ons_Nearest_ControlPoint(vector pos, float max_dist)
-{SELFPARAM();
-       entity tmp_entity, closest_target = world;
-       tmp_entity = findchain(classname, "onslaught_controlpoint");
-       while(tmp_entity)
-       {
-               if(SAME_TEAM(tmp_entity, self))
-               if(tmp_entity.iscaptured)
-               if(max_dist <= 0 || vlen(tmp_entity.origin - pos) <= max_dist)
-               if(vlen(tmp_entity.origin - pos) <= vlen(closest_target.origin - pos) || closest_target == world)
-                       closest_target = tmp_entity;
-               tmp_entity = tmp_entity.chain;
-       }
-       tmp_entity = findchain(classname, "onslaught_generator");
-       while(tmp_entity)
-       {
-               if(SAME_TEAM(tmp_entity, self))
-               if(max_dist <= 0 || vlen(tmp_entity.origin - pos) < max_dist)
-               if(vlen(tmp_entity.origin - pos) <= vlen(closest_target.origin - pos) || closest_target == world)
-                       closest_target = tmp_entity;
-               tmp_entity = tmp_entity.chain;
-       }
-
-       return closest_target;
-}
-
-/*
- * Find control point or generator owned by the same team self which is nearest to pos
- * if max_dist is positive, only control points within this range will be considered
- * This function only check distances on the XY plane, disregarding Z
- */
-entity ons_Nearest_ControlPoint_2D(vector pos, float max_dist)
-{SELFPARAM();
-       entity tmp_entity, closest_target = world;
-       vector delta;
-       float smallest_distance = 0, distance;
-
-       tmp_entity = findchain(classname, "onslaught_controlpoint");
-       while(tmp_entity)
-       {
-               delta = tmp_entity.origin - pos;
-               delta_z = 0;
-               distance = vlen(delta);
-
-               if(SAME_TEAM(tmp_entity, self))
-               if(tmp_entity.iscaptured)
-               if(max_dist <= 0 || distance <= max_dist)
-               if(closest_target == world || distance <= smallest_distance )
-               {
-                       closest_target = tmp_entity;
-                       smallest_distance = distance;
-               }
-
-               tmp_entity = tmp_entity.chain;
-       }
-       tmp_entity = findchain(classname, "onslaught_generator");
-       while(tmp_entity)
-       {
-               delta = tmp_entity.origin - pos;
-               delta_z = 0;
-               distance = vlen(delta);
-
-               if(SAME_TEAM(tmp_entity, self))
-               if(max_dist <= 0 || distance <= max_dist)
-               if(closest_target == world || distance <= smallest_distance )
-               {
-                       closest_target = tmp_entity;
-                       smallest_distance = distance;
-               }
-
-               tmp_entity = tmp_entity.chain;
-       }
-
-       return closest_target;
-}
-/**
- * find the number of control points and generators in the same team as self
- */
-int ons_Count_SelfControlPoints()
-{SELFPARAM();
-       entity tmp_entity;
-       tmp_entity = findchain(classname, "onslaught_controlpoint");
-       int n = 0;
-       while(tmp_entity)
-       {
-               if(SAME_TEAM(tmp_entity, self))
-               if(tmp_entity.iscaptured)
-                       n++;
-               tmp_entity = tmp_entity.chain;
-       }
-       tmp_entity = findchain(classname, "onslaught_generator");
-       while(tmp_entity)
-       {
-               if(SAME_TEAM(tmp_entity, self))
-                       n++;
-               tmp_entity = tmp_entity.chain;
-       }
-       return n;
-}
-
-/**
- * Teleport player to a random position near tele_target
- * if tele_effects is true, teleport sound+particles are created
- * return false on failure
- */
-bool ons_Teleport(entity player, entity tele_target, float range, bool tele_effects)
-{
-       if ( !tele_target )
-               return false;
-
-       int i;
-       vector loc;
-       float theta;
-       // narrow the range for each iteration to increase chances that a spawnpoint
-       // can be found even if there's little room around the control point
-       float iteration_scale = 1;
-       for(i = 0; i < 16; ++i)
-       {
-               iteration_scale -= i / 16;
-               theta = random() * 2 * M_PI;
-               loc_y = sin(theta);
-               loc_x = cos(theta);
-               loc_z = 0;
-               loc *= random() * range * iteration_scale;
-
-               loc += tele_target.origin + '0 0 128' * iteration_scale;
-
-               tracebox(loc, PL_MIN, PL_MAX, loc, MOVE_NORMAL, player);
-               if(trace_fraction == 1.0 && !trace_startsolid)
-               {
-                       traceline(tele_target.origin, loc, MOVE_NOMONSTERS, tele_target); // double check to make sure we're not spawning outside the world
-                       if(trace_fraction == 1.0 && !trace_startsolid)
-                       {
-                               if ( tele_effects )
-                               {
-                                       Send_Effect(EFFECT_TELEPORT, player.origin, '0 0 0', 1);
-                                       sound (player, CH_TRIGGER, SND_TELEPORT, VOL_BASE, ATTEN_NORM);
-                               }
-                               setorigin(player, loc);
-                               player.angles = '0 1 0' * ( theta * RAD2DEG + 180 );
-                               makevectors(player.angles);
-                               player.fixangle = true;
-                               player.teleport_antispam = time + autocvar_g_onslaught_teleport_wait;
-
-                               if ( tele_effects )
-                                       Send_Effect(EFFECT_TELEPORT, player.origin + v_forward * 32, '0 0 0', 1);
-                               return true;
-                       }
-               }
-       }
-
-       return false;
-}
-
-// ==============
-// Hook Functions
-// ==============
-
-MUTATOR_HOOKFUNCTION(ons_ResetMap)
-{SELFPARAM();
-       entity e;
-       FOR_EACH_PLAYER(e)
-       {
-               e.ons_roundlost = false;
-               e.ons_deathloc = '0 0 0';
-               WITH(entity, self, e, PutClientInServer());
-       }
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ons_RemovePlayer)
-{SELFPARAM();
-       self.ons_deathloc = '0 0 0';
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ons_PlayerSpawn)
-{SELFPARAM();
-       if(!round_handler_IsRoundStarted())
-       {
-               self.player_blocked = true;
-               return false;
-       }
-
-       entity l;
-       for(l = ons_worldgeneratorlist; l; l = l.ons_worldgeneratornext)
-       {
-               l.sprite.SendFlags |= 16;
-       }
-       for(l = ons_worldcplist; l; l = l.ons_worldcpnext)
-       {
-               l.sprite.SendFlags |= 16;
-       }
-
-       if(ons_stalemate) { Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_OVERTIME_CONTROLPOINT); }
-
-       if ( autocvar_g_onslaught_spawn_choose )
-       if ( self.ons_spawn_by )
-       if ( ons_Teleport(self,self.ons_spawn_by,autocvar_g_onslaught_teleport_radius,false) )
-       {
-               self.ons_spawn_by = world;
-               return false;
-       }
-
-       if(autocvar_g_onslaught_spawn_at_controlpoints)
-       if(random() <= autocvar_g_onslaught_spawn_at_controlpoints_chance)
-       {
-               float random_target = autocvar_g_onslaught_spawn_at_controlpoints_random;
-               entity tmp_entity, closest_target = world;
-               vector spawn_loc = self.ons_deathloc;
-
-               // new joining player or round reset, don't bother checking
-               if(spawn_loc == '0 0 0') { return false; }
-
-               if(random_target) { RandomSelection_Init(); }
-
-               for(tmp_entity = ons_worldcplist; tmp_entity; tmp_entity = tmp_entity.ons_worldcpnext)
-               {
-                       if(SAME_TEAM(tmp_entity, self))
-                       if(random_target)
-                               RandomSelection_Add(tmp_entity, 0, string_null, 1, 1);
-                       else if(vlen(tmp_entity.origin - spawn_loc) <= vlen(closest_target.origin - spawn_loc) || closest_target == world)
-                               closest_target = tmp_entity;
-               }
-
-               if(random_target) { closest_target = RandomSelection_chosen_ent; }
-
-               if(closest_target)
-               {
-                       float i;
-                       vector loc;
-                       float iteration_scale = 1;
-                       for(i = 0; i < 10; ++i)
-                       {
-                               iteration_scale -= i / 10;
-                               loc = closest_target.origin + '0 0 96' * iteration_scale;
-                               loc += ('0 1 0' * random()) * 128 * iteration_scale;
-                               tracebox(loc, PL_MIN, PL_MAX, loc, MOVE_NORMAL, self);
-                               if(trace_fraction == 1.0 && !trace_startsolid)
-                               {
-                                       traceline(closest_target.origin, loc, MOVE_NOMONSTERS, closest_target); // double check to make sure we're not spawning outside the world
-                                       if(trace_fraction == 1.0 && !trace_startsolid)
-                                       {
-                                               setorigin(self, loc);
-                                               self.angles = normalize(loc - closest_target.origin) * RAD2DEG;
-                                               return false;
-                                       }
-                               }
-                       }
-               }
-       }
-
-       if(autocvar_g_onslaught_spawn_at_generator)
-       if(random() <= autocvar_g_onslaught_spawn_at_generator_chance)
-       {
-               float random_target = autocvar_g_onslaught_spawn_at_generator_random;
-               entity tmp_entity, closest_target = world;
-               vector spawn_loc = self.ons_deathloc;
-
-               // new joining player or round reset, don't bother checking
-               if(spawn_loc == '0 0 0') { return false; }
-
-               if(random_target) { RandomSelection_Init(); }
-
-               for(tmp_entity = ons_worldgeneratorlist; tmp_entity; tmp_entity = tmp_entity.ons_worldgeneratornext)
-               {
-                       if(random_target)
-                               RandomSelection_Add(tmp_entity, 0, string_null, 1, 1);
-                       else
-                       {
-                               if(SAME_TEAM(tmp_entity, self))
-                               if(vlen(tmp_entity.origin - spawn_loc) <= vlen(closest_target.origin - spawn_loc) || closest_target == world)
-                                       closest_target = tmp_entity;
-                       }
-               }
-
-               if(random_target) { closest_target = RandomSelection_chosen_ent; }
-
-               if(closest_target)
-               {
-                       float i;
-                       vector loc;
-                       float iteration_scale = 1;
-                       for(i = 0; i < 10; ++i)
-                       {
-                               iteration_scale -= i / 10;
-                               loc = closest_target.origin + '0 0 128' * iteration_scale;
-                               loc += ('0 1 0' * random()) * 256 * iteration_scale;
-                               tracebox(loc, PL_MIN, PL_MAX, loc, MOVE_NORMAL, self);
-                               if(trace_fraction == 1.0 && !trace_startsolid)
-                               {
-                                       traceline(closest_target.origin, loc, MOVE_NOMONSTERS, closest_target); // double check to make sure we're not spawning outside the world
-                                       if(trace_fraction == 1.0 && !trace_startsolid)
-                                       {
-                                               setorigin(self, loc);
-                                               self.angles = normalize(loc - closest_target.origin) * RAD2DEG;
-                                               return false;
-                                       }
-                               }
-                       }
-               }
-       }
-
-    return false;
-}
-
-MUTATOR_HOOKFUNCTION(ons_PlayerDies)
-{SELFPARAM();
-       frag_target.ons_deathloc = frag_target.origin;
-       entity l;
-       for(l = ons_worldgeneratorlist; l; l = l.ons_worldgeneratornext)
-       {
-               l.sprite.SendFlags |= 16;
-       }
-       for(l = ons_worldcplist; l; l = l.ons_worldcpnext)
-       {
-               l.sprite.SendFlags |= 16;
-       }
-
-       if ( autocvar_g_onslaught_spawn_choose )
-       if ( ons_Count_SelfControlPoints() > 1 )
-               stuffcmd(self, "qc_cmd_cl hud clickradar\n");
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ons_MonsterThink)
-{SELFPARAM();
-       entity e = find(world, targetname, self.target);
-       if (e != world)
-               self.team = e.team;
-
-       return false;
-}
-
-void ons_MonsterSpawn_Delayed()
-{SELFPARAM();
-       entity e, own = self.owner;
-
-       if(!own) { remove(self); return; }
-
-       if(own.targetname)
-       {
-               e = find(world, target, own.targetname);
-               if(e != world)
-               {
-                       own.team = e.team;
-
-                       activator = e;
-                       own.use();
-               }
-       }
-
-       remove(self);
-}
-
-MUTATOR_HOOKFUNCTION(ons_MonsterSpawn)
-{SELFPARAM();
-       entity e = spawn();
-       e.owner = self;
-       InitializeEntity(e, ons_MonsterSpawn_Delayed, INITPRIO_FINDTARGET);
-
-       return false;
-}
-
-void ons_TurretSpawn_Delayed()
-{SELFPARAM();
-       entity e, own = self.owner;
-
-       if(!own) { remove(self); return; }
-
-       if(own.targetname)
-       {
-               e = find(world, target, own.targetname);
-               if(e != world)
-               {
-                       own.team = e.team;
-                       own.active = ACTIVE_NOT;
-
-                       activator = e;
-                       own.use();
-               }
-       }
-
-       remove(self);
-}
-
-MUTATOR_HOOKFUNCTION(ons_TurretSpawn)
-{SELFPARAM();
-       entity e = spawn();
-       e.owner = self;
-       InitializeEntity(e, ons_TurretSpawn_Delayed, INITPRIO_FINDTARGET);
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ons_BotRoles)
-{SELFPARAM();
-       havocbot_ons_reset_role(self);
-       return true;
-}
-
-MUTATOR_HOOKFUNCTION(ons_GetTeamCount)
-{
-       // onslaught is special
-       entity tmp_entity;
-       for(tmp_entity = ons_worldgeneratorlist; tmp_entity; tmp_entity = tmp_entity.ons_worldgeneratornext)
-       {
-               switch(tmp_entity.team)
-               {
-                       case NUM_TEAM_1: c1 = 0; break;
-                       case NUM_TEAM_2: c2 = 0; break;
-                       case NUM_TEAM_3: c3 = 0; break;
-                       case NUM_TEAM_4: c4 = 0; break;
-               }
-       }
-
-       return true;
-}
-
-MUTATOR_HOOKFUNCTION(ons_SpectateCopy)
-{SELFPARAM();
-       self.ons_roundlost = other.ons_roundlost; // make spectators see it too
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ons_SV_ParseClientCommand)
-{SELFPARAM();
-       if(MUTATOR_RETURNVALUE) // command was already handled?
-               return false;
-
-       if ( cmd_name == "ons_spawn" )
-       {
-               vector pos = self.origin;
-               if(cmd_argc > 1)
-                       pos_x = stof(argv(1));
-               if(cmd_argc > 2)
-                       pos_y = stof(argv(2));
-               if(cmd_argc > 3)
-                       pos_z = stof(argv(3));
-
-               if ( IS_PLAYER(self) )
-               {
-                       if ( !self.frozen )
-                       {
-                               entity source_point = ons_Nearest_ControlPoint(self.origin, autocvar_g_onslaught_teleport_radius);
-
-                               if ( !source_point && self.health > 0 )
-                               {
-                                       sprint(self, "\nYou need to be next to a control point\n");
-                                       return 1;
-                               }
-
-
-                               entity closest_target = ons_Nearest_ControlPoint_2D(pos, autocvar_g_onslaught_click_radius);
-
-                               if ( closest_target == world )
-                               {
-                                       sprint(self, "\nNo control point found\n");
-                                       return 1;
-                               }
-
-                               if ( self.health <= 0 )
-                               {
-                                       self.ons_spawn_by = closest_target;
-                                       self.respawn_flags = self.respawn_flags | RESPAWN_FORCE;
-                               }
-                               else
-                               {
-                                       if ( source_point == closest_target )
-                                       {
-                                               sprint(self, "\nTeleporting to the same point\n");
-                                               return 1;
-                                       }
-
-                                       if ( !ons_Teleport(self,closest_target,autocvar_g_onslaught_teleport_radius,true) )
-                                               sprint(self, "\nUnable to teleport there\n");
-                               }
-
-                               return 1;
-                       }
-
-                       sprint(self, "\nNo teleportation for you\n");
-               }
-
-               return 1;
-       }
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(ons_PlayerUseKey)
-{SELFPARAM();
-       if(MUTATOR_RETURNVALUE || gameover) { return false; }
-
-       if((time > self.teleport_antispam) && (self.deadflag == DEAD_NO) && !self.vehicle)
-       {
-               entity source_point = ons_Nearest_ControlPoint(self.origin, autocvar_g_onslaught_teleport_radius);
-               if ( source_point )
-               {
-                       stuffcmd(self, "qc_cmd_cl hud clickradar\n");
-                       return true;
-               }
-       }
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ons_PlayHitsound)
-{
-       return (frag_victim.classname == "onslaught_generator" && !frag_victim.isshielded)
-               || (frag_victim.classname == "onslaught_controlpoint_icon" && !frag_victim.owner.isshielded);
-}
-
-// ==========
-// Spawnfuncs
-// ==========
-
-/*QUAKED spawnfunc_onslaught_link (0 .5 .8) (-16 -16 -16) (16 16 16)
-  Link between control points.
-
-  This entity targets two different spawnfunc_onslaught_controlpoint or spawnfunc_onslaught_generator entities, and suppresses shielding on both if they are owned by different teams.
-
-keys:
-"target" - first control point.
-"target2" - second control point.
- */
-spawnfunc(onslaught_link)
-{
-       if(!g_onslaught) { remove(self); return; }
-
-       if (self.target == "" || self.target2 == "")
-               objerror("target and target2 must be set\n");
-
-       self.ons_worldlinknext = ons_worldlinklist; // link into ons_worldlinklist
-       ons_worldlinklist = self;
-
-       InitializeEntity(self, ons_DelayedLinkSetup, INITPRIO_FINDTARGET);
-       Net_LinkEntity(self, false, 0, ons_Link_Send);
-}
-
-/*QUAKED spawnfunc_onslaught_controlpoint (0 .5 .8) (-32 -32 0) (32 32 128)
-  Control point. Be sure to give this enough clearance so that the shootable part has room to exist
-
-  This should link to an spawnfunc_onslaught_controlpoint entity or spawnfunc_onslaught_generator entity.
-
-keys:
-"targetname" - name that spawnfunc_onslaught_link entities will use to target this.
-"target" - target any entities that are tied to this control point, such as vehicles and buildable structure entities.
-"message" - name of this control point (should reflect the location in the map, such as "center bridge", "north tower", etc)
- */
-
-spawnfunc(onslaught_controlpoint)
-{
-       if(!g_onslaught) { remove(self); return; }
-
-       ons_ControlPoint_Setup(self);
-}
-
-/*QUAKED spawnfunc_onslaught_generator (0 .5 .8) (-32 -32 -24) (32 32 64)
-  Base generator.
-
-  spawnfunc_onslaught_link entities can target this.
-
-keys:
-"team" - team that owns this generator (5 = red, 14 = blue, etc), MUST BE SET.
-"targetname" - name that spawnfunc_onslaught_link entities will use to target this.
- */
-spawnfunc(onslaught_generator)
-{
-       if(!g_onslaught) { remove(self); return; }
-       if(!self.team) { objerror("team must be set"); }
-
-       ons_GeneratorSetup(self);
-}
-
-// scoreboard setup
-void ons_ScoreRules()
-{
-       CheckAllowedTeams(world);
-       ScoreRules_basics(((c4>=0) ? 4 : (c3>=0) ? 3 : 2), SFL_SORT_PRIO_PRIMARY, 0, true);
-       ScoreInfo_SetLabel_TeamScore  (ST_ONS_CAPS,     "destroyed", SFL_SORT_PRIO_PRIMARY);
-       ScoreInfo_SetLabel_PlayerScore(SP_ONS_CAPS,     "caps",      SFL_SORT_PRIO_SECONDARY);
-       ScoreInfo_SetLabel_PlayerScore(SP_ONS_TAKES,    "takes",     0);
-       ScoreRules_basics_end();
-}
-
-void ons_DelayedInit() // Do this check with a delay so we can wait for teams to be set up
-{
-       ons_ScoreRules();
-
-       round_handler_Spawn(Onslaught_CheckPlayers, Onslaught_CheckWinner, Onslaught_RoundStart);
-       round_handler_Init(5, autocvar_g_onslaught_warmup, autocvar_g_onslaught_round_timelimit);
-}
-
-void ons_Initialize()
-{
-       ons_captureshield_force = autocvar_g_onslaught_shield_force;
-
-       addstat(STAT_ROUNDLOST, AS_INT, ons_roundlost);
-
-       InitializeEntity(world, ons_DelayedInit, INITPRIO_GAMETYPE);
-}
-
-MUTATOR_DEFINITION(gamemode_onslaught)
-{
-       MUTATOR_HOOK(reset_map_global, ons_ResetMap, CBC_ORDER_ANY);
-       MUTATOR_HOOK(MakePlayerObserver, ons_RemovePlayer, CBC_ORDER_ANY);
-       MUTATOR_HOOK(ClientDisconnect, ons_RemovePlayer, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerSpawn, ons_PlayerSpawn, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerDies, ons_PlayerDies, CBC_ORDER_ANY);
-       MUTATOR_HOOK(MonsterMove, ons_MonsterThink, CBC_ORDER_ANY);
-       MUTATOR_HOOK(MonsterSpawn, ons_MonsterSpawn, CBC_ORDER_ANY);
-       MUTATOR_HOOK(TurretSpawn, ons_TurretSpawn, CBC_ORDER_ANY);
-       MUTATOR_HOOK(HavocBot_ChooseRole, ons_BotRoles, CBC_ORDER_ANY);
-       MUTATOR_HOOK(GetTeamCount, ons_GetTeamCount, CBC_ORDER_ANY);
-       MUTATOR_HOOK(SpectateCopy, ons_SpectateCopy, CBC_ORDER_ANY);
-       MUTATOR_HOOK(SV_ParseClientCommand, ons_SV_ParseClientCommand, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerUseKey, ons_PlayerUseKey, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayHitsound, ons_PlayHitsound, 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.");
-               ons_Initialize();
-       }
-
-       MUTATOR_ONROLLBACK_OR_REMOVE
-       {
-               // we actually cannot roll back ons_Initialize here
-               // BUT: we don't need to! If this gets called, adding always
-               // succeeds.
-       }
-
-       MUTATOR_ONREMOVE
-       {
-               LOG_INFO("This is a game type and it cannot be removed at runtime.");
-               return -1;
-       }
-
-       return false;
-}
diff --git a/qcsrc/server/mutators/gamemode_onslaught.qh b/qcsrc/server/mutators/gamemode_onslaught.qh
deleted file mode 100644 (file)
index c6c3d18..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-// these are needed since mutators are compiled last
-
-#ifdef SVQC
-
-.entity ons_toucher; // player who touched the control point
-
-// control point / generator constants
-const float ONS_CP_THINKRATE = 0.2;
-const float GEN_THINKRATE = 1;
-#define CPGEN_SPAWN_OFFSET ('0 0 1' * (PL_MAX_CONST.z - 13))
-const vector CPGEN_WAYPOINT_OFFSET = ('0 0 128');
-const vector CPICON_OFFSET = ('0 0 96');
-
-// list of generators on the map
-entity ons_worldgeneratorlist;
-.entity ons_worldgeneratornext;
-.entity ons_stalegeneratornext;
-
-// list of control points on the map
-entity ons_worldcplist;
-.entity ons_worldcpnext;
-.entity ons_stalecpnext;
-
-// list of links on the map
-entity ons_worldlinklist;
-.entity ons_worldlinknext;
-.entity ons_stalelinknext;
-
-// definitions
-.entity sprite;
-.string target2;
-.int iscaptured;
-.int islinked;
-.int isshielded;
-.float lasthealth;
-.int lastteam;
-.int lastshielded;
-.int lastcaptured;
-
-.bool waslinked;
-
-bool ons_stalemate;
-
-.float teleport_antispam;
-
-.bool ons_roundlost;
-
-// waypoint sprites
-.entity bot_basewaypoint; // generator waypointsprite
-
-.bool isgenneighbor[17];
-.bool iscpneighbor[17];
-float ons_notification_time[17];
-
-.float ons_overtime_damagedelay;
-
-.vector ons_deathloc;
-
-.entity ons_spawn_by;
-
-// declarations for functions used outside gamemode_onslaught.qc
-void ons_Generator_UpdateSprite(entity e);
-void ons_ControlPoint_UpdateSprite(entity e);
-bool ons_ControlPoint_Attackable(entity cp, int teamnumber);
-
-// CaptureShield: Prevent capturing or destroying control point/generator if it is not available yet
-float ons_captureshield_force; // push force of the shield
-
-// bot player logic
-const int HAVOCBOT_ONS_ROLE_NONE               = 0;
-const int HAVOCBOT_ONS_ROLE_DEFENSE    = 2;
-const int HAVOCBOT_ONS_ROLE_ASSISTANT  = 4;
-const int HAVOCBOT_ONS_ROLE_OFFENSE    = 8;
-
-.entity havocbot_ons_target;
-
-.int havocbot_role_flags;
-.float havocbot_attack_time;
-
-void havocbot_role_ons_defense();
-void havocbot_role_ons_offense();
-void havocbot_role_ons_assistant();
-
-void havocbot_ons_reset_role(entity bot);
-void havocbot_goalrating_items(float ratingscale, vector org, float sradius);
-void havocbot_goalrating_enemyplayers(float ratingscale, vector org, float sradius);
-
-// score rule declarations
-const int ST_ONS_CAPS = 1;
-const int SP_ONS_CAPS = 4;
-const int SP_ONS_TAKES = 6;
-
-#endif
diff --git a/qcsrc/server/mutators/gamemode_race.qc b/qcsrc/server/mutators/gamemode_race.qc
deleted file mode 100644 (file)
index 2714569..0000000
+++ /dev/null
@@ -1,328 +0,0 @@
-#include "gamemode_race.qh"
-
-#include "gamemode.qh"
-
-#include "../race.qh"
-
-// legacy bot roles
-.float race_checkpoint;
-void havocbot_role_race()
-{SELFPARAM();
-       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)
-{SELFPARAM();
-       // 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)
-{SELFPARAM();
-       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)
-{SELFPARAM();
-       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)
-{SELFPARAM();
-       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)
-{SELFPARAM();
-       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)
-{SELFPARAM();
-       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)
-{SELFPARAM();
-       self.respawn_flags |= RESPAWN_FORCE;
-       race_AbandonRaceCheck(self);
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(race_BotRoles)
-{SELFPARAM();
-       self.havocbot_role = havocbot_role_race;
-       return true;
-}
-
-MUTATOR_HOOKFUNCTION(race_PlayerPostThink)
-{SELFPARAM();
-       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;
-}
-
-MUTATOR_HOOKFUNCTION(race_CountFrags)
-{
-       // announce remaining frags if not in qualifying mode
-       if(!g_race_qualifying)
-               return true;
-
-       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_HOOK(Scores_CountFragsRemaining, race_CountFrags, 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
-       {
-               LOG_INFO("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
deleted file mode 100644 (file)
index 0e20b9b..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef GAMEMODE_RACE_H
-#define GAMEMODE_RACE_H
-
-float g_race_qualifying;
-float race_teams;
-
-// scores
-const float ST_RACE_LAPS = 1;
-const float SP_RACE_LAPS = 4;
-const float SP_RACE_TIME = 5;
-const float SP_RACE_FASTEST = 6;
-#endif
diff --git a/qcsrc/server/mutators/gamemode_tdm.qc b/qcsrc/server/mutators/gamemode_tdm.qc
deleted file mode 100644 (file)
index 2ff647d..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-
-#include "gamemode.qh"
-
-/*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)... */
-spawnfunc(tdm_team)
-{
-       if(!g_tdm || !self.cnt) { 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 this = new(tdm_team);
-       this.netname = teamname;
-       this.cnt = teamcolor;
-       this.spawnfunc_checked = true;
-       WITH(entity, self, this, spawnfunc_tdm_team(this));
-}
-
-void tdm_DelayedInit()
-{
-       // if no teams are found, spawn defaults
-       if(find(world, classname, "tdm_team") == world)
-       {
-               LOG_INFO("No ""tdm_team"" entities found on this map, creating them anyway.\n");
-
-               int 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_HOOKFUNCTION(tdm_CountFrags)
-{
-       // announce remaining frags
-       return true;
-}
-
-MUTATOR_DEFINITION(gamemode_tdm)
-{
-       MUTATOR_HOOK(GetTeamCount, tdm_GetTeamCount, CBC_ORDER_ANY);
-       MUTATOR_HOOK(Scores_CountFragsRemaining, tdm_CountFrags, 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
-       {
-               LOG_INFO("This is a game type and it cannot be removed at runtime.");
-               return -1;
-       }
-
-       return 0;
-}
index e8054bc0442bc3efa2ae451298c9bacaaa23c8f4..f883b84b4baa0a93cfb699f9e1b3a20396b6659b 100644 (file)
@@ -2,7 +2,6 @@
 #define MUTATOR_H
 
 #include "../../common/mutators/base.qh"
-#include "mutator_nades.qh"
 
 #include "../cl_client.qh"
 #include "../cl_player.qh"
@@ -19,7 +18,6 @@
 
 #include "../bot/havocbot/havocbot.qh"
 #include "../bot/havocbot/roles.qh"
-#include "../bot/havocbot/role_keyhunt.qh"
 
 #include "../command/vote.qh"
 #include "../command/common.qh"
diff --git a/qcsrc/server/mutators/mutator/gamemode_assault.qc b/qcsrc/server/mutators/mutator/gamemode_assault.qc
new file mode 100644 (file)
index 0000000..fdc2662
--- /dev/null
@@ -0,0 +1,674 @@
+#ifndef GAMEMODE_ASSAULT_H
+#define GAMEMODE_ASSAULT_H
+
+void assault_ScoreRules();
+
+REGISTER_MUTATOR(as, false)
+{
+       ActivateTeamplay();
+       have_team_spawns = -1; // request team spawns
+
+       MUTATOR_ONADD
+       {
+               if (time > 1) // game loads at time 1
+                       error("This is a game type and it cannot be added at runtime.");
+               assault_ScoreRules();
+       }
+
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               // we actually cannot roll back assault_Initialize here
+               // BUT: we don't need to! If this gets called, adding always
+               // succeeds.
+       }
+
+       MUTATOR_ONREMOVE
+       {
+               LOG_INFO("This is a game type and it cannot be removed at runtime.");
+               return -1;
+       }
+
+       return 0;
+}
+
+// sprites
+.entity assault_decreaser;
+.entity assault_sprite;
+
+// legacy bot defs
+const int HAVOCBOT_AST_ROLE_NONE = 0;
+const int HAVOCBOT_AST_ROLE_DEFENSE = 2;
+const int HAVOCBOT_AST_ROLE_OFFENSE = 4;
+
+.int havocbot_role_flags;
+.float havocbot_attack_time;
+
+.void() havocbot_role;
+.void() havocbot_previous_role;
+
+void() havocbot_role_ast_defense;
+void() havocbot_role_ast_offense;
+.entity havocbot_ast_target;
+
+void(entity bot) havocbot_ast_reset_role;
+
+void(float ratingscale, vector org, float sradius) havocbot_goalrating_items;
+void(float ratingscale, vector org, float sradius) havocbot_goalrating_enemyplayers;
+
+// scoreboard stuff
+const float ST_ASSAULT_OBJECTIVES = 1;
+const float SP_ASSAULT_OBJECTIVES = 4;
+
+// predefined spawnfuncs
+void target_objective_decrease_activate();
+#endif
+
+#ifdef IMPLEMENTATION
+.entity sprite;
+
+// random functions
+void assault_objective_use()
+{SELFPARAM();
+       // activate objective
+       self.health = 100;
+       //print("^2Activated objective ", self.targetname, "=", etos(self), "\n");
+       //print("Activator is ", activator.classname, "\n");
+
+       for (entity e = world; (e = find(e, target, this.targetname)); )
+       {
+               if (e.classname == "target_objective_decrease")
+               {
+                       WITH(entity, self, e, target_objective_decrease_activate());
+               }
+       }
+
+       setself(this);
+}
+
+vector target_objective_spawn_evalfunc(entity player, entity spot, vector current)
+{SELFPARAM();
+       if(self.health < 0 || self.health >= ASSAULT_VALUE_INACTIVE)
+               return '-1 0 0';
+       return current;
+}
+
+// reset this objective. Used when spawning an objective
+// and when a new round starts
+void assault_objective_reset()
+{SELFPARAM();
+       self.health = ASSAULT_VALUE_INACTIVE;
+}
+
+// decrease the health of targeted objectives
+void assault_objective_decrease_use()
+{SELFPARAM();
+       if(activator.team != assault_attacker_team)
+       {
+               // wrong team triggered decrease
+               return;
+       }
+
+       if(other.assault_sprite)
+       {
+               WaypointSprite_Disown(other.assault_sprite, waypointsprite_deadlifetime);
+               if(other.classname == "func_assault_destructible")
+                       other.sprite = world;
+       }
+       else
+               return; // already activated! cannot activate again!
+
+       if(self.enemy.health < ASSAULT_VALUE_INACTIVE)
+       {
+               if(self.enemy.health - self.dmg > 0.5)
+               {
+                       PlayerTeamScore_Add(activator, SP_SCORE, ST_SCORE, self.dmg);
+                       self.enemy.health = self.enemy.health - self.dmg;
+               }
+               else
+               {
+                       PlayerTeamScore_Add(activator, SP_SCORE, ST_SCORE, self.enemy.health);
+                       PlayerTeamScore_Add(activator, SP_ASSAULT_OBJECTIVES, ST_ASSAULT_OBJECTIVES, 1);
+                       self.enemy.health = -1;
+
+                       entity oldactivator, head;
+
+                       setself(this.enemy);
+                       if(self.message)
+                       FOR_EACH_PLAYER(head)
+                               centerprint(head, self.message);
+
+                       oldactivator = activator;
+                       activator = this;
+                       SUB_UseTargets();
+                       activator = oldactivator;
+                       setself(this);
+               }
+       }
+}
+
+void assault_setenemytoobjective()
+{SELFPARAM();
+       entity objective;
+       for(objective = world; (objective = find(objective, targetname, self.target)); )
+       {
+               if(objective.classname == "target_objective")
+               {
+                       if(self.enemy == world)
+                               self.enemy = objective;
+                       else
+                               objerror("more than one objective as target - fix the map!");
+                       break;
+               }
+       }
+
+       if(self.enemy == world)
+               objerror("no objective as target - fix the map!");
+}
+
+float assault_decreaser_sprite_visible(entity e)
+{SELFPARAM();
+       entity decreaser;
+
+       decreaser = self.assault_decreaser;
+
+       if(decreaser.enemy.health >= ASSAULT_VALUE_INACTIVE)
+               return false;
+
+       return true;
+}
+
+void target_objective_decrease_activate()
+{SELFPARAM();
+       entity ent, spr;
+       self.owner = world;
+       for(ent = world; (ent = find(ent, target, self.targetname)); )
+       {
+               if(ent.assault_sprite != world)
+               {
+                       WaypointSprite_Disown(ent.assault_sprite, waypointsprite_deadlifetime);
+                       if(ent.classname == "func_assault_destructible")
+                               ent.sprite = world;
+               }
+
+               spr = WaypointSprite_SpawnFixed(WP_Assault, 0.5 * (ent.absmin + ent.absmax), ent, assault_sprite, RADARICON_OBJECTIVE);
+               spr.assault_decreaser = self;
+               spr.waypointsprite_visible_for_player = assault_decreaser_sprite_visible;
+               spr.classname = "sprite_waypoint";
+               WaypointSprite_UpdateRule(spr, assault_attacker_team, SPRITERULE_TEAMPLAY);
+               if(ent.classname == "func_assault_destructible")
+               {
+                       WaypointSprite_UpdateSprites(spr, WP_AssaultDefend, WP_AssaultDestroy, WP_AssaultDestroy);
+                       WaypointSprite_UpdateMaxHealth(spr, ent.max_health);
+                       WaypointSprite_UpdateHealth(spr, ent.health);
+                       ent.sprite = spr;
+               }
+               else
+                       WaypointSprite_UpdateSprites(spr, WP_AssaultDefend, WP_AssaultPush, WP_AssaultPush);
+       }
+}
+
+void target_objective_decrease_findtarget()
+{
+       assault_setenemytoobjective();
+}
+
+void target_assault_roundend_reset()
+{SELFPARAM();
+       //print("round end reset\n");
+       self.cnt = self.cnt + 1; // up round counter
+       self.winning = 0; // up round
+}
+
+void target_assault_roundend_use()
+{SELFPARAM();
+       self.winning = 1; // round has been won by attackers
+}
+
+void assault_roundstart_use()
+{SELFPARAM();
+       activator = self;
+       SUB_UseTargets();
+
+       //(Re)spawn all turrets
+       for(entity ent = NULL; (ent = find(ent, classname, "turret_main")); ) {
+               // Swap turret teams
+               if(ent.team == NUM_TEAM_1)
+                       ent.team = NUM_TEAM_2;
+               else
+                       ent.team = NUM_TEAM_1;
+
+               // Dubbles as teamchange
+               WITH(entity, self, ent, turret_respawn());
+       }
+}
+
+void assault_wall_think()
+{SELFPARAM();
+       if(self.enemy.health < 0)
+       {
+               self.model = "";
+               self.solid = SOLID_NOT;
+       }
+       else
+       {
+               self.model = self.mdl;
+               self.solid = SOLID_BSP;
+       }
+
+       self.nextthink = time + 0.2;
+}
+
+// trigger new round
+// reset objectives, toggle spawnpoints, reset triggers, ...
+void vehicles_clearreturn(entity veh);
+void vehicles_spawn();
+void assault_new_round()
+{SELFPARAM();
+       //bprint("ASSAULT: new round\n");
+
+       // Eject players from vehicles
+       entity e;
+    FOR_EACH_PLAYER(e)
+    {
+        if(e.vehicle)
+        {
+               WITH(entity, self, e, vehicles_exit(VHEF_RELEASE));
+        }
+    }
+
+    for (entity e_ = findchainflags(vehicle_flags, VHF_ISVEHICLE); e_; e_ = e_.chain)
+    {
+       setself(e_);
+        vehicles_clearreturn(self);
+        vehicles_spawn();
+    }
+
+    setself(this);
+
+       // up round counter
+       self.winning = self.winning + 1;
+
+       // swap attacker/defender roles
+       if(assault_attacker_team == NUM_TEAM_1)
+               assault_attacker_team = NUM_TEAM_2;
+       else
+               assault_attacker_team = NUM_TEAM_1;
+
+       entity ent;
+       for(ent = world; (ent = nextent(ent)); )
+       {
+               if(clienttype(ent) == CLIENTTYPE_NOTACLIENT)
+               {
+                       if(ent.team_saved == NUM_TEAM_1)
+                               ent.team_saved = NUM_TEAM_2;
+                       else if(ent.team_saved == NUM_TEAM_2)
+                               ent.team_saved = NUM_TEAM_1;
+               }
+       }
+
+       // reset the level with a countdown
+       cvar_set("timelimit", ftos(ceil(time - game_starttime) / 60));
+       ReadyRestart_force(); // sets game_starttime
+}
+
+// spawnfuncs
+spawnfunc(info_player_attacker)
+{
+       if (!g_assault) { remove(self); return; }
+
+       self.team = NUM_TEAM_1; // red, gets swapped every round
+       spawnfunc_info_player_deathmatch(this);
+}
+
+spawnfunc(info_player_defender)
+{
+       if (!g_assault) { remove(self); return; }
+
+       self.team = NUM_TEAM_2; // blue, gets swapped every round
+       spawnfunc_info_player_deathmatch(this);
+}
+
+spawnfunc(target_objective)
+{
+       if (!g_assault) { remove(self); return; }
+
+       self.classname = "target_objective";
+       self.use = assault_objective_use;
+       assault_objective_reset();
+       self.reset = assault_objective_reset;
+       self.spawn_evalfunc = target_objective_spawn_evalfunc;
+}
+
+spawnfunc(target_objective_decrease)
+{
+       if (!g_assault) { remove(self); return; }
+
+       self.classname = "target_objective_decrease";
+
+       if(!self.dmg)
+               self.dmg = 101;
+
+       self.use = assault_objective_decrease_use;
+       self.health = ASSAULT_VALUE_INACTIVE;
+       self.max_health = ASSAULT_VALUE_INACTIVE;
+       self.enemy = world;
+
+       InitializeEntity(self, target_objective_decrease_findtarget, INITPRIO_FINDTARGET);
+}
+
+// destructible walls that can be used to trigger target_objective_decrease
+spawnfunc(func_breakable);
+spawnfunc(func_assault_destructible)
+{
+       if (!g_assault) { remove(self); return; }
+
+       self.spawnflags = 3;
+       self.classname = "func_assault_destructible";
+
+       if(assault_attacker_team == NUM_TEAM_1)
+               self.team = NUM_TEAM_2;
+       else
+               self.team = NUM_TEAM_1;
+
+       spawnfunc_func_breakable(this);
+}
+
+spawnfunc(func_assault_wall)
+{
+       if (!g_assault) { remove(self); return; }
+
+       self.classname = "func_assault_wall";
+       self.mdl = self.model;
+       _setmodel(self, self.mdl);
+       self.solid = SOLID_BSP;
+       self.think = assault_wall_think;
+       self.nextthink = time;
+       InitializeEntity(self, assault_setenemytoobjective, INITPRIO_FINDTARGET);
+}
+
+spawnfunc(target_assault_roundend)
+{
+       if (!g_assault) { remove(self); return; }
+
+       self.winning = 0; // round not yet won by attackers
+       self.classname = "target_assault_roundend";
+       self.use = target_assault_roundend_use;
+       self.cnt = 0; // first round
+       self.reset = target_assault_roundend_reset;
+}
+
+spawnfunc(target_assault_roundstart)
+{
+       if (!g_assault) { remove(self); return; }
+
+       assault_attacker_team = NUM_TEAM_1;
+       self.classname = "target_assault_roundstart";
+       self.use = assault_roundstart_use;
+       self.reset2 = assault_roundstart_use;
+       InitializeEntity(self, assault_roundstart_use, INITPRIO_FINDTARGET);
+}
+
+// legacy bot code
+void havocbot_goalrating_ast_targets(float ratingscale)
+{SELFPARAM();
+       entity ad, best, wp, tod;
+       float radius, found, bestvalue;
+       vector p;
+
+       ad = findchain(classname, "func_assault_destructible");
+
+       for (; ad; ad = ad.chain)
+       {
+               if (ad.target == "")
+                       continue;
+
+               if (!ad.bot_attack)
+                       continue;
+
+               found = false;
+               for(tod = world; (tod = find(tod, targetname, ad.target)); )
+               {
+                       if(tod.classname == "target_objective_decrease")
+                       {
+                               if(tod.enemy.health > 0 && tod.enemy.health < ASSAULT_VALUE_INACTIVE)
+                               {
+                               //      dprint(etos(ad),"\n");
+                                       found = true;
+                                       break;
+                               }
+                       }
+               }
+
+               if(!found)
+               {
+               ///     dprint("target not found\n");
+                       continue;
+               }
+               /// dprint("target #", etos(ad), " found\n");
+
+
+               p = 0.5 * (ad.absmin + ad.absmax);
+       //      dprint(vtos(ad.origin), " ", vtos(ad.absmin), " ", vtos(ad.absmax),"\n");
+       //      te_knightspike(p);
+       //      te_lightning2(world, '0 0 0', p);
+
+               // Find and rate waypoints around it
+               found = false;
+               best = world;
+               bestvalue = 99999999999;
+               for(radius=0; radius<1500 && !found; radius+=500)
+               {
+                       for(wp=findradius(p, radius); wp; wp=wp.chain)
+                       {
+                               if(!(wp.wpflags & WAYPOINTFLAG_GENERATED))
+                               if(wp.classname=="waypoint")
+                               if(checkpvs(wp.origin, ad))
+                               {
+                                       found = true;
+                                       if(wp.cnt<bestvalue)
+                                       {
+                                               best = wp;
+                                               bestvalue = wp.cnt;
+                                       }
+                               }
+                       }
+               }
+
+               if(best)
+               {
+               ///     dprint("waypoints around target were found\n");
+               //      te_lightning2(world, '0 0 0', best.origin);
+               //      te_knightspike(best.origin);
+
+                       navigation_routerating(best, ratingscale, 4000);
+                       best.cnt += 1;
+
+                       self.havocbot_attack_time = 0;
+
+                       if(checkpvs(self.view_ofs,ad))
+                       if(checkpvs(self.view_ofs,best))
+                       {
+                       //      dprint("increasing attack time for this target\n");
+                               self.havocbot_attack_time = time + 2;
+                       }
+               }
+       }
+}
+
+void havocbot_role_ast_offense()
+{SELFPARAM();
+       if(self.deadflag != DEAD_NO)
+       {
+               self.havocbot_attack_time = 0;
+               havocbot_ast_reset_role(self);
+               return;
+       }
+
+       // Set the role timeout if necessary
+       if (!self.havocbot_role_timeout)
+               self.havocbot_role_timeout = time + 120;
+
+       if (time > self.havocbot_role_timeout)
+       {
+               havocbot_ast_reset_role(self);
+               return;
+       }
+
+       if(self.havocbot_attack_time>time)
+               return;
+
+       if (self.bot_strategytime < time)
+       {
+               navigation_goalrating_start();
+               havocbot_goalrating_enemyplayers(20000, self.origin, 650);
+               havocbot_goalrating_ast_targets(20000);
+               havocbot_goalrating_items(15000, self.origin, 10000);
+               navigation_goalrating_end();
+
+               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+       }
+}
+
+void havocbot_role_ast_defense()
+{SELFPARAM();
+       if(self.deadflag != DEAD_NO)
+       {
+               self.havocbot_attack_time = 0;
+               havocbot_ast_reset_role(self);
+               return;
+       }
+
+       // Set the role timeout if necessary
+       if (!self.havocbot_role_timeout)
+               self.havocbot_role_timeout = time + 120;
+
+       if (time > self.havocbot_role_timeout)
+       {
+               havocbot_ast_reset_role(self);
+               return;
+       }
+
+       if(self.havocbot_attack_time>time)
+               return;
+
+       if (self.bot_strategytime < time)
+       {
+               navigation_goalrating_start();
+               havocbot_goalrating_enemyplayers(20000, self.origin, 3000);
+               havocbot_goalrating_ast_targets(20000);
+               havocbot_goalrating_items(15000, self.origin, 10000);
+               navigation_goalrating_end();
+
+               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+       }
+}
+
+void havocbot_role_ast_setrole(entity bot, float role)
+{
+       switch(role)
+       {
+               case HAVOCBOT_AST_ROLE_DEFENSE:
+                       bot.havocbot_role = havocbot_role_ast_defense;
+                       bot.havocbot_role_flags = HAVOCBOT_AST_ROLE_DEFENSE;
+                       bot.havocbot_role_timeout = 0;
+                       break;
+               case HAVOCBOT_AST_ROLE_OFFENSE:
+                       bot.havocbot_role = havocbot_role_ast_offense;
+                       bot.havocbot_role_flags = HAVOCBOT_AST_ROLE_OFFENSE;
+                       bot.havocbot_role_timeout = 0;
+                       break;
+       }
+}
+
+void havocbot_ast_reset_role(entity bot)
+{SELFPARAM();
+       if(self.deadflag != DEAD_NO)
+               return;
+
+       if(bot.team == assault_attacker_team)
+               havocbot_role_ast_setrole(bot, HAVOCBOT_AST_ROLE_OFFENSE);
+       else
+               havocbot_role_ast_setrole(bot, HAVOCBOT_AST_ROLE_DEFENSE);
+}
+
+// mutator hooks
+MUTATOR_HOOKFUNCTION(as, PlayerSpawn)
+{SELFPARAM();
+       if(self.team == assault_attacker_team)
+               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_ASSAULT_ATTACKING);
+       else
+               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_ASSAULT_DEFENDING);
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(as, TurretSpawn)
+{SELFPARAM();
+       if(!self.team || self.team == MAX_SHOT_DISTANCE)
+               self.team = 5; // this gets reversed when match starts?
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(as, VehicleSpawn)
+{SELFPARAM();
+       self.nextthink = time + 0.5;
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(as, HavocBot_ChooseRole)
+{SELFPARAM();
+       havocbot_ast_reset_role(self);
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(as, PlayHitsound)
+{
+       return (frag_victim.classname == "func_assault_destructible");
+}
+
+MUTATOR_HOOKFUNCTION(as, GetTeamCount)
+{
+       // assault always has 2 teams
+       c1 = c2 = 0;
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(as, CheckRules_World)
+{
+       ret_float = WinningCondition_Assault();
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(as, ReadLevelCvars)
+{
+       // no assault warmups
+       warmup_stage = 0;
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(as, OnEntityPreSpawn)
+{
+       switch(self.classname)
+       {
+               case "info_player_team1":
+               case "info_player_team2":
+               case "info_player_team3":
+               case "info_player_team4":
+                       return true;
+       }
+
+       return false;
+}
+
+// scoreboard setup
+void assault_ScoreRules()
+{
+       ScoreRules_basics(2, SFL_SORT_PRIO_SECONDARY, SFL_SORT_PRIO_SECONDARY, true);
+       ScoreInfo_SetLabel_TeamScore(  ST_ASSAULT_OBJECTIVES,    "objectives",      SFL_SORT_PRIO_PRIMARY);
+       ScoreInfo_SetLabel_PlayerScore(SP_ASSAULT_OBJECTIVES,    "objectives",      SFL_SORT_PRIO_PRIMARY);
+       ScoreRules_basics_end();
+}
+
+#endif
diff --git a/qcsrc/server/mutators/mutator/gamemode_ca.qc b/qcsrc/server/mutators/mutator/gamemode_ca.qc
new file mode 100644 (file)
index 0000000..88e56bb
--- /dev/null
@@ -0,0 +1,533 @@
+#ifndef GAMEMODE_CA_H
+#define GAMEMODE_CA_H
+
+int autocvar_g_ca_point_limit;
+int autocvar_g_ca_point_leadlimit;
+bool autocvar_g_ca_team_spawns;
+
+void ca_Initialize();
+
+REGISTER_MUTATOR(ca, false)
+{
+       ActivateTeamplay();
+       SetLimits(autocvar_g_ca_point_limit, autocvar_g_ca_point_leadlimit, -1, -1);
+
+       if (autocvar_g_ca_team_spawns)
+               have_team_spawns = -1; // request team spawns
+
+       MUTATOR_ONADD
+       {
+               if (time > 1) // game loads at time 1
+                       error("This is a game type and it cannot be added at runtime.");
+               ca_Initialize();
+       }
+
+       MUTATOR_ONREMOVE
+       {
+               LOG_INFO("This is a game type and it cannot be removed at runtime.");
+               return -1;
+       }
+
+       return 0;
+}
+
+// should be removed in the future, as other code should not have to care
+.float caplayer; // 0.5 if scheduled to join the next round
+#endif
+
+#ifdef IMPLEMENTATION
+float autocvar_g_ca_damage2score_multiplier;
+float autocvar_g_ca_round_timelimit;
+bool autocvar_g_ca_spectate_enemies;
+int autocvar_g_ca_teams;
+int autocvar_g_ca_teams_override;
+float autocvar_g_ca_warmup;
+
+float ca_teams;
+float allowed_to_spawn;
+
+const float ST_CA_ROUNDS = 1;
+void ca_ScoreRules(float teams)
+{
+       ScoreRules_basics(teams, SFL_SORT_PRIO_PRIMARY, 0, true);
+       ScoreInfo_SetLabel_TeamScore(ST_CA_ROUNDS, "rounds", SFL_SORT_PRIO_PRIMARY);
+       ScoreRules_basics_end();
+}
+
+void CA_count_alive_players()
+{
+       entity e;
+       total_players = redalive = bluealive = yellowalive = pinkalive = 0;
+       FOR_EACH_PLAYER(e) {
+               if(e.team == NUM_TEAM_1)
+               {
+                       ++total_players;
+                       if (e.health >= 1) ++redalive;
+               }
+               else if(e.team == NUM_TEAM_2)
+               {
+                       ++total_players;
+                       if (e.health >= 1) ++bluealive;
+               }
+               else if(e.team == NUM_TEAM_3)
+               {
+                       ++total_players;
+                       if (e.health >= 1) ++yellowalive;
+               }
+               else if(e.team == NUM_TEAM_4)
+               {
+                       ++total_players;
+                       if (e.health >= 1) ++pinkalive;
+               }
+       }
+       FOR_EACH_REALCLIENT(e) {
+               e.redalive_stat = redalive;
+               e.bluealive_stat = bluealive;
+               e.yellowalive_stat = yellowalive;
+               e.pinkalive_stat = pinkalive;
+       }
+}
+
+float CA_GetWinnerTeam()
+{
+       float winner_team = 0;
+       if(redalive >= 1)
+               winner_team = NUM_TEAM_1;
+       if(bluealive >= 1)
+       {
+               if(winner_team) return 0;
+               winner_team = NUM_TEAM_2;
+       }
+       if(yellowalive >= 1)
+       {
+               if(winner_team) return 0;
+               winner_team = NUM_TEAM_3;
+       }
+       if(pinkalive >= 1)
+       {
+               if(winner_team) return 0;
+               winner_team = NUM_TEAM_4;
+       }
+       if(winner_team)
+               return winner_team;
+       return -1; // no player left
+}
+
+#define CA_ALIVE_TEAMS() ((redalive > 0) + (bluealive > 0) + (yellowalive > 0) + (pinkalive > 0))
+#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;
+       }
+
+       CA_count_alive_players();
+       if(CA_ALIVE_TEAMS() > 1)
+               return 0;
+
+       float winner_team = CA_GetWinnerTeam();
+       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_CA_ROUNDS, +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);
+       }
+
+       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;
+}
+
+void CA_RoundStart()
+{
+       if(warmup_stage)
+               allowed_to_spawn = true;
+       else
+               allowed_to_spawn = false;
+}
+
+float CA_CheckTeams()
+{
+       static float prev_missing_teams_mask;
+       allowed_to_spawn = true;
+       CA_count_alive_players();
+       if(CA_ALIVE_TEAMS_OK())
+       {
+               if(prev_missing_teams_mask > 0)
+                       Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_MISSING_TEAMS);
+               prev_missing_teams_mask = -1;
+               return 1;
+       }
+       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)
+       {
+               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;
+}
+
+// Returns next available player to spectate if g_ca_spectate_enemies == 0
+entity CA_SpectateNext(entity player, entity start)
+{
+       if(SAME_TEAM(start, player))
+               return start;
+
+       entity spec_other = start;
+       // continue from current player
+       while(spec_other && DIFF_TEAM(spec_other, player))
+               spec_other = find(spec_other, classname, "player");
+
+       if (!spec_other)
+       {
+               // restart from begining
+               spec_other = find(spec_other, classname, "player");
+               while(spec_other && DIFF_TEAM(spec_other, player))
+                       spec_other = find(spec_other, classname, "player");
+       }
+
+       return spec_other;
+}
+
+MUTATOR_HOOKFUNCTION(ca, PlayerSpawn)
+{SELFPARAM();
+       self.caplayer = 1;
+       if(!warmup_stage)
+               eliminatedPlayers.SendFlags |= 1;
+       return 1;
+}
+
+MUTATOR_HOOKFUNCTION(ca, PutClientInServer)
+{SELFPARAM();
+       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
+               if(!self.caplayer)
+               {
+                       self.caplayer = 0.5;
+                       if(IS_REAL_CLIENT(self))
+                               Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_CA_JOIN_LATE);
+               }
+       }
+       return 1;
+}
+
+MUTATOR_HOOKFUNCTION(ca, reset_map_players)
+{SELFPARAM();
+       entity e;
+       FOR_EACH_CLIENT(e)
+       {
+               setself(e);
+               self.killcount = 0;
+               if(!self.caplayer && IS_BOT_CLIENT(self))
+               {
+                       self.team = -1;
+                       self.caplayer = 1;
+               }
+               if(self.caplayer)
+               {
+                       self.classname = "player";
+                       self.caplayer = 1;
+                       PutClientInServer();
+               }
+       }
+       return 1;
+}
+
+MUTATOR_HOOKFUNCTION(ca, ClientConnect)
+{SELFPARAM();
+       self.classname = "observer";
+       return 1;
+}
+
+MUTATOR_HOOKFUNCTION(ca, reset_map_global)
+{
+       allowed_to_spawn = true;
+       return 1;
+}
+
+MUTATOR_HOOKFUNCTION(ca, GetTeamCount, CBC_ORDER_EXCLUSIVE)
+{
+       ret_float = ca_teams;
+       return false;
+}
+
+entity ca_LastPlayerForTeam()
+{SELFPARAM();
+       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)
+{SELFPARAM();
+       ca_LastPlayerForTeam_Notify();
+       if(!allowed_to_spawn)
+               self.respawn_flags =  RESPAWN_SILENT;
+       if(!warmup_stage)
+               eliminatedPlayers.SendFlags |= 1;
+       return 1;
+}
+
+MUTATOR_HOOKFUNCTION(ca, ClientDisconnect)
+{SELFPARAM();
+       if(self.caplayer == 1)
+               ca_LastPlayerForTeam_Notify();
+       return 1;
+}
+
+MUTATOR_HOOKFUNCTION(ca, ForbidPlayerScore_Clear)
+{
+       return 1;
+}
+
+MUTATOR_HOOKFUNCTION(ca, MakePlayerObserver)
+{SELFPARAM();
+       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 true;
+}
+
+MUTATOR_HOOKFUNCTION(ca, ForbidThrowCurrentWeapon)
+{
+       return 1;
+}
+
+MUTATOR_HOOKFUNCTION(ca, GiveFragsForKill, CBC_ORDER_FIRST)
+{
+       frag_score = 0; // score will be given to the winner team when the round ends
+       return 1;
+}
+
+MUTATOR_HOOKFUNCTION(ca, SetStartItems)
+{
+       start_items &= ~IT_UNLIMITED_AMMO;
+       start_health       = warmup_start_health       = cvar("g_lms_start_health");
+       start_armorvalue   = warmup_start_armorvalue   = cvar("g_lms_start_armor");
+       start_ammo_shells  = warmup_start_ammo_shells  = cvar("g_lms_start_ammo_shells");
+       start_ammo_nails   = warmup_start_ammo_nails   = cvar("g_lms_start_ammo_nails");
+       start_ammo_rockets = warmup_start_ammo_rockets = cvar("g_lms_start_ammo_rockets");
+       start_ammo_cells   = warmup_start_ammo_cells   = cvar("g_lms_start_ammo_cells");
+       start_ammo_plasma  = warmup_start_ammo_plasma  = cvar("g_lms_start_ammo_plasma");
+       start_ammo_fuel    = warmup_start_ammo_fuel    = cvar("g_lms_start_ammo_fuel");
+
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(ca, PlayerDamage_Calculate)
+{
+       if(IS_PLAYER(frag_target))
+       if(frag_target.deadflag == DEAD_NO)
+       if(frag_target == frag_attacker || SAME_TEAM(frag_target, frag_attacker) || frag_deathtype == DEATH_FALL.m_id)
+               frag_damage = 0;
+
+       frag_mirrordamage = 0;
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ca, FilterItem)
+{SELFPARAM();
+       if(autocvar_g_powerups <= 0)
+       if(self.flags & FL_POWERUP)
+               return true;
+
+       if(autocvar_g_pickup_items <= 0)
+               return true;
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ca, PlayerDamage_SplitHealthArmor)
+{
+       float excess = max(0, frag_damage - damage_take - damage_save);
+
+       if(frag_target != frag_attacker && IS_PLAYER(frag_attacker))
+               PlayerTeamScore_Add(frag_attacker, SP_SCORE, ST_SCORE, (frag_damage - excess) * autocvar_g_ca_damage2score_multiplier);
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ca, PlayerRegen)
+{
+       // no regeneration in CA
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(ca, Scores_CountFragsRemaining)
+{
+       // announce remaining frags
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(ca, SpectateSet)
+{
+       if(!autocvar_g_ca_spectate_enemies && self.caplayer)
+       if(DIFF_TEAM(spec_player, self))
+               return true;
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ca, SpectateNext)
+{SELFPARAM();
+       if(!autocvar_g_ca_spectate_enemies && self.caplayer)
+       {
+               spec_player = CA_SpectateNext(self, spec_player);
+               return true;
+       }
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ca, SpectatePrev)
+{SELFPARAM();
+       if(!autocvar_g_ca_spectate_enemies && self.caplayer)
+       {
+               do { spec_player = spec_player.chain; }
+               while(spec_player && DIFF_TEAM(spec_player, self));
+
+               if (!spec_player)
+               {
+                       spec_player = spec_first;
+                       while(spec_player && DIFF_TEAM(spec_player, self))
+                               spec_player = spec_player.chain;
+                       if(spec_player == self.enemy)
+                               return MUT_SPECPREV_RETURN;
+               }
+       }
+
+       return MUT_SPECPREV_FOUND;
+}
+
+MUTATOR_HOOKFUNCTION(ca, Bot_FixCount, CBC_ORDER_EXCLUSIVE)
+{
+       entity head;
+       FOR_EACH_REALCLIENT(head)
+       {
+               if(IS_PLAYER(head) || head.caplayer == 1)
+                       ++bot_activerealplayers;
+               ++bot_realplayers;
+       }
+
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(ca, ClientCommand_Spectate)
+{
+       if(self.caplayer)
+       {
+               // they're going to spec, we can do other checks
+               if(autocvar_sv_spectate && (IS_SPEC(self) || IS_OBSERVER(self)))
+                       Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_CA_LEAVE);
+               return MUT_SPECCMD_FORCE;
+       }
+
+       return MUT_SPECCMD_CONTINUE;
+}
+
+MUTATOR_HOOKFUNCTION(ca, WantWeapon)
+{
+       want_allguns = true;
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ca, GetPlayerStatus)
+{
+       if(set_player.caplayer == 1)
+               return true;
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ca, SetWeaponArena)
+{
+       // most weapons arena
+       if(ret_string == "0" || ret_string == "")
+               ret_string = "most";
+       return false;
+}
+
+void ca_Initialize()
+{
+       allowed_to_spawn = true;
+
+       ca_teams = autocvar_g_ca_teams_override;
+       if(ca_teams < 2)
+               ca_teams = autocvar_g_ca_teams;
+       ca_teams = bound(2, ca_teams, 4);
+       ret_float = ca_teams;
+       ca_ScoreRules(ca_teams);
+
+       round_handler_Spawn(CA_CheckTeams, CA_CheckWinner, CA_RoundStart);
+       round_handler_Init(5, autocvar_g_ca_warmup, autocvar_g_ca_round_timelimit);
+
+       addstat(STAT_REDALIVE, AS_INT, redalive_stat);
+       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);
+}
+
+#endif
diff --git a/qcsrc/server/mutators/mutator/gamemode_ctf.qc b/qcsrc/server/mutators/mutator/gamemode_ctf.qc
new file mode 100644 (file)
index 0000000..73e992c
--- /dev/null
@@ -0,0 +1,2777 @@
+#ifndef GAMEMODE_CTF_H
+#define GAMEMODE_CTF_H
+
+#ifndef CSQC
+void ctf_Initialize();
+
+REGISTER_MUTATOR(ctf, false)
+{
+       ActivateTeamplay();
+       SetLimits(autocvar_capturelimit_override, -1, autocvar_captureleadlimit_override, -1);
+       have_team_spawns = -1; // request team spawns
+
+       MUTATOR_ONADD
+       {
+               if (time > 1) // game loads at time 1
+                       error("This is a game type and it cannot be added at runtime.");
+               ctf_Initialize();
+       }
+
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               // we actually cannot roll back ctf_Initialize here
+               // BUT: we don't need to! If this gets called, adding always
+               // succeeds.
+       }
+
+       MUTATOR_ONREMOVE
+       {
+               LOG_INFO("This is a game type and it cannot be removed at runtime.");
+               return -1;
+       }
+
+       return 0;
+}
+#endif
+
+#ifdef SVQC
+// used in cheats.qc
+void ctf_RespawnFlag(entity flag);
+
+// score rule declarations
+const int ST_CTF_CAPS = 1;
+const int SP_CTF_CAPS = 4;
+const int SP_CTF_CAPTIME = 5;
+const int SP_CTF_PICKUPS = 6;
+const int SP_CTF_DROPS = 7;
+const int SP_CTF_FCKILLS = 8;
+const int SP_CTF_RETURNS = 9;
+
+// flag constants // for most of these, there is just one question to be asked: WHYYYYY?
+#define FLAG_MIN (PL_MIN_CONST + '0 0 -13')
+#define FLAG_MAX (PL_MAX_CONST + '0 0 -13')
+
+const float FLAG_SCALE = 0.6;
+
+const float FLAG_THINKRATE = 0.2;
+const float FLAG_TOUCHRATE = 0.5;
+const float WPFE_THINKRATE = 0.5;
+
+const vector FLAG_DROP_OFFSET = ('0 0 32');
+const vector FLAG_CARRY_OFFSET = ('-16 0 8');
+#define FLAG_SPAWN_OFFSET ('0 0 1' * (PL_MAX_CONST.z - 13))
+const vector FLAG_WAYPOINT_OFFSET = ('0 0 64');
+const vector FLAG_FLOAT_OFFSET = ('0 0 32');
+const vector FLAG_PASS_ARC_OFFSET = ('0 0 -10');
+
+const vector VEHICLE_FLAG_OFFSET = ('0 0 96');
+const float VEHICLE_FLAG_SCALE = 1.0;
+
+// waypoint colors
+#define WPCOLOR_ENEMYFC(t) ((t) ? colormapPaletteColor(t - 1, false) * 0.75 : '1 1 1')
+#define WPCOLOR_FLAGCARRIER(t) (WP_FlagCarrier.m_color)
+#define WPCOLOR_DROPPEDFLAG(t) ((t) ? ('0.25 0.25 0.25' + colormapPaletteColor(t - 1, false)) * 0.5 : '1 1 1')
+
+// sounds
+#define snd_flag_taken noise
+#define snd_flag_returned noise1
+#define snd_flag_capture noise2
+#define snd_flag_respawn noise3
+.string snd_flag_dropped;
+.string snd_flag_touch;
+.string snd_flag_pass;
+
+// effects
+.string toucheffect;
+.string passeffect;
+.string capeffect;
+
+// list of flags on the map
+entity ctf_worldflaglist;
+.entity ctf_worldflagnext;
+.entity ctf_staleflagnext;
+
+// waypoint sprites
+.entity bot_basewaypoint; // flag waypointsprite
+.entity wps_helpme;
+.entity wps_flagbase;
+.entity wps_flagcarrier;
+.entity wps_flagdropped;
+.entity wps_enemyflagcarrier;
+.float wps_helpme_time;
+bool wpforenemy_announced;
+float wpforenemy_nextthink;
+
+// statuses
+const int FLAG_BASE = 1;
+const int FLAG_DROPPED = 2;
+const int FLAG_CARRY = 3;
+const int FLAG_PASSING = 4;
+
+const int DROP_NORMAL = 1;
+const int DROP_THROW = 2;
+const int DROP_PASS = 3;
+const int DROP_RESET = 4;
+
+const int PICKUP_BASE = 1;
+const int PICKUP_DROPPED = 2;
+
+const int CAPTURE_NORMAL = 1;
+const int CAPTURE_DROPPED = 2;
+
+const int RETURN_TIMEOUT = 1;
+const int RETURN_DROPPED = 2;
+const int RETURN_DAMAGE = 3;
+const int RETURN_SPEEDRUN = 4;
+const int RETURN_NEEDKILL = 5;
+
+// flag properties
+#define ctf_spawnorigin dropped_origin
+bool ctf_stalemate; // indicates that a stalemate is active
+float ctf_captimerecord; // record time for capturing the flag
+.float ctf_pickuptime;
+.float ctf_droptime;
+.int ctf_status; // status of the flag (FLAG_BASE, FLAG_DROPPED, FLAG_CARRY declared globally)
+.entity ctf_dropper; // don't allow spam of dropping the flag
+.int max_flag_health;
+.float next_take_time;
+.bool ctf_flagdamaged;
+int ctf_teams;
+
+// passing/throwing properties
+.float pass_distance;
+.entity pass_sender;
+.entity pass_target;
+.float throw_antispam;
+.float throw_prevtime;
+.int throw_count;
+
+// CaptureShield: If the player is too bad to be allowed to capture, shield them from taking the flag.
+.bool ctf_captureshielded; // set to 1 if the player is too bad to be allowed to capture
+float ctf_captureshield_min_negscore; // punish at -20 points
+float ctf_captureshield_max_ratio; // punish at most 30% of each team
+float ctf_captureshield_force; // push force of the shield
+
+// 1 flag ctf
+bool ctf_oneflag; // indicates whether or not a neutral flag has been found
+
+// bot player logic
+const int HAVOCBOT_CTF_ROLE_NONE = 0;
+const int HAVOCBOT_CTF_ROLE_DEFENSE = 2;
+const int HAVOCBOT_CTF_ROLE_MIDDLE = 4;
+const int HAVOCBOT_CTF_ROLE_OFFENSE = 8;
+const int HAVOCBOT_CTF_ROLE_CARRIER = 16;
+const int HAVOCBOT_CTF_ROLE_RETRIEVER = 32;
+const int HAVOCBOT_CTF_ROLE_ESCORT = 64;
+
+.bool havocbot_cantfindflag;
+
+vector havocbot_ctf_middlepoint;
+float havocbot_ctf_middlepoint_radius;
+
+void havocbot_role_ctf_setrole(entity bot, int role);
+
+// team checking
+#define CTF_SAMETEAM(a,b) ((autocvar_g_ctf_reverse || (ctf_oneflag && autocvar_g_ctf_oneflag_reverse)) ? DIFF_TEAM(a,b) : SAME_TEAM(a,b))
+#define CTF_DIFFTEAM(a,b) ((autocvar_g_ctf_reverse || (ctf_oneflag && autocvar_g_ctf_oneflag_reverse)) ? SAME_TEAM(a,b) : DIFF_TEAM(a,b))
+
+// networked flag statuses
+.int ctf_flagstatus;
+#endif
+
+const int CTF_RED_FLAG_TAKEN                   = 1;
+const int CTF_RED_FLAG_LOST                            = 2;
+const int CTF_RED_FLAG_CARRYING                        = 3;
+const int CTF_BLUE_FLAG_TAKEN                  = 4;
+const int CTF_BLUE_FLAG_LOST                   = 8;
+const int CTF_BLUE_FLAG_CARRYING               = 12;
+const int CTF_YELLOW_FLAG_TAKEN                        = 16;
+const int CTF_YELLOW_FLAG_LOST                 = 32;
+const int CTF_YELLOW_FLAG_CARRYING             = 48;
+const int CTF_PINK_FLAG_TAKEN                  = 64;
+const int CTF_PINK_FLAG_LOST                   = 128;
+const int CTF_PINK_FLAG_CARRYING               = 192;
+const int CTF_NEUTRAL_FLAG_TAKEN               = 256;
+const int CTF_NEUTRAL_FLAG_LOST                        = 512;
+const int CTF_NEUTRAL_FLAG_CARRYING            = 768;
+const int CTF_FLAG_NEUTRAL                             = 2048;
+const int CTF_SHIELDED                                 = 4096;
+#endif
+
+#ifdef IMPLEMENTATION
+
+#ifdef SVQC
+#include "../../../common/vehicles/all.qh"
+#include "../../teamplay.qh"
+#endif
+
+#include "../../../lib/warpzone/common.qh"
+
+bool autocvar_g_ctf_allow_vehicle_carry;
+bool autocvar_g_ctf_allow_vehicle_touch;
+bool autocvar_g_ctf_allow_monster_touch;
+bool autocvar_g_ctf_throw;
+float autocvar_g_ctf_throw_angle_max;
+float autocvar_g_ctf_throw_angle_min;
+int autocvar_g_ctf_throw_punish_count;
+float autocvar_g_ctf_throw_punish_delay;
+float autocvar_g_ctf_throw_punish_time;
+float autocvar_g_ctf_throw_strengthmultiplier;
+float autocvar_g_ctf_throw_velocity_forward;
+float autocvar_g_ctf_throw_velocity_up;
+float autocvar_g_ctf_drop_velocity_up;
+float autocvar_g_ctf_drop_velocity_side;
+bool autocvar_g_ctf_oneflag_reverse;
+bool autocvar_g_ctf_portalteleport;
+bool autocvar_g_ctf_pass;
+float autocvar_g_ctf_pass_arc;
+float autocvar_g_ctf_pass_arc_max;
+float autocvar_g_ctf_pass_directional_max;
+float autocvar_g_ctf_pass_directional_min;
+float autocvar_g_ctf_pass_radius;
+float autocvar_g_ctf_pass_wait;
+bool autocvar_g_ctf_pass_request;
+float autocvar_g_ctf_pass_turnrate;
+float autocvar_g_ctf_pass_timelimit;
+float autocvar_g_ctf_pass_velocity;
+bool autocvar_g_ctf_dynamiclights;
+float autocvar_g_ctf_flag_collect_delay;
+float autocvar_g_ctf_flag_damageforcescale;
+bool autocvar_g_ctf_flag_dropped_waypoint;
+bool autocvar_g_ctf_flag_dropped_floatinwater;
+bool autocvar_g_ctf_flag_glowtrails;
+int autocvar_g_ctf_flag_health;
+bool autocvar_g_ctf_flag_return;
+float autocvar_g_ctf_flag_return_carried_radius;
+float autocvar_g_ctf_flag_return_time;
+bool autocvar_g_ctf_flag_return_when_unreachable;
+float autocvar_g_ctf_flag_return_damage;
+float autocvar_g_ctf_flag_return_damage_delay;
+float autocvar_g_ctf_flag_return_dropped;
+float autocvar_g_ctf_flagcarrier_auto_helpme_damage;
+float autocvar_g_ctf_flagcarrier_auto_helpme_time;
+float autocvar_g_ctf_flagcarrier_selfdamagefactor;
+float autocvar_g_ctf_flagcarrier_selfforcefactor;
+float autocvar_g_ctf_flagcarrier_damagefactor;
+float autocvar_g_ctf_flagcarrier_forcefactor;
+//float autocvar_g_ctf_flagcarrier_waypointforenemy_spotting;
+bool autocvar_g_ctf_fullbrightflags;
+bool autocvar_g_ctf_ignore_frags;
+int autocvar_g_ctf_score_capture;
+int autocvar_g_ctf_score_capture_assist;
+int autocvar_g_ctf_score_kill;
+int autocvar_g_ctf_score_penalty_drop;
+int autocvar_g_ctf_score_penalty_returned;
+int autocvar_g_ctf_score_pickup_base;
+int autocvar_g_ctf_score_pickup_dropped_early;
+int autocvar_g_ctf_score_pickup_dropped_late;
+int autocvar_g_ctf_score_return;
+float autocvar_g_ctf_shield_force;
+float autocvar_g_ctf_shield_max_ratio;
+int autocvar_g_ctf_shield_min_negscore;
+bool autocvar_g_ctf_stalemate;
+int autocvar_g_ctf_stalemate_endcondition;
+float autocvar_g_ctf_stalemate_time;
+bool autocvar_g_ctf_reverse;
+float autocvar_g_ctf_dropped_capture_delay;
+float autocvar_g_ctf_dropped_capture_radius;
+
+void ctf_FakeTimeLimit(entity e, float t)
+{
+       msg_entity = e;
+       WriteByte(MSG_ONE, 3); // svc_updatestat
+       WriteByte(MSG_ONE, 236); // STAT_TIMELIMIT
+       if(t < 0)
+               WriteCoord(MSG_ONE, autocvar_timelimit);
+       else
+               WriteCoord(MSG_ONE, (t + 1) / 60);
+}
+
+void ctf_EventLog(string mode, int flagteam, entity actor) // use an alias for easy changing and quick editing later
+{
+       if(autocvar_sv_eventlog)
+               GameLogEcho(sprintf(":ctf:%s:%d:%d:%s", mode, flagteam, actor.team, ((actor != world) ? ftos(actor.playerid) : "")));
+               //GameLogEcho(strcat(":ctf:", mode, ":", ftos(flagteam), ((actor != world) ? (strcat(":", ftos(actor.playerid))) : "")));
+}
+
+void ctf_CaptureRecord(entity flag, entity player)
+{
+       float cap_record = ctf_captimerecord;
+       float cap_time = (time - flag.ctf_pickuptime);
+       string refername = db_get(ServerProgsDB, strcat(GetMapname(), "/captimerecord/netname"));
+
+       // notify about shit
+       if(ctf_oneflag) { Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_CTF_CAPTURE_NEUTRAL, player.netname); }
+       else if(!ctf_captimerecord) { Send_Notification(NOTIF_ALL, world, MSG_CHOICE, APP_TEAM_ENT_4(flag, CHOICE_CTF_CAPTURE_TIME_), player.netname, (cap_time * 100)); }
+       else if(cap_time < cap_record) { Send_Notification(NOTIF_ALL, world, MSG_CHOICE, APP_TEAM_ENT_4(flag, CHOICE_CTF_CAPTURE_BROKEN_), player.netname, refername, (cap_time * 100), (cap_record * 100)); }
+       else { Send_Notification(NOTIF_ALL, world, MSG_CHOICE, APP_TEAM_ENT_4(flag, CHOICE_CTF_CAPTURE_UNBROKEN_), player.netname, refername, (cap_time * 100), (cap_record * 100)); }
+
+       // write that shit in the database
+       if(!ctf_oneflag) // but not in 1-flag mode
+       if((!ctf_captimerecord) || (cap_time < cap_record))
+       {
+               ctf_captimerecord = cap_time;
+               db_put(ServerProgsDB, strcat(GetMapname(), "/captimerecord/time"), ftos(cap_time));
+               db_put(ServerProgsDB, strcat(GetMapname(), "/captimerecord/netname"), player.netname);
+               write_recordmarker(player, (time - cap_time), cap_time);
+       }
+}
+
+void ctf_FlagcarrierWaypoints(entity player)
+{
+       WaypointSprite_Spawn(WP_FlagCarrier, 0, 0, player, FLAG_WAYPOINT_OFFSET, world, player.team, player, wps_flagcarrier, true, RADARICON_FLAG);
+       WaypointSprite_UpdateMaxHealth(player.wps_flagcarrier, '1 0 0' * healtharmor_maxdamage(start_health, start_armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id) * 2);
+       WaypointSprite_UpdateHealth(player.wps_flagcarrier, '1 0 0' * healtharmor_maxdamage(player.health, player.armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id));
+       WaypointSprite_UpdateTeamRadar(player.wps_flagcarrier, RADARICON_FLAGCARRIER, WPCOLOR_FLAGCARRIER(player.team));
+}
+
+void ctf_CalculatePassVelocity(entity flag, vector to, vector from, float turnrate)
+{
+       float current_distance = vlen((('1 0 0' * to.x) + ('0 1 0' * to.y)) - (('1 0 0' * from.x) + ('0 1 0' * from.y))); // for the sake of this check, exclude Z axis
+       float initial_height = min(autocvar_g_ctf_pass_arc_max, (flag.pass_distance * tanh(autocvar_g_ctf_pass_arc)));
+       float current_height = (initial_height * min(1, (current_distance / flag.pass_distance)));
+       //print("current_height = ", ftos(current_height), ", initial_height = ", ftos(initial_height), ".\n");
+
+       vector targpos;
+       if(current_height) // make sure we can actually do this arcing path
+       {
+               targpos = (to + ('0 0 1' * current_height));
+               WarpZone_TraceLine(flag.origin, targpos, MOVE_NOMONSTERS, flag);
+               if(trace_fraction < 1)
+               {
+                       //print("normal arc line failed, trying to find new pos...");
+                       WarpZone_TraceLine(to, targpos, MOVE_NOMONSTERS, flag);
+                       targpos = (trace_endpos + FLAG_PASS_ARC_OFFSET);
+                       WarpZone_TraceLine(flag.origin, targpos, MOVE_NOMONSTERS, flag);
+                       if(trace_fraction < 1) { targpos = to; /* print(" ^1FAILURE^7, reverting to original direction.\n"); */ }
+                       /*else { print(" ^3SUCCESS^7, using new arc line.\n"); } */
+               }
+       }
+       else { targpos = to; }
+
+       //flag.angles = normalize(('0 1 0' * to_y) - ('0 1 0' * from_y));
+
+       vector desired_direction = normalize(targpos - from);
+       if(turnrate) { flag.velocity = (normalize(normalize(flag.velocity) + (desired_direction * autocvar_g_ctf_pass_turnrate)) * autocvar_g_ctf_pass_velocity); }
+       else { flag.velocity = (desired_direction * autocvar_g_ctf_pass_velocity); }
+}
+
+bool ctf_CheckPassDirection(vector head_center, vector passer_center, vector passer_angle, vector nearest_to_passer)
+{
+       if(autocvar_g_ctf_pass_directional_max || autocvar_g_ctf_pass_directional_min)
+       {
+               // directional tracing only
+               float spreadlimit;
+               makevectors(passer_angle);
+
+               // find the closest point on the enemy to the center of the attack
+               float h; // hypotenuse, which is the distance between attacker to head
+               float a; // adjacent side, which is the distance between attacker and the point on w_shotdir that is closest to head.origin
+
+               h = vlen(head_center - passer_center);
+               a = h * (normalize(head_center - passer_center) * v_forward);
+
+               vector nearest_on_line = (passer_center + a * v_forward);
+               float distance_from_line = vlen(nearest_to_passer - nearest_on_line);
+
+               spreadlimit = (autocvar_g_ctf_pass_radius ? min(1, (vlen(passer_center - nearest_on_line) / autocvar_g_ctf_pass_radius)) : 1);
+               spreadlimit = (autocvar_g_ctf_pass_directional_min * (1 - spreadlimit) + autocvar_g_ctf_pass_directional_max * spreadlimit);
+
+               if(spreadlimit && (distance_from_line <= spreadlimit) && ((vlen(normalize(head_center - passer_center) - v_forward) * RAD2DEG) <= 90))
+                       { return true; }
+               else
+                       { return false; }
+       }
+       else { return true; }
+}
+
+
+// =======================
+// CaptureShield Functions
+// =======================
+
+bool ctf_CaptureShield_CheckStatus(entity p)
+{
+       int s, s2, s3, s4, se, se2, se3, se4, sr, ser;
+       entity e;
+       int players_worseeq, players_total;
+
+       if(ctf_captureshield_max_ratio <= 0)
+               return false;
+
+       s = PlayerScore_Add(p, SP_CTF_CAPS, 0);
+       s2 = PlayerScore_Add(p, SP_CTF_PICKUPS, 0);
+       s3 = PlayerScore_Add(p, SP_CTF_RETURNS, 0);
+       s4 = PlayerScore_Add(p, SP_CTF_FCKILLS, 0);
+
+       sr = ((s - s2) + (s3 + s4));
+
+       if(sr >= -ctf_captureshield_min_negscore)
+               return false;
+
+       players_total = players_worseeq = 0;
+       FOR_EACH_PLAYER(e)
+       {
+               if(DIFF_TEAM(e, p))
+                       continue;
+               se = PlayerScore_Add(e, SP_CTF_CAPS, 0);
+               se2 = PlayerScore_Add(e, SP_CTF_PICKUPS, 0);
+               se3 = PlayerScore_Add(e, SP_CTF_RETURNS, 0);
+               se4 = PlayerScore_Add(e, SP_CTF_FCKILLS, 0);
+
+               ser = ((se - se2) + (se3 + se4));
+
+               if(ser <= sr)
+                       ++players_worseeq;
+               ++players_total;
+       }
+
+       // player is in the worse half, if >= half the players are better than him, or consequently, if < half of the players are worse
+       // use this rule here
+
+       if(players_worseeq >= players_total * ctf_captureshield_max_ratio)
+               return false;
+
+       return true;
+}
+
+void ctf_CaptureShield_Update(entity player, bool wanted_status)
+{
+       bool updated_status = ctf_CaptureShield_CheckStatus(player);
+       if((wanted_status == player.ctf_captureshielded) && (updated_status != wanted_status)) // 0: shield only, 1: unshield only
+       {
+               Send_Notification(NOTIF_ONE, player, MSG_CENTER, ((updated_status) ? CENTER_CTF_CAPTURESHIELD_SHIELDED : CENTER_CTF_CAPTURESHIELD_FREE));
+               player.ctf_captureshielded = updated_status;
+       }
+}
+
+bool ctf_CaptureShield_Customize()
+{SELFPARAM();
+       if(!other.ctf_captureshielded) { return false; }
+       if(CTF_SAMETEAM(self, other)) { return false; }
+
+       return true;
+}
+
+void ctf_CaptureShield_Touch()
+{SELFPARAM();
+       if(!other.ctf_captureshielded) { return; }
+       if(CTF_SAMETEAM(self, other)) { return; }
+
+       vector mymid = (self.absmin + self.absmax) * 0.5;
+       vector othermid = (other.absmin + other.absmax) * 0.5;
+
+       Damage(other, self, self, 0, DEATH_HURTTRIGGER.m_id, mymid, normalize(othermid - mymid) * ctf_captureshield_force);
+       if(IS_REAL_CLIENT(other)) { Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_CTF_CAPTURESHIELD_SHIELDED); }
+}
+
+void ctf_CaptureShield_Spawn(entity flag)
+{SELFPARAM();
+       entity shield = spawn();
+
+       shield.enemy = self;
+       shield.team = self.team;
+       shield.touch = ctf_CaptureShield_Touch;
+       shield.customizeentityforclient = ctf_CaptureShield_Customize;
+       shield.classname = "ctf_captureshield";
+       shield.effects = EF_ADDITIVE;
+       shield.movetype = MOVETYPE_NOCLIP;
+       shield.solid = SOLID_TRIGGER;
+       shield.avelocity = '7 0 11';
+       shield.scale = 0.5;
+
+       setorigin(shield, self.origin);
+       setmodel(shield, MDL_CTF_SHIELD);
+       setsize(shield, shield.scale * shield.mins, shield.scale * shield.maxs);
+}
+
+
+// ====================
+// Drop/Pass/Throw Code
+// ====================
+
+void ctf_Handle_Drop(entity flag, entity player, int droptype)
+{
+       // declarations
+       player = (player ? player : flag.pass_sender);
+
+       // main
+       flag.movetype = MOVETYPE_TOSS;
+       flag.takedamage = DAMAGE_YES;
+       flag.angles = '0 0 0';
+       flag.health = flag.max_flag_health;
+       flag.ctf_droptime = time;
+       flag.ctf_dropper = player;
+       flag.ctf_status = FLAG_DROPPED;
+
+       // messages and sounds
+       Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_LOST_) : INFO_CTF_LOST_NEUTRAL), player.netname);
+       _sound(flag, CH_TRIGGER, flag.snd_flag_dropped, VOL_BASE, ATTEN_NONE);
+       ctf_EventLog("dropped", player.team, player);
+
+       // scoring
+       PlayerTeamScore_AddScore(player, -autocvar_g_ctf_score_penalty_drop);
+       PlayerScore_Add(player, SP_CTF_DROPS, 1);
+
+       // waypoints
+       if(autocvar_g_ctf_flag_dropped_waypoint) {
+               entity wp = WaypointSprite_Spawn(WP_FlagDropped, 0, 0, flag, FLAG_WAYPOINT_OFFSET, world, ((autocvar_g_ctf_flag_dropped_waypoint == 2) ? 0 : player.team), flag, wps_flagdropped, true, RADARICON_FLAG);
+               wp.colormod = WPCOLOR_DROPPEDFLAG(flag.team);
+       }
+
+       if(autocvar_g_ctf_flag_return_time || (autocvar_g_ctf_flag_return_damage && autocvar_g_ctf_flag_health))
+       {
+               WaypointSprite_UpdateMaxHealth(flag.wps_flagdropped, flag.max_flag_health);
+               WaypointSprite_UpdateHealth(flag.wps_flagdropped, flag.health);
+       }
+
+       player.throw_antispam = time + autocvar_g_ctf_pass_wait;
+
+       if(droptype == DROP_PASS)
+       {
+               flag.pass_distance = 0;
+               flag.pass_sender = world;
+               flag.pass_target = world;
+       }
+}
+
+void ctf_Handle_Retrieve(entity flag, entity player)
+{
+       entity tmp_player; // temporary entity which the FOR_EACH_PLAYER loop uses to scan players
+       entity sender = flag.pass_sender;
+
+       // transfer flag to player
+       flag.owner = player;
+       flag.owner.flagcarried = flag;
+
+       // reset flag
+       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;
+       flag.angles = '0 0 0';
+       flag.ctf_status = FLAG_CARRY;
+
+       // messages and sounds
+       _sound(player, CH_TRIGGER, flag.snd_flag_pass, VOL_BASE, ATTEN_NORM);
+       ctf_EventLog("receive", flag.team, player);
+
+       FOR_EACH_REALPLAYER(tmp_player)
+       {
+               if(tmp_player == sender)
+                       Send_Notification(NOTIF_ONE, tmp_player, MSG_CENTER, ((flag.team) ? APP_TEAM_ENT_4(flag, CENTER_CTF_PASS_SENT_) : CENTER_CTF_PASS_SENT_NEUTRAL), player.netname);
+               else if(tmp_player == player)
+                       Send_Notification(NOTIF_ONE, tmp_player, MSG_CENTER, ((flag.team) ? APP_TEAM_ENT_4(flag, CENTER_CTF_PASS_RECEIVED_) : CENTER_CTF_PASS_RECEIVED_NEUTRAL), sender.netname);
+               else if(SAME_TEAM(tmp_player, sender))
+                       Send_Notification(NOTIF_ONE, tmp_player, MSG_CENTER, ((flag.team) ? APP_TEAM_ENT_4(flag, CENTER_CTF_PASS_OTHER_) : CENTER_CTF_PASS_OTHER_NEUTRAL), sender.netname, player.netname);
+       }
+
+       // create new waypoint
+       ctf_FlagcarrierWaypoints(player);
+
+       sender.throw_antispam = time + autocvar_g_ctf_pass_wait;
+       player.throw_antispam = sender.throw_antispam;
+
+       flag.pass_distance = 0;
+       flag.pass_sender = world;
+       flag.pass_target = world;
+}
+
+void ctf_Handle_Throw(entity player, entity receiver, int droptype)
+{
+       entity flag = player.flagcarried;
+       vector targ_origin, flag_velocity;
+
+       if(!flag) { return; }
+       if((droptype == DROP_PASS) && !receiver) { return; }
+
+       if(flag.speedrunning) { ctf_RespawnFlag(flag); return; }
+
+       // reset the flag
+       setattachment(flag, world, "");
+       setorigin(flag, player.origin + FLAG_DROP_OFFSET);
+       flag.owner.flagcarried = world;
+       flag.owner = world;
+       flag.solid = SOLID_TRIGGER;
+       flag.ctf_dropper = player;
+       flag.ctf_droptime = time;
+
+       flag.flags = FL_ITEM | FL_NOTARGET; // clear FL_ONGROUND for MOVETYPE_TOSS
+
+       switch(droptype)
+       {
+               case DROP_PASS:
+               {
+                       // warpzone support:
+                       // for the examples, we assume player -> wz1 -> ... -> wzn -> receiver
+                       // findradius has already put wzn ... wz1 into receiver's warpzone parameters!
+                       WarpZone_RefSys_Copy(flag, receiver);
+                       WarpZone_RefSys_AddInverse(flag, receiver); // wz1^-1 ... wzn^-1 receiver
+                       targ_origin = WarpZone_RefSys_TransformOrigin(receiver, flag, (0.5 * (receiver.absmin + receiver.absmax))); // this is target origin as seen by the flag
+
+                       flag.pass_distance = vlen((('1 0 0' * targ_origin.x) + ('0 1 0' * targ_origin.y)) - (('1 0 0' *  player.origin.x) + ('0 1 0' *  player.origin.y))); // for the sake of this check, exclude Z axis
+                       ctf_CalculatePassVelocity(flag, targ_origin, player.origin, false);
+
+                       // main
+                       flag.movetype = MOVETYPE_FLY;
+                       flag.takedamage = DAMAGE_NO;
+                       flag.pass_sender = player;
+                       flag.pass_target = receiver;
+                       flag.ctf_status = FLAG_PASSING;
+
+                       // other
+                       _sound(player, CH_TRIGGER, flag.snd_flag_touch, VOL_BASE, ATTEN_NORM);
+                       WarpZone_TrailParticles(world, _particleeffectnum(flag.passeffect), player.origin, targ_origin);
+                       ctf_EventLog("pass", flag.team, player);
+                       break;
+               }
+
+               case DROP_THROW:
+               {
+                       makevectors((player.v_angle.y * '0 1 0') + (bound(autocvar_g_ctf_throw_angle_min, player.v_angle.x, autocvar_g_ctf_throw_angle_max) * '1 0 0'));
+
+                       flag_velocity = (('0 0 1' * autocvar_g_ctf_throw_velocity_up) + ((v_forward * autocvar_g_ctf_throw_velocity_forward) * ((player.items & ITEM_Strength.m_itemid) ? autocvar_g_ctf_throw_strengthmultiplier : 1)));
+                       flag.velocity = W_CalculateProjectileVelocity(player.velocity, flag_velocity, false);
+                       ctf_Handle_Drop(flag, player, droptype);
+                       break;
+               }
+
+               case DROP_RESET:
+               {
+                       flag.velocity = '0 0 0'; // do nothing
+                       break;
+               }
+
+               default:
+               case DROP_NORMAL:
+               {
+                       flag.velocity = W_CalculateProjectileVelocity(player.velocity, (('0 0 1' * autocvar_g_ctf_drop_velocity_up) + ((('0 1 0' * crandom()) + ('1 0 0' * crandom())) * autocvar_g_ctf_drop_velocity_side)), false);
+                       ctf_Handle_Drop(flag, player, droptype);
+                       break;
+               }
+       }
+
+       // kill old waypointsprite
+       WaypointSprite_Ping(player.wps_flagcarrier);
+       WaypointSprite_Kill(player.wps_flagcarrier);
+
+       if(player.wps_enemyflagcarrier)
+               WaypointSprite_Kill(player.wps_enemyflagcarrier);
+
+       // captureshield
+       ctf_CaptureShield_Update(player, 0); // shield player from picking up flag
+}
+
+
+// ==============
+// Event Handlers
+// ==============
+
+void ctf_Handle_Capture(entity flag, entity toucher, int capturetype)
+{
+       entity enemy_flag = ((capturetype == CAPTURE_NORMAL) ? toucher.flagcarried : toucher);
+       entity player = ((capturetype == CAPTURE_NORMAL) ? toucher : enemy_flag.ctf_dropper);
+       entity player_team_flag = world, tmp_entity;
+       float old_time, new_time;
+
+       if(!player) { return; } // without someone to give the reward to, we can't possibly cap
+       if(CTF_DIFFTEAM(player, flag)) { return; }
+
+       if(ctf_oneflag)
+       for(tmp_entity = ctf_worldflaglist; tmp_entity; tmp_entity = tmp_entity.ctf_worldflagnext)
+       if(SAME_TEAM(tmp_entity, player))
+       {
+               player_team_flag = tmp_entity;
+               break;
+       }
+
+       nades_GiveBonus(player, autocvar_g_nades_bonus_score_high );
+
+       player.throw_prevtime = time;
+       player.throw_count = 0;
+
+       // messages and sounds
+       Send_Notification(NOTIF_ONE, player, MSG_CENTER, ((enemy_flag.team) ? APP_TEAM_ENT_4(enemy_flag, CENTER_CTF_CAPTURE_) : CENTER_CTF_CAPTURE_NEUTRAL));
+       ctf_CaptureRecord(enemy_flag, player);
+       _sound(player, CH_TRIGGER, ((ctf_oneflag) ? player_team_flag.snd_flag_capture : ((DIFF_TEAM(player, flag)) ? enemy_flag.snd_flag_capture : flag.snd_flag_capture)), VOL_BASE, ATTEN_NONE);
+
+       switch(capturetype)
+       {
+               case CAPTURE_NORMAL: ctf_EventLog("capture", enemy_flag.team, player); break;
+               case CAPTURE_DROPPED: ctf_EventLog("droppedcapture", enemy_flag.team, player); break;
+               default: break;
+       }
+
+       // scoring
+       PlayerTeamScore_AddScore(player, autocvar_g_ctf_score_capture);
+       PlayerTeamScore_Add(player, SP_CTF_CAPS, ST_CTF_CAPS, 1);
+
+       old_time = PlayerScore_Add(player, SP_CTF_CAPTIME, 0);
+       new_time = TIME_ENCODE(time - enemy_flag.ctf_pickuptime);
+       if(!old_time || new_time < old_time)
+               PlayerScore_Add(player, SP_CTF_CAPTIME, new_time - old_time);
+
+       // effects
+       Send_Effect_(flag.capeffect, flag.origin, '0 0 0', 1);
+       //shockwave_spawn("models/ctf/shockwavetransring.md3", flag.origin - '0 0 15', -0.8, 0, 1);
+
+       // other
+       if(capturetype == CAPTURE_NORMAL)
+       {
+               WaypointSprite_Kill(player.wps_flagcarrier);
+               if(flag.speedrunning) { ctf_FakeTimeLimit(player, -1); }
+
+               if((enemy_flag.ctf_dropper) && (player != enemy_flag.ctf_dropper))
+                       { PlayerTeamScore_AddScore(enemy_flag.ctf_dropper, autocvar_g_ctf_score_capture_assist); }
+       }
+
+       // reset the flag
+       player.next_take_time = time + autocvar_g_ctf_flag_collect_delay;
+       ctf_RespawnFlag(enemy_flag);
+}
+
+void ctf_Handle_Return(entity flag, entity player)
+{
+       // messages and sounds
+       if(IS_MONSTER(player))
+       {
+               Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(flag, INFO_CTF_RETURN_MONSTER_), player.monster_name);
+       }
+       else if(flag.team)
+       {
+               Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT_4(flag, CENTER_CTF_RETURN_));
+               Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(flag, INFO_CTF_RETURN_), player.netname);
+       }
+       _sound(player, CH_TRIGGER, flag.snd_flag_returned, VOL_BASE, ATTEN_NONE);
+       ctf_EventLog("return", flag.team, player);
+
+       // scoring
+       if(IS_PLAYER(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
+
+       if(flag.ctf_dropper)
+       {
+               PlayerScore_Add(flag.ctf_dropper, SP_SCORE, -autocvar_g_ctf_score_penalty_returned); // punish the player who dropped the flag
+               ctf_CaptureShield_Update(flag.ctf_dropper, 0); // shield player from picking up flag
+               flag.ctf_dropper.next_take_time = time + autocvar_g_ctf_flag_collect_delay; // set next take time
+       }
+
+       // other
+       if(player.flagcarried == flag)
+               WaypointSprite_Kill(player.wps_flagcarrier);
+
+       // reset the flag
+       ctf_RespawnFlag(flag);
+}
+
+void ctf_Handle_Pickup(entity flag, entity player, int pickuptype)
+{
+       // declarations
+       float pickup_dropped_score; // used to calculate dropped pickup score
+       entity tmp_entity; // temporary entity
+
+       // attach the flag to the player
+       flag.owner = player;
+       player.flagcarried = flag;
+       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;
+       flag.takedamage = DAMAGE_NO;
+       flag.solid = SOLID_NOT;
+       flag.angles = '0 0 0';
+       flag.ctf_status = FLAG_CARRY;
+
+       switch(pickuptype)
+       {
+               case PICKUP_BASE: flag.ctf_pickuptime = time; break; // used for timing runs
+               case PICKUP_DROPPED: flag.health = flag.max_flag_health; break; // reset health/return timelimit
+               default: break;
+       }
+
+       // messages and sounds
+       Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_PICKUP_) : INFO_CTF_PICKUP_NEUTRAL), player.netname);
+       if(ctf_stalemate) { Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_STALEMATE_CARRIER); }
+       if(!flag.team) { Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_PICKUP_NEUTRAL); }
+       else if(CTF_DIFFTEAM(player, flag)) { Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT_4(flag, CENTER_CTF_PICKUP_)); }
+       else { Send_Notification(NOTIF_ONE, player, MSG_CENTER, ((SAME_TEAM(player, flag)) ? CENTER_CTF_PICKUP_TEAM : CENTER_CTF_PICKUP_TEAM_ENEMY), Team_ColorCode(flag.team)); }
+
+       Send_Notification(NOTIF_TEAM_EXCEPT, player, MSG_CHOICE, ((flag.team) ? APP_TEAM_ENT_4(flag, CHOICE_CTF_PICKUP_TEAM_) : CHOICE_CTF_PICKUP_TEAM_NEUTRAL), Team_ColorCode(player.team), player.netname);
+
+       if(!flag.team)
+       FOR_EACH_PLAYER(tmp_entity)
+       if(tmp_entity != player)
+       if(DIFF_TEAM(player, tmp_entity))
+               Send_Notification(NOTIF_ONE, tmp_entity, MSG_CHOICE, CHOICE_CTF_PICKUP_ENEMY_NEUTRAL, Team_ColorCode(player.team), player.netname);
+
+       if(flag.team)
+       FOR_EACH_PLAYER(tmp_entity)
+       if(tmp_entity != player)
+       if(CTF_SAMETEAM(flag, tmp_entity))
+       if(SAME_TEAM(player, tmp_entity))
+               Send_Notification(NOTIF_ONE, tmp_entity, MSG_CHOICE, APP_TEAM_ENT_4(flag, CHOICE_CTF_PICKUP_TEAM_), Team_ColorCode(player.team), player.netname);
+       else
+               Send_Notification(NOTIF_ONE, tmp_entity, MSG_CHOICE, ((SAME_TEAM(flag, player)) ? CHOICE_CTF_PICKUP_ENEMY_TEAM : CHOICE_CTF_PICKUP_ENEMY), Team_ColorCode(player.team), player.netname);
+
+       _sound(player, CH_TRIGGER, flag.snd_flag_taken, VOL_BASE, ATTEN_NONE);
+
+       // scoring
+       PlayerScore_Add(player, SP_CTF_PICKUPS, 1);
+       nades_GiveBonus(player, autocvar_g_nades_bonus_score_minor);
+       switch(pickuptype)
+       {
+               case PICKUP_BASE:
+               {
+                       PlayerTeamScore_AddScore(player, autocvar_g_ctf_score_pickup_base);
+                       ctf_EventLog("steal", flag.team, player);
+                       break;
+               }
+
+               case PICKUP_DROPPED:
+               {
+                       pickup_dropped_score = (autocvar_g_ctf_flag_return_time ? bound(0, ((flag.ctf_droptime + autocvar_g_ctf_flag_return_time) - time) / autocvar_g_ctf_flag_return_time, 1) : 1);
+                       pickup_dropped_score = floor((autocvar_g_ctf_score_pickup_dropped_late * (1 - pickup_dropped_score) + autocvar_g_ctf_score_pickup_dropped_early * pickup_dropped_score) + 0.5);
+                       LOG_TRACE("pickup_dropped_score is ", ftos(pickup_dropped_score), "\n");
+                       PlayerTeamScore_AddScore(player, pickup_dropped_score);
+                       ctf_EventLog("pickup", flag.team, player);
+                       break;
+               }
+
+               default: break;
+       }
+
+       // speedrunning
+       if(pickuptype == PICKUP_BASE)
+       {
+               flag.speedrunning = player.speedrunning; // if speedrunning, flag will flag-return and teleport the owner back after the record
+               if((player.speedrunning) && (ctf_captimerecord))
+                       ctf_FakeTimeLimit(player, time + ctf_captimerecord);
+       }
+
+       // effects
+       Send_Effect_(flag.toucheffect, player.origin, '0 0 0', 1);
+
+       // waypoints
+       if(pickuptype == PICKUP_DROPPED) { WaypointSprite_Kill(flag.wps_flagdropped); }
+       ctf_FlagcarrierWaypoints(player);
+       WaypointSprite_Ping(player.wps_flagcarrier);
+}
+
+
+// ===================
+// Main Flag Functions
+// ===================
+
+void ctf_CheckFlagReturn(entity flag, int returntype)
+{
+       if((flag.ctf_status == FLAG_DROPPED) || (flag.ctf_status == FLAG_PASSING))
+       {
+               if(flag.wps_flagdropped) { WaypointSprite_UpdateHealth(flag.wps_flagdropped, flag.health); }
+
+               if((flag.health <= 0) || (time >= flag.ctf_droptime + autocvar_g_ctf_flag_return_time))
+               {
+                       switch(returntype)
+                       {
+                               case RETURN_DROPPED: Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_DROPPED_) : INFO_CTF_FLAGRETURN_DROPPED_NEUTRAL)); break;
+                               case RETURN_DAMAGE: Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_DAMAGED_) : INFO_CTF_FLAGRETURN_DAMAGED_NEUTRAL)); break;
+                               case RETURN_SPEEDRUN: Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_SPEEDRUN_) : INFO_CTF_FLAGRETURN_SPEEDRUN_NEUTRAL), ctf_captimerecord); break;
+                               case RETURN_NEEDKILL: Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_NEEDKILL_) : INFO_CTF_FLAGRETURN_NEEDKILL_NEUTRAL)); break;
+
+                               default:
+                               case RETURN_TIMEOUT:
+                                       { Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_TIMEOUT_) : INFO_CTF_FLAGRETURN_TIMEOUT_NEUTRAL)); break; }
+                       }
+                       _sound(flag, CH_TRIGGER, flag.snd_flag_respawn, VOL_BASE, ATTEN_NONE);
+                       ctf_EventLog("returned", flag.team, world);
+                       ctf_RespawnFlag(flag);
+               }
+       }
+}
+
+bool ctf_Stalemate_Customize()
+{SELFPARAM();
+       // make spectators see what the player would see
+       entity e, wp_owner;
+       e = WaypointSprite_getviewentity(other);
+       wp_owner = self.owner;
+
+       // team waypoints
+       if(CTF_SAMETEAM(wp_owner.flagcarried, wp_owner)) { return false; }
+       if(SAME_TEAM(wp_owner, e)) { return false; }
+       if(!IS_PLAYER(e)) { return false; }
+
+       return true;
+}
+
+void ctf_CheckStalemate(void)
+{
+       // declarations
+       int stale_flags = 0, stale_red_flags = 0, stale_blue_flags = 0, stale_yellow_flags = 0, stale_pink_flags = 0, stale_neutral_flags = 0;
+       entity tmp_entity;
+
+       entity ctf_staleflaglist = world; // reset the list, we need to build the list each time this function runs
+
+       // build list of stale flags
+       for(tmp_entity = ctf_worldflaglist; tmp_entity; tmp_entity = tmp_entity.ctf_worldflagnext)
+       {
+               if(autocvar_g_ctf_stalemate)
+               if(tmp_entity.ctf_status != FLAG_BASE)
+               if(time >= tmp_entity.ctf_pickuptime + autocvar_g_ctf_stalemate_time || !tmp_entity.team) // instant stalemate in oneflag
+               {
+                       tmp_entity.ctf_staleflagnext = ctf_staleflaglist; // link flag into staleflaglist
+                       ctf_staleflaglist = tmp_entity;
+
+                       switch(tmp_entity.team)
+                       {
+                               case NUM_TEAM_1: ++stale_red_flags; break;
+                               case NUM_TEAM_2: ++stale_blue_flags; break;
+                               case NUM_TEAM_3: ++stale_yellow_flags; break;
+                               case NUM_TEAM_4: ++stale_pink_flags; break;
+                               default: ++stale_neutral_flags; break;
+                       }
+               }
+       }
+
+       if(ctf_oneflag)
+               stale_flags = (stale_neutral_flags >= 1);
+       else
+               stale_flags = (stale_red_flags >= 1) + (stale_blue_flags >= 1) + (stale_yellow_flags >= 1) + (stale_pink_flags >= 1);
+
+       if(ctf_oneflag && stale_flags == 1)
+               ctf_stalemate = true;
+       else if(stale_flags >= 2)
+               ctf_stalemate = true;
+       else if(stale_flags == 0 && autocvar_g_ctf_stalemate_endcondition == 2)
+               { ctf_stalemate = false; wpforenemy_announced = false; }
+       else if(stale_flags < 2 && autocvar_g_ctf_stalemate_endcondition == 1)
+               { ctf_stalemate = false; wpforenemy_announced = false; }
+
+       // if sufficient stalemate, then set up the waypointsprite and announce the stalemate if necessary
+       if(ctf_stalemate)
+       {
+               for(tmp_entity = ctf_staleflaglist; tmp_entity; tmp_entity = tmp_entity.ctf_staleflagnext)
+               {
+                       if((tmp_entity.owner) && (!tmp_entity.owner.wps_enemyflagcarrier))
+                       {
+                               entity wp = WaypointSprite_Spawn(((ctf_oneflag) ? WP_FlagCarrier : WP_FlagCarrierEnemy), 0, 0, tmp_entity.owner, FLAG_WAYPOINT_OFFSET, world, 0, tmp_entity.owner, wps_enemyflagcarrier, true, RADARICON_FLAG);
+                               wp.colormod = WPCOLOR_ENEMYFC(tmp_entity.owner.team);
+                               tmp_entity.owner.wps_enemyflagcarrier.customizeentityforclient = ctf_Stalemate_Customize;
+                       }
+               }
+
+               if (!wpforenemy_announced)
+               {
+                       FOR_EACH_REALPLAYER(tmp_entity)
+                               Send_Notification(NOTIF_ONE, tmp_entity, MSG_CENTER, ((tmp_entity.flagcarried) ? CENTER_CTF_STALEMATE_CARRIER : CENTER_CTF_STALEMATE_OTHER));
+
+                       wpforenemy_announced = true;
+               }
+       }
+}
+
+void ctf_FlagDamage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
+{SELFPARAM();
+       if(ITEM_DAMAGE_NEEDKILL(deathtype))
+       {
+               if(autocvar_g_ctf_flag_return_damage_delay)
+               {
+                       self.ctf_flagdamaged = true;
+               }
+               else
+               {
+                       self.health = 0;
+                       ctf_CheckFlagReturn(self, RETURN_NEEDKILL);
+               }
+               return;
+       }
+       if(autocvar_g_ctf_flag_return_damage)
+       {
+               // reduce health and check if it should be returned
+               self.health = self.health - damage;
+               ctf_CheckFlagReturn(self, RETURN_DAMAGE);
+               return;
+       }
+}
+
+void ctf_FlagThink()
+{SELFPARAM();
+       // declarations
+       entity tmp_entity;
+
+       self.nextthink = time + FLAG_THINKRATE; // only 5 fps, more is unnecessary.
+
+       // captureshield
+       if(self == ctf_worldflaglist) // only for the first flag
+               FOR_EACH_CLIENT(tmp_entity)
+                       ctf_CaptureShield_Update(tmp_entity, 1); // release shield only
+
+       // sanity checks
+       if(self.mins != FLAG_MIN || self.maxs != FLAG_MAX) { // reset the flag boundaries in case it got squished
+               LOG_TRACE("wtf the flag got squashed?\n");
+               tracebox(self.origin, FLAG_MIN, FLAG_MAX, self.origin, MOVE_NOMONSTERS, self);
+               if(!trace_startsolid || self.noalign) // can we resize it without getting stuck?
+                       setsize(self, FLAG_MIN, FLAG_MAX); }
+
+       switch(self.ctf_status) // reset flag angles in case warpzones adjust it
+       {
+               case FLAG_DROPPED:
+               {
+                       self.angles = '0 0 0';
+                       break;
+               }
+
+               default: break;
+       }
+
+       // main think method
+       switch(self.ctf_status)
+       {
+               case FLAG_BASE:
+               {
+                       if(autocvar_g_ctf_dropped_capture_radius)
+                       {
+                               for(tmp_entity = ctf_worldflaglist; tmp_entity; tmp_entity = tmp_entity.ctf_worldflagnext)
+                                       if(tmp_entity.ctf_status == FLAG_DROPPED)
+                                       if(vlen(self.origin - tmp_entity.origin) < autocvar_g_ctf_dropped_capture_radius)
+                                       if(time > tmp_entity.ctf_droptime + autocvar_g_ctf_dropped_capture_delay)
+                                               ctf_Handle_Capture(self, tmp_entity, CAPTURE_DROPPED);
+                       }
+                       return;
+               }
+
+               case FLAG_DROPPED:
+               {
+                       if(autocvar_g_ctf_flag_dropped_floatinwater)
+                       {
+                               vector midpoint = ((self.absmin + self.absmax) * 0.5);
+                               if(pointcontents(midpoint) == CONTENT_WATER)
+                               {
+                                       self.velocity = self.velocity * 0.5;
+
+                                       if(pointcontents(midpoint + FLAG_FLOAT_OFFSET) == CONTENT_WATER)
+                                               { self.velocity_z = autocvar_g_ctf_flag_dropped_floatinwater; }
+                                       else
+                                               { self.movetype = MOVETYPE_FLY; }
+                               }
+                               else if(self.movetype == MOVETYPE_FLY) { self.movetype = MOVETYPE_TOSS; }
+                       }
+                       if(autocvar_g_ctf_flag_return_dropped)
+                       {
+                               if((vlen(self.origin - self.ctf_spawnorigin) <= autocvar_g_ctf_flag_return_dropped) || (autocvar_g_ctf_flag_return_dropped == -1))
+                               {
+                                       self.health = 0;
+                                       ctf_CheckFlagReturn(self, RETURN_DROPPED);
+                                       return;
+                               }
+                       }
+                       if(self.ctf_flagdamaged)
+                       {
+                               self.health -= ((self.max_flag_health / autocvar_g_ctf_flag_return_damage_delay) * FLAG_THINKRATE);
+                               ctf_CheckFlagReturn(self, RETURN_NEEDKILL);
+                               return;
+                       }
+                       else if(autocvar_g_ctf_flag_return_time)
+                       {
+                               self.health -= ((self.max_flag_health / autocvar_g_ctf_flag_return_time) * FLAG_THINKRATE);
+                               ctf_CheckFlagReturn(self, RETURN_TIMEOUT);
+                               return;
+                       }
+                       return;
+               }
+
+               case FLAG_CARRY:
+               {
+                       if(self.speedrunning && ctf_captimerecord && (time >= self.ctf_pickuptime + ctf_captimerecord))
+                       {
+                               self.health = 0;
+                               ctf_CheckFlagReturn(self, RETURN_SPEEDRUN);
+
+                               setself(self.owner);
+                               self.impulse = CHIMPULSE_SPEEDRUN; // move the player back to the waypoint they set
+                               ImpulseCommands();
+                               setself(this);
+                       }
+                       if(autocvar_g_ctf_stalemate)
+                       {
+                               if(time >= wpforenemy_nextthink)
+                               {
+                                       ctf_CheckStalemate();
+                                       wpforenemy_nextthink = time + WPFE_THINKRATE; // waypoint for enemy think rate (to reduce unnecessary spam of this check)
+                               }
+                       }
+                       if(CTF_SAMETEAM(self, self.owner) && self.team)
+                       {
+                               if(autocvar_g_ctf_flag_return) // drop the flag if reverse status has changed
+                                       ctf_Handle_Throw(self.owner, world, DROP_THROW);
+                               else if(vlen(self.owner.origin - self.ctf_spawnorigin) <= autocvar_g_ctf_flag_return_carried_radius)
+                                       ctf_Handle_Return(self, self.owner);
+                       }
+                       return;
+               }
+
+               case FLAG_PASSING:
+               {
+                       vector targ_origin = ((self.pass_target.absmin + self.pass_target.absmax) * 0.5);
+                       targ_origin = WarpZone_RefSys_TransformOrigin(self.pass_target, self, targ_origin); // origin of target as seen by the flag (us)
+                       WarpZone_TraceLine(self.origin, targ_origin, MOVE_NOMONSTERS, self);
+
+                       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))
+                       {
+                               // give up, pass failed
+                               ctf_Handle_Drop(self, world, DROP_PASS);
+                       }
+                       else
+                       {
+                               // still a viable target, go for it
+                               ctf_CalculatePassVelocity(self, targ_origin, self.origin, true);
+                       }
+                       return;
+               }
+
+               default: // this should never happen
+               {
+                       LOG_TRACE("ctf_FlagThink(): Flag exists with no status?\n");
+                       return;
+               }
+       }
+}
+
+void ctf_FlagTouch()
+{SELFPARAM();
+       if(gameover) { return; }
+       if(trace_dphitcontents & (DPCONTENTS_PLAYERCLIP | DPCONTENTS_MONSTERCLIP)) { return; }
+
+       entity toucher = other, tmp_entity;
+       bool is_not_monster = (!IS_MONSTER(toucher)), num_perteam = 0;
+
+       // automatically kill the flag and return it if it touched lava/slime/nodrop surfaces
+       if(ITEM_TOUCH_NEEDKILL())
+       {
+               if(!autocvar_g_ctf_flag_return_damage_delay)
+               {
+                       self.health = 0;
+                       ctf_CheckFlagReturn(self, RETURN_NEEDKILL);
+               }
+               if(!self.ctf_flagdamaged) { return; }
+       }
+
+       FOR_EACH_PLAYER(tmp_entity) if(SAME_TEAM(toucher, tmp_entity)) { ++num_perteam; }
+
+       // special touch behaviors
+       if(toucher.frozen) { return; }
+       else if(IS_VEHICLE(toucher))
+       {
+               if(autocvar_g_ctf_allow_vehicle_touch && toucher.owner)
+                       toucher = toucher.owner; // the player is actually the vehicle owner, not other
+               else
+                       return; // do nothing
+       }
+       else if(IS_MONSTER(toucher))
+       {
+               if(!autocvar_g_ctf_allow_monster_touch)
+                       return; // do nothing
+       }
+       else if (!IS_PLAYER(toucher)) // The flag just touched an object, most likely the world
+       {
+               if(time > self.wait) // if we haven't in a while, play a sound/effect
+               {
+                       Send_Effect_(self.toucheffect, self.origin, '0 0 0', 1);
+                       _sound(self, CH_TRIGGER, self.snd_flag_touch, VOL_BASE, ATTEN_NORM);
+                       self.wait = time + FLAG_TOUCHRATE;
+               }
+               return;
+       }
+       else if(toucher.deadflag != DEAD_NO) { return; }
+
+       switch(self.ctf_status)
+       {
+               case FLAG_BASE:
+               {
+                       if(ctf_oneflag)
+                       {
+                               if(CTF_SAMETEAM(toucher, self) && (toucher.flagcarried) && !toucher.flagcarried.team && is_not_monster)
+                                       ctf_Handle_Capture(self, toucher, CAPTURE_NORMAL); // toucher just captured the neutral flag to enemy base
+                               else if(!self.team && (!toucher.flagcarried) && (!toucher.ctf_captureshielded) && (time > toucher.next_take_time) && is_not_monster)
+                                       ctf_Handle_Pickup(self, toucher, PICKUP_BASE); // toucher just stole the neutral flag
+                       }
+                       else if(CTF_SAMETEAM(toucher, self) && (toucher.flagcarried) && DIFF_TEAM(toucher.flagcarried, self) && is_not_monster)
+                               ctf_Handle_Capture(self, toucher, CAPTURE_NORMAL); // toucher just captured the enemies flag to his base
+                       else if(CTF_DIFFTEAM(toucher, self) && (!toucher.flagcarried) && (!toucher.ctf_captureshielded) && (time > toucher.next_take_time) && is_not_monster)
+                               ctf_Handle_Pickup(self, toucher, PICKUP_BASE); // toucher just stole the enemies flag
+                       break;
+               }
+
+               case FLAG_DROPPED:
+               {
+                       if(CTF_SAMETEAM(toucher, self) && (autocvar_g_ctf_flag_return || num_perteam <= 1) && self.team) // automatically return if there's only 1 player on the team
+                               ctf_Handle_Return(self, toucher); // toucher just returned his own flag
+                       else if(is_not_monster && (!toucher.flagcarried) && ((toucher != self.ctf_dropper) || (time > self.ctf_droptime + autocvar_g_ctf_flag_collect_delay)))
+                               ctf_Handle_Pickup(self, toucher, PICKUP_DROPPED); // toucher just picked up a dropped enemy flag
+                       break;
+               }
+
+               case FLAG_CARRY:
+               {
+                       LOG_TRACE("Someone touched a flag even though it was being carried?\n");
+                       break;
+               }
+
+               case FLAG_PASSING:
+               {
+                       if((IS_PLAYER(toucher)) && (toucher.deadflag == DEAD_NO) && (toucher != self.pass_sender))
+                       {
+                               if(DIFF_TEAM(toucher, self.pass_sender))
+                                       ctf_Handle_Return(self, toucher);
+                               else
+                                       ctf_Handle_Retrieve(self, toucher);
+                       }
+                       break;
+               }
+       }
+}
+
+.float last_respawn;
+void ctf_RespawnFlag(entity flag)
+{
+       // check for flag respawn being called twice in a row
+       if(flag.last_respawn > time - 0.5)
+               { backtrace("flag respawn called twice quickly! please notify Samual about this..."); }
+
+       flag.last_respawn = time;
+
+       // reset the player (if there is one)
+       if((flag.owner) && (flag.owner.flagcarried == flag))
+       {
+               WaypointSprite_Kill(flag.owner.wps_enemyflagcarrier);
+               WaypointSprite_Kill(flag.wps_flagcarrier);
+
+               flag.owner.flagcarried = world;
+
+               if(flag.speedrunning)
+                       ctf_FakeTimeLimit(flag.owner, -1);
+       }
+
+       if((flag.owner) && (flag.owner.vehicle))
+               flag.scale = FLAG_SCALE;
+
+       if(flag.ctf_status == FLAG_DROPPED)
+               { WaypointSprite_Kill(flag.wps_flagdropped); }
+
+       // reset the flag
+       setattachment(flag, world, "");
+       setorigin(flag, flag.ctf_spawnorigin);
+
+       flag.movetype = ((flag.noalign) ? MOVETYPE_NONE : MOVETYPE_TOSS);
+       flag.takedamage = DAMAGE_NO;
+       flag.health = flag.max_flag_health;
+       flag.solid = SOLID_TRIGGER;
+       flag.velocity = '0 0 0';
+       flag.angles = flag.mangle;
+       flag.flags = FL_ITEM | FL_NOTARGET;
+
+       flag.ctf_status = FLAG_BASE;
+       flag.owner = world;
+       flag.pass_distance = 0;
+       flag.pass_sender = world;
+       flag.pass_target = world;
+       flag.ctf_dropper = world;
+       flag.ctf_pickuptime = 0;
+       flag.ctf_droptime = 0;
+       flag.ctf_flagdamaged = 0;
+
+       ctf_CheckStalemate();
+}
+
+void ctf_Reset()
+{SELFPARAM();
+       if(self.owner)
+               if(IS_PLAYER(self.owner))
+                       ctf_Handle_Throw(self.owner, world, DROP_RESET);
+
+       ctf_RespawnFlag(self);
+}
+
+void ctf_DelayedFlagSetup(void) // called after a flag is placed on a map by ctf_FlagSetup()
+{SELFPARAM();
+       // bot waypoints
+       waypoint_spawnforitem_force(self, self.origin);
+       self.nearestwaypointtimeout = 0; // activate waypointing again
+       self.bot_basewaypoint = self.nearestwaypoint;
+
+       // waypointsprites
+       entity basename;
+       switch (self.team)
+       {
+               case NUM_TEAM_1: basename = WP_FlagBaseRed; break;
+               case NUM_TEAM_2: basename = WP_FlagBaseBlue; break;
+               case NUM_TEAM_3: basename = WP_FlagBaseYellow; break;
+               case NUM_TEAM_4: basename = WP_FlagBasePink; break;
+               default: basename = WP_FlagBaseNeutral; break;
+       }
+
+       entity wp = WaypointSprite_SpawnFixed(basename, self.origin + FLAG_WAYPOINT_OFFSET, self, wps_flagbase, RADARICON_FLAG);
+       wp.colormod = ((self.team) ? Team_ColorRGB(self.team) : '1 1 1');
+       WaypointSprite_UpdateTeamRadar(self.wps_flagbase, RADARICON_FLAG, ((self.team) ? colormapPaletteColor(self.team - 1, false) : '1 1 1'));
+
+       // captureshield setup
+       ctf_CaptureShield_Spawn(self);
+}
+
+void set_flag_string(entity flag, .string field, string value, string teamname)
+{
+       if(flag.(field) == "")
+               flag.(field) = strzone(sprintf(value,teamname));
+}
+
+void ctf_FlagSetup(int teamnumber, entity flag) // called when spawning a flag entity on the map as a spawnfunc
+{SELFPARAM();
+       // declarations
+       setself(flag); // for later usage with droptofloor()
+
+       // main setup
+       flag.ctf_worldflagnext = ctf_worldflaglist; // link flag into ctf_worldflaglist
+       ctf_worldflaglist = flag;
+
+       setattachment(flag, world, "");
+
+       flag.netname = strzone(sprintf("%s%s^7 flag", Team_ColorCode(teamnumber), Team_ColorName_Upper(teamnumber)));
+       flag.team = teamnumber;
+       flag.classname = "item_flag_team";
+       flag.target = "###item###"; // wut?
+       flag.flags = FL_ITEM | FL_NOTARGET;
+       flag.solid = SOLID_TRIGGER;
+       flag.takedamage = DAMAGE_NO;
+       flag.damageforcescale = autocvar_g_ctf_flag_damageforcescale;
+       flag.max_flag_health = ((autocvar_g_ctf_flag_return_damage && autocvar_g_ctf_flag_health) ? autocvar_g_ctf_flag_health : 100);
+       flag.health = flag.max_flag_health;
+       flag.event_damage = ctf_FlagDamage;
+       flag.pushable = true;
+       flag.teleportable = TELEPORT_NORMAL;
+       flag.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
+       flag.damagedbytriggers = autocvar_g_ctf_flag_return_when_unreachable;
+       flag.damagedbycontents = autocvar_g_ctf_flag_return_when_unreachable;
+       flag.velocity = '0 0 0';
+       flag.mangle = flag.angles;
+       flag.reset = ctf_Reset;
+       flag.touch = ctf_FlagTouch;
+       flag.think = ctf_FlagThink;
+       flag.nextthink = time + FLAG_THINKRATE;
+       flag.ctf_status = FLAG_BASE;
+
+       string teamname = Static_Team_ColorName_Lower(teamnumber);
+       // appearence
+       if(!flag.scale)                         { flag.scale = FLAG_SCALE; }
+       if(flag.skin == 0)                      { flag.skin = cvar(sprintf("g_ctf_flag_%s_skin", teamname)); }
+       if(flag.model == "")            { flag.model = cvar_string(sprintf("g_ctf_flag_%s_model", teamname)); }
+       set_flag_string(flag, toucheffect,      "%sflag_touch", teamname);
+       set_flag_string(flag, passeffect,       "%s_pass",              teamname);
+       set_flag_string(flag, capeffect,        "%s_cap",               teamname);
+
+       // sounds
+       flag.snd_flag_taken = SND(CTF_TAKEN(teamnumber));
+       flag.snd_flag_returned = SND(CTF_RETURNED(teamnumber));
+       flag.snd_flag_capture = SND(CTF_CAPTURE(teamnumber));
+       flag.snd_flag_dropped = SND(CTF_DROPPED(teamnumber));
+       if (flag.snd_flag_respawn == "") flag.snd_flag_respawn = SND(CTF_RESPAWN); // if there is ever a team-based sound for this, update the code to match.
+       precache_sound(flag.snd_flag_respawn);
+       if (flag.snd_flag_touch == "") flag.snd_flag_touch = SND(CTF_TOUCH); // again has no team-based sound
+       precache_sound(flag.snd_flag_touch);
+       if (flag.snd_flag_pass == "") flag.snd_flag_pass = SND(CTF_PASS); // same story here
+       precache_sound(flag.snd_flag_pass);
+
+       // precache
+       precache_model(flag.model);
+
+       // appearence
+       _setmodel(flag, flag.model); // precision set below
+       setsize(flag, FLAG_MIN, FLAG_MAX);
+       setorigin(flag, (flag.origin + FLAG_SPAWN_OFFSET));
+
+       if(autocvar_g_ctf_flag_glowtrails)
+       {
+               switch(teamnumber)
+               {
+                       case NUM_TEAM_1: flag.glow_color = 251; break;
+                       case NUM_TEAM_2: flag.glow_color = 210; break;
+                       case NUM_TEAM_3: flag.glow_color = 110; break;
+                       case NUM_TEAM_4: flag.glow_color = 145; break;
+                       default:                 flag.glow_color = 254; break;
+               }
+               flag.glow_size = 25;
+               flag.glow_trail = 1;
+       }
+
+       flag.effects |= EF_LOWPRECISION;
+       if(autocvar_g_ctf_fullbrightflags) { flag.effects |= EF_FULLBRIGHT; }
+       if(autocvar_g_ctf_dynamiclights)
+       {
+               switch(teamnumber)
+               {
+                       case NUM_TEAM_1: flag.effects |= EF_RED; break;
+                       case NUM_TEAM_2: flag.effects |= EF_BLUE; break;
+                       case NUM_TEAM_3: flag.effects |= EF_DIMLIGHT; break;
+                       case NUM_TEAM_4: flag.effects |= EF_RED; break;
+                       default:                 flag.effects |= EF_DIMLIGHT; break;
+               }
+       }
+
+       // flag placement
+       if((flag.spawnflags & 1) || flag.noalign) // don't drop to floor, just stay at fixed location
+       {
+               flag.dropped_origin = flag.origin;
+               flag.noalign = true;
+               flag.movetype = MOVETYPE_NONE;
+       }
+       else // drop to floor, automatically find a platform and set that as spawn origin
+       {
+               flag.noalign = false;
+               setself(flag);
+               droptofloor();
+               flag.movetype = MOVETYPE_TOSS;
+       }
+
+       InitializeEntity(flag, ctf_DelayedFlagSetup, INITPRIO_SETLOCATION);
+}
+
+
+// ================
+// Bot player logic
+// ================
+
+// NOTE: LEGACY CODE, needs to be re-written!
+
+void havocbot_calculate_middlepoint()
+{
+       entity f;
+       vector s = '0 0 0';
+       vector fo = '0 0 0';
+       float n = 0;
+
+       f = ctf_worldflaglist;
+       while (f)
+       {
+               fo = f.origin;
+               s = s + fo;
+               f = f.ctf_worldflagnext;
+       }
+       if(!n)
+               return;
+       havocbot_ctf_middlepoint = s * (1.0 / n);
+       havocbot_ctf_middlepoint_radius  = vlen(fo - havocbot_ctf_middlepoint);
+}
+
+
+entity havocbot_ctf_find_flag(entity bot)
+{
+       entity f;
+       f = ctf_worldflaglist;
+       while (f)
+       {
+               if (CTF_SAMETEAM(bot, f))
+                       return f;
+               f = f.ctf_worldflagnext;
+       }
+       return world;
+}
+
+entity havocbot_ctf_find_enemy_flag(entity bot)
+{
+       entity f;
+       f = ctf_worldflaglist;
+       while (f)
+       {
+               if(ctf_oneflag)
+               {
+                       if(CTF_DIFFTEAM(bot, f))
+                       {
+                               if(f.team)
+                               {
+                                       if(bot.flagcarried)
+                                               return f;
+                               }
+                               else if(!bot.flagcarried)
+                                       return f;
+                       }
+               }
+               else if (CTF_DIFFTEAM(bot, f))
+                       return f;
+               f = f.ctf_worldflagnext;
+       }
+       return world;
+}
+
+int havocbot_ctf_teamcount(entity bot, vector org, float tc_radius)
+{
+       if (!teamplay)
+               return 0;
+
+       int c = 0;
+       entity head;
+
+       FOR_EACH_PLAYER(head)
+       {
+               if(DIFF_TEAM(head, bot) || head.deadflag != DEAD_NO || head == bot)
+                       continue;
+
+               if(vlen(head.origin - org) < tc_radius)
+                       ++c;
+       }
+
+       return c;
+}
+
+void havocbot_goalrating_ctf_ourflag(float ratingscale)
+{SELFPARAM();
+       entity head;
+       head = ctf_worldflaglist;
+       while (head)
+       {
+               if (CTF_SAMETEAM(self, head))
+                       break;
+               head = head.ctf_worldflagnext;
+       }
+       if (head)
+               navigation_routerating(head, ratingscale, 10000);
+}
+
+void havocbot_goalrating_ctf_ourbase(float ratingscale)
+{SELFPARAM();
+       entity head;
+       head = ctf_worldflaglist;
+       while (head)
+       {
+               if (CTF_SAMETEAM(self, head))
+                       break;
+               head = head.ctf_worldflagnext;
+       }
+       if (!head)
+               return;
+
+       navigation_routerating(head.bot_basewaypoint, ratingscale, 10000);
+}
+
+void havocbot_goalrating_ctf_enemyflag(float ratingscale)
+{SELFPARAM();
+       entity head;
+       head = ctf_worldflaglist;
+       while (head)
+       {
+               if(ctf_oneflag)
+               {
+                       if(CTF_DIFFTEAM(self, head))
+                       {
+                               if(head.team)
+                               {
+                                       if(self.flagcarried)
+                                               break;
+                               }
+                               else if(!self.flagcarried)
+                                       break;
+                       }
+               }
+               else if(CTF_DIFFTEAM(self, head))
+                       break;
+               head = head.ctf_worldflagnext;
+       }
+       if (head)
+               navigation_routerating(head, ratingscale, 10000);
+}
+
+void havocbot_goalrating_ctf_enemybase(float ratingscale)
+{SELFPARAM();
+       if (!bot_waypoints_for_items)
+       {
+               havocbot_goalrating_ctf_enemyflag(ratingscale);
+               return;
+       }
+
+       entity head;
+
+       head = havocbot_ctf_find_enemy_flag(self);
+
+       if (!head)
+               return;
+
+       navigation_routerating(head.bot_basewaypoint, ratingscale, 10000);
+}
+
+void havocbot_goalrating_ctf_ourstolenflag(float ratingscale)
+{SELFPARAM();
+       entity mf;
+
+       mf = havocbot_ctf_find_flag(self);
+
+       if(mf.ctf_status == FLAG_BASE)
+               return;
+
+       if(mf.tag_entity)
+               navigation_routerating(mf.tag_entity, ratingscale, 10000);
+}
+
+void havocbot_goalrating_ctf_droppedflags(float ratingscale, vector org, float df_radius)
+{
+       entity head;
+       head = ctf_worldflaglist;
+       while (head)
+       {
+               // flag is out in the field
+               if(head.ctf_status != FLAG_BASE)
+               if(head.tag_entity==world)      // dropped
+               {
+                       if(df_radius)
+                       {
+                               if(vlen(org-head.origin)<df_radius)
+                                       navigation_routerating(head, ratingscale, 10000);
+                       }
+                       else
+                               navigation_routerating(head, ratingscale, 10000);
+               }
+
+               head = head.ctf_worldflagnext;
+       }
+}
+
+void havocbot_goalrating_ctf_carrieritems(float ratingscale, vector org, float sradius)
+{SELFPARAM();
+       entity head;
+       float t;
+       head = findchainfloat(bot_pickup, true);
+       while (head)
+       {
+               // gather health and armor only
+               if (head.solid)
+               if (head.health || head.armorvalue)
+               if (vlen(head.origin - org) < sradius)
+               {
+                       // get the value of the item
+                       t = head.bot_pickupevalfunc(self, head) * 0.0001;
+                       if (t > 0)
+                               navigation_routerating(head, t * ratingscale, 500);
+               }
+               head = head.chain;
+       }
+}
+
+void havocbot_ctf_reset_role(entity bot)
+{
+       float cdefense, cmiddle, coffense;
+       entity mf, ef, head;
+       float c;
+
+       if(bot.deadflag != DEAD_NO)
+               return;
+
+       if(vlen(havocbot_ctf_middlepoint)==0)
+               havocbot_calculate_middlepoint();
+
+       // Check ctf flags
+       if (bot.flagcarried)
+       {
+               havocbot_role_ctf_setrole(bot, HAVOCBOT_CTF_ROLE_CARRIER);
+               return;
+       }
+
+       mf = havocbot_ctf_find_flag(bot);
+       ef = havocbot_ctf_find_enemy_flag(bot);
+
+       // Retrieve stolen flag
+       if(mf.ctf_status!=FLAG_BASE)
+       {
+               havocbot_role_ctf_setrole(bot, HAVOCBOT_CTF_ROLE_RETRIEVER);
+               return;
+       }
+
+       // If enemy flag is taken go to the middle to intercept pursuers
+       if(ef.ctf_status!=FLAG_BASE)
+       {
+               havocbot_role_ctf_setrole(bot, HAVOCBOT_CTF_ROLE_MIDDLE);
+               return;
+       }
+
+       // if there is only me on the team switch to offense
+       c = 0;
+       FOR_EACH_PLAYER(head)
+       if(SAME_TEAM(head, bot))
+               ++c;
+
+       if(c==1)
+       {
+               havocbot_role_ctf_setrole(bot, HAVOCBOT_CTF_ROLE_OFFENSE);
+               return;
+       }
+
+       // Evaluate best position to take
+       // Count mates on middle position
+       cmiddle = havocbot_ctf_teamcount(bot, havocbot_ctf_middlepoint, havocbot_ctf_middlepoint_radius * 0.5);
+
+       // Count mates on defense position
+       cdefense = havocbot_ctf_teamcount(bot, mf.dropped_origin, havocbot_ctf_middlepoint_radius * 0.5);
+
+       // Count mates on offense position
+       coffense = havocbot_ctf_teamcount(bot, ef.dropped_origin, havocbot_ctf_middlepoint_radius);
+
+       if(cdefense<=coffense)
+               havocbot_role_ctf_setrole(bot, HAVOCBOT_CTF_ROLE_DEFENSE);
+       else if(coffense<=cmiddle)
+               havocbot_role_ctf_setrole(bot, HAVOCBOT_CTF_ROLE_OFFENSE);
+       else
+               havocbot_role_ctf_setrole(bot, HAVOCBOT_CTF_ROLE_MIDDLE);
+}
+
+void havocbot_role_ctf_carrier()
+{SELFPARAM();
+       if(self.deadflag != DEAD_NO)
+       {
+               havocbot_ctf_reset_role(self);
+               return;
+       }
+
+       if (self.flagcarried == world)
+       {
+               havocbot_ctf_reset_role(self);
+               return;
+       }
+
+       if (self.bot_strategytime < time)
+       {
+               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+
+               navigation_goalrating_start();
+               if(ctf_oneflag)
+                       havocbot_goalrating_ctf_enemybase(50000);
+               else
+                       havocbot_goalrating_ctf_ourbase(50000);
+
+               if(self.health<100)
+                       havocbot_goalrating_ctf_carrieritems(1000, self.origin, 1000);
+
+               navigation_goalrating_end();
+
+               if (self.navigation_hasgoals)
+                       self.havocbot_cantfindflag = time + 10;
+               else if (time > self.havocbot_cantfindflag)
+               {
+                       // Can't navigate to my own base, suicide!
+                       // TODO: drop it and wander around
+                       Damage(self, self, self, 100000, DEATH_KILL.m_id, self.origin, '0 0 0');
+                       return;
+               }
+       }
+}
+
+void havocbot_role_ctf_escort()
+{SELFPARAM();
+       entity mf, ef;
+
+       if(self.deadflag != DEAD_NO)
+       {
+               havocbot_ctf_reset_role(self);
+               return;
+       }
+
+       if (self.flagcarried)
+       {
+               havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_CARRIER);
+               return;
+       }
+
+       // If enemy flag is back on the base switch to previous role
+       ef = havocbot_ctf_find_enemy_flag(self);
+       if(ef.ctf_status==FLAG_BASE)
+       {
+               self.havocbot_role = self.havocbot_previous_role;
+               self.havocbot_role_timeout = 0;
+               return;
+       }
+
+       // If the flag carrier reached the base switch to defense
+       mf = havocbot_ctf_find_flag(self);
+       if(mf.ctf_status!=FLAG_BASE)
+       if(vlen(ef.origin - mf.dropped_origin) < 300)
+       {
+               havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_DEFENSE);
+               return;
+       }
+
+       // Set the role timeout if necessary
+       if (!self.havocbot_role_timeout)
+       {
+               self.havocbot_role_timeout = time + random() * 30 + 60;
+       }
+
+       // If nothing happened just switch to previous role
+       if (time > self.havocbot_role_timeout)
+       {
+               self.havocbot_role = self.havocbot_previous_role;
+               self.havocbot_role_timeout = 0;
+               return;
+       }
+
+       // Chase the flag carrier
+       if (self.bot_strategytime < time)
+       {
+               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+               navigation_goalrating_start();
+               havocbot_goalrating_ctf_enemyflag(30000);
+               havocbot_goalrating_ctf_ourstolenflag(40000);
+               havocbot_goalrating_items(10000, self.origin, 10000);
+               navigation_goalrating_end();
+       }
+}
+
+void havocbot_role_ctf_offense()
+{SELFPARAM();
+       entity mf, ef;
+       vector pos;
+
+       if(self.deadflag != DEAD_NO)
+       {
+               havocbot_ctf_reset_role(self);
+               return;
+       }
+
+       if (self.flagcarried)
+       {
+               havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_CARRIER);
+               return;
+       }
+
+       // Check flags
+       mf = havocbot_ctf_find_flag(self);
+       ef = havocbot_ctf_find_enemy_flag(self);
+
+       // Own flag stolen
+       if(mf.ctf_status!=FLAG_BASE)
+       {
+               if(mf.tag_entity)
+                       pos = mf.tag_entity.origin;
+               else
+                       pos = mf.origin;
+
+               // Try to get it if closer than the enemy base
+               if(vlen(self.origin-ef.dropped_origin)>vlen(self.origin-pos))
+               {
+                       havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_RETRIEVER);
+                       return;
+               }
+       }
+
+       // Escort flag carrier
+       if(ef.ctf_status!=FLAG_BASE)
+       {
+               if(ef.tag_entity)
+                       pos = ef.tag_entity.origin;
+               else
+                       pos = ef.origin;
+
+               if(vlen(pos-mf.dropped_origin)>700)
+               {
+                       havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_ESCORT);
+                       return;
+               }
+       }
+
+       // About to fail, switch to middlefield
+       if(self.health<50)
+       {
+               havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_MIDDLE);
+               return;
+       }
+
+       // Set the role timeout if necessary
+       if (!self.havocbot_role_timeout)
+               self.havocbot_role_timeout = time + 120;
+
+       if (time > self.havocbot_role_timeout)
+       {
+               havocbot_ctf_reset_role(self);
+               return;
+       }
+
+       if (self.bot_strategytime < time)
+       {
+               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+               navigation_goalrating_start();
+               havocbot_goalrating_ctf_ourstolenflag(50000);
+               havocbot_goalrating_ctf_enemybase(20000);
+               havocbot_goalrating_items(5000, self.origin, 1000);
+               havocbot_goalrating_items(1000, self.origin, 10000);
+               navigation_goalrating_end();
+       }
+}
+
+// Retriever (temporary role):
+void havocbot_role_ctf_retriever()
+{SELFPARAM();
+       entity mf;
+
+       if(self.deadflag != DEAD_NO)
+       {
+               havocbot_ctf_reset_role(self);
+               return;
+       }
+
+       if (self.flagcarried)
+       {
+               havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_CARRIER);
+               return;
+       }
+
+       // If flag is back on the base switch to previous role
+       mf = havocbot_ctf_find_flag(self);
+       if(mf.ctf_status==FLAG_BASE)
+       {
+               havocbot_ctf_reset_role(self);
+               return;
+       }
+
+       if (!self.havocbot_role_timeout)
+               self.havocbot_role_timeout = time + 20;
+
+       if (time > self.havocbot_role_timeout)
+       {
+               havocbot_ctf_reset_role(self);
+               return;
+       }
+
+       if (self.bot_strategytime < time)
+       {
+               float rt_radius;
+               rt_radius = 10000;
+
+               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+               navigation_goalrating_start();
+               havocbot_goalrating_ctf_ourstolenflag(50000);
+               havocbot_goalrating_ctf_droppedflags(40000, self.origin, rt_radius);
+               havocbot_goalrating_ctf_enemybase(30000);
+               havocbot_goalrating_items(500, self.origin, rt_radius);
+               navigation_goalrating_end();
+       }
+}
+
+void havocbot_role_ctf_middle()
+{SELFPARAM();
+       entity mf;
+
+       if(self.deadflag != DEAD_NO)
+       {
+               havocbot_ctf_reset_role(self);
+               return;
+       }
+
+       if (self.flagcarried)
+       {
+               havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_CARRIER);
+               return;
+       }
+
+       mf = havocbot_ctf_find_flag(self);
+       if(mf.ctf_status!=FLAG_BASE)
+       {
+               havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_RETRIEVER);
+               return;
+       }
+
+       if (!self.havocbot_role_timeout)
+               self.havocbot_role_timeout = time + 10;
+
+       if (time > self.havocbot_role_timeout)
+       {
+               havocbot_ctf_reset_role(self);
+               return;
+       }
+
+       if (self.bot_strategytime < time)
+       {
+               vector org;
+
+               org = havocbot_ctf_middlepoint;
+               org.z = self.origin.z;
+
+               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+               navigation_goalrating_start();
+               havocbot_goalrating_ctf_ourstolenflag(50000);
+               havocbot_goalrating_ctf_droppedflags(30000, self.origin, 10000);
+               havocbot_goalrating_enemyplayers(10000, org, havocbot_ctf_middlepoint_radius * 0.5);
+               havocbot_goalrating_items(5000, org, havocbot_ctf_middlepoint_radius * 0.5);
+               havocbot_goalrating_items(2500, self.origin, 10000);
+               havocbot_goalrating_ctf_enemybase(2500);
+               navigation_goalrating_end();
+       }
+}
+
+void havocbot_role_ctf_defense()
+{SELFPARAM();
+       entity mf;
+
+       if(self.deadflag != DEAD_NO)
+       {
+               havocbot_ctf_reset_role(self);
+               return;
+       }
+
+       if (self.flagcarried)
+       {
+               havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_CARRIER);
+               return;
+       }
+
+       // If own flag was captured
+       mf = havocbot_ctf_find_flag(self);
+       if(mf.ctf_status!=FLAG_BASE)
+       {
+               havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_RETRIEVER);
+               return;
+       }
+
+       if (!self.havocbot_role_timeout)
+               self.havocbot_role_timeout = time + 30;
+
+       if (time > self.havocbot_role_timeout)
+       {
+               havocbot_ctf_reset_role(self);
+               return;
+       }
+       if (self.bot_strategytime < time)
+       {
+               float mp_radius;
+               vector org;
+
+               org = mf.dropped_origin;
+               mp_radius = havocbot_ctf_middlepoint_radius;
+
+               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+               navigation_goalrating_start();
+
+               // if enemies are closer to our base, go there
+               entity head, closestplayer = world;
+               float distance, bestdistance = 10000;
+               FOR_EACH_PLAYER(head)
+               {
+                       if(head.deadflag!=DEAD_NO)
+                               continue;
+
+                       distance = vlen(org - head.origin);
+                       if(distance<bestdistance)
+                       {
+                               closestplayer = head;
+                               bestdistance = distance;
+                       }
+               }
+
+               if(closestplayer)
+               if(DIFF_TEAM(closestplayer, self))
+               if(vlen(org - self.origin)>1000)
+               if(checkpvs(self.origin,closestplayer)||random()<0.5)
+                       havocbot_goalrating_ctf_ourbase(30000);
+
+               havocbot_goalrating_ctf_ourstolenflag(20000);
+               havocbot_goalrating_ctf_droppedflags(20000, org, mp_radius);
+               havocbot_goalrating_enemyplayers(15000, org, mp_radius);
+               havocbot_goalrating_items(10000, org, mp_radius);
+               havocbot_goalrating_items(5000, self.origin, 10000);
+               navigation_goalrating_end();
+       }
+}
+
+void havocbot_role_ctf_setrole(entity bot, int role)
+{
+       LOG_TRACE(strcat(bot.netname," switched to "));
+       switch(role)
+       {
+               case HAVOCBOT_CTF_ROLE_CARRIER:
+                       LOG_TRACE("carrier");
+                       bot.havocbot_role = havocbot_role_ctf_carrier;
+                       bot.havocbot_role_timeout = 0;
+                       bot.havocbot_cantfindflag = time + 10;
+                       bot.bot_strategytime = 0;
+                       break;
+               case HAVOCBOT_CTF_ROLE_DEFENSE:
+                       LOG_TRACE("defense");
+                       bot.havocbot_role = havocbot_role_ctf_defense;
+                       bot.havocbot_role_timeout = 0;
+                       break;
+               case HAVOCBOT_CTF_ROLE_MIDDLE:
+                       LOG_TRACE("middle");
+                       bot.havocbot_role = havocbot_role_ctf_middle;
+                       bot.havocbot_role_timeout = 0;
+                       break;
+               case HAVOCBOT_CTF_ROLE_OFFENSE:
+                       LOG_TRACE("offense");
+                       bot.havocbot_role = havocbot_role_ctf_offense;
+                       bot.havocbot_role_timeout = 0;
+                       break;
+               case HAVOCBOT_CTF_ROLE_RETRIEVER:
+                       LOG_TRACE("retriever");
+                       bot.havocbot_previous_role = bot.havocbot_role;
+                       bot.havocbot_role = havocbot_role_ctf_retriever;
+                       bot.havocbot_role_timeout = time + 10;
+                       bot.bot_strategytime = 0;
+                       break;
+               case HAVOCBOT_CTF_ROLE_ESCORT:
+                       LOG_TRACE("escort");
+                       bot.havocbot_previous_role = bot.havocbot_role;
+                       bot.havocbot_role = havocbot_role_ctf_escort;
+                       bot.havocbot_role_timeout = time + 30;
+                       bot.bot_strategytime = 0;
+                       break;
+       }
+       LOG_TRACE("\n");
+}
+
+
+// ==============
+// Hook Functions
+// ==============
+
+MUTATOR_HOOKFUNCTION(ctf, PlayerPreThink)
+{SELFPARAM();
+       entity flag;
+       int t = 0, t2 = 0, t3 = 0;
+
+       // initially clear items so they can be set as necessary later.
+       self.ctf_flagstatus &= ~(CTF_RED_FLAG_CARRYING          | CTF_RED_FLAG_TAKEN            | CTF_RED_FLAG_LOST
+                                                  | CTF_BLUE_FLAG_CARRYING             | CTF_BLUE_FLAG_TAKEN           | CTF_BLUE_FLAG_LOST
+                                                  | CTF_YELLOW_FLAG_CARRYING   | CTF_YELLOW_FLAG_TAKEN         | CTF_YELLOW_FLAG_LOST
+                                                  | CTF_PINK_FLAG_CARRYING     | CTF_PINK_FLAG_TAKEN           | CTF_PINK_FLAG_LOST
+                                                  | CTF_NEUTRAL_FLAG_CARRYING  | CTF_NEUTRAL_FLAG_TAKEN        | CTF_NEUTRAL_FLAG_LOST
+                                                  | CTF_FLAG_NEUTRAL | CTF_SHIELDED);
+
+       // scan through all the flags and notify the client about them
+       for(flag = ctf_worldflaglist; flag; flag = flag.ctf_worldflagnext)
+       {
+               if(flag.team == NUM_TEAM_1) { t = CTF_RED_FLAG_CARRYING;                t2 = CTF_RED_FLAG_TAKEN;                t3 = CTF_RED_FLAG_LOST; }
+               if(flag.team == NUM_TEAM_2) { t = CTF_BLUE_FLAG_CARRYING;               t2 = CTF_BLUE_FLAG_TAKEN;               t3 = CTF_BLUE_FLAG_LOST; }
+               if(flag.team == NUM_TEAM_3) { t = CTF_YELLOW_FLAG_CARRYING;     t2 = CTF_YELLOW_FLAG_TAKEN;             t3 = CTF_YELLOW_FLAG_LOST; }
+               if(flag.team == NUM_TEAM_4) { t = CTF_PINK_FLAG_CARRYING;               t2 = CTF_PINK_FLAG_TAKEN;               t3 = CTF_PINK_FLAG_LOST; }
+               if(flag.team == 0)                      { t = CTF_NEUTRAL_FLAG_CARRYING;        t2 = CTF_NEUTRAL_FLAG_TAKEN;    t3 = CTF_NEUTRAL_FLAG_LOST; self.ctf_flagstatus |= CTF_FLAG_NEUTRAL; }
+
+               switch(flag.ctf_status)
+               {
+                       case FLAG_PASSING:
+                       case FLAG_CARRY:
+                       {
+                               if((flag.owner == self) || (flag.pass_sender == self))
+                                       self.ctf_flagstatus |= t; // carrying: self is currently carrying the flag
+                               else
+                                       self.ctf_flagstatus |= t2; // taken: someone else is carrying the flag
+                               break;
+                       }
+                       case FLAG_DROPPED:
+                       {
+                               self.ctf_flagstatus |= t3; // lost: the flag is dropped somewhere on the map
+                               break;
+                       }
+               }
+       }
+
+       // item for stopping players from capturing the flag too often
+       if(self.ctf_captureshielded)
+               self.ctf_flagstatus |= CTF_SHIELDED;
+
+       // update the health of the flag carrier waypointsprite
+       if(self.wps_flagcarrier)
+               WaypointSprite_UpdateHealth(self.wps_flagcarrier, '1 0 0' * healtharmor_maxdamage(self.health, self.armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id));
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ctf, PlayerDamage_Calculate) // for changing damage and force values that are applied to players in g_damage.qc
+{
+       if(frag_attacker.flagcarried) // if the attacker is a flagcarrier
+       {
+               if(frag_target == frag_attacker) // damage done to yourself
+               {
+                       frag_damage *= autocvar_g_ctf_flagcarrier_selfdamagefactor;
+                       frag_force *= autocvar_g_ctf_flagcarrier_selfforcefactor;
+               }
+               else // damage done to everyone else
+               {
+                       frag_damage *= autocvar_g_ctf_flagcarrier_damagefactor;
+                       frag_force *= autocvar_g_ctf_flagcarrier_forcefactor;
+               }
+       }
+       else if(frag_target.flagcarried && (frag_target.deadflag == DEAD_NO) && CTF_DIFFTEAM(frag_target, frag_attacker)) // if the target is a flagcarrier
+       {
+               if(autocvar_g_ctf_flagcarrier_auto_helpme_damage > ('1 0 0' * healtharmor_maxdamage(frag_target.health, frag_target.armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id)))
+               if(time > frag_target.wps_helpme_time + autocvar_g_ctf_flagcarrier_auto_helpme_time)
+               {
+                       frag_target.wps_helpme_time = time;
+                       WaypointSprite_HelpMePing(frag_target.wps_flagcarrier);
+               }
+               // todo: add notification for when flag carrier needs help?
+       }
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ctf, PlayerDies)
+{
+       if((frag_attacker != frag_target) && (IS_PLAYER(frag_attacker)) && (frag_target.flagcarried))
+       {
+               PlayerTeamScore_AddScore(frag_attacker, autocvar_g_ctf_score_kill);
+               PlayerScore_Add(frag_attacker, SP_CTF_FCKILLS, 1);
+       }
+
+       if(frag_target.flagcarried)
+       {
+               entity tmp_entity = frag_target.flagcarried;
+               ctf_Handle_Throw(frag_target, world, DROP_NORMAL);
+               tmp_entity.ctf_dropper = world;
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ctf, GiveFragsForKill)
+{
+       frag_score = 0;
+       return (autocvar_g_ctf_ignore_frags); // no frags counted in ctf if this is true
+}
+
+void ctf_RemovePlayer(entity player)
+{
+       if(player.flagcarried)
+               { ctf_Handle_Throw(player, world, DROP_NORMAL); }
+
+       for(entity flag = ctf_worldflaglist; flag; flag = flag.ctf_worldflagnext)
+       {
+               if(flag.pass_sender == player) { flag.pass_sender = world; }
+               if(flag.pass_target == player) { flag.pass_target = world; }
+               if(flag.ctf_dropper == player) { flag.ctf_dropper = world; }
+       }
+}
+
+MUTATOR_HOOKFUNCTION(ctf, MakePlayerObserver)
+{SELFPARAM();
+       ctf_RemovePlayer(self);
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ctf, ClientDisconnect)
+{SELFPARAM();
+       ctf_RemovePlayer(self);
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ctf, PortalTeleport)
+{SELFPARAM();
+       if(self.flagcarried)
+       if(!autocvar_g_ctf_portalteleport)
+               { ctf_Handle_Throw(self, world, DROP_NORMAL); }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ctf, PlayerUseKey)
+{SELFPARAM();
+       if(MUTATOR_RETURNVALUE || gameover) { return false; }
+
+       entity player = self;
+
+       if((time > player.throw_antispam) && (player.deadflag == DEAD_NO) && !player.speedrunning && (!player.vehicle || autocvar_g_ctf_allow_vehicle_touch))
+       {
+               // pass the flag to a team mate
+               if(autocvar_g_ctf_pass)
+               {
+                       entity head, closest_target = world;
+                       head = WarpZone_FindRadius(player.origin, autocvar_g_ctf_pass_radius, true);
+
+                       while(head) // find the closest acceptable target to pass to
+                       {
+                               if(IS_PLAYER(head) && head.deadflag == DEAD_NO)
+                               if(head != player && SAME_TEAM(head, player))
+                               if(!head.speedrunning && !head.vehicle)
+                               {
+                                       // if it's a player, use the view origin as reference (stolen from RadiusDamage functions in g_damage.qc)
+                                       vector head_center = WarpZone_UnTransformOrigin(head, CENTER_OR_VIEWOFS(head));
+                                       vector passer_center = CENTER_OR_VIEWOFS(player);
+
+                                       if(ctf_CheckPassDirection(head_center, passer_center, player.v_angle, head.WarpZone_findradius_nearest))
+                                       {
+                                               if(autocvar_g_ctf_pass_request && !player.flagcarried && head.flagcarried)
+                                               {
+                                                       if(IS_BOT_CLIENT(head))
+                                                       {
+                                                               Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_PASS_REQUESTING, head.netname);
+                                                               ctf_Handle_Throw(head, player, DROP_PASS);
+                                                       }
+                                                       else
+                                                       {
+                                                               Send_Notification(NOTIF_ONE, head, MSG_CENTER, CENTER_CTF_PASS_REQUESTED, player.netname);
+                                                               Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_PASS_REQUESTING, head.netname);
+                                                       }
+                                                       player.throw_antispam = time + autocvar_g_ctf_pass_wait;
+                                                       return true;
+                                               }
+                                               else if(player.flagcarried)
+                                               {
+                                                       if(closest_target)
+                                                       {
+                                                               vector closest_target_center = WarpZone_UnTransformOrigin(closest_target, CENTER_OR_VIEWOFS(closest_target));
+                                                               if(vlen(passer_center - head_center) < vlen(passer_center - closest_target_center))
+                                                                       { closest_target = head; }
+                                                       }
+                                                       else { closest_target = head; }
+                                               }
+                                       }
+                               }
+                               head = head.chain;
+                       }
+
+                       if(closest_target) { ctf_Handle_Throw(player, closest_target, DROP_PASS); return true; }
+               }
+
+               // throw the flag in front of you
+               if(autocvar_g_ctf_throw && player.flagcarried)
+               {
+                       if(player.throw_count == -1)
+                       {
+                               if(time > player.throw_prevtime + autocvar_g_ctf_throw_punish_delay)
+                               {
+                                       player.throw_prevtime = time;
+                                       player.throw_count = 1;
+                                       ctf_Handle_Throw(player, world, DROP_THROW);
+                                       return true;
+                               }
+                               else
+                               {
+                                       Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_CTF_FLAG_THROW_PUNISH, rint((player.throw_prevtime + autocvar_g_ctf_throw_punish_delay) - time));
+                                       return false;
+                               }
+                       }
+                       else
+                       {
+                               if(time > player.throw_prevtime + autocvar_g_ctf_throw_punish_time) { player.throw_count = 1; }
+                               else { player.throw_count += 1; }
+                               if(player.throw_count >= autocvar_g_ctf_throw_punish_count) { player.throw_count = -1; }
+
+                               player.throw_prevtime = time;
+                               ctf_Handle_Throw(player, world, DROP_THROW);
+                               return true;
+                       }
+               }
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ctf, HelpMePing)
+{SELFPARAM();
+       if(self.wps_flagcarrier) // update the flagcarrier waypointsprite with "NEEDING HELP" notification
+       {
+               self.wps_helpme_time = time;
+               WaypointSprite_HelpMePing(self.wps_flagcarrier);
+       }
+       else // create a normal help me waypointsprite
+       {
+               WaypointSprite_Spawn(WP_Helpme, waypointsprite_deployed_lifetime, waypointsprite_limitedrange, self, FLAG_WAYPOINT_OFFSET, world, self.team, self, wps_helpme, false, RADARICON_HELPME);
+               WaypointSprite_Ping(self.wps_helpme);
+       }
+
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(ctf, VehicleEnter)
+{
+       if(vh_player.flagcarried)
+       {
+               vh_player.flagcarried.nodrawtoclient = vh_player; // hide the flag from the driver
+
+               if(!autocvar_g_ctf_allow_vehicle_carry && !autocvar_g_ctf_allow_vehicle_touch)
+               {
+                       ctf_Handle_Throw(vh_player, world, DROP_NORMAL);
+               }
+               else
+               {
+                       setattachment(vh_player.flagcarried, vh_vehicle, "");
+                       setorigin(vh_player.flagcarried, VEHICLE_FLAG_OFFSET);
+                       vh_player.flagcarried.scale = VEHICLE_FLAG_SCALE;
+                       //vh_player.flagcarried.angles = '0 0 0';
+               }
+               return true;
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ctf, VehicleExit)
+{
+       if(vh_player.flagcarried)
+       {
+               setattachment(vh_player.flagcarried, vh_player, "");
+               setorigin(vh_player.flagcarried, FLAG_CARRY_OFFSET);
+               vh_player.flagcarried.scale = FLAG_SCALE;
+               vh_player.flagcarried.angles = '0 0 0';
+               vh_player.flagcarried.nodrawtoclient = world;
+               return true;
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ctf, AbortSpeedrun)
+{SELFPARAM();
+       if(self.flagcarried)
+       {
+               Send_Notification(NOTIF_ALL, world, MSG_INFO, ((self.flagcarried.team) ? APP_TEAM_ENT_4(self.flagcarried, INFO_CTF_FLAGRETURN_ABORTRUN_) : INFO_CTF_FLAGRETURN_ABORTRUN_NEUTRAL));
+               ctf_RespawnFlag(self.flagcarried);
+               return true;
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ctf, MatchEnd)
+{
+       entity flag; // temporary entity for the search method
+
+       for(flag = ctf_worldflaglist; flag; flag = flag.ctf_worldflagnext)
+       {
+               switch(flag.ctf_status)
+               {
+                       case FLAG_DROPPED:
+                       case FLAG_PASSING:
+                       {
+                               // lock the flag, game is over
+                               flag.movetype = MOVETYPE_NONE;
+                               flag.takedamage = DAMAGE_NO;
+                               flag.solid = SOLID_NOT;
+                               flag.nextthink = false; // stop thinking
+
+                               //dprint("stopping the ", flag.netname, " from moving.\n");
+                               break;
+                       }
+
+                       default:
+                       case FLAG_BASE:
+                       case FLAG_CARRY:
+                       {
+                               // do nothing for these flags
+                               break;
+                       }
+               }
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ctf, HavocBot_ChooseRole)
+{SELFPARAM();
+       havocbot_ctf_reset_role(self);
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(ctf, GetTeamCount)
+{
+       //ret_float = ctf_teams;
+       ret_string = "ctf_team";
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(ctf, SpectateCopy)
+{SELFPARAM();
+       self.ctf_flagstatus = other.ctf_flagstatus;
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ctf, GetRecords)
+{
+       for(int i = record_page * 200; i < MapInfo_count && i < record_page * 200 + 200; ++i)
+       {
+               if (MapInfo_Get_ByID(i))
+               {
+                       float r = stof(db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, "/captimerecord/time")));
+
+                       if(!r)
+                               continue;
+
+                       // TODO: uid2name
+                       string h = db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, "/captimerecord/netname"));
+                       ret_string = strcat(ret_string, strpad(32, MapInfo_Map_bspname), " ", strpad(-6, ftos_decimals(r, 2)), " ", h, "\n");
+               }
+       }
+
+       return false;
+}
+
+bool superspec_Spectate(entity _player); // TODO
+void superspec_msg(string _center_title, string _con_title, entity _to, string _msg, float _spamlevel); // TODO
+MUTATOR_HOOKFUNCTION(ctf, SV_ParseClientCommand)
+{
+       if(IS_PLAYER(self) || MUTATOR_RETURNVALUE || !cvar("g_superspectate")) { return false; }
+
+       if(cmd_name == "followfc")
+       {
+               if(!g_ctf)
+                       return true;
+
+               entity _player;
+               int _team = 0;
+               bool found = false;
+
+               if(cmd_argc == 2)
+               {
+                       switch(argv(1))
+                       {
+                               case "red": _team = NUM_TEAM_1; break;
+                               case "blue": _team = NUM_TEAM_2; break;
+                               case "yellow": if(ctf_teams >= 3) _team = NUM_TEAM_3; break;
+                               case "pink": if(ctf_teams >= 4) _team = NUM_TEAM_4; break;
+                       }
+               }
+
+               FOR_EACH_PLAYER(_player)
+               {
+                       if(_player.flagcarried && (_player.team == _team || _team == 0))
+                       {
+                               found = true;
+                               if(_team == 0 && IS_SPEC(self) && self.enemy == _player)
+                                       continue; // already spectating a fc, try to find the other fc
+                               return superspec_Spectate(_player);
+                       }
+               }
+
+               if(!found)
+                       superspec_msg("", "", self, "No active flag carrier\n", 1);
+               return true;
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ctf, DropSpecialItems)
+{
+       if(frag_target.flagcarried)
+               ctf_Handle_Throw(frag_target, world, DROP_THROW);
+
+       return false;
+}
+
+
+// ==========
+// Spawnfuncs
+// ==========
+
+/*QUAKED spawnfunc_item_flag_team1 (0 0.5 0.8) (-48 -48 -37) (48 48 37)
+CTF flag for team one (Red).
+Keys:
+"angle" Angle the flag will point (minus 90 degrees)...
+"model" model to use, note this needs red and blue as skins 0 and 1...
+"noise" sound played when flag is picked up...
+"noise1" sound played when flag is returned by a teammate...
+"noise2" sound played when flag is captured...
+"noise3" sound played when flag is lost in the field and respawns itself...
+"noise4" sound played when flag is dropped by a player...
+"noise5" sound played when flag touches the ground... */
+spawnfunc(item_flag_team1)
+{
+       if(!g_ctf) { remove(self); return; }
+
+       ctf_FlagSetup(NUM_TEAM_1, self);
+}
+
+/*QUAKED spawnfunc_item_flag_team2 (0 0.5 0.8) (-48 -48 -37) (48 48 37)
+CTF flag for team two (Blue).
+Keys:
+"angle" Angle the flag will point (minus 90 degrees)...
+"model" model to use, note this needs red and blue as skins 0 and 1...
+"noise" sound played when flag is picked up...
+"noise1" sound played when flag is returned by a teammate...
+"noise2" sound played when flag is captured...
+"noise3" sound played when flag is lost in the field and respawns itself...
+"noise4" sound played when flag is dropped by a player...
+"noise5" sound played when flag touches the ground... */
+spawnfunc(item_flag_team2)
+{
+       if(!g_ctf) { remove(self); return; }
+
+       ctf_FlagSetup(NUM_TEAM_2, self);
+}
+
+/*QUAKED spawnfunc_item_flag_team3 (0 0.5 0.8) (-48 -48 -37) (48 48 37)
+CTF flag for team three (Yellow).
+Keys:
+"angle" Angle the flag will point (minus 90 degrees)...
+"model" model to use, note this needs red, blue yellow and pink as skins 0, 1, 2 and 3...
+"noise" sound played when flag is picked up...
+"noise1" sound played when flag is returned by a teammate...
+"noise2" sound played when flag is captured...
+"noise3" sound played when flag is lost in the field and respawns itself...
+"noise4" sound played when flag is dropped by a player...
+"noise5" sound played when flag touches the ground... */
+spawnfunc(item_flag_team3)
+{
+       if(!g_ctf) { remove(self); return; }
+
+       ctf_FlagSetup(NUM_TEAM_3, self);
+}
+
+/*QUAKED spawnfunc_item_flag_team4 (0 0.5 0.8) (-48 -48 -37) (48 48 37)
+CTF flag for team four (Pink).
+Keys:
+"angle" Angle the flag will point (minus 90 degrees)...
+"model" model to use, note this needs red, blue yellow and pink as skins 0, 1, 2 and 3...
+"noise" sound played when flag is picked up...
+"noise1" sound played when flag is returned by a teammate...
+"noise2" sound played when flag is captured...
+"noise3" sound played when flag is lost in the field and respawns itself...
+"noise4" sound played when flag is dropped by a player...
+"noise5" sound played when flag touches the ground... */
+spawnfunc(item_flag_team4)
+{
+       if(!g_ctf) { remove(self); return; }
+
+       ctf_FlagSetup(NUM_TEAM_4, self);
+}
+
+/*QUAKED spawnfunc_item_flag_neutral (0 0.5 0.8) (-48 -48 -37) (48 48 37)
+CTF flag (Neutral).
+Keys:
+"angle" Angle the flag will point (minus 90 degrees)...
+"model" model to use, note this needs red, blue yellow and pink as skins 0, 1, 2 and 3...
+"noise" sound played when flag is picked up...
+"noise1" sound played when flag is returned by a teammate...
+"noise2" sound played when flag is captured...
+"noise3" sound played when flag is lost in the field and respawns itself...
+"noise4" sound played when flag is dropped by a player...
+"noise5" sound played when flag touches the ground... */
+spawnfunc(item_flag_neutral)
+{
+       if(!g_ctf) { remove(self); return; }
+       if(!cvar("g_ctf_oneflag")) { remove(self); return; }
+
+       ctf_FlagSetup(0, self);
+}
+
+/*QUAKED spawnfunc_ctf_team (0 .5 .8) (-16 -16 -24) (16 16 32)
+Team declaration for CTF gameplay, this allows you to decide what team names and control point models are used in your map.
+Note: If you use spawnfunc_ctf_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)... */
+spawnfunc(ctf_team)
+{
+       if(!g_ctf) { remove(self); return; }
+
+       self.classname = "ctf_team";
+       self.team = self.cnt + 1;
+}
+
+// compatibility for quake maps
+spawnfunc(team_CTF_redflag)    { spawnfunc_item_flag_team1(this);    }
+spawnfunc(team_CTF_blueflag)   { spawnfunc_item_flag_team2(this);    }
+spawnfunc(info_player_team1);
+spawnfunc(team_CTF_redplayer)  { spawnfunc_info_player_team1(this);  }
+spawnfunc(team_CTF_redspawn)   { spawnfunc_info_player_team1(this);  }
+spawnfunc(info_player_team2);
+spawnfunc(team_CTF_blueplayer) { spawnfunc_info_player_team2(this);  }
+spawnfunc(team_CTF_bluespawn)  { spawnfunc_info_player_team2(this);  }
+
+void team_CTF_neutralflag()                     { SELFPARAM(); spawnfunc_item_flag_neutral(self);  }
+void team_neutralobelisk()                      { SELFPARAM(); spawnfunc_item_flag_neutral(self);  }
+
+
+// ==============
+// Initialization
+// ==============
+
+// scoreboard setup
+void ctf_ScoreRules(int teams)
+{
+       CheckAllowedTeams(world);
+       ScoreRules_basics(teams, SFL_SORT_PRIO_PRIMARY, 0, true);
+       ScoreInfo_SetLabel_TeamScore  (ST_CTF_CAPS,     "caps",      SFL_SORT_PRIO_PRIMARY);
+       ScoreInfo_SetLabel_PlayerScore(SP_CTF_CAPS,     "caps",      SFL_SORT_PRIO_SECONDARY);
+       ScoreInfo_SetLabel_PlayerScore(SP_CTF_CAPTIME,  "captime",   SFL_LOWER_IS_BETTER | SFL_TIME);
+       ScoreInfo_SetLabel_PlayerScore(SP_CTF_PICKUPS,  "pickups",   0);
+       ScoreInfo_SetLabel_PlayerScore(SP_CTF_FCKILLS,  "fckills",   0);
+       ScoreInfo_SetLabel_PlayerScore(SP_CTF_RETURNS,  "returns",   0);
+       ScoreInfo_SetLabel_PlayerScore(SP_CTF_DROPS,    "drops",     SFL_LOWER_IS_BETTER);
+       ScoreRules_basics_end();
+}
+
+// code from here on is just to support maps that don't have flag and team entities
+void ctf_SpawnTeam (string teamname, int teamcolor)
+{
+       entity this = new(ctf_team);
+       this.netname = teamname;
+       this.cnt = teamcolor;
+       this.spawnfunc_checked = true;
+       WITH(entity, self, this, spawnfunc_ctf_team(this));
+}
+
+void ctf_DelayedInit() // Do this check with a delay so we can wait for teams to be set up.
+{
+       ctf_teams = 2;
+
+       entity tmp_entity;
+       for(tmp_entity = ctf_worldflaglist; tmp_entity; tmp_entity = tmp_entity.ctf_worldflagnext)
+       {
+               if(tmp_entity.team == NUM_TEAM_3) { ctf_teams = max(3, ctf_teams); }
+               if(tmp_entity.team == NUM_TEAM_4) { ctf_teams = max(4, ctf_teams); }
+               if(tmp_entity.team == 0) { ctf_oneflag = true; }
+       }
+
+       ctf_teams = bound(2, ctf_teams, 4);
+
+       // if no teams are found, spawn defaults
+       if(find(world, classname, "ctf_team") == world)
+       {
+               LOG_INFO("No ""ctf_team"" entities found on this map, creating them anyway.\n");
+               ctf_SpawnTeam("Red", NUM_TEAM_1 - 1);
+               ctf_SpawnTeam("Blue", NUM_TEAM_2 - 1);
+               if(ctf_teams >= 3)
+                       ctf_SpawnTeam("Yellow", NUM_TEAM_3 - 1);
+               if(ctf_teams >= 4)
+                       ctf_SpawnTeam("Pink", NUM_TEAM_4 - 1);
+       }
+
+       ctf_ScoreRules(ctf_teams);
+}
+
+void ctf_Initialize()
+{
+       ctf_captimerecord = stof(db_get(ServerProgsDB, strcat(GetMapname(), "/captimerecord/time")));
+
+       ctf_captureshield_min_negscore = autocvar_g_ctf_shield_min_negscore;
+       ctf_captureshield_max_ratio = autocvar_g_ctf_shield_max_ratio;
+       ctf_captureshield_force = autocvar_g_ctf_shield_force;
+
+       addstat(STAT_CTF_FLAGSTATUS, AS_INT, ctf_flagstatus);
+
+       InitializeEntity(world, ctf_DelayedInit, INITPRIO_GAMETYPE);
+}
+
+#endif
diff --git a/qcsrc/server/mutators/mutator/gamemode_cts.qc b/qcsrc/server/mutators/mutator/gamemode_cts.qc
new file mode 100644 (file)
index 0000000..0640311
--- /dev/null
@@ -0,0 +1,450 @@
+#include "../../race.qh"
+
+#ifndef GAMEMODE_CTS_H
+#define GAMEMODE_CTS_H
+
+void cts_Initialize();
+
+REGISTER_MUTATOR(cts, false)
+{
+       g_race_qualifying = true;
+       independent_players = 1;
+       SetLimits(0, 0, 0, -1);
+
+       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
+       {
+               LOG_INFO("This is a game type and it cannot be removed at runtime.");
+               return -1;
+       }
+
+       return 0;
+}
+
+// scores
+const float ST_CTS_LAPS = 1;
+const float SP_CTS_LAPS = 4;
+const float SP_CTS_TIME = 5;
+const float SP_CTS_FASTEST = 6;
+#endif
+
+#ifdef IMPLEMENTATION
+
+#include "../../race.qh"
+
+float autocvar_g_cts_finish_kill_delay;
+bool autocvar_g_cts_selfdamage;
+
+// legacy bot roles
+.float race_checkpoint;
+void havocbot_role_cts()
+{SELFPARAM();
+       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))) : "")));
+}
+
+void CTS_ClientKill(entity e) // silent version of ClientKill, used when player finishes a CTS run. Useful to prevent cheating by running back to the start line and starting out with more speed
+{
+    e.killindicator = spawn();
+    e.killindicator.owner = e;
+    e.killindicator.think = KillIndicator_Think;
+    e.killindicator.nextthink = time + (e.lip) * 0.05;
+    e.killindicator.cnt = ceil(autocvar_g_cts_finish_kill_delay);
+    e.killindicator.health = 1; // this is used to indicate that it should be silent
+    e.lip = 0;
+}
+
+MUTATOR_HOOKFUNCTION(cts, PlayerPhysics)
+{SELFPARAM();
+       self.race_movetime_frac += PHYS_INPUT_TIMELENGTH;
+       float f = floor(self.race_movetime_frac);
+       self.race_movetime_frac -= f;
+       self.race_movetime_count += f;
+       self.race_movetime = self.race_movetime_frac + self.race_movetime_count;
+
+#ifdef SVQC
+       if(IS_PLAYER(self))
+       {
+               if (self.race_penalty)
+                       if (time > self.race_penalty)
+                               self.race_penalty = 0;
+               if(self.race_penalty)
+               {
+                       self.velocity = '0 0 0';
+                       self.movetype = MOVETYPE_NONE;
+                       self.disableclientprediction = 2;
+               }
+       }
+#endif
+
+       // 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, reset_map_global)
+{
+       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)
+{SELFPARAM();
+       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)
+{SELFPARAM();
+       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)
+{SELFPARAM();
+       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)
+{SELFPARAM();
+       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)
+{SELFPARAM();
+       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)
+{SELFPARAM();
+       self.respawn_flags |= RESPAWN_FORCE;
+       race_AbandonRaceCheck(self);
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(cts, HavocBot_ChooseRole)
+{SELFPARAM();
+       self.havocbot_role = havocbot_role_cts;
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(cts, GetPressedKeys)
+{SELFPARAM();
+       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);
+               }
+       }
+
+       if (!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 = CTS_RECORD;
+                       race_send_speedaward(MSG_ALL);
+                       speedaward_lastsent = speedaward_speed;
+                       if (speedaward_speed > speedaward_alltimebest && speedaward_uid != "")
+                       {
+                               speedaward_alltimebest = speedaward_speed;
+                               speedaward_alltimebest_holder = speedaward_holder;
+                               speedaward_alltimebest_uid = speedaward_uid;
+                               db_put(ServerProgsDB, strcat(GetMapname(), rr, "speed/speed"), ftos(speedaward_alltimebest));
+                               db_put(ServerProgsDB, strcat(GetMapname(), rr, "speed/crypto_idfp"), speedaward_alltimebest_uid);
+                               race_send_speedaward_alltimebest(MSG_ALL);
+                       }
+               }
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(cts, ForbidThrowCurrentWeapon)
+{
+       // no weapon dropping in CTS
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(cts, FilterItem)
+{SELFPARAM();
+       if(self.classname == "droppedweapon")
+               return true;
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(cts, PlayerDamage_Calculate)
+{
+       if(frag_target == frag_attacker || frag_deathtype == DEATH_FALL.m_id)
+       if(!autocvar_g_cts_selfdamage)
+               frag_damage = 0;
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(cts, ForbidPlayerScore_Clear)
+{
+       return true; // in CTS, you don't lose score by observing
+}
+
+MUTATOR_HOOKFUNCTION(cts, SetModname)
+{
+       g_cloaked = 1; // always enable cloak in CTS
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(cts, GetRecords)
+{
+       for(int i = record_page * 200; i < MapInfo_count && i < record_page * 200 + 200; ++i)
+       {
+               if(MapInfo_Get_ByID(i))
+               {
+                       float r = race_readTime(MapInfo_Map_bspname, 1);
+
+                       if(!r)
+                               continue;
+
+                       string h = race_readName(MapInfo_Map_bspname, 1);
+                       ret_string = strcat(ret_string, strpad(32, MapInfo_Map_bspname), " ", strpad(-8, TIME_ENCODED_TOSTRING(r)), " ", h, "\n");
+               }
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(cts, ClientKill)
+{
+       ret_float = 0;
+
+       if(self.killindicator && self.killindicator.health == 1) // self.killindicator.health == 1 means that the kill indicator was spawned by CTS_ClientKill
+       {
+               remove(self.killindicator);
+               self.killindicator = world;
+
+               ClientKill_Now(); // allow instant kill in this case
+               return;
+       }
+
+}
+
+MUTATOR_HOOKFUNCTION(cts, Race_FinalCheckpoint)
+{
+       if(autocvar_g_cts_finish_kill_delay)
+               CTS_ClientKill(self);
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(cts, FixClientCvars)
+{
+       stuffcmd(fix_client, "cl_cmd settemp cl_movecliptokeyboard 2\n");
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(cts, WantWeapon)
+{
+       ret_float = (want_weaponinfo.weapon == WEP_SHOTGUN.m_id);
+       want_mutatorblocked = true;
+       return true;
+}
+
+void cts_Initialize()
+{
+       cts_ScoreRules();
+}
+
+#endif
diff --git a/qcsrc/server/mutators/mutator/gamemode_deathmatch.qc b/qcsrc/server/mutators/mutator/gamemode_deathmatch.qc
new file mode 100644 (file)
index 0000000..5ebd7c6
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef GAMEMODE_DEATHMATCH_H
+#define GAMEMODE_DEATHMATCH_H
+
+REGISTER_MUTATOR(dm, false)
+{
+       MUTATOR_ONADD
+       {
+               if (time > 1) // game loads at time 1
+                       error("This is a game type and it cannot be added at runtime.");
+       }
+
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               // we actually cannot roll back dm_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;
+}
+
+#endif
+
+#ifdef IMPLEMENTATION
+MUTATOR_HOOKFUNCTION(dm, Scores_CountFragsRemaining)
+{
+       // announce remaining frags
+       return true;
+}
+#endif
diff --git a/qcsrc/server/mutators/mutator/gamemode_domination.qc b/qcsrc/server/mutators/mutator/gamemode_domination.qc
new file mode 100644 (file)
index 0000000..5195177
--- /dev/null
@@ -0,0 +1,727 @@
+#ifndef GAMEMODE_DOMINATION_H
+#define GAMEMODE_DOMINATION_H
+
+#define autocvar_g_domination_point_limit cvar("g_domination_point_limit")
+bool autocvar_g_domination_roundbased;
+int autocvar_g_domination_roundbased_point_limit;
+int autocvar_g_domination_point_leadlimit;
+
+void dom_Initialize();
+
+REGISTER_MUTATOR(dom, false)
+{
+       int fraglimit_override = autocvar_g_domination_point_limit;
+       if (autocvar_g_domination_roundbased && autocvar_g_domination_roundbased_point_limit)
+               fraglimit_override = autocvar_g_domination_roundbased_point_limit;
+
+       ActivateTeamplay();
+       SetLimits(fraglimit_override, autocvar_g_domination_point_leadlimit, -1, -1);
+       have_team_spawns = -1; // request team spawns
+
+       MUTATOR_ONADD
+       {
+               if (time > 1) // game loads at time 1
+                       error("This is a game type and it cannot be added at runtime.");
+               dom_Initialize();
+       }
+
+       MUTATOR_ONREMOVE
+       {
+               LOG_INFO("This is a game type and it cannot be removed at runtime.");
+               return -1;
+       }
+
+       return 0;
+}
+
+// score rule declarations
+const float ST_DOM_TICKS = 1;
+const float SP_DOM_TICKS = 4;
+const float SP_DOM_TAKES = 5;
+const float ST_DOM_CAPS = 1;
+const float SP_DOM_CAPS = 4;
+
+// pps: points per second
+.float dom_total_pps;
+.float dom_pps_red;
+.float dom_pps_blue;
+.float dom_pps_yellow;
+.float dom_pps_pink;
+float total_pps;
+float pps_red;
+float pps_blue;
+float pps_yellow;
+float pps_pink;
+
+// capture declarations
+.float enemy_playerid;
+.entity sprite;
+.float captime;
+
+// misc globals
+float domination_roundbased;
+float domination_teams;
+#endif
+
+#ifdef IMPLEMENTATION
+
+#include "../../teamplay.qh"
+
+bool g_domination;
+
+int autocvar_g_domination_default_teams;
+bool autocvar_g_domination_disable_frags;
+int autocvar_g_domination_point_amt;
+bool autocvar_g_domination_point_fullbright;
+float autocvar_g_domination_round_timelimit;
+float autocvar_g_domination_warmup;
+float autocvar_g_domination_point_rate;
+int autocvar_g_domination_teams_override;
+
+void dom_EventLog(string mode, float team_before, entity actor) // use an alias for easy changing and quick editing later
+{
+       if(autocvar_sv_eventlog)
+               GameLogEcho(strcat(":dom:", mode, ":", ftos(team_before), ((actor != world) ? (strcat(":", ftos(actor.playerid))) : "")));
+}
+
+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(domination_teams >= 3)
+               e.dom_pps_yellow = pps_yellow;
+       if(domination_teams >= 4)
+               e.dom_pps_pink = pps_pink;
+}
+
+void dompoint_captured ()
+{SELFPARAM();
+       entity head;
+       float old_delay, old_team, real_team;
+
+       // now that the delay has expired, switch to the latest team to lay claim to this point
+       head = self.owner;
+
+       real_team = self.cnt;
+       self.cnt = -1;
+
+       dom_EventLog("taken", self.team, self.dmg_inflictor);
+       self.dmg_inflictor = world;
+
+       self.goalentity = head;
+       self.model = head.mdl;
+       self.modelindex = head.dmg;
+       self.skin = head.skin;
+
+       float points, wait_time;
+       if (autocvar_g_domination_point_amt)
+               points = autocvar_g_domination_point_amt;
+       else
+               points = self.frags;
+       if (autocvar_g_domination_point_rate)
+               wait_time = autocvar_g_domination_point_rate;
+       else
+               wait_time = self.wait;
+
+       if(domination_roundbased)
+               bprint(sprintf("^3%s^3%s\n", head.netname, self.message));
+       else
+               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);
+       else
+               self.enemy = world;
+
+       if (head.noise != "")
+               if(self.enemy)
+                       _sound(self.enemy, CH_TRIGGER, head.noise, VOL_BASE, ATTEN_NORM);
+               else
+                       _sound(self, CH_TRIGGER, head.noise, VOL_BASE, ATTEN_NORM);
+       if (head.noise1 != "")
+               play2all(head.noise1);
+
+       self.delay = time + wait_time;
+
+       // do trigger work
+       old_delay = self.delay;
+       old_team = self.team;
+       self.team = real_team;
+       self.delay = 0;
+       activator = self;
+       SUB_UseTargets ();
+       self.delay = old_delay;
+       self.team = old_team;
+
+       entity msg = WP_DomNeut;
+       switch(self.team)
+       {
+               case NUM_TEAM_1: msg = WP_DomRed; break;
+               case NUM_TEAM_2: msg = WP_DomBlue; break;
+               case NUM_TEAM_3: msg = WP_DomYellow; break;
+               case NUM_TEAM_4: msg = WP_DomPink; break;
+       }
+
+       WaypointSprite_UpdateSprites(self.sprite, msg, WP_Null, WP_Null);
+
+       total_pps = 0, pps_red = 0, pps_blue = 0, pps_yellow = 0, pps_pink = 0;
+       for(head = world; (head = find(head, classname, "dom_controlpoint")) != world; )
+       {
+               if (autocvar_g_domination_point_amt)
+                       points = autocvar_g_domination_point_amt;
+               else
+                       points = head.frags;
+               if (autocvar_g_domination_point_rate)
+                       wait_time = autocvar_g_domination_point_rate;
+               else
+                       wait_time = head.wait;
+               switch(head.goalentity.team)
+               {
+                       case NUM_TEAM_1:
+                               pps_red += points/wait_time;
+                               break;
+                       case NUM_TEAM_2:
+                               pps_blue += points/wait_time;
+                               break;
+                       case NUM_TEAM_3:
+                               pps_yellow += points/wait_time;
+                               break;
+                       case NUM_TEAM_4:
+                               pps_pink += points/wait_time;
+                               break;
+               }
+               total_pps += points/wait_time;
+       }
+
+       WaypointSprite_UpdateTeamRadar(self.sprite, RADARICON_DOMPOINT, colormapPaletteColor(self.goalentity.team - 1, 0));
+       WaypointSprite_Ping(self.sprite);
+
+       self.captime = time;
+
+       FOR_EACH_REALCLIENT(head)
+               set_dom_state(head);
+}
+
+void AnimateDomPoint()
+{SELFPARAM();
+       if(self.pain_finished > time)
+               return;
+       self.pain_finished = time + self.t_width;
+       if(self.nextthink > self.pain_finished)
+               self.nextthink = self.pain_finished;
+
+       self.frame = self.frame + 1;
+       if(self.frame > self.t_length)
+               self.frame = 0;
+}
+
+void dompointthink()
+{SELFPARAM();
+       float fragamt;
+
+       self.nextthink = time + 0.1;
+
+       //self.frame = self.frame + 1;
+       //if(self.frame > 119)
+       //      self.frame = 0;
+       AnimateDomPoint();
+
+       // give points
+
+       if (gameover || self.delay > time || time < game_starttime)     // game has ended, don't keep giving points
+               return;
+
+       if(autocvar_g_domination_point_rate)
+               self.delay = time + autocvar_g_domination_point_rate;
+       else
+               self.delay = time + self.wait;
+
+       // give credit to the team
+       // NOTE: this defaults to 0
+       if (!domination_roundbased)
+       if (self.goalentity.netname != "")
+       {
+               if(autocvar_g_domination_point_amt)
+                       fragamt = autocvar_g_domination_point_amt;
+               else
+                       fragamt = self.frags;
+               TeamScore_AddToTeam(self.goalentity.team, ST_SCORE, fragamt);
+               TeamScore_AddToTeam(self.goalentity.team, ST_DOM_TICKS, fragamt);
+
+               // give credit to the individual player, if he is still there
+               if (self.enemy.playerid == self.enemy_playerid)
+               {
+                       PlayerScore_Add(self.enemy, SP_SCORE, fragamt);
+                       PlayerScore_Add(self.enemy, SP_DOM_TICKS, fragamt);
+               }
+               else
+                       self.enemy = world;
+       }
+}
+
+void dompointtouch()
+{SELFPARAM();
+       entity head;
+       if (!IS_PLAYER(other))
+               return;
+       if (other.health < 1)
+               return;
+
+       if(round_handler_IsActive() && !round_handler_IsRoundStarted())
+               return;
+
+       if(time < self.captime + 0.3)
+               return;
+
+       // only valid teams can claim it
+       head = find(world, classname, "dom_team");
+       while (head && head.team != other.team)
+               head = find(head, classname, "dom_team");
+       if (!head || head.netname == "" || head == self.goalentity)
+               return;
+
+       // delay capture
+
+       self.team = self.goalentity.team; // this stores the PREVIOUS team!
+
+       self.cnt = other.team;
+       self.owner = head; // team to switch to after the delay
+       self.dmg_inflictor = other;
+
+       // self.state = 1;
+       // self.delay = time + cvar("g_domination_point_capturetime");
+       //self.nextthink = time + cvar("g_domination_point_capturetime");
+       //self.think = dompoint_captured;
+
+       // go to neutral team in the mean time
+       head = find(world, classname, "dom_team");
+       while (head && head.netname != "")
+               head = find(head, classname, "dom_team");
+       if(head == world)
+               return;
+
+       WaypointSprite_UpdateSprites(self.sprite, WP_DomNeut, WP_Null, WP_Null);
+       WaypointSprite_UpdateTeamRadar(self.sprite, RADARICON_DOMPOINT, '0 1 1');
+       WaypointSprite_Ping(self.sprite);
+
+       self.goalentity = head;
+       self.model = head.mdl;
+       self.modelindex = head.dmg;
+       self.skin = head.skin;
+
+       self.enemy = other; // individual player scoring
+       self.enemy_playerid = other.playerid;
+       dompoint_captured();
+}
+
+void dom_controlpoint_setup()
+{SELFPARAM();
+       entity head;
+       // find the spawnfunc_dom_team representing unclaimed points
+       head = find(world, classname, "dom_team");
+       while(head && head.netname != "")
+               head = find(head, classname, "dom_team");
+       if (!head)
+               objerror("no spawnfunc_dom_team with netname \"\" found\n");
+
+       // copy important properties from spawnfunc_dom_team entity
+       self.goalentity = head;
+       _setmodel(self, head.mdl); // precision already set
+       self.skin = head.skin;
+
+       self.cnt = -1;
+
+       if(self.message == "")
+               self.message = " has captured a control point";
+
+       if(self.frags <= 0)
+               self.frags = 1;
+       if(self.wait <= 0)
+               self.wait = 5;
+
+       float points, waittime;
+       if (autocvar_g_domination_point_amt)
+               points = autocvar_g_domination_point_amt;
+       else
+               points = self.frags;
+       if (autocvar_g_domination_point_rate)
+               waittime = autocvar_g_domination_point_rate;
+       else
+               waittime = self.wait;
+
+       total_pps += points/waittime;
+
+       if(!self.t_width)
+               self.t_width = 0.02; // frame animation rate
+       if(!self.t_length)
+               self.t_length = 239; // maximum frame
+
+       self.think = dompointthink;
+       self.nextthink = time;
+       self.touch = dompointtouch;
+       self.solid = SOLID_TRIGGER;
+       self.flags = FL_ITEM;
+       setsize(self, '-32 -32 -32', '32 32 32');
+       setorigin(self, self.origin + '0 0 20');
+       droptofloor();
+
+       waypoint_spawnforitem(self);
+       WaypointSprite_SpawnFixed(WP_DomNeut, self.origin + '0 0 32', self, sprite, RADARICON_DOMPOINT);
+}
+
+float total_controlpoints;
+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()
+{SELFPARAM();
+       if(self.deadflag != DEAD_NO)
+               return;
+
+       if (self.bot_strategytime < time)
+       {
+               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+               navigation_goalrating_start();
+               havocbot_goalrating_controlpoints(10000, self.origin, 15000);
+               havocbot_goalrating_items(8000, self.origin, 8000);
+               //havocbot_goalrating_enemyplayers(3000, self.origin, 2000);
+               //havocbot_goalrating_waypoints(1, self.origin, 1000);
+               navigation_goalrating_end();
+       }
+}
+
+MUTATOR_HOOKFUNCTION(dom, GetTeamCount)
+{
+       // fallback?
+       ret_float = domination_teams;
+       ret_string = "dom_team";
+
+       entity head = find(world, classname, ret_string);
+       while(head)
+       {
+               if(head.netname != "")
+               {
+                       switch(head.team)
+                       {
+                               case NUM_TEAM_1: c1 = 0; break;
+                               case NUM_TEAM_2: c2 = 0; break;
+                               case NUM_TEAM_3: c3 = 0; break;
+                               case NUM_TEAM_4: c4 = 0; break;
+                       }
+               }
+
+               head = find(head, classname, ret_string);
+       }
+
+       ret_string = string_null;
+
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(dom, reset_map_players)
+{SELFPARAM();
+       total_pps = 0, pps_red = 0, pps_blue = 0, pps_yellow = 0, pps_pink = 0;
+       entity e;
+       FOR_EACH_PLAYER(e)
+       {
+               setself(e);
+               PutClientInServer();
+               self.player_blocked = 1;
+               if(IS_REAL_CLIENT(self))
+                       set_dom_state(self);
+       }
+       return 1;
+}
+
+MUTATOR_HOOKFUNCTION(dom, PlayerSpawn)
+{SELFPARAM();
+       if(domination_roundbased)
+       if(!round_handler_IsRoundStarted())
+               self.player_blocked = 1;
+       else
+               self.player_blocked = 0;
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(dom, ClientConnect)
+{SELFPARAM();
+       set_dom_state(self);
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(dom, HavocBot_ChooseRole)
+{SELFPARAM();
+       self.havocbot_role = havocbot_role_dom;
+       return true;
+}
+
+/*QUAKED spawnfunc_dom_controlpoint (0 .5 .8) (-16 -16 -24) (16 16 32)
+Control point for Domination gameplay.
+*/
+spawnfunc(dom_controlpoint)
+{
+       if(!g_domination)
+       {
+               remove(self);
+               return;
+       }
+       self.think = dom_controlpoint_setup;
+       self.nextthink = time + 0.1;
+       self.reset = dom_controlpoint_setup;
+
+       if(!self.scale)
+               self.scale = 0.6;
+
+       self.effects = self.effects | EF_LOWPRECISION;
+       if (autocvar_g_domination_point_fullbright)
+               self.effects |= EF_FULLBRIGHT;
+}
+
+/*QUAKED spawnfunc_dom_team (0 .5 .8) (-32 -32 -24) (32 32 32)
+Team declaration for Domination gameplay, this allows you to decide what team
+names and control point models are used in your map.
+
+Note: If you use spawnfunc_dom_team entities you must define at least 3 and only two
+can have netname set!  The nameless team owns all control points at start.
+
+Keys:
+"netname"
+ Name of the team (for example Red Team, Blue Team, Green Team, Yellow Team, Life, Death, etc)
+"cnt"
+ Scoreboard color of the team (for example 4 is red and 13 is blue)
+"model"
+ Model to use for control points owned by this team (for example
+ "progs/b_g_key.mdl" is a gold keycard, and "progs/b_s_key.mdl" is a silver
+ keycard)
+"skin"
+ Skin of the model to use (for team skins on a single model)
+"noise"
+ Sound to play when this team captures a point.
+ (this is a localized sound, like a small alarm or other effect)
+"noise1"
+ Narrator speech to play when this team captures a point.
+ (this is a global sound, like "Red team has captured a control point")
+*/
+
+spawnfunc(dom_team)
+{
+       if(!g_domination || autocvar_g_domination_teams_override >= 2)
+       {
+               remove(self);
+               return;
+       }
+       precache_model(self.model);
+       if (self.noise != "")
+               precache_sound(self.noise);
+       if (self.noise1 != "")
+               precache_sound(self.noise1);
+       self.classname = "dom_team";
+       _setmodel(self, self.model); // precision not needed
+       self.mdl = self.model;
+       self.dmg = self.modelindex;
+       self.model = "";
+       self.modelindex = 0;
+       // this would have to be changed if used in quakeworld
+       if(self.cnt)
+               self.team = self.cnt + 1; // WHY are these different anyway?
+}
+
+// scoreboard setup
+void ScoreRules_dom(float teams)
+{
+       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
+       {
+               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
+void dom_spawnteam (string teamname, float teamcolor, string pointmodel, float pointskin, string capsound, string capnarration, string capmessage)
+{SELFPARAM();
+       setself(spawn());
+       self.classname = "dom_team";
+       self.netname = teamname;
+       self.cnt = teamcolor;
+       self.model = pointmodel;
+       self.skin = pointskin;
+       self.noise = capsound;
+       self.noise1 = capnarration;
+       self.message = capmessage;
+
+       // this code is identical to spawnfunc_dom_team
+       _setmodel(self, self.model); // precision not needed
+       self.mdl = self.model;
+       self.dmg = self.modelindex;
+       self.model = "";
+       self.modelindex = 0;
+       // this would have to be changed if used in quakeworld
+       self.team = self.cnt + 1;
+
+       //eprint(self);
+       setself(this);
+}
+
+void _spawnfunc_dom_controlpoint() { SELFPARAM(); spawnfunc_dom_controlpoint(self); }
+void dom_spawnpoint(vector org)
+{SELFPARAM();
+       setself(spawn());
+       self.classname = "dom_controlpoint";
+       self.think = _spawnfunc_dom_controlpoint;
+       self.nextthink = time;
+       setorigin(self, org);
+       spawnfunc_dom_controlpoint(this);
+       setself(this);
+}
+
+// spawn some default teams if the map is not set up for domination
+void dom_spawnteams(float teams)
+{
+       dom_spawnteam("Red", NUM_TEAM_1-1, "models/domination/dom_red.md3", 0, SND(DOM_CLAIM), "", "Red team has captured a control point");
+       dom_spawnteam("Blue", NUM_TEAM_2-1, "models/domination/dom_blue.md3", 0, SND(DOM_CLAIM), "", "Blue team has captured a control point");
+       if(teams >= 3)
+               dom_spawnteam("Yellow", NUM_TEAM_3-1, "models/domination/dom_yellow.md3", 0, SND(DOM_CLAIM), "", "Yellow team has captured a control point");
+       if(teams >= 4)
+               dom_spawnteam("Pink", NUM_TEAM_4-1, "models/domination/dom_pink.md3", 0, SND(DOM_CLAIM), "", "Pink team has captured a control point");
+       dom_spawnteam("", 0, "models/domination/dom_unclaimed.md3", 0, "", "", "");
+}
+
+void dom_DelayedInit() // Do this check with a delay so we can wait for teams to be set up.
+{
+       // if no teams are found, spawn defaults
+       if(find(world, classname, "dom_team") == world || autocvar_g_domination_teams_override >= 2)
+       {
+               LOG_INFO("No ""dom_team"" entities found on this map, creating them anyway.\n");
+               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);
+
+       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()
+{
+       g_domination = true;
+       InitializeEntity(world, dom_DelayedInit, INITPRIO_GAMETYPE);
+}
+
+#endif
diff --git a/qcsrc/server/mutators/mutator/gamemode_freezetag.qc b/qcsrc/server/mutators/mutator/gamemode_freezetag.qc
new file mode 100644 (file)
index 0000000..c392c4b
--- /dev/null
@@ -0,0 +1,657 @@
+#ifndef GAMEMODE_FREEZETAG_H
+#define GAMEMODE_FREEZETAG_H
+
+int autocvar_g_freezetag_point_limit;
+int autocvar_g_freezetag_point_leadlimit;
+bool autocvar_g_freezetag_team_spawns;
+void freezetag_Initialize();
+
+REGISTER_MUTATOR(ft, false)
+{
+       ActivateTeamplay();
+       SetLimits(autocvar_g_freezetag_point_limit, autocvar_g_freezetag_point_leadlimit, -1, -1);
+
+       if (autocvar_g_freezetag_team_spawns)
+               have_team_spawns = -1; // request team spawns
+
+       MUTATOR_ONADD
+       {
+               if (time > 1) // game loads at time 1
+                       error("This is a game type and it cannot be added at runtime.");
+               freezetag_Initialize();
+       }
+
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               // we actually cannot roll back freezetag_Initialize here
+               // BUT: we don't need to! If this gets called, adding always
+               // succeeds.
+       }
+
+       MUTATOR_ONREMOVE
+       {
+               LOG_INFO("This is a game type and it cannot be removed at runtime.");
+               return -1;
+       }
+
+       return 0;
+}
+
+.float freezetag_frozen_time;
+.float freezetag_frozen_timeout;
+const float ICE_MAX_ALPHA = 1;
+const float ICE_MIN_ALPHA = 0.1;
+float freezetag_teams;
+
+.float reviving; // temp var
+#endif
+
+#ifdef IMPLEMENTATION
+
+float autocvar_g_freezetag_frozen_maxtime;
+bool autocvar_g_freezetag_revive_nade;
+float autocvar_g_freezetag_revive_nade_health;
+float autocvar_g_freezetag_revive_extra_size;
+float autocvar_g_freezetag_revive_speed;
+float autocvar_g_freezetag_revive_clearspeed;
+float autocvar_g_freezetag_round_timelimit;
+int autocvar_g_freezetag_teams;
+int autocvar_g_freezetag_teams_override;
+float autocvar_g_freezetag_warmup;
+
+const float SP_FREEZETAG_REVIVALS = 4;
+void freezetag_ScoreRules(float teams)
+{
+       ScoreRules_basics(teams, SFL_SORT_PRIO_PRIMARY, SFL_SORT_PRIO_PRIMARY, true); // SFL_SORT_PRIO_PRIMARY
+       ScoreInfo_SetLabel_PlayerScore(SP_FREEZETAG_REVIVALS, "revivals", 0);
+       ScoreRules_basics_end();
+}
+
+void freezetag_count_alive_players()
+{
+       entity e;
+       total_players = redalive = bluealive = yellowalive = pinkalive = 0;
+       FOR_EACH_PLAYER(e)
+       {
+               switch(e.team)
+               {
+                       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)
+       {
+               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 freezetag_CheckTeams()
+{
+       static float prev_missing_teams_mask;
+       if(FREEZETAG_ALIVE_TEAMS_OK())
+       {
+               if(prev_missing_teams_mask > 0)
+                       Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_MISSING_TEAMS);
+               prev_missing_teams_mask = -1;
+               return 1;
+       }
+       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)
+       {
+               Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_MISSING_TEAMS, missing_teams_mask);
+               prev_missing_teams_mask = missing_teams_mask;
+       }
+       return 0;
+}
+
+float freezetag_getWinnerTeam()
+{
+       float winner_team = 0;
+       if(redalive >= 1)
+               winner_team = NUM_TEAM_1;
+       if(bluealive >= 1)
+       {
+               if(winner_team) return 0;
+               winner_team = NUM_TEAM_2;
+       }
+       if(yellowalive >= 1)
+       {
+               if(winner_team) return 0;
+               winner_team = NUM_TEAM_3;
+       }
+       if(pinkalive >= 1)
+       {
+               if(winner_team) return 0;
+               winner_team = NUM_TEAM_4;
+       }
+       if(winner_team)
+               return winner_team;
+       return -1; // no player left
+}
+
+float freezetag_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);
+               FOR_EACH_PLAYER(e)
+               {
+                       e.freezetag_frozen_timeout = 0;
+                       nades_Clear(e);
+               }
+               round_handler_Init(5, autocvar_g_freezetag_warmup, autocvar_g_freezetag_round_timelimit);
+               return 1;
+       }
+
+       if(FREEZETAG_ALIVE_TEAMS() > 1)
+               return 0;
+
+       float winner_team;
+       winner_team = freezetag_getWinnerTeam();
+       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_SCORE, +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);
+       }
+
+       FOR_EACH_PLAYER(e)
+       {
+               e.freezetag_frozen_timeout = 0;
+               nades_Clear(e);
+       }
+       round_handler_Init(5, autocvar_g_freezetag_warmup, autocvar_g_freezetag_round_timelimit);
+       return 1;
+}
+
+entity freezetag_LastPlayerForTeam()
+{SELFPARAM();
+       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)
+{SELFPARAM();
+       if(attacker == self)
+       {
+               // you froze your own dumb self
+               // counted as "suicide" already
+               PlayerScore_Add(self, SP_SCORE, -1);
+       }
+       else if(IS_PLAYER(attacker))
+       {
+               // got frozen by an enemy
+               // counted as "kill" and "death" already
+               PlayerScore_Add(self, SP_SCORE, -1);
+               PlayerScore_Add(attacker, SP_SCORE, +1);
+       }
+       // else nothing - got frozen by the game type rules themselves
+}
+
+void freezetag_Freeze(entity attacker)
+{SELFPARAM();
+       if(self.frozen)
+               return;
+
+       if(autocvar_g_freezetag_frozen_maxtime > 0)
+               self.freezetag_frozen_timeout = time + autocvar_g_freezetag_frozen_maxtime;
+
+       Freeze(self, 0, 1, true);
+
+       freezetag_count_alive_players();
+
+       freezetag_Add_Score(attacker);
+}
+
+void freezetag_Unfreeze(entity attacker)
+{SELFPARAM();
+       self.freezetag_frozen_time = 0;
+       self.freezetag_frozen_timeout = 0;
+
+       Unfreeze(self);
+}
+
+float freezetag_isEliminated(entity e)
+{
+       if(IS_PLAYER(e) && (e.frozen == 1 || e.deadflag != DEAD_NO))
+               return true;
+       return false;
+}
+
+
+// ================
+// Bot player logic
+// ================
+
+void() havocbot_role_ft_freeing;
+void() havocbot_role_ft_offense;
+
+void havocbot_goalrating_freeplayers(float ratingscale, vector org, float sradius)
+{SELFPARAM();
+       entity head;
+       float distance;
+
+       FOR_EACH_PLAYER(head)
+       {
+               if ((head != self) && (head.team == self.team))
+               {
+                       if (head.frozen == 1)
+                       {
+                               distance = vlen(head.origin - org);
+                               if (distance > sradius)
+                                       continue;
+                               navigation_routerating(head, ratingscale, 2000);
+                       }
+                       else
+                       {
+                               // If teamate is not frozen still seek them out as fight better
+                               // in a group.
+                               navigation_routerating(head, ratingscale/3, 2000);
+                       }
+               }
+       }
+}
+
+void havocbot_role_ft_offense()
+{SELFPARAM();
+       entity head;
+       float unfrozen;
+
+       if(self.deadflag != DEAD_NO)
+               return;
+
+       if (!self.havocbot_role_timeout)
+               self.havocbot_role_timeout = time + random() * 10 + 20;
+
+       // Count how many players on team are unfrozen.
+       unfrozen = 0;
+       FOR_EACH_PLAYER(head)
+       {
+               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.frozen)) || (time > self.havocbot_role_timeout))
+       {
+               LOG_TRACE("changing role to freeing\n");
+               self.havocbot_role = havocbot_role_ft_freeing;
+               self.havocbot_role_timeout = 0;
+               return;
+       }
+
+       if (time > self.bot_strategytime)
+       {
+               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+
+               navigation_goalrating_start();
+               havocbot_goalrating_items(10000, self.origin, 10000);
+               havocbot_goalrating_enemyplayers(20000, self.origin, 10000);
+               havocbot_goalrating_freeplayers(9000, self.origin, 10000);
+               //havocbot_goalrating_waypoints(1, self.origin, 1000);
+               navigation_goalrating_end();
+       }
+}
+
+void havocbot_role_ft_freeing()
+{SELFPARAM();
+       if(self.deadflag != DEAD_NO)
+               return;
+
+       if (!self.havocbot_role_timeout)
+               self.havocbot_role_timeout = time + random() * 10 + 20;
+
+       if (time > self.havocbot_role_timeout)
+       {
+               LOG_TRACE("changing role to offense\n");
+               self.havocbot_role = havocbot_role_ft_offense;
+               self.havocbot_role_timeout = 0;
+               return;
+       }
+
+       if (time > self.bot_strategytime)
+       {
+               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+
+               navigation_goalrating_start();
+               havocbot_goalrating_items(8000, self.origin, 10000);
+               havocbot_goalrating_enemyplayers(10000, self.origin, 10000);
+               havocbot_goalrating_freeplayers(20000, self.origin, 10000);
+               //havocbot_goalrating_waypoints(1, self.origin, 1000);
+               navigation_goalrating_end();
+       }
+}
+
+
+// ==============
+// Hook Functions
+// ==============
+
+void ft_RemovePlayer()
+{SELFPARAM();
+       self.health = 0; // neccessary to update correctly alive stats
+       if(!self.frozen)
+               freezetag_LastPlayerForTeam_Notify();
+       freezetag_Unfreeze(world);
+       freezetag_count_alive_players();
+}
+
+MUTATOR_HOOKFUNCTION(ft, ClientDisconnect)
+{SELFPARAM();
+       ft_RemovePlayer();
+       return 1;
+}
+
+MUTATOR_HOOKFUNCTION(ft, MakePlayerObserver)
+{SELFPARAM();
+       ft_RemovePlayer();
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ft, PlayerDies)
+{SELFPARAM();
+       if(round_handler_IsActive())
+       if(round_handler_CountdownRunning())
+       {
+               if(self.frozen)
+                       freezetag_Unfreeze(world);
+               freezetag_count_alive_players();
+               return 1; // let the player die so that he can respawn whenever he wants
+       }
+
+       // Cases DEATH_TEAMCHANGE and DEATH_AUTOTEAMCHANGE are needed to fix a bug whe
+       // you succeed changing team through the menu: you both really die (gibbing) and get frozen
+       if(ITEM_DAMAGE_NEEDKILL(frag_deathtype)
+               || frag_deathtype == DEATH_TEAMCHANGE.m_id || frag_deathtype == DEATH_AUTOTEAMCHANGE.m_id)
+       {
+               // let the player die, he will be automatically frozen when he respawns
+               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.frozen)
+               return 1;
+
+       freezetag_Freeze(frag_attacker);
+       freezetag_LastPlayerForTeam_Notify();
+
+       if(frag_attacker == frag_target || frag_attacker == world)
+       {
+               if(IS_PLAYER(frag_target))
+                       Send_Notification(NOTIF_ONE, frag_target, MSG_CENTER, CENTER_FREEZETAG_SELF);
+               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_FREEZETAG_SELF, frag_target.netname);
+       }
+       else
+       {
+               if(IS_PLAYER(frag_target))
+                       Send_Notification(NOTIF_ONE, frag_target, MSG_CENTER, CENTER_FREEZETAG_FROZEN, frag_attacker.netname);
+               if(IS_PLAYER(frag_attacker))
+                       Send_Notification(NOTIF_ONE, frag_attacker, MSG_CENTER, CENTER_FREEZETAG_FREEZE, frag_target.netname);
+               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_FREEZETAG_FREEZE, frag_target.netname, frag_attacker.netname);
+       }
+
+       return 1;
+}
+
+MUTATOR_HOOKFUNCTION(ft, PlayerSpawn)
+{SELFPARAM();
+       if(self.freezetag_frozen_timeout == -1) // if PlayerSpawn is called by reset_map_players
+               return 1; // do nothing, round is starting right now
+
+       if(self.freezetag_frozen_timeout == -2) // player was dead
+       {
+               freezetag_Freeze(world);
+               return 1;
+       }
+
+       freezetag_count_alive_players();
+
+       if(round_handler_IsActive())
+       if(round_handler_IsRoundStarted())
+       {
+               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_FREEZETAG_SPAWN_LATE);
+               freezetag_Freeze(world);
+       }
+
+       return 1;
+}
+
+MUTATOR_HOOKFUNCTION(ft, reset_map_players)
+{SELFPARAM();
+       entity e;
+       FOR_EACH_PLAYER(e)
+       {
+               e.killcount = 0;
+               e.freezetag_frozen_timeout = -1;
+               setself(e);
+               PutClientInServer();
+               e.freezetag_frozen_timeout = 0;
+       }
+       freezetag_count_alive_players();
+       return 1;
+}
+
+MUTATOR_HOOKFUNCTION(ft, GiveFragsForKill, CBC_ORDER_FIRST)
+{
+       frag_score = 0; // no frags counted in Freeze Tag
+       return 1;
+}
+
+MUTATOR_HOOKFUNCTION(ft, PlayerPreThink, CBC_ORDER_FIRST)
+{SELFPARAM();
+       float n;
+
+       if(gameover)
+               return 1;
+
+       if(self.frozen == 1)
+       {
+               // keep health = 1
+               self.pauseregen_finished = time + autocvar_g_balance_pause_health_regen;
+       }
+
+       if(round_handler_IsActive())
+       if(!round_handler_IsRoundStarted())
+               return 1;
+
+       entity o;
+       o = world;
+       //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;
+       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.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(!o)
+                               o = other;
+                       if(self.frozen == 1)
+                               other.reviving = true;
+                       ++n;
+               }
+       }
+
+       if(n && self.frozen == 1) // 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 * ((warmup_stage) ? warmup_start_health : start_health));
+
+               if(self.revive_progress >= 1)
+               {
+                       freezetag_Unfreeze(self);
+                       freezetag_count_alive_players();
+
+                       if(n == -1)
+                       {
+                               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_FREEZETAG_AUTO_REVIVED, autocvar_g_freezetag_frozen_maxtime);
+                               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_FREEZETAG_AUTO_REVIVED, self.netname, autocvar_g_freezetag_frozen_maxtime);
+                               return 1;
+                       }
+
+                       // EVERY team mate nearby gets a point (even if multiple!)
+                       FOR_EACH_PLAYER(other)
+                       {
+                               if(other.reviving)
+                               {
+                                       PlayerScore_Add(other, SP_FREEZETAG_REVIVALS, +1);
+                                       PlayerScore_Add(other, SP_SCORE, +1);
+
+                                       nades_GiveBonus(other,autocvar_g_nades_bonus_score_low);
+                               }
+                       }
+
+                       Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_FREEZETAG_REVIVED, o.netname);
+                       Send_Notification(NOTIF_ONE, o, MSG_CENTER, CENTER_FREEZETAG_REVIVE, self.netname);
+                       Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_FREEZETAG_REVIVED, self.netname, o.netname);
+               }
+
+               FOR_EACH_PLAYER(other)
+               {
+                       if(other.reviving)
+                       {
+                               other.revive_progress = self.revive_progress;
+                               other.reviving = false;
+                       }
+               }
+       }
+       else if(!n && self.frozen == 1) // only if no teammate is nearby will we reset
+       {
+               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));
+       }
+       else if(!n && !self.frozen)
+       {
+               self.revive_progress = 0; // thawing nobody
+       }
+
+       return 1;
+}
+
+MUTATOR_HOOKFUNCTION(ft, SetStartItems)
+{
+       start_items &= ~IT_UNLIMITED_AMMO;
+       //start_health       = warmup_start_health       = cvar("g_lms_start_health");
+       //start_armorvalue   = warmup_start_armorvalue   = cvar("g_lms_start_armor");
+       start_ammo_shells  = warmup_start_ammo_shells  = cvar("g_lms_start_ammo_shells");
+       start_ammo_nails   = warmup_start_ammo_nails   = cvar("g_lms_start_ammo_nails");
+       start_ammo_rockets = warmup_start_ammo_rockets = cvar("g_lms_start_ammo_rockets");
+       start_ammo_cells   = warmup_start_ammo_cells   = cvar("g_lms_start_ammo_cells");
+       start_ammo_plasma  = warmup_start_ammo_plasma  = cvar("g_lms_start_ammo_plasma");
+       start_ammo_fuel    = warmup_start_ammo_fuel    = cvar("g_lms_start_ammo_fuel");
+
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(ft, HavocBot_ChooseRole)
+{SELFPARAM();
+       if (!self.deadflag)
+       {
+               if (random() < 0.5)
+                       self.havocbot_role = havocbot_role_ft_freeing;
+               else
+                       self.havocbot_role = havocbot_role_ft_offense;
+       }
+
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(ft, GetTeamCount, CBC_ORDER_EXCLUSIVE)
+{
+       ret_float = freezetag_teams;
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ft, SetWeaponArena)
+{
+       // most weapons arena
+       if(ret_string == "0" || ret_string == "")
+               ret_string = "most";
+       return false;
+}
+
+void freezetag_Initialize()
+{
+       freezetag_teams = autocvar_g_freezetag_teams_override;
+       if(freezetag_teams < 2)
+               freezetag_teams = autocvar_g_freezetag_teams;
+       freezetag_teams = bound(2, freezetag_teams, 4);
+       freezetag_ScoreRules(freezetag_teams);
+
+       round_handler_Spawn(freezetag_CheckTeams, freezetag_CheckWinner, func_null);
+       round_handler_Init(5, autocvar_g_freezetag_warmup, autocvar_g_freezetag_round_timelimit);
+
+       addstat(STAT_REDALIVE, AS_INT, redalive_stat);
+       addstat(STAT_BLUEALIVE, AS_INT, bluealive_stat);
+       addstat(STAT_YELLOWALIVE, AS_INT, yellowalive_stat);
+       addstat(STAT_PINKALIVE, AS_INT, pinkalive_stat);
+
+       EliminatedPlayers_Init(freezetag_isEliminated);
+}
+
+#endif
diff --git a/qcsrc/server/mutators/mutator/gamemode_invasion.qc b/qcsrc/server/mutators/mutator/gamemode_invasion.qc
new file mode 100644 (file)
index 0000000..f52afb9
--- /dev/null
@@ -0,0 +1,528 @@
+#ifndef GAMEMODE_INVASION_H
+#define GAMEMODE_INVASION_H
+
+#define autocvar_g_invasion_point_limit cvar("g_invasion_point_limit")
+int autocvar_g_invasion_teams;
+bool autocvar_g_invasion_team_spawns;
+bool g_invasion;
+void invasion_Initialize();
+
+REGISTER_MUTATOR(inv, false)
+{
+       SetLimits(autocvar_g_invasion_point_limit, -1, -1, -1);
+       if (autocvar_g_invasion_teams >= 2)
+       {
+               ActivateTeamplay();
+               if (autocvar_g_invasion_team_spawns)
+                       have_team_spawns = -1; // request team spawns
+       }
+
+       MUTATOR_ONADD
+       {
+               if (time > 1) // game loads at time 1
+                       error("This is a game type and it cannot be added at runtime.");
+               g_invasion = true;
+               invasion_Initialize();
+
+               cvar_settemp("g_monsters", "1");
+       }
+
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               // we actually cannot roll back invasion_Initialize here
+               // BUT: we don't need to! If this gets called, adding always
+               // succeeds.
+       }
+
+       MUTATOR_ONREMOVE
+       {
+               LOG_INFO("This is a game type and it cannot be removed at runtime.");
+               return -1;
+       }
+
+       return 0;
+}
+
+float inv_numspawned;
+float inv_maxspawned;
+float inv_roundcnt;
+float inv_maxrounds;
+float inv_numkilled;
+float inv_lastcheck;
+float inv_maxcurrent;
+
+float invasion_teams;
+float inv_monsters_perteam[17];
+
+float inv_monsterskill;
+
+const float ST_INV_KILLS = 1;
+#endif
+
+#ifdef IMPLEMENTATION
+
+#include "../../../common/monsters/spawn.qh"
+#include "../../../common/monsters/sv_monsters.qh"
+
+#include "../../teamplay.qh"
+
+
+float autocvar_g_invasion_round_timelimit;
+float autocvar_g_invasion_spawnpoint_spawn_delay;
+float autocvar_g_invasion_warmup;
+int autocvar_g_invasion_monster_count;
+bool autocvar_g_invasion_zombies_only;
+float autocvar_g_invasion_spawn_delay;
+
+spawnfunc(invasion_spawnpoint)
+{
+       if(!g_invasion) { remove(self); return; }
+
+       self.classname = "invasion_spawnpoint";
+
+       if(autocvar_g_invasion_zombies_only) // precache only if it hasn't been already
+       if(self.monsterid) {
+               Monster mon = get_monsterinfo(self.monsterid);
+               mon.mr_precache(mon);
+       }
+}
+
+float invasion_PickMonster(float supermonster_count)
+{
+       if(autocvar_g_invasion_zombies_only)
+               return MON_ZOMBIE.monsterid;
+
+       float i;
+       entity mon;
+
+       RandomSelection_Init();
+
+       for(i = MON_FIRST; i <= MON_LAST; ++i)
+       {
+               mon = get_monsterinfo(i);
+               if((mon.spawnflags & MONSTER_TYPE_FLY) || (mon.spawnflags & MONSTER_TYPE_SWIM) || ((mon.spawnflags & MON_FLAG_SUPERMONSTER) && supermonster_count >= 1))
+                       continue; // flying/swimming monsters not yet supported
+
+               RandomSelection_Add(world, i, string_null, 1, 1);
+       }
+
+       return RandomSelection_chosen_float;
+}
+
+entity invasion_PickSpawn()
+{
+       entity e;
+
+       RandomSelection_Init();
+
+       for(e = world;(e = find(e, classname, "invasion_spawnpoint")); )
+       {
+               RandomSelection_Add(e, 0, string_null, 1, ((time >= e.spawnshieldtime) ? 0.2 : 1)); // give recently used spawnpoints a very low rating
+               e.spawnshieldtime = time + autocvar_g_invasion_spawnpoint_spawn_delay;
+       }
+
+       return RandomSelection_chosen_ent;
+}
+
+void invasion_SpawnChosenMonster(float mon)
+{
+       entity spawn_point, monster;
+
+       spawn_point = invasion_PickSpawn();
+
+       if(spawn_point == world)
+       {
+               LOG_TRACE("Warning: couldn't find any invasion_spawnpoint spawnpoints, attempting to spawn monsters in random locations\n");
+               entity e = spawn();
+               setsize(e, (get_monsterinfo(mon)).mins, (get_monsterinfo(mon)).maxs);
+
+               if(MoveToRandomMapLocation(e, DPCONTENTS_SOLID | DPCONTENTS_CORPSE | DPCONTENTS_PLAYERCLIP, DPCONTENTS_SLIME | DPCONTENTS_LAVA | DPCONTENTS_SKY | DPCONTENTS_BODY | DPCONTENTS_DONOTENTER, Q3SURFACEFLAG_SKY, 10, 1024, 256))
+                       monster = spawnmonster("", mon, world, world, e.origin, false, false, 2);
+               else return;
+
+               e.think = SUB_Remove;
+               e.nextthink = time + 0.1;
+       }
+       else
+               monster = spawnmonster("", ((spawn_point.monsterid) ? spawn_point.monsterid : mon), spawn_point, spawn_point, spawn_point.origin, false, false, 2);
+
+       if(spawn_point) monster.target2 = spawn_point.target2;
+       monster.spawnshieldtime = time;
+       if(spawn_point && spawn_point.target_range) monster.target_range = spawn_point.target_range;
+
+       if(teamplay)
+       if(spawn_point && spawn_point.team && inv_monsters_perteam[spawn_point.team] > 0)
+               monster.team = spawn_point.team;
+       else
+       {
+               RandomSelection_Init();
+               if(inv_monsters_perteam[NUM_TEAM_1] > 0) RandomSelection_Add(world, NUM_TEAM_1, string_null, 1, 1);
+               if(inv_monsters_perteam[NUM_TEAM_2] > 0) RandomSelection_Add(world, NUM_TEAM_2, string_null, 1, 1);
+               if(invasion_teams >= 3) if(inv_monsters_perteam[NUM_TEAM_3] > 0) { RandomSelection_Add(world, NUM_TEAM_3, string_null, 1, 1); }
+               if(invasion_teams >= 4) if(inv_monsters_perteam[NUM_TEAM_4] > 0) { RandomSelection_Add(world, NUM_TEAM_4, string_null, 1, 1); }
+
+               monster.team = RandomSelection_chosen_float;
+       }
+
+       if(teamplay)
+       {
+               monster_setupcolors(monster);
+
+               if(monster.sprite)
+               {
+                       WaypointSprite_UpdateTeamRadar(monster.sprite, RADARICON_DANGER, ((monster.team) ? Team_ColorRGB(monster.team) : '1 0 0'));
+
+                       monster.sprite.team = 0;
+                       monster.sprite.SendFlags |= 1;
+               }
+       }
+
+       monster.monster_attack = false; // it's the player's job to kill all the monsters
+
+       if(inv_roundcnt >= inv_maxrounds)
+               monster.spawnflags |= MONSTERFLAG_MINIBOSS; // last round spawns minibosses
+}
+
+void invasion_SpawnMonsters(float supermonster_count)
+{
+       float chosen_monster = invasion_PickMonster(supermonster_count);
+
+       invasion_SpawnChosenMonster(chosen_monster);
+}
+
+float Invasion_CheckWinner()
+{
+       entity head;
+       if(round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0)
+       {
+               FOR_EACH_MONSTER(head)
+                       Monster_Remove(head);
+
+               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_invasion_warmup, autocvar_g_invasion_round_timelimit);
+               return 1;
+       }
+
+       float total_alive_monsters = 0, supermonster_count = 0, red_alive = 0, blue_alive = 0, yellow_alive = 0, pink_alive = 0;
+
+       FOR_EACH_MONSTER(head) if(head.health > 0)
+       {
+               if((get_monsterinfo(head.monsterid)).spawnflags & MON_FLAG_SUPERMONSTER)
+                       ++supermonster_count;
+               ++total_alive_monsters;
+
+               if(teamplay)
+               switch(head.team)
+               {
+                       case NUM_TEAM_1: ++red_alive; break;
+                       case NUM_TEAM_2: ++blue_alive; break;
+                       case NUM_TEAM_3: ++yellow_alive; break;
+                       case NUM_TEAM_4: ++pink_alive; break;
+               }
+       }
+
+       if((total_alive_monsters + inv_numkilled) < inv_maxspawned && inv_maxcurrent < inv_maxspawned)
+       {
+               if(time >= inv_lastcheck)
+               {
+                       invasion_SpawnMonsters(supermonster_count);
+                       inv_lastcheck = time + autocvar_g_invasion_spawn_delay;
+               }
+
+               return 0;
+       }
+
+       if(inv_numspawned < 1)
+               return 0; // nothing has spawned yet
+
+       if(teamplay)
+       {
+               if(((red_alive > 0) + (blue_alive > 0) + (yellow_alive > 0) + (pink_alive > 0)) > 1)
+                       return 0;
+       }
+       else if(inv_numkilled < inv_maxspawned)
+               return 0;
+
+       entity winner = world;
+       float winning_score = 0, winner_team = 0;
+
+
+       if(teamplay)
+       {
+               if(red_alive > 0) { winner_team = NUM_TEAM_1; }
+               if(blue_alive > 0)
+               if(winner_team) { winner_team = 0; }
+               else { winner_team = NUM_TEAM_2; }
+               if(yellow_alive > 0)
+               if(winner_team) { winner_team = 0; }
+               else { winner_team = NUM_TEAM_3; }
+               if(pink_alive > 0)
+               if(winner_team) { winner_team = 0; }
+               else { winner_team = NUM_TEAM_4; }
+       }
+       else
+       FOR_EACH_PLAYER(head)
+       {
+               float cs = PlayerScore_Add(head, SP_KILLS, 0);
+               if(cs > winning_score)
+               {
+                       winning_score = cs;
+                       winner = head;
+               }
+       }
+
+       FOR_EACH_MONSTER(head)
+               Monster_Remove(head);
+
+       if(teamplay)
+       {
+               if(winner_team)
+               {
+                       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_));
+               }
+       }
+       else if(winner)
+       {
+               Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_ROUND_PLAYER_WIN, winner.netname);
+               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_ROUND_PLAYER_WIN, winner.netname);
+       }
+
+       round_handler_Init(5, autocvar_g_invasion_warmup, autocvar_g_invasion_round_timelimit);
+
+       return 1;
+}
+
+float Invasion_CheckPlayers()
+{
+       return true;
+}
+
+void Invasion_RoundStart()
+{
+       entity e;
+       float numplayers = 0;
+       FOR_EACH_PLAYER(e)
+       {
+               e.player_blocked = 0;
+               ++numplayers;
+       }
+
+       if(inv_roundcnt < inv_maxrounds)
+               inv_roundcnt += 1; // a limiter to stop crazy counts
+
+       inv_monsterskill = inv_roundcnt + max(1, numplayers * 0.3);
+
+       inv_maxcurrent = 0;
+       inv_numspawned = 0;
+       inv_numkilled = 0;
+
+       inv_maxspawned = rint(max(autocvar_g_invasion_monster_count, autocvar_g_invasion_monster_count * (inv_roundcnt * 0.5)));
+
+       if(teamplay)
+       {
+               DistributeEvenly_Init(inv_maxspawned, invasion_teams);
+               inv_monsters_perteam[NUM_TEAM_1] = DistributeEvenly_Get(1);
+               inv_monsters_perteam[NUM_TEAM_2] = DistributeEvenly_Get(1);
+               if(invasion_teams >= 3) inv_monsters_perteam[NUM_TEAM_3] = DistributeEvenly_Get(1);
+               if(invasion_teams >= 4) inv_monsters_perteam[NUM_TEAM_4] = DistributeEvenly_Get(1);
+       }
+}
+
+MUTATOR_HOOKFUNCTION(inv, MonsterDies)
+{SELFPARAM();
+       if(!(self.spawnflags & MONSTERFLAG_RESPAWNED))
+       {
+               inv_numkilled += 1;
+               inv_maxcurrent -= 1;
+               if(teamplay) { inv_monsters_perteam[self.team] -= 1; }
+
+               if(IS_PLAYER(frag_attacker))
+               if(SAME_TEAM(frag_attacker, self)) // in non-teamplay modes, same team = same player, so this works
+                       PlayerScore_Add(frag_attacker, SP_KILLS, -1);
+               else
+               {
+                       PlayerScore_Add(frag_attacker, SP_KILLS, +1);
+                       if(teamplay)
+                               TeamScore_AddToTeam(frag_attacker.team, ST_INV_KILLS, +1);
+               }
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(inv, MonsterSpawn)
+{SELFPARAM();
+       if(!(self.spawnflags & MONSTERFLAG_SPAWNED))
+               return true;
+
+       if(!(self.spawnflags & MONSTERFLAG_RESPAWNED))
+       {
+               inv_numspawned += 1;
+               inv_maxcurrent += 1;
+       }
+
+       self.monster_skill = inv_monsterskill;
+
+       if((get_monsterinfo(self.monsterid)).spawnflags & MON_FLAG_SUPERMONSTER)
+               Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_INVASION_SUPERMONSTER, self.monster_name);
+
+       self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_BOTCLIP | DPCONTENTS_MONSTERCLIP;
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(inv, OnEntityPreSpawn)
+{SELFPARAM();
+       if(startsWith(self.classname, "monster_"))
+       if(!(self.spawnflags & MONSTERFLAG_SPAWNED))
+               return true;
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(inv, SV_StartFrame)
+{
+       monsters_total = inv_maxspawned; // TODO: make sure numspawned never exceeds maxspawned
+       monsters_killed = inv_numkilled;
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(inv, PlayerRegen)
+{
+       // no regeneration in invasion
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(inv, PlayerSpawn)
+{SELFPARAM();
+       self.bot_attack = false;
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(inv, PlayerDamage_Calculate)
+{
+       if(IS_PLAYER(frag_attacker) && IS_PLAYER(frag_target) && frag_attacker != frag_target)
+       {
+               frag_damage = 0;
+               frag_force = '0 0 0';
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(inv, SV_ParseClientCommand)
+{SELFPARAM();
+       if(MUTATOR_RETURNVALUE) // command was already handled?
+               return false;
+
+       if(cmd_name == "debuginvasion")
+       {
+               sprint(self, strcat("inv_maxspawned = ", ftos(inv_maxspawned), "\n"));
+               sprint(self, strcat("inv_numspawned = ", ftos(inv_numspawned), "\n"));
+               sprint(self, strcat("inv_numkilled = ", ftos(inv_numkilled), "\n"));
+               sprint(self, strcat("inv_roundcnt = ", ftos(inv_roundcnt), "\n"));
+               sprint(self, strcat("monsters_total = ", ftos(monsters_total), "\n"));
+               sprint(self, strcat("monsters_killed = ", ftos(monsters_killed), "\n"));
+               sprint(self, strcat("inv_monsterskill = ", ftos(inv_monsterskill), "\n"));
+
+               return true;
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(inv, BotShouldAttack)
+{
+       if(!IS_MONSTER(checkentity))
+               return true;
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(inv, SetStartItems)
+{
+       start_health = 200;
+       start_armorvalue = 200;
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(inv, AccuracyTargetValid)
+{
+       if(IS_MONSTER(frag_target))
+               return MUT_ACCADD_INVALID;
+       return MUT_ACCADD_INDIFFERENT;
+}
+
+MUTATOR_HOOKFUNCTION(inv, AllowMobSpawning)
+{
+       // monster spawning disabled during an invasion
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(inv, GetTeamCount, CBC_ORDER_EXCLUSIVE)
+{
+       ret_float = invasion_teams;
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(inv, AllowMobButcher)
+{
+       ret_string = "This command does not work during an invasion!";
+       return true;
+}
+
+void invasion_ScoreRules(float inv_teams)
+{
+       if(inv_teams) { CheckAllowedTeams(world); }
+       ScoreRules_basics(inv_teams, 0, 0, false);
+       if(inv_teams) ScoreInfo_SetLabel_TeamScore(ST_INV_KILLS, "frags", SFL_SORT_PRIO_PRIMARY);
+       ScoreInfo_SetLabel_PlayerScore(SP_KILLS, "frags", ((inv_teams) ? SFL_SORT_PRIO_SECONDARY : SFL_SORT_PRIO_PRIMARY));
+       ScoreRules_basics_end();
+}
+
+void invasion_DelayedInit() // Do this check with a delay so we can wait for teams to be set up.
+{
+       if(autocvar_g_invasion_teams)
+               invasion_teams = bound(2, autocvar_g_invasion_teams, 4);
+       else
+               invasion_teams = 0;
+
+       independent_players = 1; // to disable extra useless scores
+
+       invasion_ScoreRules(invasion_teams);
+
+       independent_players = 0;
+
+       round_handler_Spawn(Invasion_CheckPlayers, Invasion_CheckWinner, Invasion_RoundStart);
+       round_handler_Init(5, autocvar_g_invasion_warmup, autocvar_g_invasion_round_timelimit);
+
+       inv_roundcnt = 0;
+       inv_maxrounds = 15; // 15?
+}
+
+void invasion_Initialize()
+{
+       if(autocvar_g_invasion_zombies_only) {
+               Monster mon = MON_ZOMBIE;
+               mon.mr_precache(mon);
+       } else
+       {
+               float i;
+               entity mon;
+               for(i = MON_FIRST; i <= MON_LAST; ++i)
+               {
+                       mon = get_monsterinfo(i);
+                       if((mon.spawnflags & MONSTER_TYPE_FLY) || (mon.spawnflags & MONSTER_TYPE_SWIM))
+                               continue; // flying/swimming monsters not yet supported
+
+                       mon.mr_precache(mon);
+               }
+       }
+
+       InitializeEntity(world, invasion_DelayedInit, INITPRIO_GAMETYPE);
+}
+
+#endif
diff --git a/qcsrc/server/mutators/mutator/gamemode_keepaway.qc b/qcsrc/server/mutators/mutator/gamemode_keepaway.qc
new file mode 100644 (file)
index 0000000..8961e6b
--- /dev/null
@@ -0,0 +1,502 @@
+#ifndef GAMEMODE_KEEPAWAY_H
+#define GAMEMODE_KEEPAWAY_H
+
+void ka_Initialize();
+
+REGISTER_MUTATOR(ka, false)
+{
+       MUTATOR_ONADD
+       {
+               if (time > 1) // game loads at time 1
+                       error("This is a game type and it cannot be added at runtime.");
+               ka_Initialize();
+       }
+
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               // we actually cannot roll back ka_Initialize here
+               // BUT: we don't need to! If this gets called, adding always
+               // succeeds.
+       }
+
+       MUTATOR_ONREMOVE
+       {
+               LOG_INFO("This is a game type and it cannot be removed at runtime.");
+               return -1;
+       }
+
+       return 0;
+}
+
+
+entity ka_ball;
+
+const float SP_KEEPAWAY_PICKUPS = 4;
+const float SP_KEEPAWAY_CARRIERKILLS = 5;
+const float SP_KEEPAWAY_BCTIME = 6;
+
+void() havocbot_role_ka_carrier;
+void() havocbot_role_ka_collector;
+
+void ka_DropEvent(entity plyr);
+#endif
+
+#ifdef IMPLEMENTATION
+
+int autocvar_g_keepaway_ballcarrier_effects;
+float autocvar_g_keepaway_ballcarrier_damage;
+float autocvar_g_keepaway_ballcarrier_force;
+float autocvar_g_keepaway_ballcarrier_highspeed;
+float autocvar_g_keepaway_ballcarrier_selfdamage;
+float autocvar_g_keepaway_ballcarrier_selfforce;
+float autocvar_g_keepaway_noncarrier_damage;
+float autocvar_g_keepaway_noncarrier_force;
+float autocvar_g_keepaway_noncarrier_selfdamage;
+float autocvar_g_keepaway_noncarrier_selfforce;
+bool autocvar_g_keepaway_noncarrier_warn;
+int autocvar_g_keepaway_score_bckill;
+int autocvar_g_keepaway_score_killac;
+int autocvar_g_keepaway_score_timepoints;
+float autocvar_g_keepaway_score_timeinterval;
+float autocvar_g_keepawayball_damageforcescale;
+int autocvar_g_keepawayball_effects;
+float autocvar_g_keepawayball_respawntime;
+int autocvar_g_keepawayball_trail_color;
+
+float ka_ballcarrier_waypointsprite_visible_for_player(entity e) // runs on waypoints which are attached to ballcarriers, updates once per frame
+{
+       if(e.ballcarried)
+               if(IS_SPEC(other))
+                       return false; // we don't want spectators of the ballcarrier to see the attached waypoint on the top of their screen
+
+       // TODO: Make the ballcarrier lack a waypointsprite whenever they have the invisibility powerup
+
+       return true;
+}
+
+void ka_EventLog(string mode, entity actor) // use an alias for easy changing and quick editing later
+{
+       if(autocvar_sv_eventlog)
+               GameLogEcho(strcat(":ka:", mode, ((actor != world) ? (strcat(":", ftos(actor.playerid))) : "")));
+}
+
+void ka_TouchEvent();
+void ka_RespawnBall() // runs whenever the ball needs to be relocated
+{SELFPARAM();
+       if(gameover) { return; }
+       vector oldballorigin = self.origin;
+
+       if(!MoveToRandomMapLocation(self, DPCONTENTS_SOLID | DPCONTENTS_CORPSE | DPCONTENTS_PLAYERCLIP, DPCONTENTS_SLIME | DPCONTENTS_LAVA | DPCONTENTS_SKY | DPCONTENTS_BODY | DPCONTENTS_DONOTENTER, Q3SURFACEFLAG_SKY, 10, 1024, 256))
+       {
+               entity spot = SelectSpawnPoint(true);
+               setorigin(self, spot.origin);
+               self.angles = spot.angles;
+       }
+
+       makevectors(self.angles);
+       self.movetype = MOVETYPE_BOUNCE;
+       self.velocity = '0 0 200';
+       self.angles = '0 0 0';
+       self.effects = autocvar_g_keepawayball_effects;
+       self.touch = ka_TouchEvent;
+       self.think = ka_RespawnBall;
+       self.nextthink = time + autocvar_g_keepawayball_respawntime;
+
+       Send_Effect(EFFECT_ELECTRO_COMBO, oldballorigin, '0 0 0', 1);
+       Send_Effect(EFFECT_ELECTRO_COMBO, self.origin, '0 0 0', 1);
+
+       WaypointSprite_Spawn(WP_KaBall, 0, 0, self, '0 0 64', world, self.team, self, waypointsprite_attachedforcarrier, false, RADARICON_FLAGCARRIER);
+       WaypointSprite_Ping(self.waypointsprite_attachedforcarrier);
+
+       sound(self, CH_TRIGGER, SND_KA_RESPAWN, VOL_BASE, ATTEN_NONE); // ATTEN_NONE (it's a sound intended to be heard anywhere)
+}
+
+void ka_TimeScoring()
+{SELFPARAM();
+       if(self.owner.ballcarried)
+       { // add points for holding the ball after a certain amount of time
+               if(autocvar_g_keepaway_score_timepoints)
+                       PlayerScore_Add(self.owner, SP_SCORE, autocvar_g_keepaway_score_timepoints);
+
+               PlayerScore_Add(self.owner, SP_KEEPAWAY_BCTIME, (autocvar_g_keepaway_score_timeinterval / 1)); // interval is divided by 1 so that time always shows "seconds"
+               self.nextthink = time + autocvar_g_keepaway_score_timeinterval;
+       }
+}
+
+void ka_TouchEvent() // runs any time that the ball comes in contact with something
+{SELFPARAM();
+       if(gameover) { return; }
+       if(!self) { return; }
+       if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
+       { // The ball fell off the map, respawn it since players can't get to it
+               ka_RespawnBall();
+               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
+               Send_Effect(EFFECT_BALL_SPARKS, self.origin, '0 0 0', 1);
+               sound(self, CH_TRIGGER, SND_KA_TOUCH, VOL_BASE, ATTEN_NORM);
+               return;
+       }
+       else if(self.wait > time) { return; }
+
+       // attach the ball to the player
+       self.owner = other;
+       other.ballcarried = self;
+       setattachment(self, other, "");
+       setorigin(self, '0 0 0');
+
+       // make the ball invisible/unable to do anything/set up time scoring
+       self.velocity = '0 0 0';
+       self.movetype = MOVETYPE_NONE;
+       self.effects |= EF_NODRAW;
+       self.touch = func_null;
+       self.think = ka_TimeScoring;
+       self.nextthink = time + autocvar_g_keepaway_score_timeinterval;
+       self.takedamage = DAMAGE_NO;
+
+       // apply effects to player
+       other.glow_color = autocvar_g_keepawayball_trail_color;
+       other.glow_trail = true;
+       other.effects |= autocvar_g_keepaway_ballcarrier_effects;
+
+       // messages and sounds
+       ka_EventLog("pickup", other);
+       Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_KEEPAWAY_PICKUP, other.netname);
+       Send_Notification(NOTIF_ALL_EXCEPT, other, MSG_CENTER, CENTER_KEEPAWAY_PICKUP, other.netname);
+       Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_KEEPAWAY_PICKUP_SELF);
+       sound(self.owner, CH_TRIGGER, SND_KA_PICKEDUP, VOL_BASE, ATTEN_NONE); // ATTEN_NONE (it's a sound intended to be heard anywhere)
+
+       // scoring
+       PlayerScore_Add(other, SP_KEEPAWAY_PICKUPS, 1);
+
+       // waypoints
+       WaypointSprite_AttachCarrier(WP_KaBallCarrier, other, RADARICON_FLAGCARRIER);
+       other.waypointsprite_attachedforcarrier.waypointsprite_visible_for_player = ka_ballcarrier_waypointsprite_visible_for_player;
+       WaypointSprite_UpdateRule(other.waypointsprite_attachedforcarrier, 0, SPRITERULE_DEFAULT);
+       WaypointSprite_Ping(other.waypointsprite_attachedforcarrier);
+       WaypointSprite_Kill(self.waypointsprite_attachedforcarrier);
+}
+
+void ka_DropEvent(entity plyr) // runs any time that a player is supposed to lose the ball
+{
+       entity ball;
+       ball = plyr.ballcarried;
+
+       if(!ball) { return; }
+
+       // reset the ball
+       setattachment(ball, world, "");
+       ball.movetype = MOVETYPE_BOUNCE;
+       ball.wait = time + 1;
+       ball.touch = ka_TouchEvent;
+       ball.think = ka_RespawnBall;
+       ball.nextthink = time + autocvar_g_keepawayball_respawntime;
+       ball.takedamage = DAMAGE_YES;
+       ball.effects &= ~EF_NODRAW;
+       setorigin(ball, plyr.origin + '0 0 10');
+       ball.velocity = '0 0 200' + '0 100 0'*crandom() + '100 0 0'*crandom();
+       ball.owner.ballcarried = world; // I hope nothing checks to see if the world has the ball in the rest of my code :P
+       ball.owner = world;
+
+       // reset the player effects
+       plyr.glow_trail = false;
+       plyr.effects &= ~autocvar_g_keepaway_ballcarrier_effects;
+
+       // messages and sounds
+       ka_EventLog("dropped", plyr);
+       Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_KEEPAWAY_DROPPED, plyr.netname);
+       Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_KEEPAWAY_DROPPED, plyr.netname);
+       sound(other, CH_TRIGGER, SND_KA_DROPPED, VOL_BASE, ATTEN_NONE); // ATTEN_NONE (it's a sound intended to be heard anywhere)
+
+       // scoring
+       // PlayerScore_Add(plyr, SP_KEEPAWAY_DROPS, 1); Not anymore, this is 100% the same as pickups and is useless.
+
+       // waypoints
+       WaypointSprite_Spawn(WP_KaBall, 0, 0, ball, '0 0 64', world, ball.team, ball, waypointsprite_attachedforcarrier, false, RADARICON_FLAGCARRIER);
+       WaypointSprite_UpdateRule(ball.waypointsprite_attachedforcarrier, 0, SPRITERULE_DEFAULT);
+       WaypointSprite_Ping(ball.waypointsprite_attachedforcarrier);
+       WaypointSprite_Kill(plyr.waypointsprite_attachedforcarrier);
+}
+
+void ka_Reset() // used to clear the ballcarrier whenever the match switches from warmup to normal
+{SELFPARAM();
+       if((self.owner) && (IS_PLAYER(self.owner)))
+               ka_DropEvent(self.owner);
+
+       if(time < game_starttime)
+       {
+               self.think = ka_RespawnBall;
+               self.touch = func_null;
+               self.nextthink = game_starttime;
+       }
+       else
+               ka_RespawnBall();
+}
+
+
+// ================
+// Bot player logic
+// ================
+
+void havocbot_goalrating_ball(float ratingscale, vector org)
+{SELFPARAM();
+       float t;
+       entity ball_owner;
+       ball_owner = ka_ball.owner;
+
+       if (ball_owner == self)
+               return;
+
+       // If ball is carried by player then hunt them down.
+       if (ball_owner)
+       {
+               t = (self.health + self.armorvalue) / (ball_owner.health + ball_owner.armorvalue);
+               navigation_routerating(ball_owner, t * ratingscale, 2000);
+       }
+       else // Ball has been dropped so collect.
+               navigation_routerating(ka_ball, ratingscale, 2000);
+}
+
+void havocbot_role_ka_carrier()
+{SELFPARAM();
+       if (self.deadflag != DEAD_NO)
+               return;
+
+       if (time > self.bot_strategytime)
+       {
+               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+
+               navigation_goalrating_start();
+               havocbot_goalrating_items(10000, self.origin, 10000);
+               havocbot_goalrating_enemyplayers(20000, self.origin, 10000);
+               //havocbot_goalrating_waypoints(1, self.origin, 1000);
+               navigation_goalrating_end();
+       }
+
+       if (!self.ballcarried)
+       {
+               self.havocbot_role = havocbot_role_ka_collector;
+               self.bot_strategytime = 0;
+       }
+}
+
+void havocbot_role_ka_collector()
+{SELFPARAM();
+       if (self.deadflag != DEAD_NO)
+               return;
+
+       if (time > self.bot_strategytime)
+       {
+               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+
+               navigation_goalrating_start();
+               havocbot_goalrating_items(10000, self.origin, 10000);
+               havocbot_goalrating_enemyplayers(1000, self.origin, 10000);
+               havocbot_goalrating_ball(20000, self.origin);
+               navigation_goalrating_end();
+       }
+
+       if (self.ballcarried)
+       {
+               self.havocbot_role = havocbot_role_ka_carrier;
+               self.bot_strategytime = 0;
+       }
+}
+
+
+// ==============
+// Hook Functions
+// ==============
+
+MUTATOR_HOOKFUNCTION(ka, PlayerDies)
+{SELFPARAM();
+       if((frag_attacker != frag_target) && (IS_PLAYER(frag_attacker)))
+       {
+               if(frag_target.ballcarried) { // add to amount of times killing carrier
+                       PlayerScore_Add(frag_attacker, SP_KEEPAWAY_CARRIERKILLS, 1);
+                       if(autocvar_g_keepaway_score_bckill) // add bckills to the score
+                               PlayerScore_Add(frag_attacker, SP_SCORE, autocvar_g_keepaway_score_bckill);
+               }
+               else if(!frag_attacker.ballcarried)
+                       if(autocvar_g_keepaway_noncarrier_warn)
+                               Send_Notification(NOTIF_ONE_ONLY, frag_attacker, MSG_CENTER, CENTER_KEEPAWAY_WARN);
+
+               if(frag_attacker.ballcarried) // add to amount of kills while ballcarrier
+                       PlayerScore_Add(frag_attacker, SP_SCORE, autocvar_g_keepaway_score_killac);
+       }
+
+       if(self.ballcarried) { ka_DropEvent(self); } // a player with the ball has died, drop it
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(ka, GiveFragsForKill)
+{
+       frag_score = 0; // no frags counted in keepaway
+       return 1; // you deceptive little bugger ;3 This needs to be true in order for this function to even count.
+}
+
+MUTATOR_HOOKFUNCTION(ka, PlayerPreThink)
+{SELFPARAM();
+       // clear the item used for the ball in keepaway
+       self.items &= ~IT_KEY1;
+
+       // if the player has the ball, make sure they have the item for it (Used for HUD primarily)
+       if(self.ballcarried)
+               self.items |= IT_KEY1;
+
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(ka, PlayerUseKey)
+{SELFPARAM();
+       if(MUTATOR_RETURNVALUE == 0)
+       if(self.ballcarried)
+       {
+               ka_DropEvent(self);
+               return 1;
+       }
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(ka, PlayerDamage_Calculate) // for changing damage and force values that are applied to players in g_damage.qc
+{
+       if(frag_attacker.ballcarried) // if the attacker is a ballcarrier
+       {
+               if(frag_target == frag_attacker) // damage done to yourself
+               {
+                       frag_damage *= autocvar_g_keepaway_ballcarrier_selfdamage;
+                       frag_force *= autocvar_g_keepaway_ballcarrier_selfforce;
+               }
+               else // damage done to noncarriers
+               {
+                       frag_damage *= autocvar_g_keepaway_ballcarrier_damage;
+                       frag_force *= autocvar_g_keepaway_ballcarrier_force;
+               }
+       }
+       else if (!frag_target.ballcarried) // if the target is a noncarrier
+       {
+               if(frag_target == frag_attacker) // damage done to yourself
+               {
+                       frag_damage *= autocvar_g_keepaway_noncarrier_selfdamage;
+                       frag_force *= autocvar_g_keepaway_noncarrier_selfforce;
+               }
+               else // damage done to other noncarriers
+               {
+                       frag_damage *= autocvar_g_keepaway_noncarrier_damage;
+                       frag_force *= autocvar_g_keepaway_noncarrier_force;
+               }
+       }
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(ka, ClientDisconnect)
+{SELFPARAM();
+       if(self.ballcarried) { ka_DropEvent(self); } // a player with the ball has left the match, drop it
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(ka, MakePlayerObserver)
+{SELFPARAM();
+       if(self.ballcarried) { ka_DropEvent(self); } // a player with the ball has left the match, drop it
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(ka, PlayerPowerups)
+{SELFPARAM();
+       // In the future this hook is supposed to allow me to do some extra stuff with waypointsprites and invisibility powerup
+       // So bare with me until I can fix a certain bug with ka_ballcarrier_waypointsprite_visible_for_player()
+
+       self.effects &= ~autocvar_g_keepaway_ballcarrier_effects;
+
+       if(self.ballcarried)
+               self.effects |= autocvar_g_keepaway_ballcarrier_effects;
+
+       return 0;
+}
+
+.float stat_sv_airspeedlimit_nonqw;
+.float stat_sv_maxspeed;
+
+MUTATOR_HOOKFUNCTION(ka, PlayerPhysics)
+{SELFPARAM();
+       if(self.ballcarried)
+       {
+               self.stat_sv_airspeedlimit_nonqw *= autocvar_g_keepaway_ballcarrier_highspeed;
+               self.stat_sv_maxspeed *= autocvar_g_keepaway_ballcarrier_highspeed;
+       }
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ka, BotShouldAttack)
+{SELFPARAM();
+       // if neither player has ball then don't attack unless the ball is on the ground
+       if(!checkentity.ballcarried && !self.ballcarried && ka_ball.owner)
+               return true;
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ka, HavocBot_ChooseRole)
+{SELFPARAM();
+       if (self.ballcarried)
+               self.havocbot_role = havocbot_role_ka_carrier;
+       else
+               self.havocbot_role = havocbot_role_ka_collector;
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(ka, DropSpecialItems)
+{
+       if(frag_target.ballcarried)
+               ka_DropEvent(frag_target);
+
+       return false;
+}
+
+
+// ==============
+// Initialization
+// ==============
+
+void ka_SpawnBall() // loads various values for the ball, runs only once at start of match
+{
+       entity e;
+       e = spawn();
+       e.model = "models/orbs/orbblue.md3";
+       precache_model(e.model);
+       _setmodel(e, e.model);
+       setsize(e, '-16 -16 -20', '16 16 20'); // 20 20 20 was too big, player is only 16 16 24... gotta cheat with the Z (20) axis so that the particle isn't cut off
+       e.classname = "keepawayball";
+       e.damageforcescale = autocvar_g_keepawayball_damageforcescale;
+       e.takedamage = DAMAGE_YES;
+       e.solid = SOLID_TRIGGER;
+       e.movetype = MOVETYPE_BOUNCE;
+       e.glow_color = autocvar_g_keepawayball_trail_color;
+       e.glow_trail = true;
+       e.flags = FL_ITEM;
+       e.reset = ka_Reset;
+       e.touch = ka_TouchEvent;
+       e.owner = world;
+       ka_ball = e;
+
+       InitializeEntity(e, ka_RespawnBall, INITPRIO_SETLOCATION); // is this the right priority? Neh, I have no idea.. Well-- it works! So.
+}
+
+void ka_ScoreRules()
+{
+       ScoreRules_basics(0, SFL_SORT_PRIO_PRIMARY, 0, true); // SFL_SORT_PRIO_PRIMARY
+       ScoreInfo_SetLabel_PlayerScore(SP_KEEPAWAY_PICKUPS,                     "pickups",              0);
+       ScoreInfo_SetLabel_PlayerScore(SP_KEEPAWAY_CARRIERKILLS,        "bckills",              0);
+       ScoreInfo_SetLabel_PlayerScore(SP_KEEPAWAY_BCTIME,                      "bctime",               SFL_SORT_PRIO_SECONDARY);
+       ScoreRules_basics_end();
+}
+
+void ka_Initialize() // run at the start of a match, initiates game mode
+{
+       ka_ScoreRules();
+       ka_SpawnBall();
+}
+
+#endif
diff --git a/qcsrc/server/mutators/mutator/gamemode_keyhunt.qc b/qcsrc/server/mutators/mutator/gamemode_keyhunt.qc
new file mode 100644 (file)
index 0000000..5982cf2
--- /dev/null
@@ -0,0 +1,1402 @@
+#ifndef GAMEMODE_KEYHUNT_H
+#define GAMEMODE_KEYHUNT_H
+
+#define autocvar_g_keyhunt_point_limit cvar("g_keyhunt_point_limit")
+int autocvar_g_keyhunt_point_leadlimit;
+bool autocvar_g_keyhunt_team_spawns;
+void kh_Initialize();
+
+REGISTER_MUTATOR(kh, false)
+{
+       ActivateTeamplay();
+       SetLimits(autocvar_g_keyhunt_point_limit, autocvar_g_keyhunt_point_leadlimit, -1, -1);
+       if (autocvar_g_keyhunt_team_spawns)
+               have_team_spawns = -1; // request team spawns
+
+       MUTATOR_ONADD
+       {
+               if (time > 1) // game loads at time 1
+                       error("This is a game type and it cannot be added at runtime.");
+               kh_Initialize();
+       }
+
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               // we actually cannot roll back kh_Initialize here
+               // BUT: we don't need to! If this gets called, adding always
+               // succeeds.
+       }
+
+       MUTATOR_ONREMOVE
+       {
+               LOG_INFO("This is a game type and it cannot be removed at runtime.");
+               return -1;
+       }
+
+       return 0;
+}
+
+#define FOR_EACH_KH_KEY(v) for(v = kh_worldkeylist; v; v = v.kh_worldkeynext )
+
+// ALL OF THESE should be removed in the future, as other code should not have to care
+
+// used by bots:
+float kh_tracking_enabled;
+.entity kh_next;
+float kh_Key_AllOwnedByWhichTeam();
+
+typedef void(void) kh_Think_t;
+void kh_StartRound();
+void kh_Controller_SetThink(float t, kh_Think_t func);
+
+entity kh_worldkeylist;
+.entity kh_worldkeynext;
+#endif
+
+#ifdef IMPLEMENTATION
+
+float autocvar_g_balance_keyhunt_damageforcescale;
+float autocvar_g_balance_keyhunt_delay_collect;
+float autocvar_g_balance_keyhunt_delay_return;
+float autocvar_g_balance_keyhunt_delay_round;
+float autocvar_g_balance_keyhunt_delay_tracking;
+float autocvar_g_balance_keyhunt_dropvelocity;
+float autocvar_g_balance_keyhunt_maxdist;
+float autocvar_g_balance_keyhunt_protecttime;
+
+int autocvar_g_balance_keyhunt_score_capture;
+int autocvar_g_balance_keyhunt_score_carrierfrag;
+int autocvar_g_balance_keyhunt_score_collect;
+int autocvar_g_balance_keyhunt_score_destroyed;
+int autocvar_g_balance_keyhunt_score_destroyed_ownfactor;
+int autocvar_g_balance_keyhunt_score_push;
+float autocvar_g_balance_keyhunt_throwvelocity;
+
+int autocvar_g_keyhunt_teams;
+int autocvar_g_keyhunt_teams_override;
+
+// #define KH_PLAYER_USE_ATTACHMENT
+// #define KH_PLAYER_USE_CARRIEDMODEL
+
+#ifdef KH_PLAYER_USE_ATTACHMENT
+const vector KH_PLAYER_ATTACHMENT_DIST_ROTATED = '0 -4 0';
+const vector KH_PLAYER_ATTACHMENT_DIST = '4 0 0';
+const vector KH_PLAYER_ATTACHMENT = '0 0 0';
+const vector KH_PLAYER_ATTACHMENT_ANGLES = '0 0 0';
+const string KH_PLAYER_ATTACHMENT_BONE = "";
+#else
+const float KH_KEY_ZSHIFT = 22;
+const float KH_KEY_XYDIST = 24;
+const float KH_KEY_XYSPEED = 45;
+#endif
+const float KH_KEY_WP_ZSHIFT = 20;
+
+const vector KH_KEY_MIN = '-10 -10 -46';
+const vector KH_KEY_MAX = '10 10 3';
+const float KH_KEY_BRIGHTNESS = 2;
+
+float kh_no_radar_circles;
+
+// kh_state
+//     bits  0- 4: team of key 1, or 0 for no such key, or 30 for dropped, or 31 for self
+//     bits  5- 9: team of key 2, or 0 for no such key, or 30 for dropped, or 31 for self
+//     bits 10-14: team of key 3, or 0 for no such key, or 30 for dropped, or 31 for self
+//     bits 15-19: team of key 4, or 0 for no such key, or 30 for dropped, or 31 for self
+.float kh_state;
+.float siren_time;  //  time delay the siren
+//.float stuff_time;  //  time delay to stuffcmd a cvar
+
+float kh_keystatus[17];
+//kh_keystatus[0] = status of dropped keys, kh_keystatus[1 - 16] = player #
+//replace 17 with cvar("maxplayers") or similar !!!!!!!!!
+//for(i = 0; i < maxplayers; ++i)
+//     kh_keystatus[i] = "0";
+
+float kh_Team_ByID(float t)
+{
+       if(t == 0) return NUM_TEAM_1;
+       if(t == 1) return NUM_TEAM_2;
+       if(t == 2) return NUM_TEAM_3;
+       if(t == 3) return NUM_TEAM_4;
+       return 0;
+}
+
+//entity kh_worldkeylist;
+.entity kh_worldkeynext;
+entity kh_controller;
+//float kh_tracking_enabled;
+float kh_teams;
+float kh_interferemsg_time, kh_interferemsg_team;
+.entity kh_next, kh_prev; // linked list
+.float kh_droptime;
+.float kh_dropperteam;
+.entity kh_previous_owner;
+.float kh_previous_owner_playerid;
+.float kh_cp_duration;
+
+float kh_key_dropped, kh_key_carried;
+
+const float ST_KH_CAPS = 1;
+const float SP_KH_CAPS = 4;
+const float SP_KH_PUSHES = 5;
+const float SP_KH_DESTROYS = 6;
+const float SP_KH_PICKUPS = 7;
+const float SP_KH_KCKILLS = 8;
+const float SP_KH_LOSSES = 9;
+void kh_ScoreRules(float teams)
+{
+       ScoreRules_basics(teams, SFL_SORT_PRIO_PRIMARY, SFL_SORT_PRIO_PRIMARY, true);
+       ScoreInfo_SetLabel_TeamScore(  ST_KH_CAPS,      "caps",      SFL_SORT_PRIO_SECONDARY);
+       ScoreInfo_SetLabel_PlayerScore(SP_KH_CAPS,      "caps",      SFL_SORT_PRIO_SECONDARY);
+       ScoreInfo_SetLabel_PlayerScore(SP_KH_PUSHES,    "pushes",    0);
+       ScoreInfo_SetLabel_PlayerScore(SP_KH_DESTROYS,  "destroyed", SFL_LOWER_IS_BETTER);
+       ScoreInfo_SetLabel_PlayerScore(SP_KH_PICKUPS,   "pickups",   0);
+       ScoreInfo_SetLabel_PlayerScore(SP_KH_KCKILLS,   "kckills",   0);
+       ScoreInfo_SetLabel_PlayerScore(SP_KH_LOSSES,    "losses",    SFL_LOWER_IS_BETTER);
+       ScoreRules_basics_end();
+}
+
+float kh_KeyCarrier_waypointsprite_visible_for_player(entity e)  // runs all the time
+{SELFPARAM();
+       if(!IS_PLAYER(e) || self.team != e.team)
+               if(!kh_tracking_enabled)
+                       return false;
+
+       return true;
+}
+
+float kh_Key_waypointsprite_visible_for_player(entity e) // ??
+{SELFPARAM();
+       if(!kh_tracking_enabled)
+               return false;
+       if(!self.owner)
+               return true;
+       if(!self.owner.owner)
+               return true;
+       return false;  // draw only when key is not owned
+}
+
+void kh_update_state()
+{
+       entity player;
+       entity key;
+       float s;
+       float f;
+
+       s = 0;
+       FOR_EACH_KH_KEY(key)
+       {
+               if(key.owner)
+                       f = key.team;
+               else
+                       f = 30;
+               s |= pow(32, key.count) * f;
+       }
+
+       FOR_EACH_CLIENT(player)
+       {
+               player.kh_state = s;
+       }
+
+       FOR_EACH_KH_KEY(key)
+       {
+               if(key.owner)
+                       key.owner.kh_state |= pow(32, key.count) * 31;
+       }
+       //print(ftos((nextent(world)).kh_state), "\n");
+}
+
+
+
+
+var kh_Think_t kh_Controller_Thinkfunc;
+void kh_Controller_SetThink(float t, kh_Think_t func)  // runs occasionaly
+{
+       kh_Controller_Thinkfunc = func;
+       kh_controller.cnt = ceil(t);
+       if(t == 0)
+               kh_controller.nextthink = time; // force
+}
+void kh_WaitForPlayers();
+void kh_Controller_Think()  // called a lot
+{SELFPARAM();
+       if(intermission_running)
+               return;
+       if(self.cnt > 0)
+       { if(self.think != kh_WaitForPlayers) { self.cnt -= 1; } }
+       else if(self.cnt == 0)
+       {
+               self.cnt -= 1;
+               kh_Controller_Thinkfunc();
+       }
+       self.nextthink = time + 1;
+}
+
+// frags f: take from cvar * f
+// frags 0: no frags
+void kh_Scores_Event(entity player, entity key, string what, float frags_player, float frags_owner)  // update the score when a key is captured
+{
+       string s;
+       if(intermission_running)
+               return;
+
+       if(frags_player)
+               UpdateFrags(player, frags_player);
+
+       if(key && key.owner && frags_owner)
+               UpdateFrags(key.owner, frags_owner);
+
+       if(!autocvar_sv_eventlog)  //output extra info to the console or text file
+               return;
+
+       s = strcat(":keyhunt:", what, ":", ftos(player.playerid), ":", ftos(frags_player));
+
+       if(key && key.owner)
+               s = strcat(s, ":", ftos(key.owner.playerid));
+       else
+               s = strcat(s, ":0");
+
+       s = strcat(s, ":", ftos(frags_owner), ":");
+
+       if(key)
+               s = strcat(s, key.netname);
+
+       GameLogEcho(s);
+}
+
+vector kh_AttachedOrigin(entity e)  // runs when a team captures the flag, it can run 2 or 3 times.
+{
+       if(e.tag_entity)
+       {
+               makevectors(e.tag_entity.angles);
+               return e.tag_entity.origin + e.origin.x * v_forward - e.origin.y * v_right + e.origin.z * v_up;
+       }
+       else
+               return e.origin;
+}
+
+void kh_Key_Attach(entity key)  // runs when a player picks up a key and several times when a key is assigned to a player at the start of a round
+{
+#ifdef KH_PLAYER_USE_ATTACHMENT
+       entity first;
+       first = key.owner.kh_next;
+       if(key == first)
+       {
+               setattachment(key, key.owner, KH_PLAYER_ATTACHMENT_BONE);
+               if(key.kh_next)
+               {
+                       setattachment(key.kh_next, key, "");
+                       setorigin(key, key.kh_next.origin - 0.5 * KH_PLAYER_ATTACHMENT_DIST);
+                       setorigin(key.kh_next, KH_PLAYER_ATTACHMENT_DIST_ROTATED);
+                       key.kh_next.angles = '0 0 0';
+               }
+               else
+                       setorigin(key, KH_PLAYER_ATTACHMENT);
+               key.angles = KH_PLAYER_ATTACHMENT_ANGLES;
+       }
+       else
+       {
+               setattachment(key, key.kh_prev, "");
+               if(key.kh_next)
+                       setattachment(key.kh_next, key, "");
+               setorigin(key, KH_PLAYER_ATTACHMENT_DIST_ROTATED);
+               setorigin(first, first.origin - 0.5 * KH_PLAYER_ATTACHMENT_DIST);
+               key.angles = '0 0 0';
+       }
+#else
+       setattachment(key, key.owner, "");
+       setorigin(key, '0 0 1' * KH_KEY_ZSHIFT);  // fixing x, y in think
+       key.angles_y -= key.owner.angles.y;
+#endif
+       key.flags = 0;
+       key.solid = SOLID_NOT;
+       key.movetype = MOVETYPE_NONE;
+       key.team = key.owner.team;
+       key.nextthink = time;
+       key.damageforcescale = 0;
+       key.takedamage = DAMAGE_NO;
+       key.modelindex = kh_key_carried;
+}
+
+void kh_Key_Detach(entity key) // runs every time a key is dropped or lost. Runs several times times when all the keys are captured
+{
+#ifdef KH_PLAYER_USE_ATTACHMENT
+       entity first;
+       first = key.owner.kh_next;
+       if(key == first)
+       {
+               if(key.kh_next)
+               {
+                       setattachment(key.kh_next, key.owner, KH_PLAYER_ATTACHMENT_BONE);
+                       setorigin(key.kh_next, key.origin + 0.5 * KH_PLAYER_ATTACHMENT_DIST);
+                       key.kh_next.angles = KH_PLAYER_ATTACHMENT_ANGLES;
+               }
+       }
+       else
+       {
+               if(key.kh_next)
+                       setattachment(key.kh_next, key.kh_prev, "");
+               setorigin(first, first.origin + 0.5 * KH_PLAYER_ATTACHMENT_DIST);
+       }
+       // in any case:
+       setattachment(key, world, "");
+       setorigin(key, key.owner.origin + '0 0 1' * (PL_MIN.z - KH_KEY_MIN_z));
+       key.angles = key.owner.angles;
+#else
+       setorigin(key, key.owner.origin + key.origin.z * '0 0 1');
+       setattachment(key, world, "");
+       key.angles_y += key.owner.angles.y;
+#endif
+       key.flags = FL_ITEM;
+       key.solid = SOLID_TRIGGER;
+       key.movetype = MOVETYPE_TOSS;
+       key.pain_finished = time + autocvar_g_balance_keyhunt_delay_return;
+       key.damageforcescale = autocvar_g_balance_keyhunt_damageforcescale;
+       key.takedamage = DAMAGE_YES;
+       // let key.team stay
+       key.modelindex = kh_key_dropped;
+       key.kh_previous_owner = key.owner;
+       key.kh_previous_owner_playerid = key.owner.playerid;
+}
+
+void kh_Key_AssignTo(entity key, entity player)  // runs every time a key is picked up or assigned. Runs prior to kh_key_attach
+{
+       entity k;
+       float ownerteam0, ownerteam;
+       if(key.owner == player)
+               return;
+
+       ownerteam0 = kh_Key_AllOwnedByWhichTeam();
+
+       if(key.owner)
+       {
+               kh_Key_Detach(key);
+
+               // remove from linked list
+               if(key.kh_next)
+                       key.kh_next.kh_prev = key.kh_prev;
+               key.kh_prev.kh_next = key.kh_next;
+               key.kh_next = world;
+               key.kh_prev = world;
+
+               if(key.owner.kh_next == world)
+               {
+                       // No longer a key carrier
+                       if(!kh_no_radar_circles)
+                               WaypointSprite_Ping(key.owner.waypointsprite_attachedforcarrier);
+                       WaypointSprite_DetachCarrier(key.owner);
+               }
+       }
+
+       key.owner = player;
+
+       if(player)
+       {
+               // insert into linked list
+               key.kh_next = player.kh_next;
+               key.kh_prev = player;
+               player.kh_next = key;
+               if(key.kh_next)
+                       key.kh_next.kh_prev = key;
+
+               float i;
+               i = kh_keystatus[key.owner.playerid];
+                       if(key.netname == "^1red key")
+                               i += 1;
+                       if(key.netname == "^4blue key")
+                               i += 2;
+                       if(key.netname == "^3yellow key")
+                               i += 4;
+                       if(key.netname == "^6pink key")
+                               i += 8;
+               kh_keystatus[key.owner.playerid] = i;
+
+               kh_Key_Attach(key);
+
+               if(key.kh_next == world)
+               {
+                       // player is now a key carrier
+                       entity wp = WaypointSprite_AttachCarrier(WP_Null, player, RADARICON_FLAGCARRIER);
+                       wp.colormod = colormapPaletteColor(player.team - 1, 0);
+                       player.waypointsprite_attachedforcarrier.waypointsprite_visible_for_player = kh_KeyCarrier_waypointsprite_visible_for_player;
+                       WaypointSprite_UpdateRule(player.waypointsprite_attachedforcarrier, player.team, SPRITERULE_TEAMPLAY);
+                       if(player.team == NUM_TEAM_1)
+                               WaypointSprite_UpdateSprites(player.waypointsprite_attachedforcarrier, WP_KeyCarrierRed, WP_KeyCarrierFriend, WP_KeyCarrierRed);
+                       else if(player.team == NUM_TEAM_2)
+                               WaypointSprite_UpdateSprites(player.waypointsprite_attachedforcarrier, WP_KeyCarrierBlue, WP_KeyCarrierFriend, WP_KeyCarrierBlue);
+                       else if(player.team == NUM_TEAM_3)
+                               WaypointSprite_UpdateSprites(player.waypointsprite_attachedforcarrier, WP_KeyCarrierYellow, WP_KeyCarrierFriend, WP_KeyCarrierYellow);
+                       else if(player.team == NUM_TEAM_4)
+                               WaypointSprite_UpdateSprites(player.waypointsprite_attachedforcarrier, WP_KeyCarrierPink, WP_KeyCarrierFriend, WP_KeyCarrierPink);
+                       if(!kh_no_radar_circles)
+                               WaypointSprite_Ping(player.waypointsprite_attachedforcarrier);
+               }
+       }
+
+       // moved that here, also update if there's no player
+       kh_update_state();
+
+       key.pusher = world;
+
+       ownerteam = kh_Key_AllOwnedByWhichTeam();
+       if(ownerteam != ownerteam0)
+       {
+               if(ownerteam != -1)
+               {
+                       kh_interferemsg_time = time + 0.2;
+                       kh_interferemsg_team = player.team;
+
+                       // audit all key carrier sprites, update them to RUN HERE
+                       FOR_EACH_KH_KEY(k)
+                       {
+                               if (!k.owner) continue;
+                               entity first = WP_Null;
+                               FOREACH(Waypoints, it.netname == k.owner.waypointsprite_attachedforcarrier.model1, LAMBDA(first = it; break));
+                               entity third = WP_Null;
+                               FOREACH(Waypoints, it.netname == k.owner.waypointsprite_attachedforcarrier.model3, LAMBDA(third = it; break));
+                               WaypointSprite_UpdateSprites(k.owner.waypointsprite_attachedforcarrier, first, WP_KeyCarrierFinish, third);
+                       }
+               }
+               else
+               {
+                       kh_interferemsg_time = 0;
+
+                       // audit all key carrier sprites, update them to RUN HERE
+                       FOR_EACH_KH_KEY(k)
+                       {
+                               if (!k.owner) continue;
+                               entity first = WP_Null;
+                               FOREACH(Waypoints, it.netname == k.owner.waypointsprite_attachedforcarrier.model1, LAMBDA(first = it; break));
+                               entity third = WP_Null;
+                               FOREACH(Waypoints, it.netname == k.owner.waypointsprite_attachedforcarrier.model3, LAMBDA(third = it; break));
+                               WaypointSprite_UpdateSprites(k.owner.waypointsprite_attachedforcarrier, first, WP_KeyCarrierFriend, third);
+                       }
+               }
+       }
+}
+
+void kh_Key_Damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
+{SELFPARAM();
+       if(self.owner)
+               return;
+       if(ITEM_DAMAGE_NEEDKILL(deathtype))
+       {
+               // touching lava, or hurt trigger
+               // what shall we do?
+               // immediately return is bad
+               // maybe start a shorter countdown?
+       }
+       if(vlen(force) <= 0)
+               return;
+       if(time > self.pushltime)
+               if(IS_PLAYER(attacker))
+                       self.team = attacker.team;
+}
+
+void kh_Key_Collect(entity key, entity player)  //a player picks up a dropped key
+{
+       sound(player, CH_TRIGGER, SND_KH_COLLECT, VOL_BASE, ATTEN_NORM);
+
+       if(key.kh_dropperteam != player.team)
+       {
+               kh_Scores_Event(player, key, "collect", autocvar_g_balance_keyhunt_score_collect, 0);
+               PlayerScore_Add(player, SP_KH_PICKUPS, 1);
+       }
+       key.kh_dropperteam = 0;
+       Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(key, INFO_KEYHUNT_PICKUP_), player.netname);
+
+       kh_Key_AssignTo(key, player); // this also updates .kh_state
+}
+
+void kh_Key_Touch()  // runs many, many times when a key has been dropped and can be picked up
+{SELFPARAM();
+       if(intermission_running)
+               return;
+
+       if(self.owner) // already carried
+               return;
+
+       if(ITEM_TOUCH_NEEDKILL())
+       {
+               // touching sky, or nodrop
+               // what shall we do?
+               // immediately return is bad
+               // maybe start a shorter countdown?
+       }
+
+       if (!IS_PLAYER(other))
+               return;
+       if(other.deadflag != DEAD_NO)
+               return;
+       if(other == self.enemy)
+               if(time < self.kh_droptime + autocvar_g_balance_keyhunt_delay_collect)
+                       return;  // you just dropped it!
+       kh_Key_Collect(self, other);
+}
+
+void kh_Key_Remove(entity key)  // runs after when all the keys have been collected or when a key has been dropped for more than X seconds
+{
+       entity o;
+       o = key.owner;
+       kh_Key_AssignTo(key, world);
+       if(o) // it was attached
+               WaypointSprite_Kill(key.waypointsprite_attachedforcarrier);
+       else // it was dropped
+               WaypointSprite_DetachCarrier(key);
+
+       // remove key from key list
+       if (kh_worldkeylist == key)
+               kh_worldkeylist = kh_worldkeylist.kh_worldkeynext;
+       else
+       {
+               o = kh_worldkeylist;
+               while (o)
+               {
+                       if (o.kh_worldkeynext == key)
+                       {
+                               o.kh_worldkeynext = o.kh_worldkeynext.kh_worldkeynext;
+                               break;
+                       }
+                       o = o.kh_worldkeynext;
+               }
+       }
+
+       remove(key);
+
+       kh_update_state();
+}
+
+void kh_FinishRound()  // runs when a team captures the keys
+{
+       // prepare next round
+       kh_interferemsg_time = 0;
+       entity key;
+
+       kh_no_radar_circles = true;
+       FOR_EACH_KH_KEY(key)
+               kh_Key_Remove(key);
+       kh_no_radar_circles = false;
+
+       Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_KEYHUNT_ROUNDSTART, autocvar_g_balance_keyhunt_delay_round);
+       kh_Controller_SetThink(autocvar_g_balance_keyhunt_delay_round, kh_StartRound);
+}
+
+void kh_WinnerTeam(float teem)  // runs when a team wins // Samual: Teem?.... TEEM?!?! what the fuck is wrong with you people
+{
+       // all key carriers get some points
+       vector firstorigin, lastorigin, midpoint;
+       float first;
+       entity key;
+       float score;
+       score = (kh_teams - 1) * autocvar_g_balance_keyhunt_score_capture;
+       DistributeEvenly_Init(score, kh_teams);
+       // twice the score for 3 team games, three times the score for 4 team games!
+       // note: for a win by destroying the key, this should NOT be applied
+       FOR_EACH_KH_KEY(key)
+       {
+               float f;
+               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;
+       string keyowner = "";
+       FOR_EACH_KH_KEY(key)
+               if(key.owner.kh_next == key)
+               {
+                       if(!first)
+                               keyowner = strcat(keyowner, ", ");
+                       keyowner = key.owner.netname;
+                       first = false;
+               }
+
+       Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(teem, INFO_KEYHUNT_CAPTURE_), keyowner);
+
+       first = true;
+       midpoint = '0 0 0';
+       firstorigin = '0 0 0';
+       lastorigin = '0 0 0';
+       FOR_EACH_KH_KEY(key)
+       {
+               vector thisorigin;
+
+               thisorigin = kh_AttachedOrigin(key);
+               //dprint("Key origin: ", vtos(thisorigin), "\n");
+               midpoint += thisorigin;
+
+               if(!first)
+                       te_lightning2(world, lastorigin, thisorigin);
+               lastorigin = thisorigin;
+               if(first)
+                       firstorigin = thisorigin;
+               first = false;
+       }
+       if(kh_teams > 2)
+       {
+               te_lightning2(world, lastorigin, firstorigin);
+       }
+       midpoint = midpoint * (1 / kh_teams);
+       te_customflash(midpoint, 1000, 1, Team_ColorRGB(teem) * 0.5 + '0.5 0.5 0.5');  // make the color >=0.5 in each component
+
+       play2all(SND(KH_CAPTURE));
+       kh_FinishRound();
+}
+
+void kh_LoserTeam(float teem, entity lostkey)  // runs when a player pushes a flag carrier off the map
+{
+       entity player, key, attacker;
+       float players;
+       float keys;
+       float f;
+
+       attacker = world;
+       if(lostkey.pusher)
+               if(lostkey.pusher.team != teem)
+                       if(IS_PLAYER(lostkey.pusher))
+                               attacker = lostkey.pusher;
+
+       players = keys = 0;
+
+       if(attacker)
+       {
+               if(lostkey.kh_previous_owner)
+                       kh_Scores_Event(lostkey.kh_previous_owner, world, "pushed", 0, -autocvar_g_balance_keyhunt_score_push);
+                       // don't actually GIVE him the -nn points, just log
+               kh_Scores_Event(attacker, world, "push", autocvar_g_balance_keyhunt_score_push, 0);
+               PlayerScore_Add(attacker, SP_KH_PUSHES, 1);
+               //centerprint(attacker, "Your push is the best!"); // does this really need to exist?
+       }
+       else
+       {
+               float of, fragsleft, i, j, thisteam;
+               of = autocvar_g_balance_keyhunt_score_destroyed_ownfactor;
+
+               FOR_EACH_PLAYER(player)
+                       if(player.team != teem)
+                               ++players;
+
+               FOR_EACH_KH_KEY(key)
+                       if(key.owner && key.team != teem)
+                               ++keys;
+
+               if(lostkey.kh_previous_owner)
+                       kh_Scores_Event(lostkey.kh_previous_owner, world, "destroyed", 0, -autocvar_g_balance_keyhunt_score_destroyed);
+                       // don't actually GIVE him the -nn points, just log
+
+               if(lostkey.kh_previous_owner.playerid == lostkey.kh_previous_owner_playerid)
+                       PlayerScore_Add(lostkey.kh_previous_owner, SP_KH_DESTROYS, 1);
+
+               DistributeEvenly_Init(autocvar_g_balance_keyhunt_score_destroyed, keys * of + players);
+
+               FOR_EACH_KH_KEY(key)
+                       if(key.owner && key.team != teem)
+                       {
+                               f = DistributeEvenly_Get(of);
+                               kh_Scores_Event(key.owner, world, "destroyed_holdingkey", f, 0);
+                       }
+
+               fragsleft = DistributeEvenly_Get(players);
+
+               // Now distribute these among all other teams...
+               j = kh_teams - 1;
+               for(i = 0; i < kh_teams; ++i)
+               {
+                       thisteam = kh_Team_ByID(i);
+                       if(thisteam == teem) // bad boy, no cookie - this WILL happen
+                               continue;
+
+                       players = 0;
+                       FOR_EACH_PLAYER(player)
+                               if(player.team == thisteam)
+                                       ++players;
+
+                       DistributeEvenly_Init(fragsleft, j);
+                       fragsleft = DistributeEvenly_Get(j - 1);
+                       DistributeEvenly_Init(DistributeEvenly_Get(1), players);
+
+                       FOR_EACH_PLAYER(player)
+                               if(player.team == thisteam)
+                               {
+                                       f = DistributeEvenly_Get(1);
+                                       kh_Scores_Event(player, world, "destroyed", f, 0);
+                               }
+
+                       --j;
+               }
+       }
+
+       Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(lostkey, INFO_KEYHUNT_LOST_), lostkey.kh_previous_owner.netname);
+
+       play2all(SND(KH_DESTROY));
+       te_tarexplosion(lostkey.origin);
+
+       kh_FinishRound();
+}
+
+void kh_Key_Think()  // runs all the time
+{SELFPARAM();
+       entity head;
+       //entity player;  // needed by FOR_EACH_PLAYER
+
+       if(intermission_running)
+               return;
+
+       if(self.owner)
+       {
+#ifndef KH_PLAYER_USE_ATTACHMENT
+               makevectors('0 1 0' * (self.cnt + (time % 360) * KH_KEY_XYSPEED));
+               setorigin(self, v_forward * KH_KEY_XYDIST + '0 0 1' * self.origin.z);
+#endif
+       }
+
+       // if in nodrop or time over, end the round
+       if(!self.owner)
+               if(time > self.pain_finished)
+                       kh_LoserTeam(self.team, self);
+
+       if(self.owner)
+       if(kh_Key_AllOwnedByWhichTeam() != -1)
+       {
+               if(self.siren_time < time)
+               {
+                       sound(self.owner, CH_TRIGGER, SND_KH_ALARM, VOL_BASE, ATTEN_NORM);  // play a simple alarm
+                       self.siren_time = time + 2.5;  // repeat every 2.5 seconds
+               }
+
+               entity key;
+               vector p;
+               p = self.owner.origin;
+               FOR_EACH_KH_KEY(key)
+                       if(vlen(key.owner.origin - p) > autocvar_g_balance_keyhunt_maxdist)
+                               goto not_winning;
+               kh_WinnerTeam(self.team);
+:not_winning
+       }
+
+       if(kh_interferemsg_time && time > kh_interferemsg_time)
+       {
+               kh_interferemsg_time = 0;
+               FOR_EACH_PLAYER(head)
+               {
+                       if(head.team == kh_interferemsg_team)
+                               if(head.kh_next)
+                                       Send_Notification(NOTIF_ONE, head, MSG_CENTER, CENTER_KEYHUNT_MEET);
+                               else
+                                       Send_Notification(NOTIF_ONE, head, MSG_CENTER, CENTER_KEYHUNT_HELP);
+                       else
+                               Send_Notification(NOTIF_ONE, head, MSG_CENTER, APP_TEAM_NUM_4(kh_interferemsg_team, CENTER_KEYHUNT_INTERFERE_));
+               }
+       }
+
+       self.nextthink = time + 0.05;
+}
+
+void key_reset()
+{SELFPARAM();
+       kh_Key_AssignTo(self, world);
+       kh_Key_Remove(self);
+}
+
+const string STR_ITEM_KH_KEY = "item_kh_key";
+void kh_Key_Spawn(entity initial_owner, float angle, float i)  // runs every time a new flag is created, ie after all the keys have been collected
+{
+       entity key;
+       key = spawn();
+       key.count = i;
+       key.classname = STR_ITEM_KH_KEY;
+       key.touch = kh_Key_Touch;
+       key.think = kh_Key_Think;
+       key.nextthink = time;
+       key.items = IT_KEY1 | IT_KEY2;
+       key.cnt = angle;
+       key.angles = '0 360 0' * random();
+       key.event_damage = kh_Key_Damage;
+       key.takedamage = DAMAGE_YES;
+       key.modelindex = kh_key_dropped;
+       key.model = "key";
+       key.kh_dropperteam = 0;
+       key.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
+       setsize(key, KH_KEY_MIN, KH_KEY_MAX);
+       key.colormod = Team_ColorRGB(initial_owner.team) * KH_KEY_BRIGHTNESS;
+       key.reset = key_reset;
+
+       switch(initial_owner.team)
+       {
+               case NUM_TEAM_1:
+                       key.netname = "^1red key";
+                       break;
+               case NUM_TEAM_2:
+                       key.netname = "^4blue key";
+                       break;
+               case NUM_TEAM_3:
+                       key.netname = "^3yellow key";
+                       break;
+               case NUM_TEAM_4:
+                       key.netname = "^6pink key";
+                       break;
+               default:
+                       key.netname = "NETGIER key";
+                       break;
+       }
+
+       // link into key list
+       key.kh_worldkeynext = kh_worldkeylist;
+       kh_worldkeylist = key;
+
+       Send_Notification(NOTIF_ONE, initial_owner, MSG_CENTER, APP_TEAM_NUM_4(initial_owner.team, CENTER_KEYHUNT_START_));
+
+       WaypointSprite_Spawn(WP_KeyDropped, 0, 0, key, '0 0 1' * KH_KEY_WP_ZSHIFT, world, key.team, key, waypointsprite_attachedforcarrier, false, RADARICON_FLAG);
+       key.waypointsprite_attachedforcarrier.waypointsprite_visible_for_player = kh_Key_waypointsprite_visible_for_player;
+
+       kh_Key_AssignTo(key, initial_owner);
+}
+
+// -1 when no team completely owns all keys yet
+float kh_Key_AllOwnedByWhichTeam()  // constantly called. check to see if all the keys are owned by the same team
+{
+       entity key;
+       float teem;
+       float keys;
+
+       teem = -1;
+       keys = kh_teams;
+       FOR_EACH_KH_KEY(key)
+       {
+               if(!key.owner)
+                       return -1;
+               if(teem == -1)
+                       teem = key.team;
+               else if(teem != key.team)
+                       return -1;
+               --keys;
+       }
+       if(keys != 0)
+               return -1;
+       return teem;
+}
+
+void kh_Key_DropOne(entity key)
+{
+       // prevent collecting this one for some time
+       entity player;
+       player = key.owner;
+
+       key.kh_droptime = time;
+       key.enemy = player;
+
+       kh_Scores_Event(player, key, "dropkey", 0, 0);
+       PlayerScore_Add(player, SP_KH_LOSSES, 1);
+       Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(key, INFO_KEYHUNT_DROP_), player.netname);
+
+       kh_Key_AssignTo(key, world);
+       makevectors(player.v_angle);
+       key.velocity = W_CalculateProjectileVelocity(player.velocity, autocvar_g_balance_keyhunt_throwvelocity * v_forward, false);
+       key.pusher = world;
+       key.pushltime = time + autocvar_g_balance_keyhunt_protecttime;
+       key.kh_dropperteam = key.team;
+
+       sound(player, CH_TRIGGER, SND_KH_DROP, VOL_BASE, ATTEN_NORM);
+}
+
+void kh_Key_DropAll(entity player, float suicide) // runs whenever a player dies
+{
+       entity key;
+       entity mypusher;
+       if(player.kh_next)
+       {
+               mypusher = world;
+               if(player.pusher)
+                       if(time < player.pushltime)
+                               mypusher = player.pusher;
+               while((key = player.kh_next))
+               {
+                       kh_Scores_Event(player, key, "losekey", 0, 0);
+                       PlayerScore_Add(player, SP_KH_LOSSES, 1);
+                       Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(key, INFO_KEYHUNT_LOST_), player.netname);
+                       kh_Key_AssignTo(key, world);
+                       makevectors('-1 0 0' * (45 + 45 * random()) + '0 360 0' * random());
+                       key.velocity = W_CalculateProjectileVelocity(player.velocity, autocvar_g_balance_keyhunt_dropvelocity * v_forward, false);
+                       key.pusher = mypusher;
+                       key.pushltime = time + autocvar_g_balance_keyhunt_protecttime;
+                       if(suicide)
+                               key.kh_dropperteam = player.team;
+               }
+               sound(player, CH_TRIGGER, SND_KH_DROP, VOL_BASE, ATTEN_NORM);
+       }
+}
+
+float kh_CheckPlayers(float num)
+{
+       if(num < kh_teams)
+       {
+               float t_team = kh_Team_ByID(num);
+               float players = 0;
+               entity tmp_player;
+               FOR_EACH_PLAYER(tmp_player)
+                       if(tmp_player.deadflag == DEAD_NO)
+                               if(!tmp_player.BUTTON_CHAT)
+                                       if(tmp_player.team == t_team)
+                                               ++players;
+
+               if (!players) { return t_team; }
+       }
+       return 0;
+}
+
+#define KH_READY_TEAMS() (!p1 + !p2 + ((kh_teams >= 3) ? !p3 : p3) + ((kh_teams >= 4) ? !p4 : p4))
+#define KH_READY_TEAMS_OK() (KH_READY_TEAMS() == kh_teams)
+void kh_WaitForPlayers()  // delay start of the round until enough players are present
+{
+       if(time < game_starttime)
+       {
+               kh_Controller_SetThink(game_starttime - time + 0.1, kh_WaitForPlayers);
+               return;
+       }
+
+       static float prev_missing_teams_mask;
+       float p1 = kh_CheckPlayers(0), p2 = kh_CheckPlayers(1), p3 = kh_CheckPlayers(2), p4 = kh_CheckPlayers(3);
+       if(KH_READY_TEAMS_OK())
+       {
+               if(prev_missing_teams_mask > 0)
+                       Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_MISSING_TEAMS);
+               prev_missing_teams_mask = -1;
+               Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_KEYHUNT_ROUNDSTART, autocvar_g_balance_keyhunt_delay_round);
+               kh_Controller_SetThink(autocvar_g_balance_keyhunt_delay_round, kh_StartRound);
+       }
+       else
+       {
+               if(player_count == 0)
+               {
+                       if(prev_missing_teams_mask > 0)
+                               Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_MISSING_TEAMS);
+                       prev_missing_teams_mask = -1;
+               }
+               else
+               {
+                       float missing_teams_mask = (!!p1) + (!!p2) * 2;
+                       if(kh_teams >= 3) missing_teams_mask += (!!p3) * 4;
+                       if(kh_teams >= 4) missing_teams_mask += (!!p4) * 8;
+                       if(prev_missing_teams_mask != missing_teams_mask)
+                       {
+                               Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_MISSING_TEAMS, missing_teams_mask);
+                               prev_missing_teams_mask = missing_teams_mask;
+                       }
+               }
+               kh_Controller_SetThink(1, kh_WaitForPlayers);
+       }
+}
+
+void kh_EnableTrackingDevice()  // runs after each round
+{
+       Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_KEYHUNT);
+       Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_KEYHUNT_OTHER);
+
+       kh_tracking_enabled = true;
+}
+
+void kh_StartRound()  // runs at the start of each round
+{
+       float i, players, teem;
+       entity player;
+
+       if(time < game_starttime)
+       {
+               kh_Controller_SetThink(game_starttime - time + 0.1, kh_WaitForPlayers);
+               return;
+       }
+
+       float p1 = kh_CheckPlayers(0), p2 = kh_CheckPlayers(1), p3 = kh_CheckPlayers(2), p4 = kh_CheckPlayers(3);
+       if(!KH_READY_TEAMS_OK())
+       {
+               kh_Controller_SetThink(1, kh_WaitForPlayers);
+               return;
+       }
+
+       Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_KEYHUNT);
+       Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_KEYHUNT_OTHER);
+
+       for(i = 0; i < kh_teams; ++i)
+       {
+               teem = kh_Team_ByID(i);
+               players = 0;
+               entity my_player = world;
+               FOR_EACH_PLAYER(player)
+                       if(player.deadflag == DEAD_NO)
+                               if(!player.BUTTON_CHAT)
+                                       if(player.team == teem)
+                                       {
+                                               ++players;
+                                               if(random() * players <= 1)
+                                                       my_player = player;
+                                       }
+               kh_Key_Spawn(my_player, 360 * i / kh_teams, i);
+       }
+
+       kh_tracking_enabled = false;
+       Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_KEYHUNT_SCAN, autocvar_g_balance_keyhunt_delay_tracking);
+       kh_Controller_SetThink(autocvar_g_balance_keyhunt_delay_tracking, kh_EnableTrackingDevice);
+}
+
+float kh_HandleFrags(entity attacker, entity targ, float f)  // adds to the player score
+{
+       if(attacker == targ)
+               return f;
+
+       if(targ.kh_next)
+       {
+               if(attacker.team == targ.team)
+               {
+                       entity k;
+                       float nk;
+                       nk = 0;
+                       for(k = targ.kh_next; k != world; k = k.kh_next)
+                               ++nk;
+                       kh_Scores_Event(attacker, targ.kh_next, "carrierfrag", -nk * autocvar_g_balance_keyhunt_score_collect, 0);
+               }
+               else
+               {
+                       kh_Scores_Event(attacker, targ.kh_next, "carrierfrag", autocvar_g_balance_keyhunt_score_carrierfrag-1, 0);
+                       PlayerScore_Add(attacker, SP_KH_KCKILLS, 1);
+                       // the frag gets added later
+               }
+       }
+
+       return f;
+}
+
+void kh_Initialize()  // sets up th KH environment
+{
+       // setup variables
+       kh_teams = autocvar_g_keyhunt_teams_override;
+       if(kh_teams < 2)
+               kh_teams = autocvar_g_keyhunt_teams;
+       kh_teams = bound(2, kh_teams, 4);
+
+       // make a KH entity for controlling the game
+       kh_controller = spawn();
+       kh_controller.think = kh_Controller_Think;
+       kh_Controller_SetThink(0, kh_WaitForPlayers);
+
+       setmodel(kh_controller, MDL_KH_KEY);
+       kh_key_dropped = kh_controller.modelindex;
+       /*
+       dprint(vtos(kh_controller.mins));
+       dprint(vtos(kh_controller.maxs));
+       dprint("\n");
+       */
+#ifdef KH_PLAYER_USE_CARRIEDMODEL
+       setmodel(kh_controller, MDL_KH_KEY_CARRIED);
+       kh_key_carried = kh_controller.modelindex;
+#else
+       kh_key_carried = kh_key_dropped;
+#endif
+
+       kh_controller.model = "";
+       kh_controller.modelindex = 0;
+
+       addstat(STAT_KH_KEYS, AS_INT, kh_state);
+
+       kh_ScoreRules(kh_teams);
+}
+
+void kh_finalize()
+{
+       // to be called before intermission
+       kh_FinishRound();
+       remove(kh_controller);
+       kh_controller = world;
+}
+
+// legacy bot role
+
+void() havocbot_role_kh_carrier;
+void() havocbot_role_kh_defense;
+void() havocbot_role_kh_offense;
+void() havocbot_role_kh_freelancer;
+
+
+void havocbot_goalrating_kh(float ratingscale_team, float ratingscale_dropped, float ratingscale_enemy)
+{SELFPARAM();
+       entity head;
+       for (head = kh_worldkeylist; head; head = head.kh_worldkeynext)
+       {
+               if(head.owner == self)
+                       continue;
+               if(!kh_tracking_enabled)
+               {
+                       // if it's carried by our team we know about it
+                       // otherwise we have to see it to know about it
+                       if(!head.owner || head.team != self.team)
+                       {
+                               traceline(self.origin + self.view_ofs, head.origin, MOVE_NOMONSTERS, self);
+                               if (trace_fraction < 1 && trace_ent != head)
+                                       continue; // skip what I can't see
+                       }
+               }
+               if(!head.owner)
+                       navigation_routerating(head, ratingscale_dropped * BOT_PICKUP_RATING_HIGH, 100000);
+               else if(head.team == self.team)
+                       navigation_routerating(head.owner, ratingscale_team * BOT_PICKUP_RATING_HIGH, 100000);
+               else
+                       navigation_routerating(head.owner, ratingscale_enemy * BOT_PICKUP_RATING_HIGH, 100000);
+       }
+
+       havocbot_goalrating_items(1, self.origin, 10000);
+}
+
+void havocbot_role_kh_carrier()
+{SELFPARAM();
+       if(self.deadflag != DEAD_NO)
+               return;
+
+       if (!(self.kh_next))
+       {
+               LOG_TRACE("changing role to freelancer\n");
+               self.havocbot_role = havocbot_role_kh_freelancer;
+               self.havocbot_role_timeout = 0;
+               return;
+       }
+
+       if (self.bot_strategytime < time)
+       {
+               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+               navigation_goalrating_start();
+
+               if(kh_Key_AllOwnedByWhichTeam() == self.team)
+                       havocbot_goalrating_kh(10, 0.1, 0.1); // bring home
+               else
+                       havocbot_goalrating_kh(4, 4, 1); // play defensively
+
+               navigation_goalrating_end();
+       }
+}
+
+void havocbot_role_kh_defense()
+{SELFPARAM();
+       if(self.deadflag != DEAD_NO)
+               return;
+
+       if (self.kh_next)
+       {
+               LOG_TRACE("changing role to carrier\n");
+               self.havocbot_role = havocbot_role_kh_carrier;
+               self.havocbot_role_timeout = 0;
+               return;
+       }
+
+       if (!self.havocbot_role_timeout)
+               self.havocbot_role_timeout = time + random() * 10 + 20;
+       if (time > self.havocbot_role_timeout)
+       {
+               LOG_TRACE("changing role to freelancer\n");
+               self.havocbot_role = havocbot_role_kh_freelancer;
+               self.havocbot_role_timeout = 0;
+               return;
+       }
+
+       if (self.bot_strategytime < time)
+       {
+               float key_owner_team;
+               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+               navigation_goalrating_start();
+
+               key_owner_team = kh_Key_AllOwnedByWhichTeam();
+               if(key_owner_team == self.team)
+                       havocbot_goalrating_kh(10, 0.1, 0.1); // defend key carriers
+               else if(key_owner_team == -1)
+                       havocbot_goalrating_kh(4, 1, 0.1); // play defensively
+               else
+                       havocbot_goalrating_kh(0.1, 0.1, 10); // ATTACK ANYWAY
+
+               navigation_goalrating_end();
+       }
+}
+
+void havocbot_role_kh_offense()
+{SELFPARAM();
+       if(self.deadflag != DEAD_NO)
+               return;
+
+       if (self.kh_next)
+       {
+               LOG_TRACE("changing role to carrier\n");
+               self.havocbot_role = havocbot_role_kh_carrier;
+               self.havocbot_role_timeout = 0;
+               return;
+       }
+
+       if (!self.havocbot_role_timeout)
+               self.havocbot_role_timeout = time + random() * 10 + 20;
+       if (time > self.havocbot_role_timeout)
+       {
+               LOG_TRACE("changing role to freelancer\n");
+               self.havocbot_role = havocbot_role_kh_freelancer;
+               self.havocbot_role_timeout = 0;
+               return;
+       }
+
+       if (self.bot_strategytime < time)
+       {
+               float key_owner_team;
+
+               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+               navigation_goalrating_start();
+
+               key_owner_team = kh_Key_AllOwnedByWhichTeam();
+               if(key_owner_team == self.team)
+                       havocbot_goalrating_kh(10, 0.1, 0.1); // defend anyway
+               else if(key_owner_team == -1)
+                       havocbot_goalrating_kh(0.1, 1, 4); // play offensively
+               else
+                       havocbot_goalrating_kh(0.1, 0.1, 10); // ATTACK! EMERGENCY!
+
+               navigation_goalrating_end();
+       }
+}
+
+void havocbot_role_kh_freelancer()
+{SELFPARAM();
+       if(self.deadflag != DEAD_NO)
+               return;
+
+       if (self.kh_next)
+       {
+               LOG_TRACE("changing role to carrier\n");
+               self.havocbot_role = havocbot_role_kh_carrier;
+               self.havocbot_role_timeout = 0;
+               return;
+       }
+
+       if (!self.havocbot_role_timeout)
+               self.havocbot_role_timeout = time + random() * 10 + 10;
+       if (time > self.havocbot_role_timeout)
+       {
+               if (random() < 0.5)
+               {
+                       LOG_TRACE("changing role to offense\n");
+                       self.havocbot_role = havocbot_role_kh_offense;
+               }
+               else
+               {
+                       LOG_TRACE("changing role to defense\n");
+                       self.havocbot_role = havocbot_role_kh_defense;
+               }
+               self.havocbot_role_timeout = 0;
+               return;
+       }
+
+       if (self.bot_strategytime < time)
+       {
+               float key_owner_team;
+
+               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+               navigation_goalrating_start();
+
+               key_owner_team = kh_Key_AllOwnedByWhichTeam();
+               if(key_owner_team == self.team)
+                       havocbot_goalrating_kh(10, 0.1, 0.1); // defend anyway
+               else if(key_owner_team == -1)
+                       havocbot_goalrating_kh(1, 10, 4); // prefer dropped keys
+               else
+                       havocbot_goalrating_kh(0.1, 0.1, 10); // ATTACK ANYWAY
+
+               navigation_goalrating_end();
+       }
+}
+
+
+// register this as a mutator
+
+MUTATOR_HOOKFUNCTION(kh, ClientDisconnect)
+{SELFPARAM();
+       kh_Key_DropAll(self, true);
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(kh, MakePlayerObserver)
+{SELFPARAM();
+       kh_Key_DropAll(self, true);
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(kh, PlayerDies)
+{SELFPARAM();
+       if(self == other)
+               kh_Key_DropAll(self, true);
+       else if(IS_PLAYER(other))
+               kh_Key_DropAll(self, false);
+       else
+               kh_Key_DropAll(self, true);
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(kh, GiveFragsForKill, CBC_ORDER_FIRST)
+{
+       frag_score = kh_HandleFrags(frag_attacker, frag_target, frag_score);
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(kh, MatchEnd)
+{
+       kh_finalize();
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(kh, GetTeamCount, CBC_ORDER_EXCLUSIVE)
+{
+       ret_float = kh_teams;
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(kh, SpectateCopy)
+{SELFPARAM();
+       self.kh_state = other.kh_state;
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(kh, PlayerUseKey)
+{SELFPARAM();
+       if(MUTATOR_RETURNVALUE == 0)
+       {
+               entity k;
+               k = self.kh_next;
+               if(k)
+               {
+                       kh_Key_DropOne(k);
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(kh, HavocBot_ChooseRole)
+{
+       if(self.deadflag != DEAD_NO)
+               return true;
+
+       float r = random() * 3;
+       if (r < 1)
+               self.havocbot_role = havocbot_role_kh_offense;
+       else if (r < 2)
+               self.havocbot_role = havocbot_role_kh_defense;
+       else
+               self.havocbot_role = havocbot_role_kh_freelancer;
+
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(kh, DropSpecialItems)
+{
+       kh_Key_DropAll(frag_target, false);
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(kh, reset_map_global)
+{
+       kh_Controller_SetThink(autocvar_g_balance_keyhunt_delay_round + (game_starttime - time), kh_StartRound);
+       return false;
+}
+
+#endif
diff --git a/qcsrc/server/mutators/mutator/gamemode_lms.qc b/qcsrc/server/mutators/mutator/gamemode_lms.qc
new file mode 100644 (file)
index 0000000..efab45e
--- /dev/null
@@ -0,0 +1,317 @@
+#ifndef GAMEMODE_LMS_H
+#define GAMEMODE_LMS_H
+
+#define autocvar_g_lms_lives_override cvar("g_lms_lives_override")
+void lms_Initialize();
+
+REGISTER_MUTATOR(lms, false)
+{
+       SetLimits(((!autocvar_g_lms_lives_override) ? -1 : autocvar_g_lms_lives_override), 0, -1, -1);
+
+       MUTATOR_ONADD
+       {
+               if (time > 1) // game loads at time 1
+                       error("This is a game type and it cannot be added at runtime.");
+               lms_Initialize();
+       }
+
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               // we actually cannot roll back lms_Initialize here
+               // BUT: we don't need to! If this gets called, adding always
+               // succeeds.
+       }
+
+       MUTATOR_ONREMOVE
+       {
+               LOG_INFO("This is a game type and it cannot be removed at runtime.");
+               return -1;
+       }
+
+       return 0;
+}
+
+// scoreboard stuff
+const float SP_LMS_LIVES = 4;
+const float SP_LMS_RANK = 5;
+
+// lives related defs
+float lms_lowest_lives;
+float lms_next_place;
+float LMS_NewPlayerLives();
+
+#endif
+
+#ifdef IMPLEMENTATION
+
+#include "../../campaign.qh"
+#include "../../command/cmd.qh"
+
+int autocvar_g_lms_extra_lives;
+bool autocvar_g_lms_join_anytime;
+int autocvar_g_lms_last_join;
+bool autocvar_g_lms_regenerate;
+
+// main functions
+float LMS_NewPlayerLives()
+{
+       float fl;
+       fl = autocvar_fraglimit;
+       if(fl == 0)
+               fl = 999;
+
+       // first player has left the game for dying too much? Nobody else can get in.
+       if(lms_lowest_lives < 1)
+               return 0;
+
+       if(!autocvar_g_lms_join_anytime)
+               if(lms_lowest_lives < fl - autocvar_g_lms_last_join)
+                       return 0;
+
+       return bound(1, lms_lowest_lives, fl);
+}
+
+// mutator hooks
+MUTATOR_HOOKFUNCTION(lms, reset_map_global)
+{
+       lms_lowest_lives = 999;
+       lms_next_place = player_count;
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(lms, reset_map_players)
+{SELFPARAM();
+       entity e;
+       if(restart_mapalreadyrestarted || (time < game_starttime))
+       FOR_EACH_CLIENT(e)
+       if(IS_PLAYER(e))
+       {
+               WITH(entity, self, e, PlayerScore_Add(e, SP_LMS_LIVES, LMS_NewPlayerLives()));
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(lms, PutClientInServer)
+{SELFPARAM();
+       // player is dead and becomes observer
+       // FIXME fix LMS scoring for new system
+       if(PlayerScore_Add(self, SP_LMS_RANK, 0) > 0)
+       {
+               self.classname = "observer";
+               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_LMS_NOLIVES);
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(lms, PlayerDies)
+{SELFPARAM();
+       self.respawn_flags |= RESPAWN_FORCE;
+
+       return false;
+}
+
+void lms_RemovePlayer(entity player)
+{
+       // Only if the player cannot play at all
+       if(PlayerScore_Add(player, SP_LMS_RANK, 0) == 666)
+               player.frags = FRAGS_SPECTATOR;
+       else
+               player.frags = FRAGS_LMS_LOSER;
+
+       if(player.killcount != -666)
+               if(PlayerScore_Add(player, SP_LMS_RANK, 0) > 0 && player.lms_spectate_warning != 2)
+                       Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_LMS_NOLIVES, player.netname);
+               else
+                       Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_LMS_FORFEIT, player.netname);
+}
+
+MUTATOR_HOOKFUNCTION(lms, ClientDisconnect)
+{SELFPARAM();
+       lms_RemovePlayer(self);
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(lms, MakePlayerObserver)
+{SELFPARAM();
+       lms_RemovePlayer(self);
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(lms, ClientConnect)
+{SELFPARAM();
+       self.classname = "player";
+       campaign_bots_may_start = 1;
+
+       if(PlayerScore_Add(self, SP_LMS_LIVES, LMS_NewPlayerLives()) <= 0)
+       {
+               PlayerScore_Add(self, SP_LMS_RANK, 666);
+               self.frags = FRAGS_SPECTATOR;
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(lms, PlayerPreThink)
+{SELFPARAM();
+       if(self.deadflag == DEAD_DYING)
+               self.deadflag = DEAD_RESPAWNING;
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(lms, PlayerRegen)
+{
+       if(autocvar_g_lms_regenerate)
+               return false;
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(lms, ForbidThrowCurrentWeapon)
+{
+       // forbode!
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(lms, GiveFragsForKill)
+{
+       // remove a life
+       float tl;
+       tl = PlayerScore_Add(frag_target, SP_LMS_LIVES, -1);
+       if(tl < lms_lowest_lives)
+               lms_lowest_lives = tl;
+       if(tl <= 0)
+       {
+               if(!lms_next_place)
+                       lms_next_place = player_count;
+               else
+                       lms_next_place = min(lms_next_place, player_count);
+               PlayerScore_Add(frag_target, SP_LMS_RANK, lms_next_place); // won't ever spawn again
+               --lms_next_place;
+       }
+       frag_score = 0;
+
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(lms, SetStartItems)
+{
+       start_items &= ~IT_UNLIMITED_AMMO;
+       start_health       = warmup_start_health       = cvar("g_lms_start_health");
+       start_armorvalue   = warmup_start_armorvalue   = cvar("g_lms_start_armor");
+       start_ammo_shells  = warmup_start_ammo_shells  = cvar("g_lms_start_ammo_shells");
+       start_ammo_nails   = warmup_start_ammo_nails   = cvar("g_lms_start_ammo_nails");
+       start_ammo_rockets = warmup_start_ammo_rockets = cvar("g_lms_start_ammo_rockets");
+       start_ammo_cells   = warmup_start_ammo_cells   = cvar("g_lms_start_ammo_cells");
+       start_ammo_plasma  = warmup_start_ammo_plasma  = cvar("g_lms_start_ammo_plasma");
+       start_ammo_fuel    = warmup_start_ammo_fuel    = cvar("g_lms_start_ammo_fuel");
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(lms, ForbidPlayerScore_Clear)
+{
+       // don't clear player score
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(lms, FilterItem)
+{SELFPARAM();
+       if(autocvar_g_lms_extra_lives)
+       if(self.itemdef == ITEM_HealthMega)
+       {
+               self.max_health = 1;
+               return false;
+       }
+
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(lms, ItemTouch)
+{SELFPARAM();
+       // give extra lives for mega health
+       if (self.items & ITEM_HealthMega.m_itemid)
+       {
+               Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_EXTRALIVES);
+               PlayerScore_Add(other, SP_LMS_LIVES, autocvar_g_lms_extra_lives);
+       }
+
+       return MUT_ITEMTOUCH_CONTINUE;
+}
+
+MUTATOR_HOOKFUNCTION(lms, Bot_FixCount, CBC_ORDER_EXCLUSIVE)
+{
+       entity head;
+       FOR_EACH_REALCLIENT(head)
+       {
+               ++bot_activerealplayers;
+               ++bot_realplayers;
+       }
+
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(lms, ClientCommand_Spectate)
+{
+       if(self.lms_spectate_warning)
+       {
+               // for the forfeit message...
+               self.lms_spectate_warning = 2;
+               // mark player as spectator
+               PlayerScore_Add(self, SP_LMS_RANK, 666 - PlayerScore_Add(self, SP_LMS_RANK, 0));
+       }
+       else
+       {
+               self.lms_spectate_warning = 1;
+               sprint(self, "WARNING: you won't be able to enter the game again after spectating in LMS. Use the same command again to spectate anyway.\n");
+               return MUT_SPECCMD_RETURN;
+       }
+       return MUT_SPECCMD_CONTINUE;
+}
+
+MUTATOR_HOOKFUNCTION(lms, CheckRules_World)
+{
+       ret_float = WinningCondition_LMS();
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(lms, WantWeapon)
+{
+       want_allguns = true;
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(lms, GetPlayerStatus)
+{
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(lms, AddPlayerScore)
+{
+       if(gameover)
+       if(score_field == SP_LMS_RANK)
+               return true; // allow writing to this field in intermission as it is needed for newly joining players
+       return false;
+}
+
+// scoreboard stuff
+void lms_ScoreRules()
+{
+       ScoreRules_basics(0, 0, 0, false);
+       ScoreInfo_SetLabel_PlayerScore(SP_LMS_LIVES,    "lives",     SFL_SORT_PRIO_SECONDARY);
+       ScoreInfo_SetLabel_PlayerScore(SP_LMS_RANK,     "rank",      SFL_LOWER_IS_BETTER | SFL_RANK | SFL_SORT_PRIO_PRIMARY | SFL_ALLOW_HIDE);
+       ScoreRules_basics_end();
+}
+
+void lms_Initialize()
+{
+       lms_lowest_lives = 9999;
+       lms_next_place = 0;
+
+       lms_ScoreRules();
+}
+
+
+#endif
diff --git a/qcsrc/server/mutators/mutator/gamemode_onslaught.qc b/qcsrc/server/mutators/mutator/gamemode_onslaught.qc
new file mode 100644 (file)
index 0000000..51ddcad
--- /dev/null
@@ -0,0 +1,2326 @@
+#ifndef GAMEMODE_ONSLAUGHT_H
+#define GAMEMODE_ONSLAUGHT_H
+
+float autocvar_g_onslaught_point_limit;
+void ons_Initialize();
+
+REGISTER_MUTATOR(ons, false)
+{
+       ActivateTeamplay();
+       SetLimits(autocvar_g_onslaught_point_limit, -1, -1, -1);
+       have_team_spawns = -1; // request team spawns
+
+       MUTATOR_ONADD
+       {
+               if (time > 1) // game loads at time 1
+                       error("This is a game type and it cannot be added at runtime.");
+               ons_Initialize();
+       }
+
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               // we actually cannot roll back ons_Initialize here
+               // BUT: we don't need to! If this gets called, adding always
+               // succeeds.
+       }
+
+       MUTATOR_ONREMOVE
+       {
+               LOG_INFO("This is a game type and it cannot be removed at runtime.");
+               return -1;
+       }
+
+       return false;
+}
+
+#ifdef SVQC
+
+.entity ons_toucher; // player who touched the control point
+
+// control point / generator constants
+const float ONS_CP_THINKRATE = 0.2;
+const float GEN_THINKRATE = 1;
+#define CPGEN_SPAWN_OFFSET ('0 0 1' * (PL_MAX_CONST.z - 13))
+const vector CPGEN_WAYPOINT_OFFSET = ('0 0 128');
+const vector CPICON_OFFSET = ('0 0 96');
+
+// list of generators on the map
+entity ons_worldgeneratorlist;
+.entity ons_worldgeneratornext;
+.entity ons_stalegeneratornext;
+
+// list of control points on the map
+entity ons_worldcplist;
+.entity ons_worldcpnext;
+.entity ons_stalecpnext;
+
+// list of links on the map
+entity ons_worldlinklist;
+.entity ons_worldlinknext;
+.entity ons_stalelinknext;
+
+// definitions
+.entity sprite;
+.string target2;
+.int iscaptured;
+.int islinked;
+.int isshielded;
+.float lasthealth;
+.int lastteam;
+.int lastshielded;
+.int lastcaptured;
+
+.bool waslinked;
+
+bool ons_stalemate;
+
+.float teleport_antispam;
+
+.bool ons_roundlost;
+
+// waypoint sprites
+.entity bot_basewaypoint; // generator waypointsprite
+
+.bool isgenneighbor[17];
+.bool iscpneighbor[17];
+float ons_notification_time[17];
+
+.float ons_overtime_damagedelay;
+
+.vector ons_deathloc;
+
+.entity ons_spawn_by;
+
+// declarations for functions used outside gamemode_onslaught.qc
+void ons_Generator_UpdateSprite(entity e);
+void ons_ControlPoint_UpdateSprite(entity e);
+bool ons_ControlPoint_Attackable(entity cp, int teamnumber);
+
+// CaptureShield: Prevent capturing or destroying control point/generator if it is not available yet
+float ons_captureshield_force; // push force of the shield
+
+// bot player logic
+const int HAVOCBOT_ONS_ROLE_NONE               = 0;
+const int HAVOCBOT_ONS_ROLE_DEFENSE    = 2;
+const int HAVOCBOT_ONS_ROLE_ASSISTANT  = 4;
+const int HAVOCBOT_ONS_ROLE_OFFENSE    = 8;
+
+.entity havocbot_ons_target;
+
+.int havocbot_role_flags;
+.float havocbot_attack_time;
+
+void havocbot_role_ons_defense();
+void havocbot_role_ons_offense();
+void havocbot_role_ons_assistant();
+
+void havocbot_ons_reset_role(entity bot);
+void havocbot_goalrating_items(float ratingscale, vector org, float sradius);
+void havocbot_goalrating_enemyplayers(float ratingscale, vector org, float sradius);
+
+// score rule declarations
+const int ST_ONS_CAPS = 1;
+const int SP_ONS_CAPS = 4;
+const int SP_ONS_TAKES = 6;
+
+#endif
+#endif
+
+#ifdef IMPLEMENTATION
+
+#include "../../controlpoint.qh"
+#include "../../generator.qh"
+
+bool g_onslaught;
+
+float autocvar_g_onslaught_debug;
+float autocvar_g_onslaught_teleport_wait;
+bool autocvar_g_onslaught_spawn_at_controlpoints;
+bool autocvar_g_onslaught_spawn_at_generator;
+float autocvar_g_onslaught_cp_proxydecap;
+float autocvar_g_onslaught_cp_proxydecap_distance = 512;
+float autocvar_g_onslaught_cp_proxydecap_dps = 100;
+float autocvar_g_onslaught_spawn_at_controlpoints_chance = 0.5;
+float autocvar_g_onslaught_spawn_at_controlpoints_random;
+float autocvar_g_onslaught_spawn_at_generator_chance;
+float autocvar_g_onslaught_spawn_at_generator_random;
+float autocvar_g_onslaught_cp_buildhealth;
+float autocvar_g_onslaught_cp_buildtime;
+float autocvar_g_onslaught_cp_health;
+float autocvar_g_onslaught_cp_regen;
+float autocvar_g_onslaught_gen_health;
+float autocvar_g_onslaught_shield_force = 100;
+float autocvar_g_onslaught_allow_vehicle_touch;
+float autocvar_g_onslaught_round_timelimit;
+float autocvar_g_onslaught_warmup;
+float autocvar_g_onslaught_teleport_radius;
+float autocvar_g_onslaught_spawn_choose;
+float autocvar_g_onslaught_click_radius;
+
+void FixSize(entity e);
+
+// =======================
+// CaptureShield Functions
+// =======================
+
+bool ons_CaptureShield_Customize()
+{SELFPARAM();
+       entity e = WaypointSprite_getviewentity(other);
+
+       if(!self.enemy.isshielded && (ons_ControlPoint_Attackable(self.enemy, e.team) > 0 || self.enemy.classname != "onslaught_controlpoint")) { return false; }
+       if(SAME_TEAM(self, e)) { return false; }
+
+       return true;
+}
+
+void ons_CaptureShield_Touch()
+{SELFPARAM();
+       if(!self.enemy.isshielded && (ons_ControlPoint_Attackable(self.enemy, other.team) > 0 || self.enemy.classname != "onslaught_controlpoint")) { return; }
+       if(!IS_PLAYER(other)) { return; }
+       if(SAME_TEAM(other, self)) { return; }
+
+       vector mymid = (self.absmin + self.absmax) * 0.5;
+       vector othermid = (other.absmin + other.absmax) * 0.5;
+
+       Damage(other, self, self, 0, DEATH_HURTTRIGGER.m_id, mymid, normalize(othermid - mymid) * ons_captureshield_force);
+
+       if(IS_REAL_CLIENT(other))
+       {
+               play2(other, SND(ONS_DAMAGEBLOCKEDBYSHIELD));
+
+               if(self.enemy.classname == "onslaught_generator")
+                       Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_ONS_GENERATOR_SHIELDED);
+               else
+                       Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_ONS_CONTROLPOINT_SHIELDED);
+       }
+}
+
+void ons_CaptureShield_Reset()
+{SELFPARAM();
+       self.colormap = self.enemy.colormap;
+       self.team = self.enemy.team;
+}
+
+void ons_CaptureShield_Spawn(entity generator, bool is_generator)
+{
+       entity shield = spawn();
+
+       shield.enemy = generator;
+       shield.team = generator.team;
+       shield.colormap = generator.colormap;
+       shield.reset = ons_CaptureShield_Reset;
+       shield.touch = ons_CaptureShield_Touch;
+       shield.customizeentityforclient = ons_CaptureShield_Customize;
+       shield.classname = "ons_captureshield";
+       shield.effects = EF_ADDITIVE;
+       shield.movetype = MOVETYPE_NOCLIP;
+       shield.solid = SOLID_TRIGGER;
+       shield.avelocity = '7 0 11';
+       shield.scale = 1;
+       shield.model = ((is_generator) ? "models/onslaught/generator_shield.md3" : "models/onslaught/controlpoint_shield.md3");
+
+       precache_model(shield.model);
+       setorigin(shield, generator.origin);
+       _setmodel(shield, shield.model);
+       setsize(shield, shield.scale * shield.mins, shield.scale * shield.maxs);
+}
+
+
+// ==========
+// Junk Pile
+// ==========
+
+void ons_debug(string input)
+{
+       switch(autocvar_g_onslaught_debug)
+       {
+               case 1: LOG_TRACE(input); break;
+               case 2: LOG_INFO(input); break;
+       }
+}
+
+void setmodel_fixsize(entity e, Model m)
+{
+       setmodel(e, m);
+       FixSize(e);
+}
+
+void onslaught_updatelinks()
+{
+       entity l;
+       // first check if the game has ended
+       ons_debug("--- updatelinks ---\n");
+       // mark generators as being shielded and networked
+       for(l = ons_worldgeneratorlist; l; l = l.ons_worldgeneratornext)
+       {
+               if (l.iscaptured)
+                       ons_debug(strcat(etos(l), " (generator) belongs to team ", ftos(l.team), "\n"));
+               else
+                       ons_debug(strcat(etos(l), " (generator) is destroyed\n"));
+               l.islinked = l.iscaptured;
+               l.isshielded = l.iscaptured;
+               l.sprite.SendFlags |= 16;
+       }
+       // mark points as shielded and not networked
+       for(l = ons_worldcplist; l; l = l.ons_worldcpnext)
+       {
+               l.islinked = false;
+               l.isshielded = true;
+               int i;
+               for(i = 0; i < 17; ++i) { l.isgenneighbor[i] = false; l.iscpneighbor[i] = false; }
+               ons_debug(strcat(etos(l), " (point) belongs to team ", ftos(l.team), "\n"));
+               l.sprite.SendFlags |= 16;
+       }
+       // flow power outward from the generators through the network
+       bool stop = false;
+       while (!stop)
+       {
+               stop = true;
+               for(l = ons_worldlinklist; l; l = l.ons_worldlinknext)
+               {
+                       // if both points are captured by the same team, and only one of
+                       // them is powered, mark the other one as powered as well
+                       if (l.enemy.iscaptured && l.goalentity.iscaptured)
+                               if (l.enemy.islinked != l.goalentity.islinked)
+                                       if(SAME_TEAM(l.enemy, l.goalentity))
+                                       {
+                                               if (!l.goalentity.islinked)
+                                               {
+                                                       stop = false;
+                                                       l.goalentity.islinked = true;
+                                                       ons_debug(strcat(etos(l), " (link) is marking ", etos(l.goalentity), " (point) because its team matches ", etos(l.enemy), " (point)\n"));
+                                               }
+                                               else if (!l.enemy.islinked)
+                                               {
+                                                       stop = false;
+                                                       l.enemy.islinked = true;
+                                                       ons_debug(strcat(etos(l), " (link) is marking ", etos(l.enemy), " (point) because its team matches ", etos(l.goalentity), " (point)\n"));
+                                               }
+                                       }
+               }
+       }
+       // now that we know which points are powered we can mark their neighbors
+       // as unshielded if team differs
+       for(l = ons_worldlinklist; l; l = l.ons_worldlinknext)
+       {
+               if (l.goalentity.islinked)
+               {
+                       if(DIFF_TEAM(l.goalentity, l.enemy))
+                       {
+                               ons_debug(strcat(etos(l), " (link) is unshielding ", etos(l.enemy), " (point) because its team does not match ", etos(l.goalentity), " (point)\n"));
+                               l.enemy.isshielded = false;
+                       }
+                       if(l.goalentity.classname == "onslaught_generator")
+                               l.enemy.isgenneighbor[l.goalentity.team] = true;
+                       else
+                               l.enemy.iscpneighbor[l.goalentity.team] = true;
+               }
+               if (l.enemy.islinked)
+               {
+                       if(DIFF_TEAM(l.goalentity, l.enemy))
+                       {
+                               ons_debug(strcat(etos(l), " (link) is unshielding ", etos(l.goalentity), " (point) because its team does not match ", etos(l.enemy), " (point)\n"));
+                               l.goalentity.isshielded = false;
+                       }
+                       if(l.enemy.classname == "onslaught_generator")
+                               l.goalentity.isgenneighbor[l.enemy.team] = true;
+                       else
+                               l.goalentity.iscpneighbor[l.enemy.team] = true;
+               }
+       }
+       // now update the generators
+       for(l = ons_worldgeneratorlist; l; l = l.ons_worldgeneratornext)
+       {
+               if (l.isshielded)
+               {
+                       ons_debug(strcat(etos(l), " (generator) is shielded\n"));
+                       l.takedamage = DAMAGE_NO;
+                       l.bot_attack = false;
+               }
+               else
+               {
+                       ons_debug(strcat(etos(l), " (generator) is not shielded\n"));
+                       l.takedamage = DAMAGE_AIM;
+                       l.bot_attack = true;
+               }
+
+               ons_Generator_UpdateSprite(l);
+       }
+       // now update the takedamage and alpha variables on control point icons
+       for(l = ons_worldcplist; l; l = l.ons_worldcpnext)
+       {
+               if (l.isshielded)
+               {
+                       ons_debug(strcat(etos(l), " (point) is shielded\n"));
+                       if (l.goalentity)
+                       {
+                               l.goalentity.takedamage = DAMAGE_NO;
+                               l.goalentity.bot_attack = false;
+                       }
+               }
+               else
+               {
+                       ons_debug(strcat(etos(l), " (point) is not shielded\n"));
+                       if (l.goalentity)
+                       {
+                               l.goalentity.takedamage = DAMAGE_AIM;
+                               l.goalentity.bot_attack = true;
+                       }
+               }
+               ons_ControlPoint_UpdateSprite(l);
+       }
+       l = findchain(classname, "ons_captureshield");
+       while(l)
+       {
+               l.team = l.enemy.team;
+               l.colormap = l.enemy.colormap;
+               l = l.chain;
+       }
+}
+
+
+// ===================
+// Main Link Functions
+// ===================
+
+bool ons_Link_Send(entity this, entity to, int sendflags)
+{
+       WriteByte(MSG_ENTITY, ENT_CLIENT_RADARLINK);
+       WriteByte(MSG_ENTITY, sendflags);
+       if(sendflags & 1)
+       {
+               WriteCoord(MSG_ENTITY, self.goalentity.origin_x);
+               WriteCoord(MSG_ENTITY, self.goalentity.origin_y);
+               WriteCoord(MSG_ENTITY, self.goalentity.origin_z);
+       }
+       if(sendflags & 2)
+       {
+               WriteCoord(MSG_ENTITY, self.enemy.origin_x);
+               WriteCoord(MSG_ENTITY, self.enemy.origin_y);
+               WriteCoord(MSG_ENTITY, self.enemy.origin_z);
+       }
+       if(sendflags & 4)
+       {
+               WriteByte(MSG_ENTITY, self.clientcolors); // which is goalentity's color + enemy's color * 16
+       }
+       return true;
+}
+
+void ons_Link_CheckUpdate()
+{SELFPARAM();
+       // TODO check if the two sides have moved (currently they won't move anyway)
+       float cc = 0, cc1 = 0, cc2 = 0;
+
+       if(self.goalentity.islinked || self.goalentity.iscaptured) { cc1 = (self.goalentity.team - 1) * 0x01; }
+       if(self.enemy.islinked || self.enemy.iscaptured) { cc2 = (self.enemy.team - 1) * 0x10; }
+
+       cc = cc1 + cc2;
+
+       if(cc != self.clientcolors)
+       {
+               self.clientcolors = cc;
+               self.SendFlags |= 4;
+       }
+
+       self.nextthink = time;
+}
+
+void ons_DelayedLinkSetup()
+{SELFPARAM();
+       self.goalentity = find(world, targetname, self.target);
+       self.enemy = find(world, targetname, self.target2);
+       if(!self.goalentity) { objerror("can not find target\n"); }
+       if(!self.enemy) { objerror("can not find target2\n"); }
+
+       ons_debug(strcat(etos(self.goalentity), " linked with ", etos(self.enemy), "\n"));
+       self.SendFlags |= 3;
+       self.think = ons_Link_CheckUpdate;
+       self.nextthink = time;
+}
+
+
+// =============================
+// Main Control Point Functions
+// =============================
+
+int ons_ControlPoint_CanBeLinked(entity cp, int teamnumber)
+{
+       if(cp.isgenneighbor[teamnumber]) { return 2; }
+       if(cp.iscpneighbor[teamnumber]) { return 1; }
+
+       return 0;
+}
+
+int ons_ControlPoint_Attackable(entity cp, int teamnumber)
+       // -2: SAME TEAM, attackable by enemy!
+       // -1: SAME TEAM!
+       // 0: off limits
+       // 1: attack it
+       // 2: touch it
+       // 3: attack it (HIGH PRIO)
+       // 4: touch it (HIGH PRIO)
+{
+       int a;
+
+       if(cp.isshielded)
+       {
+               return 0;
+       }
+       else if(cp.goalentity)
+       {
+               // if there's already an icon built, nothing happens
+               if(cp.team == teamnumber)
+               {
+                       a = ons_ControlPoint_CanBeLinked(cp, teamnumber);
+                       if(a) // attackable by enemy?
+                               return -2; // EMERGENCY!
+                       return -1;
+               }
+               // we know it can be linked, so no need to check
+               // but...
+               a = ons_ControlPoint_CanBeLinked(cp, teamnumber);
+               if(a == 2) // near our generator?
+                       return 3; // EMERGENCY!
+               return 1;
+       }
+       else
+       {
+               // free point
+               if(ons_ControlPoint_CanBeLinked(cp, teamnumber))
+               {
+                       a = ons_ControlPoint_CanBeLinked(cp, teamnumber); // why was this here NUM_TEAM_1 + NUM_TEAM_2 - t
+                       if(a == 2)
+                               return 4; // GET THIS ONE NOW!
+                       else
+                               return 2; // TOUCH ME
+               }
+       }
+       return 0;
+}
+
+void ons_ControlPoint_Icon_Damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
+{SELFPARAM();
+       if(damage <= 0) { return; }
+
+       if (self.owner.isshielded)
+       {
+               // this is protected by a shield, so ignore the damage
+               if (time > self.pain_finished)
+                       if (IS_PLAYER(attacker))
+                       {
+                               play2(attacker, SND(ONS_DAMAGEBLOCKEDBYSHIELD));
+                               self.pain_finished = time + 1;
+                               attacker.typehitsound += 1; // play both sounds (shield is way too quiet)
+                       }
+
+               return;
+       }
+
+       if(IS_PLAYER(attacker))
+       if(time - ons_notification_time[self.team] > 10)
+       {
+               play2team(self.team, SND(ONS_CONTROLPOINT_UNDERATTACK));
+               ons_notification_time[self.team] = time;
+       }
+
+       self.health = self.health - damage;
+       if(self.owner.iscaptured)
+               WaypointSprite_UpdateHealth(self.owner.sprite, self.health);
+       else
+               WaypointSprite_UpdateBuildFinished(self.owner.sprite, time + (self.max_health - self.health) / (self.count / ONS_CP_THINKRATE));
+       self.pain_finished = time + 1;
+       // particles on every hit
+       pointparticles(particleeffectnum(EFFECT_SPARKS), hitloc, force*-1, 1);
+       //sound on every hit
+       if (random() < 0.5)
+               sound(self, CH_TRIGGER, SND_ONS_HIT1, VOL_BASE+0.3, ATTEN_NORM);
+       else
+               sound(self, CH_TRIGGER, SND_ONS_HIT2, VOL_BASE+0.3, ATTEN_NORM);
+
+       if (self.health < 0)
+       {
+               sound(self, CH_TRIGGER, SND_GRENADE_IMPACT, VOL_BASE, ATTEN_NORM);
+               pointparticles(particleeffectnum(EFFECT_ROCKET_EXPLODE), self.origin, '0 0 0', 1);
+               Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(self.team, INFO_ONSLAUGHT_CPDESTROYED_), self.owner.message, attacker.netname);
+
+               PlayerScore_Add(attacker, SP_ONS_TAKES, 1);
+               PlayerScore_Add(attacker, SP_SCORE, 10);
+
+               self.owner.goalentity = world;
+               self.owner.islinked = false;
+               self.owner.iscaptured = false;
+               self.owner.team = 0;
+               self.owner.colormap = 1024;
+
+               WaypointSprite_UpdateMaxHealth(self.owner.sprite, 0);
+
+               onslaught_updatelinks();
+
+               // Use targets now (somebody make sure this is in the right place..)
+               setself(self.owner);
+               activator = self;
+               SUB_UseTargets ();
+               setself(this);
+
+               self.owner.waslinked = self.owner.islinked;
+               if(self.owner.model != "models/onslaught/controlpoint_pad.md3")
+                       setmodel_fixsize(self.owner, MDL_ONS_CP_PAD1);
+               //setsize(self, '-32 -32 0', '32 32 8');
+
+               remove(self);
+       }
+
+       self.SendFlags |= CPSF_STATUS;
+}
+
+void ons_ControlPoint_Icon_Think()
+{SELFPARAM();
+       self.nextthink = time + ONS_CP_THINKRATE;
+
+       if(autocvar_g_onslaught_cp_proxydecap)
+       {
+        int _enemy_count = 0;
+        int _friendly_count = 0;
+        float _dist;
+        entity _player;
+
+        FOR_EACH_PLAYER(_player)
+        {
+            if(!_player.deadflag)
+            {
+                _dist = vlen(_player.origin - self.origin);
+                if(_dist < autocvar_g_onslaught_cp_proxydecap_distance)
+                {
+                                       if(SAME_TEAM(_player, self))
+                        ++_friendly_count;
+                    else
+                        ++_enemy_count;
+                }
+            }
+        }
+
+        _friendly_count = _friendly_count * (autocvar_g_onslaught_cp_proxydecap_dps * ONS_CP_THINKRATE);
+        _enemy_count = _enemy_count * (autocvar_g_onslaught_cp_proxydecap_dps * ONS_CP_THINKRATE);
+
+        self.health = bound(0, self.health + (_friendly_count - _enemy_count), self.max_health);
+               self.SendFlags |= CPSF_STATUS;
+        if(self.health <= 0)
+        {
+            ons_ControlPoint_Icon_Damage(self, self, 1, 0, self.origin, '0 0 0');
+            return;
+        }
+    }
+
+       if (time > self.pain_finished + 5)
+       {
+               if(self.health < self.max_health)
+               {
+                       self.health = self.health + self.count;
+                       if (self.health >= self.max_health)
+                               self.health = self.max_health;
+                       WaypointSprite_UpdateHealth(self.owner.sprite, self.health);
+               }
+       }
+
+       if(self.owner.islinked != self.owner.waslinked)
+       {
+               // unteam the spawnpoint if needed
+               int t = self.owner.team;
+               if(!self.owner.islinked)
+                       self.owner.team = 0;
+
+               setself(self.owner);
+               activator = self;
+               SUB_UseTargets ();
+               setself(this);
+
+               self.owner.team = t;
+
+               self.owner.waslinked = self.owner.islinked;
+       }
+
+       // damaged fx
+       if(random() < 0.6 - self.health / self.max_health)
+       {
+               Send_Effect(EFFECT_ELECTRIC_SPARKS, self.origin + randompos('-10 -10 -20', '10 10 20'), '0 0 0', 1);
+
+               if(random() > 0.8)
+                       sound(self, CH_PAIN, SND_ONS_SPARK1, VOL_BASE, ATTEN_NORM);
+               else if (random() > 0.5)
+                       sound(self, CH_PAIN, SND_ONS_SPARK2, VOL_BASE, ATTEN_NORM);
+       }
+}
+
+void ons_ControlPoint_Icon_BuildThink()
+{SELFPARAM();
+       int a;
+
+       self.nextthink = time + ONS_CP_THINKRATE;
+
+       // only do this if there is power
+       a = ons_ControlPoint_CanBeLinked(self.owner, self.owner.team);
+       if(!a)
+               return;
+
+       self.health = self.health + self.count;
+
+       self.SendFlags |= CPSF_STATUS;
+
+       if (self.health >= self.max_health)
+       {
+               self.health = self.max_health;
+               self.count = autocvar_g_onslaught_cp_regen * ONS_CP_THINKRATE; // slow repair rate from now on
+               self.think = ons_ControlPoint_Icon_Think;
+               sound(self, CH_TRIGGER, SND_ONS_CONTROLPOINT_BUILT, VOL_BASE, ATTEN_NORM);
+               self.owner.iscaptured = true;
+               self.solid = SOLID_BBOX;
+
+               Send_Effect(EFFECT_CAP(self.owner.team), self.owner.origin, '0 0 0', 1);
+
+               WaypointSprite_UpdateMaxHealth(self.owner.sprite, self.max_health);
+               WaypointSprite_UpdateHealth(self.owner.sprite, self.health);
+
+               if(IS_PLAYER(self.owner.ons_toucher))
+               {
+                       Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_ONSLAUGHT_CAPTURE, self.owner.ons_toucher.netname, self.owner.message);
+                       Send_Notification(NOTIF_ALL_EXCEPT, self.owner.ons_toucher, MSG_CENTER, APP_TEAM_ENT_4(self.owner.ons_toucher, CENTER_ONS_CAPTURE_), self.owner.message);
+                       Send_Notification(NOTIF_ONE, self.owner.ons_toucher, MSG_CENTER, CENTER_ONS_CAPTURE, self.owner.message);
+                       PlayerScore_Add(self.owner.ons_toucher, SP_ONS_CAPS, 1);
+                       PlayerTeamScore_AddScore(self.owner.ons_toucher, 10);
+               }
+
+               self.owner.ons_toucher = world;
+
+               onslaught_updatelinks();
+
+               // Use targets now (somebody make sure this is in the right place..)
+               setself(self.owner);
+               activator = self;
+               SUB_UseTargets ();
+               setself(this);
+
+               self.SendFlags |= CPSF_SETUP;
+       }
+       if(self.owner.model != MDL_ONS_CP_PAD2.model_str())
+               setmodel_fixsize(self.owner, MDL_ONS_CP_PAD2);
+
+       if(random() < 0.9 - self.health / self.max_health)
+               Send_Effect(EFFECT_RAGE, self.origin + 10 * randomvec(), '0 0 -1', 1);
+}
+
+void onslaught_controlpoint_icon_link(entity e, void() spawnproc);
+
+void ons_ControlPoint_Icon_Spawn(entity cp, entity player)
+{
+       entity e = spawn();
+
+       setsize(e, CPICON_MIN, CPICON_MAX);
+       setorigin(e, cp.origin + CPICON_OFFSET);
+
+       e.classname = "onslaught_controlpoint_icon";
+       e.owner = cp;
+       e.max_health = autocvar_g_onslaught_cp_health;
+       e.health = autocvar_g_onslaught_cp_buildhealth;
+       e.solid = SOLID_NOT;
+       e.takedamage = DAMAGE_AIM;
+       e.bot_attack = true;
+       e.event_damage = ons_ControlPoint_Icon_Damage;
+       e.team = player.team;
+       e.colormap = 1024 + (e.team - 1) * 17;
+       e.count = (e.max_health - e.health) * ONS_CP_THINKRATE / autocvar_g_onslaught_cp_buildtime; // how long it takes to build
+
+       sound(e, CH_TRIGGER, SND_ONS_CONTROLPOINT_BUILD, VOL_BASE, ATTEN_NORM);
+
+       cp.goalentity = e;
+       cp.team = e.team;
+       cp.colormap = e.colormap;
+
+       Send_Effect(EFFECT_FLAG_TOUCH(player.team), e.origin, '0 0 0', 1);
+
+       WaypointSprite_UpdateBuildFinished(cp.sprite, time + (e.max_health - e.health) / (e.count / ONS_CP_THINKRATE));
+       WaypointSprite_UpdateRule(cp.sprite,cp.team,SPRITERULE_TEAMPLAY);
+       cp.sprite.SendFlags |= 16;
+
+       onslaught_controlpoint_icon_link(e, ons_ControlPoint_Icon_BuildThink);
+}
+
+entity ons_ControlPoint_Waypoint(entity e)
+{
+       if(e.team)
+       {
+               int a = ons_ControlPoint_Attackable(e, e.team);
+
+               if(a == -2) { return WP_OnsCPDefend; } // defend now
+               if(a == -1 || a == 1 || a == 2) { return WP_OnsCP; } // touch
+               if(a == 3 || a == 4) { return WP_OnsCPAttack; } // attack
+       }
+       else
+               return WP_OnsCP;
+
+       return WP_Null;
+}
+
+void ons_ControlPoint_UpdateSprite(entity e)
+{
+       entity s1 = ons_ControlPoint_Waypoint(e);
+       WaypointSprite_UpdateSprites(e.sprite, s1, s1, s1);
+
+       bool sh;
+       sh = !(ons_ControlPoint_CanBeLinked(e, NUM_TEAM_1) || ons_ControlPoint_CanBeLinked(e, NUM_TEAM_2) || ons_ControlPoint_CanBeLinked(e, NUM_TEAM_3) || ons_ControlPoint_CanBeLinked(e, NUM_TEAM_4));
+
+       if(e.lastteam != e.team + 2 || e.lastshielded != sh || e.iscaptured != e.lastcaptured)
+       {
+               if(e.iscaptured) // don't mess up build bars!
+               {
+                       if(sh)
+                       {
+                               WaypointSprite_UpdateMaxHealth(e.sprite, 0);
+                       }
+                       else
+                       {
+                               WaypointSprite_UpdateMaxHealth(e.sprite, e.goalentity.max_health);
+                               WaypointSprite_UpdateHealth(e.sprite, e.goalentity.health);
+                       }
+               }
+               if(e.lastshielded)
+               {
+                       if(e.team)
+                               WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_CONTROLPOINT, 0.5 * colormapPaletteColor(e.team - 1, false));
+                       else
+                               WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_CONTROLPOINT, '0.5 0.5 0.5');
+               }
+               else
+               {
+                       if(e.team)
+                               WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_CONTROLPOINT, colormapPaletteColor(e.team - 1, false));
+                       else
+                               WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_CONTROLPOINT, '0.75 0.75 0.75');
+               }
+               WaypointSprite_Ping(e.sprite);
+
+               e.lastteam = e.team + 2;
+               e.lastshielded = sh;
+               e.lastcaptured = e.iscaptured;
+       }
+}
+
+void ons_ControlPoint_Touch()
+{SELFPARAM();
+       entity toucher = other;
+       int attackable;
+
+       if(IS_VEHICLE(toucher) && toucher.owner)
+       if(autocvar_g_onslaught_allow_vehicle_touch)
+               toucher = toucher.owner;
+       else
+               return;
+
+       if(!IS_PLAYER(toucher)) { return; }
+       if(toucher.frozen) { return; }
+       if(toucher.deadflag != DEAD_NO) { return; }
+
+       if ( SAME_TEAM(self,toucher) )
+       if ( self.iscaptured )
+       {
+               if(time <= toucher.teleport_antispam)
+                       Send_Notification(NOTIF_ONE, toucher, MSG_CENTER, CENTER_ONS_TELEPORT_ANTISPAM, rint(toucher.teleport_antispam - time));
+               else
+                       Send_Notification(NOTIF_ONE, toucher, MSG_CENTER, CENTER_ONS_TELEPORT);
+       }
+
+       attackable = ons_ControlPoint_Attackable(self, toucher.team);
+       if(attackable != 2 && attackable != 4)
+               return;
+       // we've verified that this player has a legitimate claim to this point,
+       // so start building the captured point icon (which only captures this
+       // point if it successfully builds without being destroyed first)
+       ons_ControlPoint_Icon_Spawn(self, toucher);
+
+       self.ons_toucher = toucher;
+
+       onslaught_updatelinks();
+}
+
+void ons_ControlPoint_Think()
+{SELFPARAM();
+       self.nextthink = time + ONS_CP_THINKRATE;
+       CSQCMODEL_AUTOUPDATE(self);
+}
+
+void ons_ControlPoint_Reset()
+{SELFPARAM();
+       if(self.goalentity)
+               remove(self.goalentity);
+
+       self.goalentity = world;
+       self.team = 0;
+       self.colormap = 1024;
+       self.iscaptured = false;
+       self.islinked = false;
+       self.isshielded = true;
+       self.think = ons_ControlPoint_Think;
+       self.ons_toucher = world;
+       self.nextthink = time + ONS_CP_THINKRATE;
+       setmodel_fixsize(self, MDL_ONS_CP_PAD1);
+
+       WaypointSprite_UpdateMaxHealth(self.sprite, 0);
+       WaypointSprite_UpdateRule(self.sprite,self.team,SPRITERULE_TEAMPLAY);
+
+       onslaught_updatelinks();
+
+       activator = self;
+       SUB_UseTargets(); // to reset the structures, playerspawns etc.
+
+       CSQCMODEL_AUTOUPDATE(self);
+}
+
+void ons_DelayedControlPoint_Setup(void)
+{SELFPARAM();
+       onslaught_updatelinks();
+
+       // captureshield setup
+       ons_CaptureShield_Spawn(self, false);
+
+       CSQCMODEL_AUTOINIT(self);
+}
+
+void ons_ControlPoint_Setup(entity cp)
+{SELFPARAM();
+       // declarations
+       setself(cp); // for later usage with droptofloor()
+
+       // main setup
+       cp.ons_worldcpnext = ons_worldcplist; // link control point into ons_worldcplist
+       ons_worldcplist = cp;
+
+       cp.netname = "Control point";
+       cp.team = 0;
+       cp.solid = SOLID_BBOX;
+       cp.movetype = MOVETYPE_NONE;
+       cp.touch = ons_ControlPoint_Touch;
+       cp.think = ons_ControlPoint_Think;
+       cp.nextthink = time + ONS_CP_THINKRATE;
+       cp.reset = ons_ControlPoint_Reset;
+       cp.colormap = 1024;
+       cp.iscaptured = false;
+       cp.islinked = false;
+       cp.isshielded = true;
+
+       if(cp.message == "") { cp.message = "a"; }
+
+       // appearence
+       setmodel_fixsize(cp, MDL_ONS_CP_PAD1);
+
+       // control point placement
+       if((cp.spawnflags & 1) || cp.noalign) // don't drop to floor, just stay at fixed location
+       {
+               cp.noalign = true;
+               cp.movetype = MOVETYPE_NONE;
+       }
+       else // drop to floor, automatically find a platform and set that as spawn origin
+       {
+               setorigin(cp, cp.origin + '0 0 20');
+               cp.noalign = false;
+               setself(cp);
+               droptofloor();
+               cp.movetype = MOVETYPE_TOSS;
+       }
+
+       // waypointsprites
+       WaypointSprite_SpawnFixed(WP_Null, self.origin + CPGEN_WAYPOINT_OFFSET, self, sprite, RADARICON_NONE);
+       WaypointSprite_UpdateRule(self.sprite, self.team, SPRITERULE_TEAMPLAY);
+
+       InitializeEntity(cp, ons_DelayedControlPoint_Setup, INITPRIO_SETLOCATION);
+}
+
+
+// =========================
+// Main Generator Functions
+// =========================
+
+entity ons_Generator_Waypoint(entity e)
+{
+       if (e.isshielded)
+               return WP_OnsGenShielded;
+       return WP_OnsGen;
+}
+
+void ons_Generator_UpdateSprite(entity e)
+{
+       entity s1 = ons_Generator_Waypoint(e);
+       WaypointSprite_UpdateSprites(e.sprite, s1, s1, s1);
+
+       if(e.lastteam != e.team + 2 || e.lastshielded != e.isshielded)
+       {
+               e.lastteam = e.team + 2;
+               e.lastshielded = e.isshielded;
+               if(e.lastshielded)
+               {
+                       if(e.team)
+                               WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_GENERATOR, 0.5 * colormapPaletteColor(e.team - 1, false));
+                       else
+                               WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_GENERATOR, '0.5 0.5 0.5');
+               }
+               else
+               {
+                       if(e.team)
+                               WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_GENERATOR, colormapPaletteColor(e.team - 1, false));
+                       else
+                               WaypointSprite_UpdateTeamRadar(e.sprite, RADARICON_GENERATOR, '0.75 0.75 0.75');
+               }
+               WaypointSprite_Ping(e.sprite);
+       }
+}
+
+void ons_GeneratorDamage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
+{SELFPARAM();
+       if(damage <= 0) { return; }
+       if(warmup_stage || gameover) { return; }
+       if(!round_handler_IsRoundStarted()) { return; }
+
+       if (attacker != self)
+       {
+               if (self.isshielded)
+               {
+                       // this is protected by a shield, so ignore the damage
+                       if (time > self.pain_finished)
+                               if (IS_PLAYER(attacker))
+                               {
+                                       play2(attacker, SND(ONS_DAMAGEBLOCKEDBYSHIELD));
+                                       attacker.typehitsound += 1;
+                                       self.pain_finished = time + 1;
+                               }
+                       return;
+               }
+               if (time > self.pain_finished)
+               {
+                       self.pain_finished = time + 10;
+                       entity head;
+                       FOR_EACH_REALPLAYER(head) if(SAME_TEAM(head, self)) { Send_Notification(NOTIF_ONE, head, MSG_CENTER, CENTER_GENERATOR_UNDERATTACK); }
+                       play2team(self.team, SND(ONS_GENERATOR_UNDERATTACK));
+               }
+       }
+       self.health = self.health - damage;
+       WaypointSprite_UpdateHealth(self.sprite, self.health);
+       // choose an animation frame based on health
+       self.frame = 10 * bound(0, (1 - self.health / self.max_health), 1);
+       // see if the generator is still functional, or dying
+       if (self.health > 0)
+       {
+               self.lasthealth = self.health;
+       }
+       else
+       {
+               if (attacker == self)
+                       Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(self.team, INFO_ONSLAUGHT_GENDESTROYED_OVERTIME_));
+               else
+               {
+                       Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(self.team, INFO_ONSLAUGHT_GENDESTROYED_));
+                       PlayerScore_Add(attacker, SP_SCORE, 100);
+               }
+               self.iscaptured = false;
+               self.islinked = false;
+               self.isshielded = false;
+               self.takedamage = DAMAGE_NO; // can't be hurt anymore
+               self.event_damage = func_null; // won't do anything if hurt
+               self.count = 0; // reset counter
+               self.think = func_null;
+               self.nextthink = 0;
+               //self.think(); // do the first explosion now
+
+               WaypointSprite_UpdateMaxHealth(self.sprite, 0);
+               WaypointSprite_Ping(self.sprite);
+               //WaypointSprite_Kill(self.sprite); // can't do this yet, code too poor
+
+               onslaught_updatelinks();
+       }
+
+       // Throw some flaming gibs on damage, more damage = more chance for gib
+       if(random() < damage/220)
+       {
+               sound(self, CH_TRIGGER, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM);
+       }
+       else
+       {
+               // particles on every hit
+               Send_Effect(EFFECT_SPARKS, hitloc, force * -1, 1);
+
+               //sound on every hit
+               if (random() < 0.5)
+                       sound(self, CH_TRIGGER, SND_ONS_HIT1, VOL_BASE, ATTEN_NORM);
+               else
+                       sound(self, CH_TRIGGER, SND_ONS_HIT2, VOL_BASE, ATTEN_NORM);
+       }
+
+       self.SendFlags |= GSF_STATUS;
+}
+
+void ons_GeneratorThink()
+{SELFPARAM();
+       entity e;
+       self.nextthink = time + GEN_THINKRATE;
+       if (!gameover)
+       {
+        if(!self.isshielded && self.wait < time)
+        {
+            self.wait = time + 5;
+            FOR_EACH_REALPLAYER(e)
+            {
+                               if(SAME_TEAM(e, self))
+                               {
+                                       Send_Notification(NOTIF_ONE, e, MSG_CENTER, CENTER_ONS_NOTSHIELDED_TEAM);
+                    soundto(MSG_ONE, e, CHAN_AUTO, SND(KH_ALARM), VOL_BASE, ATTEN_NONE);    // FIXME: unique sound?
+                }
+                               else
+                                       Send_Notification(NOTIF_ONE, e, MSG_CENTER, APP_TEAM_NUM_4(self.team, CENTER_ONS_NOTSHIELDED_));
+            }
+        }
+       }
+}
+
+void ons_GeneratorReset()
+{SELFPARAM();
+       self.team = self.team_saved;
+       self.lasthealth = self.max_health = self.health = autocvar_g_onslaught_gen_health;
+       self.takedamage = DAMAGE_AIM;
+       self.bot_attack = true;
+       self.iscaptured = true;
+       self.islinked = true;
+       self.isshielded = true;
+       self.event_damage = ons_GeneratorDamage;
+       self.think = ons_GeneratorThink;
+       self.nextthink = time + GEN_THINKRATE;
+
+       Net_LinkEntity(self, false, 0, generator_send);
+
+       self.SendFlags = GSF_SETUP; // just incase
+       self.SendFlags |= GSF_STATUS;
+
+       WaypointSprite_UpdateMaxHealth(self.sprite, self.max_health);
+       WaypointSprite_UpdateHealth(self.sprite, self.health);
+       WaypointSprite_UpdateRule(self.sprite,self.team,SPRITERULE_TEAMPLAY);
+
+       onslaught_updatelinks();
+}
+
+void ons_DelayedGeneratorSetup()
+{SELFPARAM();
+       // bot waypoints
+       waypoint_spawnforitem_force(self, self.origin);
+       self.nearestwaypointtimeout = 0; // activate waypointing again
+       self.bot_basewaypoint = self.nearestwaypoint;
+
+       // captureshield setup
+       ons_CaptureShield_Spawn(self, true);
+
+       onslaught_updatelinks();
+
+       Net_LinkEntity(self, false, 0, generator_send);
+}
+
+
+void onslaught_generator_touch()
+{SELFPARAM();
+       if ( IS_PLAYER(other) )
+       if ( SAME_TEAM(self,other) )
+       if ( self.iscaptured )
+       {
+               Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_ONS_TELEPORT);
+       }
+}
+
+void ons_GeneratorSetup(entity gen) // called when spawning a generator entity on the map as a spawnfunc
+{SELFPARAM();
+       // declarations
+       int teamnumber = gen.team;
+       setself(gen); // for later usage with droptofloor()
+
+       // main setup
+       gen.ons_worldgeneratornext = ons_worldgeneratorlist; // link generator into ons_worldgeneratorlist
+       ons_worldgeneratorlist = gen;
+
+       gen.netname = sprintf("%s generator", Team_ColoredFullName(teamnumber));
+       gen.classname = "onslaught_generator";
+       gen.solid = SOLID_BBOX;
+       gen.team_saved = teamnumber;
+       gen.movetype = MOVETYPE_NONE;
+       gen.lasthealth = gen.max_health = gen.health = autocvar_g_onslaught_gen_health;
+       gen.takedamage = DAMAGE_AIM;
+       gen.bot_attack = true;
+       gen.event_damage = ons_GeneratorDamage;
+       gen.reset = ons_GeneratorReset;
+       gen.think = ons_GeneratorThink;
+       gen.nextthink = time + GEN_THINKRATE;
+       gen.iscaptured = true;
+       gen.islinked = true;
+       gen.isshielded = true;
+       gen.touch = onslaught_generator_touch;
+
+       // appearence
+       // model handled by CSQC
+       setsize(gen, GENERATOR_MIN, GENERATOR_MAX);
+       setorigin(gen, (gen.origin + CPGEN_SPAWN_OFFSET));
+       gen.colormap = 1024 + (teamnumber - 1) * 17;
+
+       // generator placement
+       setself(gen);
+       droptofloor();
+
+       // waypointsprites
+       WaypointSprite_SpawnFixed(WP_Null, self.origin + CPGEN_WAYPOINT_OFFSET, self, sprite, RADARICON_NONE);
+       WaypointSprite_UpdateRule(self.sprite, self.team, SPRITERULE_TEAMPLAY);
+       WaypointSprite_UpdateMaxHealth(self.sprite, self.max_health);
+       WaypointSprite_UpdateHealth(self.sprite, self.health);
+
+       InitializeEntity(gen, ons_DelayedGeneratorSetup, INITPRIO_SETLOCATION);
+}
+
+
+// ===============
+//  Round Handler
+// ===============
+
+int total_generators;
+void Onslaught_count_generators()
+{
+       entity e;
+       total_generators = redowned = blueowned = yellowowned = pinkowned = 0;
+       for(e = ons_worldgeneratorlist; e; e = e.ons_worldgeneratornext)
+       {
+               ++total_generators;
+               redowned += (e.team == NUM_TEAM_1 && e.health > 0);
+               blueowned += (e.team == NUM_TEAM_2 && e.health > 0);
+               yellowowned += (e.team == NUM_TEAM_3 && e.health > 0);
+               pinkowned += (e.team == NUM_TEAM_4 && e.health > 0);
+       }
+}
+
+int Onslaught_GetWinnerTeam()
+{
+       int winner_team = 0;
+       if(redowned > 0)
+               winner_team = NUM_TEAM_1;
+       if(blueowned > 0)
+       {
+               if(winner_team) return 0;
+               winner_team = NUM_TEAM_2;
+       }
+       if(yellowowned > 0)
+       {
+               if(winner_team) return 0;
+               winner_team = NUM_TEAM_3;
+       }
+       if(pinkowned > 0)
+       {
+               if(winner_team) return 0;
+               winner_team = NUM_TEAM_4;
+       }
+       if(winner_team)
+               return winner_team;
+       return -1; // no generators left?
+}
+
+#define ONS_OWNED_GENERATORS() ((redowned > 0) + (blueowned > 0) + (yellowowned > 0) + (pinkowned > 0))
+#define ONS_OWNED_GENERATORS_OK() (ONS_OWNED_GENERATORS() > 1)
+bool Onslaught_CheckWinner()
+{
+       entity e;
+
+       if ((autocvar_timelimit && time > game_starttime + autocvar_timelimit * 60) || (round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0))
+       {
+               ons_stalemate = true;
+
+               if (!wpforenemy_announced)
+               {
+                       Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_OVERTIME_CONTROLPOINT);
+                       sound(world, CH_INFO, SND_ONS_GENERATOR_DECAY, VOL_BASE, ATTEN_NONE);
+
+                       wpforenemy_announced = true;
+               }
+
+               entity tmp_entity; // temporary entity
+               float d;
+               for(tmp_entity = ons_worldgeneratorlist; tmp_entity; tmp_entity = tmp_entity.ons_worldgeneratornext) if(time >= tmp_entity.ons_overtime_damagedelay)
+               {
+                       // tmp_entity.max_health / 300 gives 5 minutes of overtime.
+                       // control points reduce the overtime duration.
+                       d = 1;
+                       for(e = ons_worldcplist; e; e = e.ons_worldcpnext)
+                       {
+                               if(DIFF_TEAM(e, tmp_entity))
+                               if(e.islinked)
+                                       d = d + 1;
+                       }
+
+                       if(autocvar_g_campaign && autocvar__campaign_testrun)
+                               d = d * tmp_entity.max_health;
+                       else
+                               d = d * tmp_entity.max_health / max(30, 60 * autocvar_timelimit_suddendeath);
+
+                       Damage(tmp_entity, tmp_entity, tmp_entity, d, DEATH_HURTTRIGGER.m_id, tmp_entity.origin, '0 0 0');
+
+                       tmp_entity.sprite.SendFlags |= 16;
+
+                       tmp_entity.ons_overtime_damagedelay = time + 1;
+               }
+       }
+       else { wpforenemy_announced = false; ons_stalemate = false; }
+
+       Onslaught_count_generators();
+
+       if(ONS_OWNED_GENERATORS_OK())
+               return 0;
+
+       int winner_team = Onslaught_GetWinnerTeam();
+
+       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_ONS_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);
+       }
+
+       ons_stalemate = false;
+
+       play2all(SND(CTF_CAPTURE(winner_team)));
+
+       round_handler_Init(7, autocvar_g_onslaught_warmup, autocvar_g_onslaught_round_timelimit);
+
+       FOR_EACH_PLAYER(e)
+       {
+               e.ons_roundlost = true;
+               e.player_blocked = true;
+
+               nades_Clear(e);
+       }
+
+       return 1;
+}
+
+bool Onslaught_CheckPlayers()
+{
+       return 1;
+}
+
+void Onslaught_RoundStart()
+{
+       entity tmp_entity;
+       FOR_EACH_PLAYER(tmp_entity) { tmp_entity.player_blocked = false; }
+
+       for(tmp_entity = ons_worldcplist; tmp_entity; tmp_entity = tmp_entity.ons_worldcpnext)
+               tmp_entity.sprite.SendFlags |= 16;
+
+       for(tmp_entity = ons_worldgeneratorlist; tmp_entity; tmp_entity = tmp_entity.ons_worldgeneratornext)
+               tmp_entity.sprite.SendFlags |= 16;
+}
+
+
+// ================
+// Bot player logic
+// ================
+
+// NOTE: LEGACY CODE, needs to be re-written!
+
+void havocbot_goalrating_ons_offenseitems(float ratingscale, vector org, float sradius)
+{SELFPARAM();
+       entity head;
+       float t, c;
+       int i;
+       bool needarmor = false, needweapons = false;
+
+       // Needs armor/health?
+       if(self.health<100)
+               needarmor = true;
+
+       // Needs weapons?
+       c = 0;
+       for(i = WEP_FIRST; i <= WEP_LAST ; ++i)
+       {
+               // Find weapon
+               if(self.weapons & WepSet_FromWeapon(i))
+               if(++c>=4)
+                       break;
+       }
+
+       if(c<4)
+               needweapons = true;
+
+       if(!needweapons && !needarmor)
+               return;
+
+       ons_debug(strcat(self.netname, " needs weapons ", ftos(needweapons) , "\n"));
+       ons_debug(strcat(self.netname, " needs armor ", ftos(needarmor) , "\n"));
+
+       // See what is around
+       head = findchainfloat(bot_pickup, true);
+       while (head)
+       {
+               // gather health and armor only
+               if (head.solid)
+               if ( ((head.health || head.armorvalue) && needarmor) || (head.weapons && needweapons ) )
+               if (vlen(head.origin - org) < sradius)
+               {
+                       t = head.bot_pickupevalfunc(self, head);
+                       if (t > 0)
+                               navigation_routerating(head, t * ratingscale, 500);
+               }
+               head = head.chain;
+       }
+}
+
+void havocbot_role_ons_setrole(entity bot, int role)
+{
+       ons_debug(strcat(bot.netname," switched to "));
+       switch(role)
+       {
+               case HAVOCBOT_ONS_ROLE_DEFENSE:
+                       ons_debug("defense");
+                       bot.havocbot_role = havocbot_role_ons_defense;
+                       bot.havocbot_role_flags = HAVOCBOT_ONS_ROLE_DEFENSE;
+                       bot.havocbot_role_timeout = 0;
+                       break;
+               case HAVOCBOT_ONS_ROLE_ASSISTANT:
+                       ons_debug("assistant");
+                       bot.havocbot_role = havocbot_role_ons_assistant;
+                       bot.havocbot_role_flags = HAVOCBOT_ONS_ROLE_ASSISTANT;
+                       bot.havocbot_role_timeout = 0;
+                       break;
+               case HAVOCBOT_ONS_ROLE_OFFENSE:
+                       ons_debug("offense");
+                       bot.havocbot_role = havocbot_role_ons_offense;
+                       bot.havocbot_role_flags = HAVOCBOT_ONS_ROLE_OFFENSE;
+                       bot.havocbot_role_timeout = 0;
+                       break;
+       }
+       ons_debug("\n");
+}
+
+int havocbot_ons_teamcount(entity bot, int role)
+{SELFPARAM();
+       int c = 0;
+       entity head;
+
+       FOR_EACH_PLAYER(head)
+       if(SAME_TEAM(head, self))
+       if(head.havocbot_role_flags & role)
+               ++c;
+
+       return c;
+}
+
+void havocbot_goalrating_ons_controlpoints_attack(float ratingscale)
+{SELFPARAM();
+       entity cp, cp1, cp2, best, pl, wp;
+       float radius, bestvalue;
+       int c;
+       bool found;
+
+       // Filter control points
+       for(cp2 = ons_worldcplist; cp2; cp2 = cp2.ons_worldcpnext)
+       {
+               cp2.wpcost = c = 0;
+               cp2.wpconsidered = false;
+
+               if(cp2.isshielded)
+                       continue;
+
+               // Ignore owned controlpoints
+               if(!(cp2.isgenneighbor[self.team] || cp2.iscpneighbor[self.team]))
+                       continue;
+
+               // Count team mates interested in this control point
+               // (easier and cleaner than keeping counters per cp and teams)
+               FOR_EACH_PLAYER(pl)
+               if(SAME_TEAM(pl, self))
+               if(pl.havocbot_role_flags & HAVOCBOT_ONS_ROLE_OFFENSE)
+               if(pl.havocbot_ons_target==cp2)
+                       ++c;
+
+               // NOTE: probably decrease the cost of attackable control points
+               cp2.wpcost = c;
+               cp2.wpconsidered = true;
+       }
+
+       // We'll consider only the best case
+       bestvalue = 99999999999;
+       cp = world;
+       for(cp1 = ons_worldcplist; cp1; cp1 = cp1.ons_worldcpnext)
+       {
+               if (!cp1.wpconsidered)
+                       continue;
+
+               if(cp1.wpcost<bestvalue)
+               {
+                       bestvalue = cp1.wpcost;
+                       cp = cp1;
+                       self.havocbot_ons_target = cp1;
+               }
+       }
+
+       if (!cp)
+               return;
+
+       ons_debug(strcat(self.netname, " chose cp ranked ", ftos(bestvalue), "\n"));
+
+       if(cp.goalentity)
+       {
+               // Should be attacked
+               // Rate waypoints near it
+               found = false;
+               best = world;
+               bestvalue = 99999999999;
+               for(radius=0; radius<1000 && !found; radius+=500)
+               {
+                       for(wp=findradius(cp.origin,radius); wp; wp=wp.chain)
+                       {
+                               if(!(wp.wpflags & WAYPOINTFLAG_GENERATED))
+                               if(wp.classname=="waypoint")
+                               if(checkpvs(wp.origin,cp))
+                               {
+                                       found = true;
+                                       if(wp.cnt<bestvalue)
+                                       {
+                                               best = wp;
+                                               bestvalue = wp.cnt;
+                                       }
+                               }
+                       }
+               }
+
+               if(best)
+               {
+                       navigation_routerating(best, ratingscale, 10000);
+                       best.cnt += 1;
+
+                       self.havocbot_attack_time = 0;
+                       if(checkpvs(self.view_ofs,cp))
+                       if(checkpvs(self.view_ofs,best))
+                               self.havocbot_attack_time = time + 2;
+               }
+               else
+               {
+                       navigation_routerating(cp, ratingscale, 10000);
+               }
+               ons_debug(strcat(self.netname, " found an attackable controlpoint at ", vtos(cp.origin) ,"\n"));
+       }
+       else
+       {
+               // Should be touched
+               ons_debug(strcat(self.netname, " found a touchable controlpoint at ", vtos(cp.origin) ,"\n"));
+               found = false;
+
+               // Look for auto generated waypoint
+               if (!bot_waypoints_for_items)
+               for (wp = findradius(cp.origin,100); wp; wp = wp.chain)
+               {
+                       if(wp.classname=="waypoint")
+                       {
+                               navigation_routerating(wp, ratingscale, 10000);
+                               found = true;
+                       }
+               }
+
+               // Nothing found, rate the controlpoint itself
+               if (!found)
+                       navigation_routerating(cp, ratingscale, 10000);
+       }
+}
+
+bool havocbot_goalrating_ons_generator_attack(float ratingscale)
+{SELFPARAM();
+       entity g, wp, bestwp;
+       bool found;
+       int best;
+
+       for(g = ons_worldgeneratorlist; g; g = g.ons_worldgeneratornext)
+       {
+               if(SAME_TEAM(g, self) || g.isshielded)
+                       continue;
+
+               // Should be attacked
+               // Rate waypoints near it
+               found = false;
+               bestwp = world;
+               best = 99999999999;
+
+               for(wp=findradius(g.origin,400); wp; wp=wp.chain)
+               {
+                       if(wp.classname=="waypoint")
+                       if(checkpvs(wp.origin,g))
+                       {
+                               found = true;
+                               if(wp.cnt<best)
+                               {
+                                       bestwp = wp;
+                                       best = wp.cnt;
+                               }
+                       }
+               }
+
+               if(bestwp)
+               {
+                       ons_debug("waypoints found around generator\n");
+                       navigation_routerating(bestwp, ratingscale, 10000);
+                       bestwp.cnt += 1;
+
+                       self.havocbot_attack_time = 0;
+                       if(checkpvs(self.view_ofs,g))
+                       if(checkpvs(self.view_ofs,bestwp))
+                               self.havocbot_attack_time = time + 5;
+
+                       return true;
+               }
+               else
+               {
+                       ons_debug("generator found without waypoints around\n");
+                       // if there aren't waypoints near the generator go straight to it
+                       navigation_routerating(g, ratingscale, 10000);
+                       self.havocbot_attack_time = 0;
+                       return true;
+               }
+       }
+       return false;
+}
+
+void havocbot_role_ons_offense()
+{SELFPARAM();
+       if(self.deadflag != DEAD_NO)
+       {
+               self.havocbot_attack_time = 0;
+               havocbot_ons_reset_role(self);
+               return;
+       }
+
+       // Set the role timeout if necessary
+       if (!self.havocbot_role_timeout)
+               self.havocbot_role_timeout = time + 120;
+
+       if (time > self.havocbot_role_timeout)
+       {
+               havocbot_ons_reset_role(self);
+               return;
+       }
+
+       if(self.havocbot_attack_time>time)
+               return;
+
+       if (self.bot_strategytime < time)
+       {
+               navigation_goalrating_start();
+               havocbot_goalrating_enemyplayers(20000, self.origin, 650);
+               if(!havocbot_goalrating_ons_generator_attack(20000))
+                       havocbot_goalrating_ons_controlpoints_attack(20000);
+               havocbot_goalrating_ons_offenseitems(10000, self.origin, 10000);
+               navigation_goalrating_end();
+
+               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+       }
+}
+
+void havocbot_role_ons_assistant()
+{SELFPARAM();
+       havocbot_ons_reset_role(self);
+}
+
+void havocbot_role_ons_defense()
+{SELFPARAM();
+       havocbot_ons_reset_role(self);
+}
+
+void havocbot_ons_reset_role(entity bot)
+{SELFPARAM();
+       entity head;
+       int c = 0;
+
+       if(self.deadflag != DEAD_NO)
+               return;
+
+       bot.havocbot_ons_target = world;
+
+       // TODO: Defend control points or generator if necessary
+
+       // if there is only me on the team switch to offense
+       c = 0;
+       FOR_EACH_PLAYER(head)
+       if(SAME_TEAM(head, self))
+               ++c;
+
+       if(c==1)
+       {
+               havocbot_role_ons_setrole(bot, HAVOCBOT_ONS_ROLE_OFFENSE);
+               return;
+       }
+
+       havocbot_role_ons_setrole(bot, HAVOCBOT_ONS_ROLE_OFFENSE);
+}
+
+
+/*
+ * Find control point or generator owned by the same team self which is nearest to pos
+ * if max_dist is positive, only control points within this range will be considered
+ */
+entity ons_Nearest_ControlPoint(vector pos, float max_dist)
+{SELFPARAM();
+       entity tmp_entity, closest_target = world;
+       tmp_entity = findchain(classname, "onslaught_controlpoint");
+       while(tmp_entity)
+       {
+               if(SAME_TEAM(tmp_entity, self))
+               if(tmp_entity.iscaptured)
+               if(max_dist <= 0 || vlen(tmp_entity.origin - pos) <= max_dist)
+               if(vlen(tmp_entity.origin - pos) <= vlen(closest_target.origin - pos) || closest_target == world)
+                       closest_target = tmp_entity;
+               tmp_entity = tmp_entity.chain;
+       }
+       tmp_entity = findchain(classname, "onslaught_generator");
+       while(tmp_entity)
+       {
+               if(SAME_TEAM(tmp_entity, self))
+               if(max_dist <= 0 || vlen(tmp_entity.origin - pos) < max_dist)
+               if(vlen(tmp_entity.origin - pos) <= vlen(closest_target.origin - pos) || closest_target == world)
+                       closest_target = tmp_entity;
+               tmp_entity = tmp_entity.chain;
+       }
+
+       return closest_target;
+}
+
+/*
+ * Find control point or generator owned by the same team self which is nearest to pos
+ * if max_dist is positive, only control points within this range will be considered
+ * This function only check distances on the XY plane, disregarding Z
+ */
+entity ons_Nearest_ControlPoint_2D(vector pos, float max_dist)
+{SELFPARAM();
+       entity tmp_entity, closest_target = world;
+       vector delta;
+       float smallest_distance = 0, distance;
+
+       tmp_entity = findchain(classname, "onslaught_controlpoint");
+       while(tmp_entity)
+       {
+               delta = tmp_entity.origin - pos;
+               delta_z = 0;
+               distance = vlen(delta);
+
+               if(SAME_TEAM(tmp_entity, self))
+               if(tmp_entity.iscaptured)
+               if(max_dist <= 0 || distance <= max_dist)
+               if(closest_target == world || distance <= smallest_distance )
+               {
+                       closest_target = tmp_entity;
+                       smallest_distance = distance;
+               }
+
+               tmp_entity = tmp_entity.chain;
+       }
+       tmp_entity = findchain(classname, "onslaught_generator");
+       while(tmp_entity)
+       {
+               delta = tmp_entity.origin - pos;
+               delta_z = 0;
+               distance = vlen(delta);
+
+               if(SAME_TEAM(tmp_entity, self))
+               if(max_dist <= 0 || distance <= max_dist)
+               if(closest_target == world || distance <= smallest_distance )
+               {
+                       closest_target = tmp_entity;
+                       smallest_distance = distance;
+               }
+
+               tmp_entity = tmp_entity.chain;
+       }
+
+       return closest_target;
+}
+/**
+ * find the number of control points and generators in the same team as self
+ */
+int ons_Count_SelfControlPoints()
+{SELFPARAM();
+       entity tmp_entity;
+       tmp_entity = findchain(classname, "onslaught_controlpoint");
+       int n = 0;
+       while(tmp_entity)
+       {
+               if(SAME_TEAM(tmp_entity, self))
+               if(tmp_entity.iscaptured)
+                       n++;
+               tmp_entity = tmp_entity.chain;
+       }
+       tmp_entity = findchain(classname, "onslaught_generator");
+       while(tmp_entity)
+       {
+               if(SAME_TEAM(tmp_entity, self))
+                       n++;
+               tmp_entity = tmp_entity.chain;
+       }
+       return n;
+}
+
+/**
+ * Teleport player to a random position near tele_target
+ * if tele_effects is true, teleport sound+particles are created
+ * return false on failure
+ */
+bool ons_Teleport(entity player, entity tele_target, float range, bool tele_effects)
+{
+       if ( !tele_target )
+               return false;
+
+       int i;
+       vector loc;
+       float theta;
+       // narrow the range for each iteration to increase chances that a spawnpoint
+       // can be found even if there's little room around the control point
+       float iteration_scale = 1;
+       for(i = 0; i < 16; ++i)
+       {
+               iteration_scale -= i / 16;
+               theta = random() * 2 * M_PI;
+               loc_y = sin(theta);
+               loc_x = cos(theta);
+               loc_z = 0;
+               loc *= random() * range * iteration_scale;
+
+               loc += tele_target.origin + '0 0 128' * iteration_scale;
+
+               tracebox(loc, PL_MIN, PL_MAX, loc, MOVE_NORMAL, player);
+               if(trace_fraction == 1.0 && !trace_startsolid)
+               {
+                       traceline(tele_target.origin, loc, MOVE_NOMONSTERS, tele_target); // double check to make sure we're not spawning outside the world
+                       if(trace_fraction == 1.0 && !trace_startsolid)
+                       {
+                               if ( tele_effects )
+                               {
+                                       Send_Effect(EFFECT_TELEPORT, player.origin, '0 0 0', 1);
+                                       sound (player, CH_TRIGGER, SND_TELEPORT, VOL_BASE, ATTEN_NORM);
+                               }
+                               setorigin(player, loc);
+                               player.angles = '0 1 0' * ( theta * RAD2DEG + 180 );
+                               makevectors(player.angles);
+                               player.fixangle = true;
+                               player.teleport_antispam = time + autocvar_g_onslaught_teleport_wait;
+
+                               if ( tele_effects )
+                                       Send_Effect(EFFECT_TELEPORT, player.origin + v_forward * 32, '0 0 0', 1);
+                               return true;
+                       }
+               }
+       }
+
+       return false;
+}
+
+// ==============
+// Hook Functions
+// ==============
+
+MUTATOR_HOOKFUNCTION(ons, reset_map_global)
+{SELFPARAM();
+       entity e;
+       FOR_EACH_PLAYER(e)
+       {
+               e.ons_roundlost = false;
+               e.ons_deathloc = '0 0 0';
+               WITH(entity, self, e, PutClientInServer());
+       }
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ons, ClientDisconnect)
+{SELFPARAM();
+       self.ons_deathloc = '0 0 0';
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ons, MakePlayerObserver)
+{SELFPARAM();
+       self.ons_deathloc = '0 0 0';
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ons, PlayerSpawn)
+{SELFPARAM();
+       if(!round_handler_IsRoundStarted())
+       {
+               self.player_blocked = true;
+               return false;
+       }
+
+       entity l;
+       for(l = ons_worldgeneratorlist; l; l = l.ons_worldgeneratornext)
+       {
+               l.sprite.SendFlags |= 16;
+       }
+       for(l = ons_worldcplist; l; l = l.ons_worldcpnext)
+       {
+               l.sprite.SendFlags |= 16;
+       }
+
+       if(ons_stalemate) { Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_OVERTIME_CONTROLPOINT); }
+
+       if ( autocvar_g_onslaught_spawn_choose )
+       if ( self.ons_spawn_by )
+       if ( ons_Teleport(self,self.ons_spawn_by,autocvar_g_onslaught_teleport_radius,false) )
+       {
+               self.ons_spawn_by = world;
+               return false;
+       }
+
+       if(autocvar_g_onslaught_spawn_at_controlpoints)
+       if(random() <= autocvar_g_onslaught_spawn_at_controlpoints_chance)
+       {
+               float random_target = autocvar_g_onslaught_spawn_at_controlpoints_random;
+               entity tmp_entity, closest_target = world;
+               vector spawn_loc = self.ons_deathloc;
+
+               // new joining player or round reset, don't bother checking
+               if(spawn_loc == '0 0 0') { return false; }
+
+               if(random_target) { RandomSelection_Init(); }
+
+               for(tmp_entity = ons_worldcplist; tmp_entity; tmp_entity = tmp_entity.ons_worldcpnext)
+               {
+                       if(SAME_TEAM(tmp_entity, self))
+                       if(random_target)
+                               RandomSelection_Add(tmp_entity, 0, string_null, 1, 1);
+                       else if(vlen(tmp_entity.origin - spawn_loc) <= vlen(closest_target.origin - spawn_loc) || closest_target == world)
+                               closest_target = tmp_entity;
+               }
+
+               if(random_target) { closest_target = RandomSelection_chosen_ent; }
+
+               if(closest_target)
+               {
+                       float i;
+                       vector loc;
+                       float iteration_scale = 1;
+                       for(i = 0; i < 10; ++i)
+                       {
+                               iteration_scale -= i / 10;
+                               loc = closest_target.origin + '0 0 96' * iteration_scale;
+                               loc += ('0 1 0' * random()) * 128 * iteration_scale;
+                               tracebox(loc, PL_MIN, PL_MAX, loc, MOVE_NORMAL, self);
+                               if(trace_fraction == 1.0 && !trace_startsolid)
+                               {
+                                       traceline(closest_target.origin, loc, MOVE_NOMONSTERS, closest_target); // double check to make sure we're not spawning outside the world
+                                       if(trace_fraction == 1.0 && !trace_startsolid)
+                                       {
+                                               setorigin(self, loc);
+                                               self.angles = normalize(loc - closest_target.origin) * RAD2DEG;
+                                               return false;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       if(autocvar_g_onslaught_spawn_at_generator)
+       if(random() <= autocvar_g_onslaught_spawn_at_generator_chance)
+       {
+               float random_target = autocvar_g_onslaught_spawn_at_generator_random;
+               entity tmp_entity, closest_target = world;
+               vector spawn_loc = self.ons_deathloc;
+
+               // new joining player or round reset, don't bother checking
+               if(spawn_loc == '0 0 0') { return false; }
+
+               if(random_target) { RandomSelection_Init(); }
+
+               for(tmp_entity = ons_worldgeneratorlist; tmp_entity; tmp_entity = tmp_entity.ons_worldgeneratornext)
+               {
+                       if(random_target)
+                               RandomSelection_Add(tmp_entity, 0, string_null, 1, 1);
+                       else
+                       {
+                               if(SAME_TEAM(tmp_entity, self))
+                               if(vlen(tmp_entity.origin - spawn_loc) <= vlen(closest_target.origin - spawn_loc) || closest_target == world)
+                                       closest_target = tmp_entity;
+                       }
+               }
+
+               if(random_target) { closest_target = RandomSelection_chosen_ent; }
+
+               if(closest_target)
+               {
+                       float i;
+                       vector loc;
+                       float iteration_scale = 1;
+                       for(i = 0; i < 10; ++i)
+                       {
+                               iteration_scale -= i / 10;
+                               loc = closest_target.origin + '0 0 128' * iteration_scale;
+                               loc += ('0 1 0' * random()) * 256 * iteration_scale;
+                               tracebox(loc, PL_MIN, PL_MAX, loc, MOVE_NORMAL, self);
+                               if(trace_fraction == 1.0 && !trace_startsolid)
+                               {
+                                       traceline(closest_target.origin, loc, MOVE_NOMONSTERS, closest_target); // double check to make sure we're not spawning outside the world
+                                       if(trace_fraction == 1.0 && !trace_startsolid)
+                                       {
+                                               setorigin(self, loc);
+                                               self.angles = normalize(loc - closest_target.origin) * RAD2DEG;
+                                               return false;
+                                       }
+                               }
+                       }
+               }
+       }
+
+    return false;
+}
+
+MUTATOR_HOOKFUNCTION(ons, PlayerDies)
+{SELFPARAM();
+       frag_target.ons_deathloc = frag_target.origin;
+       entity l;
+       for(l = ons_worldgeneratorlist; l; l = l.ons_worldgeneratornext)
+       {
+               l.sprite.SendFlags |= 16;
+       }
+       for(l = ons_worldcplist; l; l = l.ons_worldcpnext)
+       {
+               l.sprite.SendFlags |= 16;
+       }
+
+       if ( autocvar_g_onslaught_spawn_choose )
+       if ( ons_Count_SelfControlPoints() > 1 )
+               stuffcmd(self, "qc_cmd_cl hud clickradar\n");
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ons, MonsterMove)
+{SELFPARAM();
+       entity e = find(world, targetname, self.target);
+       if (e != world)
+               self.team = e.team;
+
+       return false;
+}
+
+void ons_MonsterSpawn_Delayed()
+{SELFPARAM();
+       entity e, own = self.owner;
+
+       if(!own) { remove(self); return; }
+
+       if(own.targetname)
+       {
+               e = find(world, target, own.targetname);
+               if(e != world)
+               {
+                       own.team = e.team;
+
+                       activator = e;
+                       own.use();
+               }
+       }
+
+       remove(self);
+}
+
+MUTATOR_HOOKFUNCTION(ons, MonsterSpawn)
+{SELFPARAM();
+       entity e = spawn();
+       e.owner = self;
+       InitializeEntity(e, ons_MonsterSpawn_Delayed, INITPRIO_FINDTARGET);
+
+       return false;
+}
+
+void ons_TurretSpawn_Delayed()
+{SELFPARAM();
+       entity e, own = self.owner;
+
+       if(!own) { remove(self); return; }
+
+       if(own.targetname)
+       {
+               e = find(world, target, own.targetname);
+               if(e != world)
+               {
+                       own.team = e.team;
+                       own.active = ACTIVE_NOT;
+
+                       activator = e;
+                       own.use();
+               }
+       }
+
+       remove(self);
+}
+
+MUTATOR_HOOKFUNCTION(ons, TurretSpawn)
+{SELFPARAM();
+       entity e = spawn();
+       e.owner = self;
+       InitializeEntity(e, ons_TurretSpawn_Delayed, INITPRIO_FINDTARGET);
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ons, HavocBot_ChooseRole)
+{SELFPARAM();
+       havocbot_ons_reset_role(self);
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(ons, GetTeamCount)
+{
+       // onslaught is special
+       for(entity tmp_entity = ons_worldgeneratorlist; tmp_entity; tmp_entity = tmp_entity.ons_worldgeneratornext)
+       {
+               switch(tmp_entity.team)
+               {
+                       case NUM_TEAM_1: c1 = 0; break;
+                       case NUM_TEAM_2: c2 = 0; break;
+                       case NUM_TEAM_3: c3 = 0; break;
+                       case NUM_TEAM_4: c4 = 0; break;
+               }
+       }
+
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(ons, SpectateCopy)
+{SELFPARAM();
+       self.ons_roundlost = other.ons_roundlost; // make spectators see it too
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ons, SV_ParseClientCommand)
+{SELFPARAM();
+       if(MUTATOR_RETURNVALUE) // command was already handled?
+               return false;
+
+       if ( cmd_name == "ons_spawn" )
+       {
+               vector pos = self.origin;
+               if(cmd_argc > 1)
+                       pos_x = stof(argv(1));
+               if(cmd_argc > 2)
+                       pos_y = stof(argv(2));
+               if(cmd_argc > 3)
+                       pos_z = stof(argv(3));
+
+               if ( IS_PLAYER(self) )
+               {
+                       if ( !self.frozen )
+                       {
+                               entity source_point = ons_Nearest_ControlPoint(self.origin, autocvar_g_onslaught_teleport_radius);
+
+                               if ( !source_point && self.health > 0 )
+                               {
+                                       sprint(self, "\nYou need to be next to a control point\n");
+                                       return 1;
+                               }
+
+
+                               entity closest_target = ons_Nearest_ControlPoint_2D(pos, autocvar_g_onslaught_click_radius);
+
+                               if ( closest_target == world )
+                               {
+                                       sprint(self, "\nNo control point found\n");
+                                       return 1;
+                               }
+
+                               if ( self.health <= 0 )
+                               {
+                                       self.ons_spawn_by = closest_target;
+                                       self.respawn_flags = self.respawn_flags | RESPAWN_FORCE;
+                               }
+                               else
+                               {
+                                       if ( source_point == closest_target )
+                                       {
+                                               sprint(self, "\nTeleporting to the same point\n");
+                                               return 1;
+                                       }
+
+                                       if ( !ons_Teleport(self,closest_target,autocvar_g_onslaught_teleport_radius,true) )
+                                               sprint(self, "\nUnable to teleport there\n");
+                               }
+
+                               return 1;
+                       }
+
+                       sprint(self, "\nNo teleportation for you\n");
+               }
+
+               return 1;
+       }
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(ons, PlayerUseKey)
+{SELFPARAM();
+       if(MUTATOR_RETURNVALUE || gameover) { return false; }
+
+       if((time > self.teleport_antispam) && (self.deadflag == DEAD_NO) && !self.vehicle)
+       {
+               entity source_point = ons_Nearest_ControlPoint(self.origin, autocvar_g_onslaught_teleport_radius);
+               if ( source_point )
+               {
+                       stuffcmd(self, "qc_cmd_cl hud clickradar\n");
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ons, PlayHitsound)
+{
+       return (frag_victim.classname == "onslaught_generator" && !frag_victim.isshielded)
+               || (frag_victim.classname == "onslaught_controlpoint_icon" && !frag_victim.owner.isshielded);
+}
+
+MUTATOR_HOOKFUNCTION(ons, SendWaypoint)
+{
+       if(wp_sendflags & 16)
+       {
+               if(self.owner.classname == "onslaught_controlpoint")
+               {
+                       entity wp_owner = self.owner;
+                       entity e = WaypointSprite_getviewentity(wp_sendto);
+                       if(SAME_TEAM(e, wp_owner) && wp_owner.goalentity.health >= wp_owner.goalentity.max_health) { wp_flag |= 2; }
+                       if(!ons_ControlPoint_Attackable(wp_owner, e.team)) { wp_flag |= 2; }
+               }
+               if(self.owner.classname == "onslaught_generator")
+               {
+                       entity wp_owner = self.owner;
+                       if(wp_owner.isshielded && wp_owner.health >= wp_owner.max_health) { wp_flag |= 2; }
+                       if(wp_owner.health <= 0) { wp_flag |= 2; }
+               }
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ons, TurretValidateTarget)
+{
+       if(substring(turret_target.classname, 0, 10) == "onslaught_") // don't attack onslaught targets, that's the player's job!
+       {
+               ret_float = -3;
+               return true;
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ons, TurretThink)
+{
+       // ONS uses somewhat backwards linking.
+       if(self.target)
+       {
+               entity e = find(world, targetname, self.target);
+               if (e != world)
+                       self.team = e.team;
+       }
+
+       if(self.team != self.tur_head.team)
+               turret_respawn();
+
+       return false;
+}
+
+
+// ==========
+// Spawnfuncs
+// ==========
+
+/*QUAKED spawnfunc_onslaught_link (0 .5 .8) (-16 -16 -16) (16 16 16)
+  Link between control points.
+
+  This entity targets two different spawnfunc_onslaught_controlpoint or spawnfunc_onslaught_generator entities, and suppresses shielding on both if they are owned by different teams.
+
+keys:
+"target" - first control point.
+"target2" - second control point.
+ */
+spawnfunc(onslaught_link)
+{
+       if(!g_onslaught) { remove(self); return; }
+
+       if (self.target == "" || self.target2 == "")
+               objerror("target and target2 must be set\n");
+
+       self.ons_worldlinknext = ons_worldlinklist; // link into ons_worldlinklist
+       ons_worldlinklist = self;
+
+       InitializeEntity(self, ons_DelayedLinkSetup, INITPRIO_FINDTARGET);
+       Net_LinkEntity(self, false, 0, ons_Link_Send);
+}
+
+/*QUAKED spawnfunc_onslaught_controlpoint (0 .5 .8) (-32 -32 0) (32 32 128)
+  Control point. Be sure to give this enough clearance so that the shootable part has room to exist
+
+  This should link to an spawnfunc_onslaught_controlpoint entity or spawnfunc_onslaught_generator entity.
+
+keys:
+"targetname" - name that spawnfunc_onslaught_link entities will use to target this.
+"target" - target any entities that are tied to this control point, such as vehicles and buildable structure entities.
+"message" - name of this control point (should reflect the location in the map, such as "center bridge", "north tower", etc)
+ */
+
+spawnfunc(onslaught_controlpoint)
+{
+       if(!g_onslaught) { remove(self); return; }
+
+       ons_ControlPoint_Setup(self);
+}
+
+/*QUAKED spawnfunc_onslaught_generator (0 .5 .8) (-32 -32 -24) (32 32 64)
+  Base generator.
+
+  spawnfunc_onslaught_link entities can target this.
+
+keys:
+"team" - team that owns this generator (5 = red, 14 = blue, etc), MUST BE SET.
+"targetname" - name that spawnfunc_onslaught_link entities will use to target this.
+ */
+spawnfunc(onslaught_generator)
+{
+       if(!g_onslaught) { remove(self); return; }
+       if(!self.team) { objerror("team must be set"); }
+
+       ons_GeneratorSetup(self);
+}
+
+// scoreboard setup
+void ons_ScoreRules()
+{
+       CheckAllowedTeams(world);
+       ScoreRules_basics(((c4>=0) ? 4 : (c3>=0) ? 3 : 2), SFL_SORT_PRIO_PRIMARY, 0, true);
+       ScoreInfo_SetLabel_TeamScore  (ST_ONS_CAPS,     "destroyed", SFL_SORT_PRIO_PRIMARY);
+       ScoreInfo_SetLabel_PlayerScore(SP_ONS_CAPS,     "caps",      SFL_SORT_PRIO_SECONDARY);
+       ScoreInfo_SetLabel_PlayerScore(SP_ONS_TAKES,    "takes",     0);
+       ScoreRules_basics_end();
+}
+
+void ons_DelayedInit() // Do this check with a delay so we can wait for teams to be set up
+{
+       ons_ScoreRules();
+
+       round_handler_Spawn(Onslaught_CheckPlayers, Onslaught_CheckWinner, Onslaught_RoundStart);
+       round_handler_Init(5, autocvar_g_onslaught_warmup, autocvar_g_onslaught_round_timelimit);
+}
+
+void ons_Initialize()
+{
+       g_onslaught = true;
+       ons_captureshield_force = autocvar_g_onslaught_shield_force;
+
+       addstat(STAT_ROUNDLOST, AS_INT, ons_roundlost);
+
+       InitializeEntity(world, ons_DelayedInit, INITPRIO_GAMETYPE);
+}
+
+#endif
diff --git a/qcsrc/server/mutators/mutator/gamemode_race.qc b/qcsrc/server/mutators/mutator/gamemode_race.qc
new file mode 100644 (file)
index 0000000..cc250df
--- /dev/null
@@ -0,0 +1,469 @@
+#ifndef GAMEMODE_RACE_H
+#define GAMEMODE_RACE_H
+
+void rc_SetLimits();
+void race_Initialize();
+
+REGISTER_MUTATOR(rc, false)
+{
+       rc_SetLimits();
+
+       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
+       {
+               LOG_INFO("This is a game type and it cannot be removed at runtime.");
+               return -1;
+       }
+
+       return 0;
+}
+
+float race_teams;
+
+// scores
+const float ST_RACE_LAPS = 1;
+const float SP_RACE_LAPS = 4;
+const float SP_RACE_TIME = 5;
+const float SP_RACE_FASTEST = 6;
+#endif
+
+#ifdef IMPLEMENTATION
+
+#include "../../race.qh"
+
+#define autocvar_g_race_laps_limit cvar("g_race_laps_limit")
+float autocvar_g_race_qualifying_timelimit;
+float autocvar_g_race_qualifying_timelimit_override;
+int autocvar_g_race_teams;
+
+// legacy bot roles
+.float race_checkpoint;
+void havocbot_role_race()
+{SELFPARAM();
+       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(rc, PlayerPhysics)
+{SELFPARAM();
+       self.race_movetime_frac += PHYS_INPUT_TIMELENGTH;
+       float f = floor(self.race_movetime_frac);
+       self.race_movetime_frac -= f;
+       self.race_movetime_count += f;
+       self.race_movetime = self.race_movetime_frac + self.race_movetime_count;
+
+#ifdef SVQC
+       if(IS_PLAYER(self))
+       {
+               if (self.race_penalty)
+                       if (time > self.race_penalty)
+                               self.race_penalty = 0;
+               if(self.race_penalty)
+               {
+                       self.velocity = '0 0 0';
+                       self.movetype = MOVETYPE_NONE;
+                       self.disableclientprediction = 2;
+               }
+       }
+#endif
+
+       // 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(rc, reset_map_global)
+{
+       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(rc, PlayerPreThink)
+{SELFPARAM();
+       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(rc, ClientConnect)
+{SELFPARAM();
+       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(rc, MakePlayerObserver)
+{SELFPARAM();
+       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(rc, PlayerSpawn)
+{SELFPARAM();
+       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(rc, PutClientInServer)
+{SELFPARAM();
+       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(rc, PlayerDies)
+{SELFPARAM();
+       self.respawn_flags |= RESPAWN_FORCE;
+       race_AbandonRaceCheck(self);
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(rc, HavocBot_ChooseRole)
+{SELFPARAM();
+       self.havocbot_role = havocbot_role_race;
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(rc, GetPressedKeys)
+{SELFPARAM();
+       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);
+               }
+       }
+
+       if (!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 = RACE_RECORD;
+                       race_send_speedaward(MSG_ALL);
+                       speedaward_lastsent = speedaward_speed;
+                       if (speedaward_speed > speedaward_alltimebest && speedaward_uid != "")
+                       {
+                               speedaward_alltimebest = speedaward_speed;
+                               speedaward_alltimebest_holder = speedaward_holder;
+                               speedaward_alltimebest_uid = speedaward_uid;
+                               db_put(ServerProgsDB, strcat(GetMapname(), rr, "speed/speed"), ftos(speedaward_alltimebest));
+                               db_put(ServerProgsDB, strcat(GetMapname(), rr, "speed/crypto_idfp"), speedaward_alltimebest_uid);
+                               race_send_speedaward_alltimebest(MSG_ALL);
+                       }
+               }
+       }
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(rc, ForbidPlayerScore_Clear)
+{
+       if(g_race_qualifying)
+               return true; // in qualifying, you don't lose score by observing
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(rc, GetTeamCount, CBC_ORDER_EXCLUSIVE)
+{
+       ret_float = race_teams;
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(rc, Scores_CountFragsRemaining)
+{
+       // announce remaining frags if not in qualifying mode
+       if(!g_race_qualifying)
+               return true;
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(rc, GetRecords)
+{
+       for(int i = record_page * 200; i < MapInfo_count && i < record_page * 200 + 200; ++i)
+       {
+               if(MapInfo_Get_ByID(i))
+               {
+                       float r = race_readTime(MapInfo_Map_bspname, 1);
+
+                       if(!r)
+                               continue;
+
+                       string h = race_readName(MapInfo_Map_bspname, 1);
+                       ret_string = strcat(ret_string, strpad(32, MapInfo_Map_bspname), " ", strpad(-8, TIME_ENCODED_TOSTRING(r)), " ", h, "\n");
+               }
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(rc, FixClientCvars)
+{
+       stuffcmd(fix_client, "cl_cmd settemp cl_movecliptokeyboard 2\n");
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(rc, CheckRules_World)
+{
+       if(g_race_qualifying == 2 && checkrules_timelimit >= 0)
+       {
+               ret_float = WinningCondition_QualifyingThenRace(checkrules_fraglimit);
+               return true;
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(rc, ReadLevelCvars)
+{
+       if(g_race_qualifying == 2)
+               warmup_stage = 0;
+       return false;
+}
+
+void race_Initialize()
+{
+       race_ScoreRules();
+       if(g_race_qualifying == 2)
+               warmup_stage = 0;
+}
+
+void rc_SetLimits()
+{
+       int fraglimit_override, leadlimit_override;
+       float timelimit_override, qualifying_override;
+
+       if(autocvar_g_race_teams)
+       {
+               ActivateTeamplay();
+               race_teams = bound(2, autocvar_g_race_teams, 4);
+               have_team_spawns = -1; // request team spawns
+       }
+       else
+               race_teams = 0;
+
+       qualifying_override = autocvar_g_race_qualifying_timelimit_override;
+       fraglimit_override = autocvar_g_race_laps_limit;
+       leadlimit_override = 0; // currently not supported by race
+       timelimit_override = -1; // use default if we don't set it below
+
+       // we need to find out the correct value for g_race_qualifying
+       float want_qualifying = ((qualifying_override >= 0) ? qualifying_override : autocvar_g_race_qualifying_timelimit) > 0;
+
+       if(autocvar_g_campaign)
+       {
+               g_race_qualifying = 1;
+               independent_players = 1;
+       }
+       else if(!autocvar_g_campaign && want_qualifying)
+       {
+               g_race_qualifying = 2;
+               independent_players = 1;
+               race_fraglimit = (race_fraglimit >= 0) ? fraglimit_override : autocvar_fraglimit;
+               race_leadlimit = (race_leadlimit >= 0) ? leadlimit_override : autocvar_leadlimit;
+               race_timelimit = (race_timelimit >= 0) ? timelimit_override : autocvar_timelimit;
+               fraglimit_override = 0;
+               leadlimit_override = 0;
+               timelimit_override = autocvar_g_race_qualifying_timelimit;
+       }
+       else
+               g_race_qualifying = 0;
+
+       SetLimits(fraglimit_override, leadlimit_override, timelimit_override, qualifying_override);
+}
+
+#endif
diff --git a/qcsrc/server/mutators/mutator/gamemode_tdm.qc b/qcsrc/server/mutators/mutator/gamemode_tdm.qc
new file mode 100644 (file)
index 0000000..49ec0ac
--- /dev/null
@@ -0,0 +1,99 @@
+#ifndef GAMEMODE_TDM_H
+#define GAMEMODE_TDM_H
+
+int autocvar_g_tdm_point_limit;
+int autocvar_g_tdm_point_leadlimit;
+bool autocvar_g_tdm_team_spawns;
+void tdm_DelayedInit();
+
+REGISTER_MUTATOR(tdm, false)
+{
+       ActivateTeamplay();
+       SetLimits(autocvar_g_tdm_point_limit, autocvar_g_tdm_point_leadlimit, -1, -1);
+       if (autocvar_g_tdm_team_spawns)
+               have_team_spawns = -1; // request team spawns
+
+       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
+       {
+               LOG_INFO("This is a game type and it cannot be removed at runtime.");
+               return -1;
+       }
+
+       return 0;
+}
+
+#endif
+
+#ifdef IMPLEMENTATION
+int autocvar_g_tdm_teams;
+int autocvar_g_tdm_teams_override;
+
+/*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)... */
+spawnfunc(tdm_team)
+{
+       if(!g_tdm || !self.cnt) { 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 this = new(tdm_team);
+       this.netname = teamname;
+       this.cnt = teamcolor;
+       this.spawnfunc_checked = true;
+       WITH(entity, self, this, spawnfunc_tdm_team(this));
+}
+
+void tdm_DelayedInit()
+{
+       // if no teams are found, spawn defaults
+       if(find(world, classname, "tdm_team") == world)
+       {
+               LOG_INFO("No ""tdm_team"" entities found on this map, creating them anyway.\n");
+
+               int 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, CBC_ORDER_EXCLUSIVE)
+{
+       ret_string = "tdm_team";
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(tdm, Scores_CountFragsRemaining)
+{
+       // announce remaining frags
+       return true;
+}
+
+#endif
diff --git a/qcsrc/server/mutators/mutator/mutator_bloodloss.qc b/qcsrc/server/mutators/mutator/mutator_bloodloss.qc
new file mode 100644 (file)
index 0000000..ca37166
--- /dev/null
@@ -0,0 +1,45 @@
+#ifdef IMPLEMENTATION
+REGISTER_MUTATOR(bloodloss, cvar("g_bloodloss"));
+
+.float bloodloss_timer;
+
+MUTATOR_HOOKFUNCTION(bloodloss, PlayerPreThink)
+{SELFPARAM();
+       if(IS_PLAYER(self))
+       if(self.health <= autocvar_g_bloodloss && self.deadflag == DEAD_NO)
+       {
+               self.BUTTON_CROUCH = true;
+
+               if(time >= self.bloodloss_timer)
+               {
+                       if(self.vehicle)
+                               vehicles_exit(VHEF_RELEASE);
+                       if(self.event_damage)
+                               self.event_damage(self, self, 1, DEATH_ROT.m_id, self.origin, '0 0 0');
+                       self.bloodloss_timer = time + 0.5 + random() * 0.5;
+               }
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(bloodloss, PlayerJump)
+{SELFPARAM();
+       if(self.health <= autocvar_g_bloodloss)
+               return true;
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(bloodloss, BuildMutatorsString)
+{
+       ret_string = strcat(ret_string, ":bloodloss");
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(bloodloss, BuildMutatorsPrettyString)
+{
+       ret_string = strcat(ret_string, ", Blood loss");
+       return false;
+}
+#endif
diff --git a/qcsrc/server/mutators/mutator/mutator_breakablehook.qc b/qcsrc/server/mutators/mutator/mutator_breakablehook.qc
new file mode 100644 (file)
index 0000000..cb9463b
--- /dev/null
@@ -0,0 +1,29 @@
+#ifdef IMPLEMENTATION
+#include "../../../common/deathtypes/all.qh"
+#include "../../g_hook.qh"
+
+REGISTER_MUTATOR(breakablehook, cvar("g_breakablehook"));
+
+bool autocvar_g_breakablehook; // allow toggling mid match?
+bool autocvar_g_breakablehook_owner;
+
+MUTATOR_HOOKFUNCTION(breakablehook, PlayerDamage_Calculate)
+{
+       if(frag_target.classname == "grapplinghook")
+       {
+               if((!autocvar_g_breakablehook)
+               || (!autocvar_g_breakablehook_owner && frag_attacker == frag_target.realowner)
+                       ) { frag_damage = 0; }
+
+               // hurt the owner of the hook
+               if(DIFF_TEAM(frag_attacker, frag_target.realowner))
+               {
+                       Damage (frag_target.realowner, frag_attacker, frag_attacker, 5, WEP_HOOK.m_id | HITTYPE_SPLASH, frag_target.realowner.origin, '0 0 0');
+                       RemoveGrapplingHook(frag_target.realowner);
+                       return false; // dead
+               }
+       }
+
+       return false;
+}
+#endif
diff --git a/qcsrc/server/mutators/mutator/mutator_buffs.qc b/qcsrc/server/mutators/mutator/mutator_buffs.qc
new file mode 100644 (file)
index 0000000..4f0758f
--- /dev/null
@@ -0,0 +1,1000 @@
+#ifndef MUTATOR_BUFFS_H
+#define MUTATOR_BUFFS_H
+
+// ammo
+.float buff_ammo_prev_infitems;
+.int buff_ammo_prev_clipload;
+// invisible
+.float buff_invisible_prev_alpha;
+// flight
+.float buff_flight_prev_gravity;
+// disability
+.float buff_disability_time;
+.float buff_disability_effect_time;
+// common buff variables
+.float buff_effect_delay;
+
+// buff definitions
+.float buff_active;
+.float buff_activetime;
+.float buff_activetime_updated;
+.entity buff_waypoint;
+.int oldbuffs; // for updating effects
+.entity buff_model; // controls effects (TODO: make csqc)
+
+const vector BUFF_MIN = ('-16 -16 -20');
+const vector BUFF_MAX = ('16 16 20');
+
+// client side options
+.float cvar_cl_buffs_autoreplace;
+#endif
+
+#ifdef IMPLEMENTATION
+
+#include "../../../common/triggers/target/music.qh"
+#include "../../../common/gamemodes/all.qh"
+#include "../../../common/buffs/all.qh"
+
+.float buff_time;
+void buffs_DelayedInit();
+
+REGISTER_MUTATOR(buffs, cvar("g_buffs"))
+{
+       MUTATOR_ONADD
+       {
+               addstat(STAT_BUFFS, AS_INT, buffs);
+               addstat(STAT_BUFF_TIME, AS_FLOAT, buff_time);
+
+               InitializeEntity(world, buffs_DelayedInit, INITPRIO_FINDTARGET);
+       }
+}
+
+entity buff_FirstFromFlags(int _buffs)
+{
+       if (flags)
+       {
+               FOREACH(Buffs, it.m_itemid & _buffs, LAMBDA(return it));
+       }
+       return BUFF_Null;
+}
+
+bool buffs_BuffModel_Customize()
+{SELFPARAM();
+       entity player, myowner;
+       bool 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(MUTATOR_CALLHOOK(BuffModel_Customize, self, player))
+               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;
+}
+
+void buffs_BuffModel_Spawn(entity player)
+{
+       player.buff_model = spawn();
+       setmodel(player.buff_model, MDL_BUFF);
+       setsize(player.buff_model, '0 0 -40', '0 0 40');
+       setattachment(player.buff_model, player, "");
+       setorigin(player.buff_model, '0 0 1' * (player.buff_model.maxs.z * 1));
+       player.buff_model.owner = player;
+       player.buff_model.scale = 0.7;
+       player.buff_model.pflags = PFLAGS_FULLDYNAMIC;
+       player.buff_model.light_lev = 200;
+       player.buff_model.customizeentityforclient = buffs_BuffModel_Customize;
+}
+
+vector buff_GlowColor(entity buff)
+{
+       //if(buff.team) { return Team_ColorRGB(buff.team); }
+       return buff.m_color;
+}
+
+void buff_Effect(entity player, string eff)
+{SELFPARAM();
+       if(!autocvar_g_buffs_effects) { return; }
+
+       if(time >= self.buff_effect_delay)
+       {
+               Send_Effect_(eff, player.origin + ((player.mins + player.maxs) * 0.5), '0 0 0', 1);
+               self.buff_effect_delay = time + 0.05; // prevent spam
+       }
+}
+
+// buff item
+float buff_Waypoint_visible_for_player(entity plr)
+{SELFPARAM();
+       if(!self.owner.buff_active && !self.owner.buff_activetime)
+               return false;
+
+       if (plr.buffs)
+       {
+               return plr.cvar_cl_buffs_autoreplace == false || plr.buffs != self.owner.buffs;
+       }
+
+       return WaypointSprite_visible_for_player(plr);
+}
+
+void buff_Waypoint_Spawn(entity e)
+{
+       entity buff = buff_FirstFromFlags(e.buffs);
+       entity wp = WaypointSprite_Spawn(WP_Buff, 0, autocvar_g_buffs_waypoint_distance, e, '0 0 1' * e.maxs.z, world, e.team, e, buff_waypoint, true, RADARICON_Buff);
+       wp.wp_extra = buff.m_id;
+       WaypointSprite_UpdateTeamRadar(e.buff_waypoint, RADARICON_Buff, e.glowmod);
+       e.buff_waypoint.waypointsprite_visible_for_player = buff_Waypoint_visible_for_player;
+}
+
+void buff_SetCooldown(float cd)
+{SELFPARAM();
+       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)
+{SELFPARAM();
+       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;
+
+       Send_Effect(EFFECT_ELECTRO_COMBO, oldbufforigin + ((ent.mins + ent.maxs) * 0.5), '0 0 0', 1);
+       Send_Effect(EFFECT_ELECTRO_COMBO, CENTER_OR_VIEWOFS(ent), '0 0 0', 1);
+
+       WaypointSprite_Ping(ent.buff_waypoint);
+
+       sound(ent, CH_TRIGGER, SND_KA_RESPAWN, VOL_BASE, ATTEN_NONE); // ATTEN_NONE (it's a sound intended to be heard anywhere)
+}
+
+void buff_Touch()
+{SELFPARAM();
+       if(gameover) { return; }
+
+       if(ITEM_TOUCH_NEEDKILL())
+       {
+               buff_Respawn(self);
+               return;
+       }
+
+       if((self.team && DIFF_TEAM(other, self))
+       || (other.frozen)
+       || (other.vehicle)
+       || (!self.buff_active)
+       )
+       {
+               // can't touch this
+               return;
+       }
+
+       if(MUTATOR_CALLHOOK(BuffTouch, self, other))
+               return;
+
+       if(!IS_PLAYER(other))
+               return; // incase mutator changed other
+
+       if (other.buffs)
+       {
+               if (other.cvar_cl_buffs_autoreplace && other.buffs != self.buffs)
+               {
+                       int buffid = buff_FirstFromFlags(other.buffs).m_id;
+                       //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, buffid);
+
+                       other.buffs = 0;
+                       //sound(other, CH_TRIGGER, SND_BUFF_LOST, VOL_BASE, ATTN_NORM);
+               }
+               else { return; } // do nothing
+       }
+
+       self.owner = other;
+       self.buff_active = false;
+       self.lifetime = 0;
+       int buffid = buff_FirstFromFlags(self.buffs).m_id;
+       Send_Notification(NOTIF_ONE, other, MSG_MULTI, ITEM_BUFF_GOT, buffid);
+       Send_Notification(NOTIF_ALL_EXCEPT, other, MSG_INFO, INFO_ITEM_BUFF, other.netname, buffid);
+
+       Send_Effect(EFFECT_ITEM_PICKUP, CENTER_OR_VIEWOFS(self), '0 0 0', 1);
+       sound(other, CH_TRIGGER, SND_SHIELD_RESPAWN, VOL_BASE, ATTN_NORM);
+       other.buffs |= (self.buffs);
+}
+
+float buff_Available(entity buff)
+{
+       if (buff == BUFF_Null)
+               return false;
+       if (buff == BUFF_AMMO && ((start_items & IT_UNLIMITED_WEAPON_AMMO) || (start_items & IT_UNLIMITED_AMMO) || (cvar("g_melee_only"))))
+               return false;
+       if (buff == BUFF_VAMPIRE && cvar("g_vampire"))
+               return false;
+       return cvar(strcat("g_buffs_", buff.m_name));
+}
+
+.int buff_seencount;
+
+void buff_NewType(entity ent, float cb)
+{
+       RandomSelection_Init();
+       FOREACH(Buffs, buff_Available(it), LAMBDA(
+               it.buff_seencount += 1;
+               // if it's already been chosen, give it a lower priority
+               RandomSelection_Add(world, it.m_itemid, string_null, 1, max(0.2, 1 / it.buff_seencount));
+       ));
+       ent.buffs = RandomSelection_chosen_float;
+}
+
+void buff_Think()
+{SELFPARAM();
+       if(self.buffs != self.oldbuffs)
+       {
+               entity buff = buff_FirstFromFlags(self.buffs);
+               self.color = buff.m_color;
+               self.glowmod = buff_GlowColor(buff);
+               self.skin = buff.m_skin;
+
+               setmodel(self, MDL_BUFF);
+
+               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 & 64))
+                       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, SND_STRENGTH_RESPAWN, VOL_BASE, ATTN_NORM);
+                       Send_Effect(EFFECT_ITEM_RESPAWN, CENTER_OR_VIEWOFS(self), '0 0 0', 1);
+               }
+       }
+
+       if(self.buff_active)
+       {
+               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()
+{SELFPARAM();
+       WaypointSprite_Kill(self.buff_waypoint);
+
+       if(self.buff_activetime) { buff_Waypoint_Spawn(self); }
+}
+
+void buff_Reset()
+{SELFPARAM();
+       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 & 64))
+               buff_Respawn(self);
+}
+
+float buff_Customize()
+{SELFPARAM();
+       entity player = WaypointSprite_getviewentity(other);
+       if(!self.buff_active || (self.team && DIFF_TEAM(player, self)))
+       {
+               self.alpha = 0.3;
+               if(self.effects & EF_FULLBRIGHT) { self.effects &= ~(EF_FULLBRIGHT); }
+               self.pflags = 0;
+       }
+       else
+       {
+               self.alpha = 1;
+               if(!(self.effects & EF_FULLBRIGHT)) { self.effects |= EF_FULLBRIGHT; }
+               self.light_lev = 220 + 36 * sin(time);
+               self.pflags = PFLAGS_FULLDYNAMIC;
+       }
+       return true;
+}
+
+void buff_Init(entity ent)
+{SELFPARAM();
+       if(!cvar("g_buffs")) { remove(ent); return; }
+
+       if(!teamplay && ent.team) { ent.team = 0; }
+
+       entity buff = buff_FirstFromFlags(self.buffs);
+
+       setself(ent);
+       if(!self.buffs || buff_Available(buff))
+               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.m_skin;
+       self.effects = EF_FULLBRIGHT | EF_STARDUST | EF_NOSHADOW;
+       self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY;
+       self.customizeentityforclient = buff_Customize;
+       //self.gravity = 100;
+       self.color = buff.m_color;
+       self.glowmod = buff_GlowColor(self);
+       buff_SetCooldown(autocvar_g_buffs_cooldown_activate + game_starttime);
+       self.buff_active = !self.buff_activetime;
+       self.pflags = PFLAGS_FULLDYNAMIC;
+
+       if(self.spawnflags & 1)
+               self.noalign = true;
+
+       if(self.noalign)
+               self.movetype = MOVETYPE_NONE; // reset by random location
+
+       setmodel(self, MDL_BUFF);
+       setsize(self, BUFF_MIN, BUFF_MAX);
+
+       if(cvar("g_buffs_random_location") || (self.spawnflags & 64))
+               buff_Respawn(self);
+
+       setself(this);
+}
+
+void buff_Init_Compat(entity ent, entity replacement)
+{
+       if (ent.spawnflags & 2)
+               ent.team = NUM_TEAM_1;
+       else if (ent.spawnflags & 4)
+               ent.team = NUM_TEAM_2;
+
+       ent.buffs = replacement.m_itemid;
+
+       buff_Init(ent);
+}
+
+void buff_SpawnReplacement(entity ent, entity old)
+{
+       setorigin(ent, old.origin);
+       ent.angles = old.angles;
+       ent.noalign = (old.noalign || (old.spawnflags & 1));
+
+       buff_Init(ent);
+}
+
+void buff_Vengeance_DelayedDamage()
+{SELFPARAM();
+       if(self.enemy)
+               Damage(self.enemy, self.owner, self.owner, self.dmg, DEATH_BUFF.m_id, self.enemy.origin, '0 0 0');
+
+       remove(self);
+       return;
+}
+
+float buff_Inferno_CalculateTime(float x, float offset_x, float offset_y, float intersect_x, float intersect_y, float base)
+{
+       return offset_y + (intersect_y - offset_y) * logn(((x - offset_x) * ((base - 1) / intersect_x)) + 1, base);
+}
+
+// mutator hooks
+MUTATOR_HOOKFUNCTION(buffs, PlayerDamage_SplitHealthArmor)
+{
+       if(frag_deathtype == DEATH_BUFF.m_id) { return false; }
+
+       if(frag_target.buffs & BUFF_RESISTANCE.m_itemid)
+       {
+               vector v = healtharmor_applydamage(50, autocvar_g_buffs_resistance_blockpercent, frag_deathtype, frag_damage);
+               damage_take = v.x;
+               damage_save = v.y;
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(buffs, PlayerDamage_Calculate)
+{
+       if(frag_deathtype == DEATH_BUFF.m_id) { return false; }
+
+       if(frag_target.buffs & BUFF_SPEED.m_itemid)
+       if(frag_target != frag_attacker)
+               frag_damage *= autocvar_g_buffs_speed_damage_take;
+
+       if(frag_target.buffs & BUFF_MEDIC.m_itemid)
+       if((frag_target.health - frag_damage) <= 0)
+       if(!ITEM_DAMAGE_NEEDKILL(frag_deathtype))
+       if(frag_attacker)
+       if(random() <= autocvar_g_buffs_medic_survive_chance)
+               frag_damage = max(5, frag_target.health - autocvar_g_buffs_medic_survive_health);
+
+       if(frag_target.buffs & BUFF_JUMP.m_itemid)
+       if(frag_deathtype == DEATH_FALL.m_id)
+               frag_damage = 0;
+
+       if(frag_target.buffs & BUFF_VENGEANCE.m_itemid)
+       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.m_itemid)
+       if(frag_attacker != frag_target)
+       if(vlen(frag_force))
+               frag_force = '0 0 0';
+
+       if(frag_attacker.buffs & BUFF_BASH.m_itemid)
+       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.m_itemid)
+       if(frag_target != frag_attacker)
+               frag_target.buff_disability_time = time + autocvar_g_buffs_disability_slowtime;
+
+       if(frag_attacker.buffs & BUFF_MEDIC.m_itemid)
+       if(DEATH_WEAPONOF(frag_deathtype) != WEP_ARC)
+       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;
+       }
+
+       if(frag_attacker.buffs & BUFF_INFERNO.m_itemid)
+       if(frag_target != frag_attacker) {
+               float time = buff_Inferno_CalculateTime(
+                       frag_damage,
+                       0,
+                       autocvar_g_buffs_inferno_burntime_min_time,
+                       autocvar_g_buffs_inferno_burntime_target_damage,
+                       autocvar_g_buffs_inferno_burntime_target_time,
+                       autocvar_g_buffs_inferno_burntime_factor
+               );
+               Fire_AddDamage(frag_target, frag_attacker, (frag_damage * autocvar_g_buffs_inferno_damagemultiplier) * time, time, DEATH_BUFF.m_id);
+       }
+
+       // this... is ridiculous (TODO: fix!)
+       if(frag_attacker.buffs & BUFF_VAMPIRE.m_itemid)
+       if(!frag_target.vehicle)
+       if(DEATH_WEAPONOF(frag_deathtype) != WEP_ARC)
+       if(!ITEM_DAMAGE_NEEDKILL(frag_deathtype))
+       if(frag_target.deadflag == DEAD_NO)
+       if(IS_PLAYER(frag_target) || IS_MONSTER(frag_target))
+       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);
+               if(frag_target.armorvalue)
+                       frag_attacker.armorvalue = bound(0, frag_attacker.armorvalue + bound(0, frag_damage * autocvar_g_buffs_vampire_damage_steal, frag_target.armorvalue), g_pickup_armorsmall_max);
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(buffs,PlayerSpawn)
+{SELFPARAM();
+       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;
+}
+
+.float stat_sv_maxspeed;
+.float stat_sv_airspeedlimit_nonqw;
+.float stat_sv_jumpvelocity;
+
+MUTATOR_HOOKFUNCTION(buffs, PlayerPhysics)
+{SELFPARAM();
+       if(self.buffs & BUFF_SPEED.m_itemid)
+       {
+               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;
+       }
+
+       if(self.buffs & BUFF_JUMP.m_itemid)
+       {
+               // automatically reset, no need to worry
+               self.stat_sv_jumpvelocity = autocvar_g_buffs_jump_height;
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(buffs, PlayerJump)
+{SELFPARAM();
+       if(self.buffs & BUFF_JUMP.m_itemid)
+               player_jumpheight = autocvar_g_buffs_jump_height;
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(buffs, MonsterMove)
+{SELFPARAM();
+       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)
+{SELFPARAM();
+       if(self.buffs)
+       {
+               int buffid = buff_FirstFromFlags(self.buffs).m_id;
+               Send_Notification(NOTIF_ALL_EXCEPT, self, MSG_INFO, INFO_ITEM_BUFF_LOST, self.netname, buffid);
+               self.buffs = 0;
+
+               if(self.buff_model)
+               {
+                       remove(self.buff_model);
+                       self.buff_model = world;
+               }
+       }
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(buffs, PlayerUseKey, CBC_ORDER_FIRST)
+{SELFPARAM();
+       if(MUTATOR_RETURNVALUE || gameover) { return false; }
+       if(self.buffs)
+       {
+               int buffid = buff_FirstFromFlags(self.buffs).m_id;
+               Send_Notification(NOTIF_ONE, self, MSG_MULTI, ITEM_BUFF_DROP, buffid);
+               Send_Notification(NOTIF_ALL_EXCEPT, self, MSG_INFO, INFO_ITEM_BUFF_LOST, self.netname, buffid);
+
+               self.buffs = 0;
+               sound(self, CH_TRIGGER, SND_BUFF_LOST, VOL_BASE, ATTN_NORM);
+               return true;
+       }
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(buffs, ForbidThrowCurrentWeapon)
+{SELFPARAM();
+       if(MUTATOR_RETURNVALUE || gameover) { return false; }
+
+       if(self.buffs & BUFF_SWAPPER.m_itemid)
+       {
+               float best_distance = autocvar_g_buffs_swapper_range;
+               entity closest = world;
+               entity player;
+               FOR_EACH_PLAYER(player)
+               if(DIFF_TEAM(self, player))
+               if(player.deadflag == DEAD_NO && !player.frozen && !player.vehicle)
+               if(vlen(self.origin - player.origin) <= best_distance)
+               {
+                       best_distance = vlen(self.origin - player.origin);
+                       closest = player;
+               }
+
+               if(closest)
+               {
+                       vector my_org, my_vel, my_ang, their_org, their_vel, their_ang;
+
+                       my_org = self.origin;
+                       my_vel = self.velocity;
+                       my_ang = self.angles;
+                       their_org = closest.origin;
+                       their_vel = closest.velocity;
+                       their_ang = closest.angles;
+
+                       Drop_Special_Items(closest);
+
+                       MUTATOR_CALLHOOK(PortalTeleport, self); // initiate flag dropper
+
+                       setorigin(self, their_org);
+                       setorigin(closest, my_org);
+
+                       closest.velocity = my_vel;
+                       closest.angles = my_ang;
+                       closest.fixangle = true;
+                       closest.oldorigin = my_org;
+                       closest.oldvelocity = my_vel;
+                       self.velocity = their_vel;
+                       self.angles = their_ang;
+                       self.fixangle = true;
+                       self.oldorigin = their_org;
+                       self.oldvelocity = their_vel;
+
+                       // set pusher so self gets the kill if they fall into void
+                       closest.pusher = self;
+                       closest.pushltime = time + autocvar_g_maxpushtime;
+                       closest.istypefrag = closest.BUTTON_CHAT;
+
+                       Send_Effect(EFFECT_ELECTRO_COMBO, their_org, '0 0 0', 1);
+                       Send_Effect(EFFECT_ELECTRO_COMBO, my_org, '0 0 0', 1);
+
+                       sound(self, CH_TRIGGER, SND_KA_RESPAWN, VOL_BASE, ATTEN_NORM);
+                       sound(closest, CH_TRIGGER, SND_KA_RESPAWN, VOL_BASE, ATTEN_NORM);
+
+                       // TODO: add a counter to handle how many times one can teleport, and a delay to prevent spam
+                       self.buffs = 0;
+                       return true;
+               }
+       }
+       return false;
+}
+
+bool buffs_RemovePlayer(entity player)
+{
+       if(player.buff_model)
+       {
+               remove(player.buff_model);
+               player.buff_model = world;
+       }
+
+       // also reset timers here to prevent them continuing after spectating
+       player.buff_disability_time = 0;
+       player.buff_disability_effect_time = 0;
+
+       return false;
+}
+MUTATOR_HOOKFUNCTION(buffs, MakePlayerObserver) { return buffs_RemovePlayer(self); }
+MUTATOR_HOOKFUNCTION(buffs, ClientDisconnect) { return buffs_RemovePlayer(self); }
+
+MUTATOR_HOOKFUNCTION(buffs, CustomizeWaypoint)
+{SELFPARAM();
+       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.m_itemid) && (e == other))
+       if(DIFF_TEAM(self.owner, e))
+               return true;
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(buffs, OnEntityPreSpawn, CBC_ORDER_LAST)
+{SELFPARAM();
+       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, WeaponRateFactor)
+{SELFPARAM();
+       if(self.buffs & BUFF_SPEED.m_itemid)
+               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, WeaponSpeedFactor)
+{SELFPARAM();
+       if(self.buffs & BUFF_SPEED.m_itemid)
+               ret_float *= autocvar_g_buffs_speed_weaponspeed;
+
+       if(time < self.buff_disability_time)
+               ret_float *= autocvar_g_buffs_disability_weaponspeed;
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink)
+{SELFPARAM();
+       if(gameover || self.deadflag != DEAD_NO) { return false; }
+
+       if(time < self.buff_disability_time)
+       if(time >= self.buff_disability_effect_time)
+       {
+               Send_Effect(EFFECT_SMOKING, self.origin + ((self.mins + self.maxs) * 0.5), '0 0 0', 1);
+               self.buff_disability_effect_time = time + 0.5;
+       }
+
+       // handle buff lost status
+       // 1: notify everyone else
+       // 2: notify carrier as well
+       int buff_lost = 0;
+
+       if(self.buff_time)
+       if(time >= self.buff_time)
+               buff_lost = 2;
+
+       if(self.frozen) { buff_lost = 1; }
+
+       if(buff_lost)
+       {
+               if(self.buffs)
+               {
+                       int buffid = buff_FirstFromFlags(self.buffs).m_id;
+                       Send_Notification(NOTIF_ALL_EXCEPT, self, MSG_INFO, INFO_ITEM_BUFF_LOST, self.netname, buffid);
+                       if(buff_lost >= 2)
+                       {
+                               Send_Notification(NOTIF_ONE, self, MSG_MULTI, ITEM_BUFF_DROP, buffid); // TODO: special timeout message?
+                               sound(self, CH_TRIGGER, SND_BUFF_LOST, VOL_BASE, ATTN_NORM);
+                       }
+                       self.buffs = 0;
+               }
+       }
+
+       if(self.buffs & BUFF_MAGNET.m_itemid)
+       {
+               vector pickup_size = '1 1 1' * autocvar_g_buffs_magnet_range_item;
+               for(other = world; (other = findflags(other, flags, FL_ITEM)); )
+               if(boxesoverlap(self.absmin - pickup_size, self.absmax + pickup_size, other.absmin, other.absmax))
+               {
+                       setself(other);
+                       other = this;
+                       if(self.touch)
+                               self.touch();
+                       other = self;
+                       setself(this);
+               }
+       }
+
+       if(self.buffs & BUFF_AMMO.m_itemid)
+       if(self.clip_size)
+               self.clip_load = self.(weapon_load[self.switchweapon]) = self.clip_size;
+
+       if((self.buffs & BUFF_INVISIBLE.m_itemid) && (self.oldbuffs & BUFF_INVISIBLE.m_itemid))
+       if(self.alpha != autocvar_g_buffs_invisible_alpha)
+               self.alpha = autocvar_g_buffs_invisible_alpha; // powerups reset alpha, so we must enforce this (TODO)
+
+#define BUFF_ONADD(b) if ( (self.buffs & (b).m_itemid) && !(self.oldbuffs & (b).m_itemid))
+#define BUFF_ONREM(b) if (!(self.buffs & (b).m_itemid) &&  (self.oldbuffs & (b).m_itemid))
+
+       if(self.buffs != self.oldbuffs)
+       {
+               entity buff = buff_FirstFromFlags(self.buffs);
+               float bufftime = buff != BUFF_Null ? buff.m_time(buff) : 0;
+               self.buff_time = (bufftime) ? time + bufftime : 0;
+
+               BUFF_ONADD(BUFF_AMMO)
+               {
+                       self.buff_ammo_prev_infitems = (self.items & IT_UNLIMITED_WEAPON_AMMO);
+                       self.items |= IT_UNLIMITED_WEAPON_AMMO;
+
+                       if(self.clip_load)
+                               self.buff_ammo_prev_clipload = self.clip_load;
+                       self.clip_load = self.(weapon_load[self.switchweapon]) = self.clip_size;
+               }
+
+               BUFF_ONREM(BUFF_AMMO)
+               {
+                       if(self.buff_ammo_prev_infitems)
+                               self.items |= IT_UNLIMITED_WEAPON_AMMO;
+                       else
+                               self.items &= ~IT_UNLIMITED_WEAPON_AMMO;
+
+                       if(self.buff_ammo_prev_clipload)
+                               self.clip_load = self.buff_ammo_prev_clipload;
+               }
+
+               BUFF_ONADD(BUFF_INVISIBLE)
+               {
+                       if(time < self.strength_finished && g_instagib)
+                               self.alpha = autocvar_g_instagib_invis_alpha;
+                       else
+                               self.alpha = self.buff_invisible_prev_alpha;
+                       self.alpha = autocvar_g_buffs_invisible_alpha;
+               }
+
+               BUFF_ONREM(BUFF_INVISIBLE)
+                       self.alpha = self.buff_invisible_prev_alpha;
+
+               BUFF_ONADD(BUFF_FLIGHT)
+               {
+                       self.buff_flight_prev_gravity = self.gravity;
+                       self.gravity = autocvar_g_buffs_flight_gravity;
+               }
+
+               BUFF_ONREM(BUFF_FLIGHT)
+                       self.gravity = self.buff_flight_prev_gravity;
+
+               self.oldbuffs = self.buffs;
+               if(self.buffs)
+               {
+                       if(!self.buff_model)
+                               buffs_BuffModel_Spawn(self);
+
+                       self.buff_model.color = buff.m_color;
+                       self.buff_model.glowmod = buff_GlowColor(self.buff_model);
+                       self.buff_model.skin = buff.m_skin;
+
+                       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;
+       }
+
+#undef BUFF_ONADD
+#undef BUFF_ONREM
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(buffs, SpectateCopy)
+{SELFPARAM();
+       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)
+{SELFPARAM();
+       if(self.buffs & BUFF_MEDIC.m_itemid)
+       {
+               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.m_itemid)
+               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 |= 64; // always randomize
+                       e.velocity = randomvec() * 250; // this gets reset anyway if random location works
+                       buff_Init(e);
+               }
+       }
+}
+#endif
diff --git a/qcsrc/server/mutators/mutator/mutator_campcheck.qc b/qcsrc/server/mutators/mutator/mutator_campcheck.qc
new file mode 100644 (file)
index 0000000..be5bfce
--- /dev/null
@@ -0,0 +1,86 @@
+#ifdef IMPLEMENTATION
+REGISTER_MUTATOR(campcheck, cvar("g_campcheck"));
+
+.float campcheck_nextcheck;
+.float campcheck_traveled_distance;
+
+MUTATOR_HOOKFUNCTION(campcheck, PlayerDies)
+{SELFPARAM();
+       Kill_Notification(NOTIF_ONE, self, MSG_CENTER_CPID, CPID_CAMPCHECK);
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(campcheck, PlayerDamage_Calculate)
+{
+       if(IS_PLAYER(frag_target))
+       if(IS_PLAYER(frag_attacker))
+       if(frag_attacker != frag_target)
+       {
+               frag_target.campcheck_traveled_distance = autocvar_g_campcheck_distance;
+               frag_attacker.campcheck_traveled_distance = autocvar_g_campcheck_distance;
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(campcheck, PlayerPreThink)
+{SELFPARAM();
+       if(!gameover)
+       if(!warmup_stage) // don't consider it camping during warmup?
+       if(time >= game_starttime)
+       if(IS_PLAYER(self))
+       if(IS_REAL_CLIENT(self)) // bots may camp, but that's no reason to constantly kill them
+       if(self.deadflag == DEAD_NO)
+       if(!self.frozen)
+       if(!self.BUTTON_CHAT)
+       if(autocvar_g_campcheck_interval)
+       {
+               vector dist;
+
+               // calculate player movement (in 2 dimensions only, so jumping on one spot doesn't count as movement)
+               dist = self.prevorigin - self.origin;
+               dist.z = 0;
+               self.campcheck_traveled_distance += fabs(vlen(dist));
+
+               if((autocvar_g_campaign && !campaign_bots_may_start) || (time < game_starttime) || (round_handler_IsActive() && !round_handler_IsRoundStarted()))
+               {
+                       self.campcheck_nextcheck = time + autocvar_g_campcheck_interval * 2;
+                       self.campcheck_traveled_distance = 0;
+               }
+
+               if(time > self.campcheck_nextcheck)
+               {
+                       if(self.campcheck_traveled_distance < autocvar_g_campcheck_distance)
+                       {
+                               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_CAMPCHECK);
+                               if(self.vehicle)
+                                       Damage(self.vehicle, self, self, autocvar_g_campcheck_damage * 2, DEATH_CAMP.m_id, self.vehicle.origin, '0 0 0');
+                               else
+                                       Damage(self, self, self, bound(0, autocvar_g_campcheck_damage, self.health + self.armorvalue * autocvar_g_balance_armor_blockpercent + 5), DEATH_CAMP.m_id, self.origin, '0 0 0');
+                       }
+                       self.campcheck_nextcheck = time + autocvar_g_campcheck_interval;
+                       self.campcheck_traveled_distance = 0;
+               }
+
+               return false;
+       }
+
+       self.campcheck_nextcheck = time + autocvar_g_campcheck_interval; // one of the above checks failed, so keep the timer up to date
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(campcheck, PlayerSpawn)
+{SELFPARAM();
+       self.campcheck_nextcheck = time + autocvar_g_campcheck_interval * 2;
+       self.campcheck_traveled_distance = 0;
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(campcheck, BuildMutatorsString)
+{
+       ret_string = strcat(ret_string, ":CampCheck");
+       return false;
+}
+#endif
diff --git a/qcsrc/server/mutators/mutator/mutator_dodging.qc b/qcsrc/server/mutators/mutator/mutator_dodging.qc
new file mode 100644 (file)
index 0000000..85b9fea
--- /dev/null
@@ -0,0 +1,323 @@
+#ifdef IMPLEMENTATION
+
+#ifdef CSQC
+       #define PHYS_DODGING_FRAMETIME                          (1 / (frametime <= 0 ? 60 : frametime))
+       #define PHYS_DODGING                                            getstati(STAT_DODGING)
+       #define PHYS_DODGING_DELAY                                      getstatf(STAT_DODGING_DELAY)
+       #define PHYS_DODGING_TIMEOUT(s)                         getstatf(STAT_DODGING_TIMEOUT)
+       #define PHYS_DODGING_HORIZ_SPEED_FROZEN         getstatf(STAT_DODGING_HORIZ_SPEED_FROZEN)
+       #define PHYS_DODGING_FROZEN_NODOUBLETAP         getstati(STAT_DODGING_FROZEN_NO_DOUBLETAP)
+       #define PHYS_DODGING_HORIZ_SPEED                        getstatf(STAT_DODGING_HORIZ_SPEED)
+       #define PHYS_DODGING_PRESSED_KEYS(s)            s.pressedkeys
+       #define PHYS_DODGING_HEIGHT_THRESHOLD           getstatf(STAT_DODGING_HEIGHT_THRESHOLD)
+       #define PHYS_DODGING_DISTANCE_THRESHOLD         getstatf(STAT_DODGING_DISTANCE_THRESHOLD)
+       #define PHYS_DODGING_RAMP_TIME                          getstatf(STAT_DODGING_RAMP_TIME)
+       #define PHYS_DODGING_UP_SPEED                           getstatf(STAT_DODGING_UP_SPEED)
+       #define PHYS_DODGING_WALL                                       getstatf(STAT_DODGING_WALL)
+#elif defined(SVQC)
+       #define PHYS_DODGING_FRAMETIME                          sys_frametime
+       #define PHYS_DODGING                                            g_dodging
+       #define PHYS_DODGING_DELAY                                      autocvar_sv_dodging_delay
+       #define PHYS_DODGING_TIMEOUT(s)                         s.cvar_cl_dodging_timeout
+       #define PHYS_DODGING_HORIZ_SPEED_FROZEN         autocvar_sv_dodging_horiz_speed_frozen
+       #define PHYS_DODGING_FROZEN_NODOUBLETAP         autocvar_sv_dodging_frozen_doubletap
+       #define PHYS_DODGING_HORIZ_SPEED                        autocvar_sv_dodging_horiz_speed
+       #define PHYS_DODGING_PRESSED_KEYS(s)            s.pressedkeys
+       #define PHYS_DODGING_HEIGHT_THRESHOLD           autocvar_sv_dodging_height_threshold
+       #define PHYS_DODGING_DISTANCE_THRESHOLD         autocvar_sv_dodging_wall_distance_threshold
+       #define PHYS_DODGING_RAMP_TIME                          autocvar_sv_dodging_ramp_time
+       #define PHYS_DODGING_UP_SPEED                           autocvar_sv_dodging_up_speed
+       #define PHYS_DODGING_WALL                                       autocvar_sv_dodging_wall_dodging
+#endif
+
+#ifdef SVQC
+
+float g_dodging;
+
+// set to 1 to indicate dodging has started.. reset by physics hook after dodge has been done..
+.float dodging_action;
+
+// the jump part of the dodge cannot be ramped
+.float dodging_single_action;
+
+#include "../../../common/animdecide.qh"
+#include "../../../common/physics.qh"
+
+.float cvar_cl_dodging_timeout;
+
+.float stat_dodging;
+.float stat_dodging_delay;
+.float stat_dodging_horiz_speed_frozen;
+.float stat_dodging_frozen_nodoubletap;
+.float stat_dodging_frozen;
+.float stat_dodging_horiz_speed;
+.float stat_dodging_height_threshold;
+.float stat_dodging_distance_threshold;
+.float stat_dodging_ramp_time;
+.float stat_dodging_up_speed;
+.float stat_dodging_wall;
+
+REGISTER_MUTATOR(dodging, cvar("g_dodging"))
+{
+       // this just turns on the cvar.
+       MUTATOR_ONADD
+       {
+               g_dodging = cvar("g_dodging");
+               addstat(STAT_DODGING, AS_INT, stat_dodging);
+               addstat(STAT_DODGING_DELAY, AS_FLOAT, stat_dodging_delay);
+               addstat(STAT_DODGING_TIMEOUT, AS_FLOAT, cvar_cl_dodging_timeout); // we stat this, so it is updated on the client when updated on server (otherwise, chaos)
+               addstat(STAT_DODGING_FROZEN_NO_DOUBLETAP, AS_INT, stat_dodging_frozen_nodoubletap);
+               addstat(STAT_DODGING_HORIZ_SPEED_FROZEN, AS_FLOAT, stat_dodging_horiz_speed_frozen);
+               addstat(STAT_DODGING_FROZEN, AS_INT, stat_dodging_frozen);
+               addstat(STAT_DODGING_HORIZ_SPEED, AS_FLOAT, stat_dodging_horiz_speed);
+               addstat(STAT_DODGING_HEIGHT_THRESHOLD, AS_FLOAT, stat_dodging_height_threshold);
+               addstat(STAT_DODGING_DISTANCE_THRESHOLD, AS_FLOAT, stat_dodging_distance_threshold);
+               addstat(STAT_DODGING_RAMP_TIME, AS_FLOAT, stat_dodging_ramp_time);
+               addstat(STAT_DODGING_UP_SPEED, AS_FLOAT, stat_dodging_up_speed);
+               addstat(STAT_DODGING_WALL, AS_FLOAT, stat_dodging_wall);
+       }
+
+       // this just turns off the cvar.
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               g_dodging = 0;
+       }
+
+       return false;
+}
+
+#endif
+
+// set to 1 to indicate dodging has started.. reset by physics hook after dodge has been done..
+.float dodging_action;
+
+// the jump part of the dodge cannot be ramped
+.float dodging_single_action;
+
+
+// these are used to store the last key press time for each of the keys..
+.float last_FORWARD_KEY_time;
+.float last_BACKWARD_KEY_time;
+.float last_LEFT_KEY_time;
+.float last_RIGHT_KEY_time;
+
+// these store the movement direction at the time of the dodge action happening.
+.vector dodging_direction;
+
+// this indicates the last time a dodge was executed. used to check if another one is allowed
+// and to ramp up the dodge acceleration in the physics hook.
+.float last_dodging_time;
+
+// This is the velocity gain to be added over the ramp time.
+// It will decrease from frame to frame during dodging_action = 1
+// until it's 0.
+.float dodging_velocity_gain;
+
+#ifdef CSQC
+.int pressedkeys;
+
+#elif defined(SVQC)
+
+void dodging_UpdateStats()
+{SELFPARAM();
+       self.stat_dodging = PHYS_DODGING;
+       self.stat_dodging_delay = PHYS_DODGING_DELAY;
+       self.stat_dodging_horiz_speed_frozen = PHYS_DODGING_HORIZ_SPEED_FROZEN;
+       self.stat_dodging_frozen = PHYS_DODGING_FROZEN;
+       self.stat_dodging_frozen_nodoubletap = PHYS_DODGING_FROZEN_NODOUBLETAP;
+       self.stat_dodging_height_threshold = PHYS_DODGING_HEIGHT_THRESHOLD;
+       self.stat_dodging_distance_threshold = PHYS_DODGING_DISTANCE_THRESHOLD;
+       self.stat_dodging_ramp_time = PHYS_DODGING_RAMP_TIME;
+       self.stat_dodging_up_speed = PHYS_DODGING_UP_SPEED;
+       self.stat_dodging_wall = PHYS_DODGING_WALL;
+}
+
+#endif
+
+// returns 1 if the player is close to a wall
+bool check_close_to_wall(float threshold)
+{SELFPARAM();
+       if (PHYS_DODGING_WALL == 0) { return false; }
+
+       #define X(OFFSET)                                                                                                                               \
+       tracebox(self.origin, self.mins, self.maxs, self.origin + OFFSET, true, self);  \
+       if (trace_fraction < 1 && vlen (self.origin - trace_endpos) < threshold)                \
+               return true;
+       X(1000*v_right);
+       X(-1000*v_right);
+       X(1000*v_forward);
+       X(-1000*v_forward);
+       #undef X
+
+       return false;
+}
+
+bool check_close_to_ground(float threshold)
+{SELFPARAM();
+       return IS_ONGROUND(self) ? true : false;
+}
+
+float PM_dodging_checkpressedkeys()
+{SELFPARAM();
+       if(!PHYS_DODGING)
+               return false;
+
+       float frozen_dodging = (PHYS_FROZEN(self) && PHYS_DODGING_FROZEN);
+       float frozen_no_doubletap = (frozen_dodging && !PHYS_DODGING_FROZEN_NODOUBLETAP);
+
+       // first check if the last dodge is far enough back in time so we can dodge again
+       if ((time - self.last_dodging_time) < PHYS_DODGING_DELAY)
+               return false;
+
+       makevectors(self.angles);
+
+       if (check_close_to_ground(PHYS_DODGING_HEIGHT_THRESHOLD) != 1
+               && check_close_to_wall(PHYS_DODGING_DISTANCE_THRESHOLD) != 1)
+               return true;
+
+       float tap_direction_x = 0;
+       float tap_direction_y = 0;
+       float dodge_detected = 0;
+
+       #define X(COND,BTN,RESULT)                                                                                                                      \
+       if (self.movement_##COND)                                                                                               \
+               /* is this a state change? */                                                                                                   \
+               if(!(PHYS_DODGING_PRESSED_KEYS(self) & KEY_##BTN) || frozen_no_doubletap) {             \
+                               tap_direction_##RESULT;                                                                                                 \
+                               if ((time - self.last_##BTN##_KEY_time) < PHYS_DODGING_TIMEOUT(self))   \
+                                       dodge_detected = 1;                                                                                                     \
+                               self.last_##BTN##_KEY_time = time;                                                                              \
+               }
+       X(x < 0, BACKWARD,      x--);
+       X(x > 0, FORWARD,       x++);
+       X(y < 0, LEFT,          y--);
+       X(y > 0, RIGHT,         y++);
+       #undef X
+
+       if (dodge_detected == 1)
+       {
+               self.last_dodging_time = time;
+
+               self.dodging_action = 1;
+               self.dodging_single_action = 1;
+
+               self.dodging_velocity_gain = PHYS_DODGING_HORIZ_SPEED;
+
+               self.dodging_direction_x = tap_direction_x;
+               self.dodging_direction_y = tap_direction_y;
+
+               // normalize the dodging_direction vector.. (unlike UT99) XD
+               float length = self.dodging_direction_x * self.dodging_direction_x
+                                       + self.dodging_direction_y * self.dodging_direction_y;
+               length = sqrt(length);
+
+               self.dodging_direction_x = self.dodging_direction_x * 1.0 / length;
+               self.dodging_direction_y = self.dodging_direction_y * 1.0 / length;
+               return true;
+       }
+       return false;
+}
+
+void PM_dodging()
+{SELFPARAM();
+       if (!PHYS_DODGING)
+               return;
+
+#ifdef SVQC
+       dodging_UpdateStats();
+#endif
+
+    if (PHYS_DEAD(self))
+        return;
+
+       // when swimming, no dodging allowed..
+       if (self.waterlevel >= WATERLEVEL_SWIMMING)
+       {
+               self.dodging_action = 0;
+               self.dodging_direction_x = 0;
+               self.dodging_direction_y = 0;
+               return;
+       }
+
+       // make sure v_up, v_right and v_forward are sane
+       makevectors(self.angles);
+
+       // if we have e.g. 0.5 sec ramptime and a frametime of 0.25, then the ramp code
+       // will be called ramp_time/frametime times = 2 times. so, we need to
+       // add 0.5 * the total speed each frame until the dodge action is done..
+       float common_factor = PHYS_DODGING_FRAMETIME / PHYS_DODGING_RAMP_TIME;
+
+       // if ramp time is smaller than frametime we get problems ;D
+       common_factor = min(common_factor, 1);
+
+       float horiz_speed = PHYS_FROZEN(self) ? PHYS_DODGING_HORIZ_SPEED_FROZEN : PHYS_DODGING_HORIZ_SPEED;
+       float new_velocity_gain = self.dodging_velocity_gain - (common_factor * horiz_speed);
+       new_velocity_gain = max(0, new_velocity_gain);
+
+       float velocity_difference = self.dodging_velocity_gain - new_velocity_gain;
+
+       // ramp up dodging speed by adding some velocity each frame.. TODO: do it! :D
+       if (self.dodging_action == 1)
+       {
+               //disable jump key during dodge accel phase
+               if(self.movement_z > 0) { self.movement_z = 0; }
+
+               self.velocity += ((self.dodging_direction_y * velocity_difference) * v_right)
+                                       + ((self.dodging_direction_x * velocity_difference) * v_forward);
+
+               self.dodging_velocity_gain = self.dodging_velocity_gain - velocity_difference;
+       }
+
+       // the up part of the dodge is a single shot action
+       if (self.dodging_single_action == 1)
+       {
+               UNSET_ONGROUND(self);
+
+               self.velocity += PHYS_DODGING_UP_SPEED * v_up;
+
+#ifdef SVQC
+               if (autocvar_sv_dodging_sound)
+                       PlayerSound(playersound_jump, CH_PLAYER, VOICETYPE_PLAYERSOUND);
+
+               animdecide_setaction(self, ANIMACTION_JUMP, true);
+#endif
+
+               self.dodging_single_action = 0;
+       }
+
+       // are we done with the dodging ramp yet?
+       if((self.dodging_action == 1) && ((time - self.last_dodging_time) > PHYS_DODGING_RAMP_TIME))
+       {
+               // reset state so next dodge can be done correctly
+               self.dodging_action = 0;
+               self.dodging_direction_x = 0;
+               self.dodging_direction_y = 0;
+       }
+}
+
+#ifdef SVQC
+
+MUTATOR_HOOKFUNCTION(dodging, GetCvars)
+{
+       GetCvars_handleFloat(get_cvars_s, get_cvars_f, cvar_cl_dodging_timeout, "cl_dodging_timeout");
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(dodging, PlayerPhysics)
+{
+       // print("dodging_PlayerPhysics\n");
+       PM_dodging();
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(dodging, GetPressedKeys)
+{
+       PM_dodging_checkpressedkeys();
+
+       return false;
+}
+
+#endif
+
+#endif
diff --git a/qcsrc/server/mutators/mutator/mutator_hook.qc b/qcsrc/server/mutators/mutator/mutator_hook.qc
new file mode 100644 (file)
index 0000000..b298e7b
--- /dev/null
@@ -0,0 +1,42 @@
+#ifdef IMPLEMENTATION
+AUTOCVAR(g_grappling_hook, bool, false, _("let players spawn with the grappling hook which allows them to pull themselves up"));
+#ifdef SVQC
+REGISTER_MUTATOR(hook, autocvar_g_grappling_hook) {
+    MUTATOR_ONADD {
+        g_grappling_hook = true;
+        WEP_HOOK.ammo_factor = 0;
+    }
+    MUTATOR_ONROLLBACK_OR_REMOVE {
+        g_grappling_hook = false;
+        WEP_HOOK.ammo_factor = 1;
+    }
+}
+
+MUTATOR_HOOKFUNCTION(hook, BuildMutatorsString)
+{
+    ret_string = strcat(ret_string, ":grappling_hook");
+}
+
+MUTATOR_HOOKFUNCTION(hook, BuildMutatorsPrettyString)
+{
+    ret_string = strcat(ret_string, ", Hook");
+}
+
+MUTATOR_HOOKFUNCTION(hook, BuildGameplayTipsString)
+{
+    ret_string = strcat(ret_string, "\n\n^3grappling hook^8 is enabled, press 'e' to use it\n");
+}
+
+MUTATOR_HOOKFUNCTION(hook, PlayerSpawn)
+{
+    SELFPARAM();
+    self.offhand = OFFHAND_HOOK;
+}
+
+MUTATOR_HOOKFUNCTION(hook, FilterItem)
+{
+    return self.weapon == WEP_HOOK.m_id;
+}
+
+#endif
+#endif
diff --git a/qcsrc/server/mutators/mutator/mutator_invincibleproj.qc b/qcsrc/server/mutators/mutator/mutator_invincibleproj.qc
new file mode 100644 (file)
index 0000000..5a781a8
--- /dev/null
@@ -0,0 +1,25 @@
+#ifdef IMPLEMENTATION
+REGISTER_MUTATOR(invincibleprojectiles, cvar("g_invincible_projectiles"));
+
+MUTATOR_HOOKFUNCTION(invincibleprojectiles, EditProjectile)
+{
+       if(other.health)
+       {
+               // disable health which in effect disables damage calculations
+               other.health = 0;
+       }
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(invincibleprojectiles, BuildMutatorsString)
+{
+       ret_string = strcat(ret_string, ":InvincibleProjectiles");
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(invincibleprojectiles, BuildMutatorsPrettyString)
+{
+       ret_string = strcat(ret_string, ", Invincible Projectiles");
+       return 0;
+}
+#endif
diff --git a/qcsrc/server/mutators/mutator/mutator_melee_only.qc b/qcsrc/server/mutators/mutator/mutator_melee_only.qc
new file mode 100644 (file)
index 0000000..5b03f46
--- /dev/null
@@ -0,0 +1,40 @@
+#ifdef IMPLEMENTATION
+REGISTER_MUTATOR(melee_only, cvar("g_melee_only") && !cvar("g_instagib") && !g_nexball);
+
+MUTATOR_HOOKFUNCTION(melee_only, SetStartItems)
+{
+       start_ammo_shells = warmup_start_ammo_shells = 0;
+       start_weapons = warmup_start_weapons = WEPSET(SHOTGUN);
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(melee_only, ForbidThrowCurrentWeapon)
+{
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(melee_only, FilterItem)
+{SELFPARAM();
+       switch (self.items)
+       {
+               case ITEM_HealthSmall.m_itemid:
+               case ITEM_ArmorSmall.m_itemid:
+                       return false;
+       }
+
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(melee_only, BuildMutatorsString)
+{
+       ret_string = strcat(ret_string, ":MeleeOnly");
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(melee_only, BuildMutatorsPrettyString)
+{
+       ret_string = strcat(ret_string, ", Melee Only Arena");
+       return false;
+}
+#endif
diff --git a/qcsrc/server/mutators/mutator/mutator_midair.qc b/qcsrc/server/mutators/mutator/mutator_midair.qc
new file mode 100644 (file)
index 0000000..bf34283
--- /dev/null
@@ -0,0 +1,47 @@
+#ifdef IMPLEMENTATION
+REGISTER_MUTATOR(midair, cvar("g_midair"));
+
+.float midair_shieldtime;
+
+MUTATOR_HOOKFUNCTION(midair, PlayerDamage_Calculate)
+{SELFPARAM();
+       if(IS_PLAYER(frag_attacker))
+       if(IS_PLAYER(frag_target))
+       if(time < self.midair_shieldtime)
+               frag_damage = false;
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(midair, PlayerPowerups)
+{SELFPARAM();
+       if(time >= game_starttime)
+       if(self.flags & FL_ONGROUND)
+       {
+               self.effects |= (EF_ADDITIVE | EF_FULLBRIGHT);
+               self.midair_shieldtime = max(self.midair_shieldtime, time + autocvar_g_midair_shieldtime);
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(midair, PlayerSpawn)
+{SELFPARAM();
+       if(IS_BOT_CLIENT(self))
+               self.bot_moveskill = 0; // disable bunnyhopping
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(midair, BuildMutatorsString)
+{
+       ret_string = strcat(ret_string, ":midair");
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(midair, BuildMutatorsPrettyString)
+{
+       ret_string = strcat(ret_string, ", Midair");
+       return false;
+}
+#endif
diff --git a/qcsrc/server/mutators/mutator/mutator_multijump.qc b/qcsrc/server/mutators/mutator/mutator_multijump.qc
new file mode 100644 (file)
index 0000000..f01a801
--- /dev/null
@@ -0,0 +1,182 @@
+#ifdef IMPLEMENTATION
+#ifdef SVQC
+       #include "../../antilag.qh"
+#endif
+#include "../../../common/physics.qh"
+
+.int multijump_count;
+.bool multijump_ready;
+.bool cvar_cl_multijump;
+
+#ifdef CSQC
+
+#define PHYS_MULTIJUMP                                 getstati(STAT_MULTIJUMP)
+#define PHYS_MULTIJUMP_SPEED           getstatf(STAT_MULTIJUMP_SPEED)
+#define PHYS_MULTIJUMP_ADD                     getstati(STAT_MULTIJUMP_ADD)
+#define PHYS_MULTIJUMP_MAXSPEED        getstatf(STAT_MULTIJUMP_MAXSPEED)
+#define PHYS_MULTIJUMP_DODGING                 getstati(STAT_MULTIJUMP_DODGING)
+
+#elif defined(SVQC)
+
+#define PHYS_MULTIJUMP                                 autocvar_g_multijump
+#define PHYS_MULTIJUMP_SPEED           autocvar_g_multijump_speed
+#define PHYS_MULTIJUMP_ADD                     autocvar_g_multijump_add
+#define PHYS_MULTIJUMP_MAXSPEED        autocvar_g_multijump_maxspeed
+#define PHYS_MULTIJUMP_DODGING                 autocvar_g_multijump_dodging
+
+
+.float stat_multijump;
+.float stat_multijump_speed;
+.float stat_multijump_add;
+.float stat_multijump_maxspeed;
+.float stat_multijump_dodging;
+
+void multijump_UpdateStats()
+{SELFPARAM();
+       self.stat_multijump = PHYS_MULTIJUMP;
+       self.stat_multijump_speed = PHYS_MULTIJUMP_SPEED;
+       self.stat_multijump_add = PHYS_MULTIJUMP_ADD;
+       self.stat_multijump_maxspeed = PHYS_MULTIJUMP_MAXSPEED;
+       self.stat_multijump_dodging = PHYS_MULTIJUMP_DODGING;
+}
+
+void multijump_AddStats()
+{
+       addstat(STAT_MULTIJUMP, AS_INT, stat_multijump);
+       addstat(STAT_MULTIJUMP_SPEED, AS_FLOAT, stat_multijump_speed);
+       addstat(STAT_MULTIJUMP_ADD, AS_INT, stat_multijump_add);
+       addstat(STAT_MULTIJUMP_MAXSPEED, AS_FLOAT, stat_multijump_maxspeed);
+       addstat(STAT_MULTIJUMP_DODGING, AS_INT, stat_multijump_dodging);
+}
+
+#endif
+
+void PM_multijump()
+{SELFPARAM();
+       if(!PHYS_MULTIJUMP) { return; }
+
+       if(IS_ONGROUND(self))
+       {
+               self.multijump_count = 0;
+       }
+}
+
+bool PM_multijump_checkjump()
+{SELFPARAM();
+       if(!PHYS_MULTIJUMP) { return false; }
+
+#ifdef SVQC
+       bool client_multijump = self.cvar_cl_multijump;
+#elif defined(CSQC)
+       bool client_multijump = cvar("cl_multijump");
+
+       if(cvar("cl_multijump") > 1)
+               return false; // nope
+#endif
+
+       if (!IS_JUMP_HELD(self) && !IS_ONGROUND(self) && client_multijump) // jump button pressed this frame and we are in midair
+               self.multijump_ready = true;  // this is necessary to check that we released the jump button and pressed it again
+       else
+               self.multijump_ready = false;
+
+       int phys_multijump = PHYS_MULTIJUMP;
+
+#ifdef CSQC
+       phys_multijump = (PHYS_MULTIJUMP) ? -1 : 0;
+#endif
+
+       if(!player_multijump && self.multijump_ready && (self.multijump_count < phys_multijump || phys_multijump == -1) && self.velocity_z > PHYS_MULTIJUMP_SPEED && (!PHYS_MULTIJUMP_MAXSPEED || vlen(self.velocity) <= PHYS_MULTIJUMP_MAXSPEED))
+       {
+               if (PHYS_MULTIJUMP)
+               {
+                       if (!PHYS_MULTIJUMP_ADD) // in this case we make the z velocity == jumpvelocity
+                       {
+                               if (self.velocity_z < PHYS_JUMPVELOCITY)
+                               {
+                                       player_multijump = true;
+                                       self.velocity_z = 0;
+                               }
+                       }
+                       else
+                               player_multijump = true;
+
+                       if(player_multijump)
+                       {
+                               if(PHYS_MULTIJUMP_DODGING)
+                               if(self.movement_x != 0 || self.movement_y != 0) // don't remove all speed if player isnt pressing any movement keys
+                               {
+                                       float curspeed;
+                                       vector wishvel, wishdir;
+
+/*#ifdef SVQC
+                                       curspeed = max(
+                                               vlen(vec2(self.velocity)), // current xy speed
+                                               vlen(vec2(antilag_takebackavgvelocity(self, max(self.lastteleporttime + sys_frametime, time - 0.25), time))) // average xy topspeed over the last 0.25 secs
+                                       );
+#elif defined(CSQC)*/
+                                       curspeed = vlen(vec2(self.velocity));
+//#endif
+
+                                       makevectors(self.v_angle_y * '0 1 0');
+                                       wishvel = v_forward * self.movement_x + v_right * self.movement_y;
+                                       wishdir = normalize(wishvel);
+
+                                       self.velocity_x = wishdir_x * curspeed; // allow "dodging" at a multijump
+                                       self.velocity_y = wishdir_y * curspeed;
+                                       // keep velocity_z unchanged!
+                               }
+                               if (PHYS_MULTIJUMP > 0)
+                               {
+                                       self.multijump_count += 1;
+                               }
+                       }
+               }
+               self.multijump_ready = false; // require releasing and pressing the jump button again for the next jump
+       }
+
+       return false;
+}
+
+#ifdef SVQC
+REGISTER_MUTATOR(multijump, cvar("g_multijump"))
+{
+       MUTATOR_ONADD
+       {
+               multijump_AddStats();
+       }
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(multijump, PlayerPhysics)
+{
+       multijump_UpdateStats();
+       PM_multijump();
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(multijump, PlayerJump)
+{
+       return PM_multijump_checkjump();
+}
+
+MUTATOR_HOOKFUNCTION(multijump, GetCvars)
+{
+       GetCvars_handleFloat(get_cvars_s, get_cvars_f, cvar_cl_multijump, "cl_multijump");
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(multijump, BuildMutatorsString)
+{
+       ret_string = strcat(ret_string, ":multijump");
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(multijump, BuildMutatorsPrettyString)
+{
+       ret_string = strcat(ret_string, ", Multi jump");
+       return false;
+}
+
+#endif
+#endif
diff --git a/qcsrc/server/mutators/mutator/mutator_nades.qc b/qcsrc/server/mutators/mutator/mutator_nades.qc
new file mode 100644 (file)
index 0000000..d9fd1c8
--- /dev/null
@@ -0,0 +1,1233 @@
+#ifndef MUTATOR_NADES_H
+#define MUTATOR_NADES_H
+
+.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;
+
+// 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;
+
+#endif
+#ifdef IMPLEMENTATION
+
+#include "../../../common/nades/all.qh"
+#include "../../../common/gamemodes/all.qh"
+#include "../../../common/monsters/spawn.qh"
+#include "../../../common/monsters/sv_monsters.qh"
+#include "../../g_subs.qh"
+
+REGISTER_MUTATOR(nades, cvar("g_nades"))
+{
+       MUTATOR_ONADD
+       {
+               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);
+       }
+
+       return false;
+}
+
+.float nade_time_primed;
+
+.entity nade_spawnloc;
+
+void nade_timer_think()
+{SELFPARAM();
+       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)
+{
+       CSQCProjectile(_nade, true, Nades[_nade.nade_type].m_projectile[true], true);
+}
+
+void nade_spawn(entity _nade)
+{
+       entity timer = spawn();
+       setmodel(timer, MDL_NADE_TIMER);
+       setattachment(timer, _nade, "");
+       timer.classname = "nade_timer";
+       timer.colormap = _nade.colormap;
+       timer.glowmod = _nade.glowmod;
+       timer.think = nade_timer_think;
+       timer.nextthink = time;
+       timer.wait = _nade.wait;
+       timer.owner = _nade;
+       timer.skin = 10;
+
+       _nade.effects |= EF_LOWPRECISION;
+
+       CSQCProjectile(_nade, true, Nades[_nade.nade_type].m_projectile[false], true);
+}
+
+void napalm_damage(float dist, float damage, float edgedamage, float burntime)
+{SELFPARAM();
+       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)
+       {
+               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(EFFECT_FIREBALL_LASER), self.origin, RandomSelection_chosen_ent.fireball_impactvec);
+               Send_Effect(EFFECT_FIREBALL_LASER, self.origin, RandomSelection_chosen_ent.fireball_impactvec - self.origin, 1);
+       }
+}
+
+
+void napalm_ball_think()
+{SELFPARAM();
+       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()
+{SELFPARAM();
+       entity proj;
+       vector kick;
+
+       spamsound(self, CH_SHOTS, SND(FIREBALL_FIRE), 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.m_id;
+       PROJECTILE_MAKETRIGGER(proj);
+       setmodel(proj, MDL_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()
+{SELFPARAM();
+
+       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()
+{SELFPARAM();
+       entity fountain;
+       int 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.m_id;
+       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;
+       Send_Effect(EFFECT_ELECTRO_IMPACT, frost_target.origin, '0 0 0', 1);
+       Freeze(frost_target, 1/freeze_time, 3, false);
+
+       Drop_Special_Items(frost_target);
+}
+
+void nade_ice_think()
+{SELFPARAM();
+
+       if(round_handler_IsActive())
+       if(!round_handler_IsRoundStarted())
+       {
+               remove(self);
+               return;
+       }
+
+       if(time >= self.ltime)
+       {
+               if ( autocvar_g_nades_ice_explode )
+               {
+                       entity expef = EFFECT_NADE_EXPLODE(self.realowner.team);
+                       Send_Effect(expef, self.origin + '0 0 1', '0 0 0', 1);
+                       sound(self, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM);
+
+                       RadiusDamage(self, self.realowner, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage,
+                               autocvar_g_nades_nade_radius, self, world, 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;
+       Send_Effect(EFFECT_ELECTRO_MUZZLEFLASH, self.origin + randomp, '0 0 0', 1);
+
+       if(time >= self.nade_special_time)
+       {
+               self.nade_special_time = time+0.7;
+
+               Send_Effect(EFFECT_ELECTRO_IMPACT, self.origin, '0 0 0', 1);
+               Send_Effect(EFFECT_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()
+{SELFPARAM();
+       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.m_id;
+       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, MDL_PROJECTILE_GRENADE);
+               entity timer = spawn();
+               setmodel(timer, MDL_NADE_TIMER);
+               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, MDL_Null);
+}
+
+void nade_translocate_boom()
+{SELFPARAM();
+       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);
+
+       MUTATOR_CALLHOOK(PortalTeleport, self.realowner);
+
+       TeleportPlayer(self, self.realowner, locout, self.realowner.angles, v_forward * vlen(self.realowner.velocity), '0 0 0', '0 0 0', TELEPORT_FLAGS_TELEPORTER);
+}
+
+void nade_spawn_boom()
+{SELFPARAM();
+       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()
+{SELFPARAM();
+       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()
+{SELFPARAM();
+       float maxhealth;
+       float health_factor;
+       if(IS_PLAYER(other) || IS_MONSTER(other))
+       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 = (IS_MONSTER(other)) ? other.max_health : g_pickup_healthmega_max;
+                       if ( other.health < maxhealth )
+                       {
+                               if ( self.nade_show_particles )
+                                       Send_Effect(EFFECT_HEALING, 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.m_id,other.origin,'0 0 0');
+               }
+
+       }
+
+       if ( IS_REAL_CLIENT(other) || IS_VEHICLE(other) )
+       {
+               entity show_red = (IS_VEHICLE(other)) ? 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()
+{SELFPARAM();
+       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, MDL_NADE_HEAL);
+       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()
+{SELFPARAM();
+       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()
+{SELFPARAM();
+       entity expef = NULL;
+       bool nade_blast = true;
+
+       switch ( Nades[self.nade_type] )
+       {
+               case NADE_TYPE_NAPALM:
+                       nade_blast = autocvar_g_nades_napalm_blast;
+                       expef = EFFECT_EXPLOSION_MEDIUM;
+                       break;
+               case NADE_TYPE_ICE:
+                       nade_blast = false;
+                       expef = EFFECT_ELECTRO_COMBO; // hookbomb_explode electro_combo bigplasma_impact
+                       break;
+               case NADE_TYPE_TRANSLOCATE:
+                       nade_blast = false;
+                       break;
+               case NADE_TYPE_MONSTER:
+               case NADE_TYPE_SPAWN:
+                       nade_blast = false;
+                       switch(self.realowner.team)
+                       {
+                               case NUM_TEAM_1: expef = EFFECT_SPAWN_RED; break;
+                               case NUM_TEAM_2: expef = EFFECT_SPAWN_BLUE; break;
+                               case NUM_TEAM_3: expef = EFFECT_SPAWN_YELLOW; break;
+                               case NUM_TEAM_4: expef = EFFECT_SPAWN_PINK; break;
+                               default: expef = EFFECT_SPAWN_NEUTRAL; break;
+                       }
+                       break;
+               case NADE_TYPE_HEAL:
+                       nade_blast = false;
+                       expef = EFFECT_SPAWN_RED;
+                       break;
+
+               default:
+               case NADE_TYPE_NORMAL:
+                       expef = EFFECT_NADE_EXPLODE(self.realowner.team);
+                       break;
+       }
+
+       if(expef)
+               Send_Effect(expef, findbetterlocation(self.origin, 8), '0 0 0', 1);
+
+       sound(self, CH_SHOTS_SINGLE, SND_Null, VOL_BASE, ATTEN_NORM);
+       sound(self, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM);
+
+       self.event_damage = func_null; // prevent somehow calling damage in the next call
+
+       if(nade_blast)
+       {
+               RadiusDamage(self, self.realowner, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage,
+                                autocvar_g_nades_nade_radius, self, world, 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);
+       }
+
+       if(self.takedamage)
+       switch ( Nades[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;
+       }
+
+       entity head;
+       for(head = world; (head = find(head, classname, "grapplinghook")); )
+       if(head.aiment == self)
+               RemoveGrapplingHook(head.realowner);
+
+       remove(self);
+}
+
+void nade_touch()
+{SELFPARAM();
+       /*float is_weapclip = 0;
+       if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NODRAW)
+       if (!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NONSOLID))
+       if (!(trace_dphitcontents & DPCONTENTS_OPAQUE))
+               is_weapclip = 1;*/
+       if(ITEM_TOUCH_NEEDKILL()) // || is_weapclip)
+       {
+               entity head;
+               for(head = world; (head = find(head, classname, "grapplinghook")); )
+               if(head.aiment == self)
+                       RemoveGrapplingHook(head.realowner);
+               remove(self);
+               return;
+       }
+
+       PROJECTILE_TOUCH;
+
+       //setsize(self, '-2 -2 -2', '2 2 2');
+       //UpdateCSQCProjectile(self);
+       if(self.health == self.max_health)
+       {
+               spamsound(self, CH_SHOTS, SND(GRENADE_BOUNCE_RANDOM()), VOL_BASE, ATTEN_NORM);
+               return;
+       }
+
+       self.enemy = other;
+       nade_boom();
+}
+
+void nade_beep()
+{SELFPARAM();
+       sound(self, CH_SHOTS_SINGLE, SND_NADE_BEEP, VOL_BASE, 0.5 *(ATTEN_LARGE + ATTEN_MAX));
+       self.think = nade_boom;
+       self.nextthink = max(self.wait, time);
+}
+
+void nade_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
+{SELFPARAM();
+       if(ITEM_DAMAGE_NEEDKILL(deathtype))
+       {
+               self.takedamage = DAMAGE_NO;
+               nade_boom();
+               return;
+       }
+
+       if(self.nade_type == NADE_TYPE_TRANSLOCATE.m_id || self.nade_type == NADE_TYPE_SPAWN.m_id)
+               return;
+
+       if(DEATH_ISWEAPON(deathtype, WEP_BLASTER))
+       {
+               force *= 1.5;
+               damage = 0;
+       }
+
+       if(DEATH_ISWEAPON(deathtype, WEP_VAPORIZER) && (deathtype & HITTYPE_SECONDARY))
+       {
+               force *= 0.5; // too much
+               frag_damage = 0;
+       }
+
+       if(DEATH_ISWEAPON(deathtype, WEP_VORTEX) || DEATH_ISWEAPON(deathtype, WEP_VAPORIZER))
+       {
+               force *= 6;
+               damage = self.max_health * 0.55;
+       }
+
+       if(DEATH_ISWEAPON(deathtype, WEP_MACHINEGUN) || DEATH_ISWEAPON(deathtype, WEP_HMG))
+               damage = self.max_health * 0.1;
+
+       if(DEATH_ISWEAPON(deathtype, WEP_SHOCKWAVE) || DEATH_ISWEAPON(deathtype, WEP_SHOTGUN)) // WEAPONTODO
+       if(deathtype & HITTYPE_SECONDARY)
+       {
+               damage = self.max_health * 0.1;
+               force *= 10;
+       }
+       else
+               damage = self.max_health * 1.15;
+
+       self.velocity += force;
+       UpdateCSQCProjectile(self);
+
+       if(damage <= 0 || ((self.flags & FL_ONGROUND) && IS_PLAYER(attacker)))
+               return;
+
+       if(self.health == self.max_health)
+       {
+               sound(self, CH_SHOTS_SINGLE, SND_Null, VOL_BASE, 0.5 *(ATTEN_LARGE + ATTEN_MAX));
+               self.nextthink = max(time + autocvar_g_nades_nade_lifetime, time);
+               self.think = nade_beep;
+       }
+
+       self.health -= damage;
+
+       if ( self.nade_type != NADE_TYPE_HEAL.m_id || IS_PLAYER(attacker) )
+               self.realowner = attacker;
+
+       if(self.health <= 0)
+               W_PrepareExplosionByDamage(attacker, nade_boom);
+       else
+               nade_burn_spawn(self);
+}
+
+void toss_nade(entity e, vector _velocity, float _time)
+{SELFPARAM();
+       if(e.nade == world)
+               return;
+
+       entity _nade = e.nade;
+       e.nade = world;
+
+       remove(e.fake_nade);
+       e.fake_nade = world;
+
+       makevectors(e.v_angle);
+
+       W_SetupShot(e, false, false, "", CH_WEAPON_A, 0);
+
+       Kill_Notification(NOTIF_ONE_ONLY, e, MSG_CENTER_CPID, CPID_NADES);
+
+       vector offset = (v_forward * autocvar_g_nades_throw_offset.x)
+                                 + (v_right * autocvar_g_nades_throw_offset.y)
+                                 + (v_up * autocvar_g_nades_throw_offset.z);
+       if(autocvar_g_nades_throw_offset == '0 0 0')
+               offset = '0 0 0';
+
+       setorigin(_nade, w_shotorg + offset + (v_right * 25) * -1);
+       //setmodel(_nade, MDL_PROJECTILE_NADE);
+       //setattachment(_nade, world, "");
+       PROJECTILE_MAKETRIGGER(_nade);
+       setsize(_nade, '-16 -16 -16', '16 16 16');
+       _nade.movetype = MOVETYPE_BOUNCE;
+
+       tracebox(_nade.origin, _nade.mins, _nade.maxs, _nade.origin, false, _nade);
+       if (trace_startsolid)
+               setorigin(_nade, e.origin);
+
+       if(self.v_angle.x >= 70 && self.v_angle.x <= 110 && self.BUTTON_CROUCH)
+               _nade.velocity = '0 0 100';
+       else if(autocvar_g_nades_nade_newton_style == 1)
+               _nade.velocity = e.velocity + _velocity;
+       else if(autocvar_g_nades_nade_newton_style == 2)
+               _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.traileffectnum = 0;
+       _nade.teleportable = true;
+       _nade.pushable = true;
+       _nade.gravity = 1;
+       _nade.missile_flags = MIF_SPLASH | MIF_ARC;
+       _nade.damagedbycontents = true;
+       _nade.angles = vectoangles(_nade.velocity);
+       _nade.flags = FL_PROJECTILE;
+       _nade.projectiledeathtype = DEATH_NADE.m_id;
+       _nade.toss_time = time;
+       _nade.solid = SOLID_CORPSE; //((_nade.nade_type == NADE_TYPE_TRANSLOCATE) ? SOLID_CORPSE : SOLID_BBOX);
+
+       if(_nade.nade_type == NADE_TYPE_TRANSLOCATE.m_id || _nade.nade_type == NADE_TYPE_SPAWN.m_id)
+               _nade.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
+       else
+               _nade.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY;
+
+       nade_spawn(_nade);
+
+       if(_time)
+       {
+               _nade.think = nade_boom;
+               _nade.nextthink = _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, SND(KH_ALARM));
+                       player.bonus_nades++;
+                       player.bonus_nade_score -= 1;
+               }
+       }
+}
+
+void nades_RemoveBonus(entity player)
+{
+       player.bonus_nades = player.bonus_nade_score = 0;
+}
+
+float nade_customize()
+{SELFPARAM();
+       //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(Nades[self.nade_type].m_projectile[false], self.team).eent_eff_name);
+               self.alpha = 1;
+       }
+
+       return true;
+}
+
+void nade_prime()
+{SELFPARAM();
+       if(autocvar_g_nades_bonus_only)
+       if(!self.bonus_nades)
+               return; // only allow bonus nades
+
+       if(self.nade)
+               remove(self.nade);
+
+       if(self.fake_nade)
+               remove(self.fake_nade);
+
+       entity n = spawn(), fn = spawn();
+
+       n.classname = "nade";
+       fn.classname = "fake_nade";
+
+       if(self.items & ITEM_Strength.m_itemid && 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, Nades_COUNT);
+
+       setmodel(n, MDL_PROJECTILE_NADE);
+       //setattachment(n, self, "bip01 l hand");
+       n.exteriormodeltoclient = self;
+       n.customizeentityforclient = nade_customize;
+       n.traileffectnum = _particleeffectnum(Nade_TrailEffect(Nades[n.nade_type].m_projectile[false], self.team).eent_eff_name);
+       n.colormod = Nades[n.nade_type].m_color;
+       n.realowner = self;
+       n.colormap = self.colormap;
+       n.glowmod = self.glowmod;
+       n.wait = time + autocvar_g_nades_nade_lifetime;
+       n.nade_time_primed = time;
+       n.think = nade_beep;
+       n.nextthink = max(n.wait - 3, time);
+       n.projectiledeathtype = DEATH_NADE.m_id;
+
+       setmodel(fn, MDL_NADE_VIEW);
+       setattachment(fn, self.weaponentity, "");
+       fn.realowner = fn.owner = self;
+       fn.colormod = Nades[n.nade_type].m_color;
+       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()
+{SELFPARAM();
+       if(self.vehicle)
+               return false;
+
+       if(gameover)
+               return false;
+
+       if(self.deadflag != DEAD_NO)
+               return false;
+
+       if (!autocvar_g_nades)
+               return false; // allow turning them off mid match
+
+       if(forbidWeaponUse(self))
+               return false;
+
+       if (!IS_PLAYER(self))
+               return false;
+
+       return true;
+}
+
+.bool nade_altbutton;
+
+void nades_CheckThrow()
+{SELFPARAM();
+       if(!CanThrowNade())
+               return;
+
+       entity held_nade = self.nade;
+       if (!held_nade)
+       {
+               self.nade_altbutton = true;
+               if(time > self.nade_refire)
+               {
+                       Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_NADE_THROW);
+                       nade_prime();
+                       self.nade_refire = time + autocvar_g_nades_nade_refire;
+               }
+       }
+       else
+       {
+               self.nade_altbutton = false;
+               if (time >= held_nade.nade_time_primed + 1) {
+                       makevectors(self.v_angle);
+                       float _force = time - held_nade.nade_time_primed;
+                       _force /= autocvar_g_nades_nade_lifetime;
+                       _force = autocvar_g_nades_nade_minforce + (_force * (autocvar_g_nades_nade_maxforce - autocvar_g_nades_nade_minforce));
+                       toss_nade(self, (v_forward * 0.75 + v_up * 0.2 + v_right * 0.05) * _force, 0);
+               }
+       }
+}
+
+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, VehicleEnter)
+{
+       if(vh_player.nade)
+               toss_nade(vh_player, '0 0 100', max(vh_player.nade.wait, time + 0.05));
+
+       return false;
+}
+
+CLASS(NadeOffhand, OffhandWeapon)
+    METHOD(NadeOffhand, offhand_think, void(NadeOffhand this, entity player, bool key_pressed))
+    {
+       entity held_nade = player.nade;
+               if (held_nade)
+               {
+                       player.nade_timer = bound(0, (time - held_nade.nade_time_primed) / autocvar_g_nades_nade_lifetime, 1);
+                       // LOG_TRACEF("%d %d\n", player.nade_timer, time - held_nade.nade_time_primed);
+                       makevectors(player.angles);
+                       held_nade.velocity = player.velocity;
+                       setorigin(held_nade, player.origin + player.view_ofs + v_forward * 8 + v_right * -8 + v_up * 0);
+                       held_nade.angles_y = player.angles.y;
+
+                       if (time + 0.1 >= held_nade.wait)
+                               toss_nade(player, '0 0 0', time + 0.05);
+               }
+
+        if (!CanThrowNade()) return;
+        if (!(time > player.nade_refire)) return;
+               if (key_pressed) {
+                       if (!held_nade) {
+                               nade_prime();
+                               held_nade = player.nade;
+                       }
+               } else if (time >= held_nade.nade_time_primed + 1) {
+                       if (held_nade) {
+                               makevectors(player.v_angle);
+                               float _force = time - held_nade.nade_time_primed;
+                               _force /= autocvar_g_nades_nade_lifetime;
+                               _force = autocvar_g_nades_nade_minforce + (_force * (autocvar_g_nades_nade_maxforce - autocvar_g_nades_nade_minforce));
+                               toss_nade(player, (v_forward * 0.7 + v_up * 0.2 + v_right * 0.1) * _force, 0);
+                       }
+               }
+    }
+ENDCLASS(NadeOffhand)
+NadeOffhand OFFHAND_NADE; STATIC_INIT(OFFHAND_NADE) { OFFHAND_NADE = NEW(NadeOffhand); }
+
+MUTATOR_HOOKFUNCTION(nades, ForbidThrowCurrentWeapon, CBC_ORDER_LAST)
+{
+       if (self.offhand != OFFHAND_NADE || (self.weapons & WEPSET(HOOK)) || autocvar_g_nades_override_dropweapon) {
+               nades_CheckThrow();
+               return true;
+       }
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(nades, PlayerPreThink)
+{SELFPARAM();
+       if (!IS_PLAYER(self)) { return false; }
+
+       if (self.nade && (self.offhand != OFFHAND_NADE || (self.weapons & WEPSET(HOOK)))) OFFHAND_NADE.offhand_think(OFFHAND_NADE, self, self.nade_altbutton);
+
+       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; }
+
+                       float time_score;
+                       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, Nades_COUNT);
+
+                       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;
+}
+
+MUTATOR_HOOKFUNCTION(nades, PlayerSpawn)
+{SELFPARAM();
+       if(autocvar_g_nades_spawn)
+               self.nade_refire = time + autocvar_g_spawnshieldtime;
+       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.offhand) self.offhand = OFFHAND_NADE;
+
+       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, CBC_ORDER_LAST)
+{
+       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_Calculate)
+{
+       if(frag_target.frozen)
+       if(autocvar_g_freezetag_revive_nade)
+       if(frag_attacker == frag_target)
+       if(frag_deathtype == DEATH_NADE.m_id)
+       if(time - frag_inflictor.toss_time <= 0.1)
+       {
+               Unfreeze(frag_target);
+               frag_target.health = autocvar_g_freezetag_revive_nade_health;
+               Send_Effect(EFFECT_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)
+{SELFPARAM();
+       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, DropSpecialItems)
+{
+       if(frag_target.nade)
+               toss_nade(frag_target, '0 0 0', time + 0.05);
+
+       return false;
+}
+
+bool nades_RemovePlayer()
+{SELFPARAM();
+       nades_Clear(self);
+       nades_RemoveBonus(self);
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(nades, MakePlayerObserver) { nades_RemovePlayer(); }
+MUTATOR_HOOKFUNCTION(nades, ClientDisconnect) { nades_RemovePlayer(); }
+MUTATOR_HOOKFUNCTION(nades, reset_map_global) { nades_RemovePlayer(); }
+
+MUTATOR_HOOKFUNCTION(nades, SpectateCopy)
+{SELFPARAM();
+       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;
+}
+
+MUTATOR_HOOKFUNCTION(nades, BuildMutatorsString)
+{
+       ret_string = strcat(ret_string, ":Nades");
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(nades, BuildMutatorsPrettyString)
+{
+       ret_string = strcat(ret_string, ", Nades");
+       return false;
+}
+#endif
diff --git a/qcsrc/server/mutators/mutator/mutator_new_toys.qc b/qcsrc/server/mutators/mutator/mutator_new_toys.qc
new file mode 100644 (file)
index 0000000..78904ff
--- /dev/null
@@ -0,0 +1,227 @@
+#ifdef IMPLEMENTATION
+/*
+
+CORE    laser   vortex     lg      rl      cry     gl      elec    hagar   fireb   hook
+                                                                       vaporizer  porto
+                                                                       tuba
+
+NEW             rifle   hlac    minel                           seeker
+IDEAS                                   OPEN    flak    OPEN            FUN FUN FUN FUN
+
+
+
+How this mutator works:
+ =======================
+
+When a gun tries to spawn, this mutator is called. It will provide alternate
+weaponreplace lists.
+
+Entity:
+
+{
+"classname" "weapon_vortex"
+"new_toys" "rifle"
+}
+-> This will spawn as Rifle in this mutator ONLY, and as Vortex otherwise.
+
+{
+"classname" "weapon_vortext"
+"new_toys" "vortex rifle"
+}
+-> This will spawn as either Vortex or Rifle in this mutator ONLY, and as Vortex otherwise.
+
+{
+"classname" "weapon_vortex"
+"new_toys" "vortex"
+}
+-> This is always a Vortex.
+
+If the map specifies no "new_toys" argument
+
+There will be two default replacements selectable: "replace all" and "replace random".
+In "replace all" mode, e.g. Vortex will have the default replacement "rifle".
+In "replace random" mode, Vortex will have the default replacement "vortex rifle".
+
+This mutator's replacements run BEFORE regular weaponreplace!
+
+The New Toys guns do NOT get a spawn function, so they can only ever be spawned
+when this mutator is active.
+
+Likewise, warmup, give all, give ALL and impulse 99 will not give them unless
+this mutator is active.
+
+Outside this mutator, they still can be spawned by:
+- setting their start weapon cvar to 1
+- give weaponname
+- weaponreplace
+- weaponarena (but all and most weapons arena again won't include them)
+
+This mutator performs the default replacements on the DEFAULTS of the
+start weapon selection.
+
+These weapons appear in the menu's priority list, BUT get a suffix
+"(Mutator weapon)".
+
+Picking up a "new toys" weapon will not play standard weapon pickup sound, but
+roflsound "New toys, new toys!" sound.
+
+*/
+
+bool nt_IsNewToy(int w);
+
+REGISTER_MUTATOR(nt, cvar("g_new_toys") && !cvar("g_instagib") && !cvar("g_overkill"))
+{
+       MUTATOR_ONADD
+       {
+               if(time > 1) // game loads at time 1
+                       error("This cannot be added at runtime\n");
+
+               // mark the guns as ok to use by e.g. impulse 99
+               for(int i = WEP_FIRST; i <= WEP_LAST; ++i)
+                       if(nt_IsNewToy(i))
+                               get_weaponinfo(i).spawnflags &= ~WEP_FLAG_MUTATORBLOCKED;
+       }
+
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               for(int i = WEP_FIRST; i <= WEP_LAST; ++i)
+                       if(nt_IsNewToy(i))
+                               get_weaponinfo(i).spawnflags |= WEP_FLAG_MUTATORBLOCKED;
+       }
+
+       MUTATOR_ONREMOVE
+       {
+               LOG_INFO("This cannot be removed at runtime\n");
+               return -1;
+       }
+
+       return 0;
+}
+
+.string new_toys;
+
+float autocvar_g_new_toys_autoreplace;
+bool autocvar_g_new_toys_use_pickupsound = true;
+const float NT_AUTOREPLACE_NEVER = 0;
+const float NT_AUTOREPLACE_ALWAYS = 1;
+const float NT_AUTOREPLACE_RANDOM = 2;
+
+MUTATOR_HOOKFUNCTION(nt, SetModname)
+{
+       modname = "NewToys";
+       return 0;
+}
+
+bool nt_IsNewToy(int w)
+{
+       switch(w)
+       {
+               case WEP_SEEKER.m_id:
+               case WEP_MINE_LAYER.m_id:
+               case WEP_HLAC.m_id:
+               case WEP_RIFLE.m_id:
+               case WEP_SHOCKWAVE.m_id:
+                       return true;
+               default:
+                       return false;
+       }
+}
+
+string nt_GetFullReplacement(string w)
+{
+       switch(w)
+       {
+               case "hagar": return "seeker";
+               case "devastator": return "minelayer";
+               case "machinegun": return "hlac";
+               case "vortex": return "rifle";
+               //case "shotgun": return "shockwave";
+               default: return string_null;
+       }
+}
+
+string nt_GetReplacement(string w, float m)
+{
+       if(m == NT_AUTOREPLACE_NEVER)
+               return w;
+       string s = nt_GetFullReplacement(w);
+       if (!s)
+               return w;
+       if(m == NT_AUTOREPLACE_RANDOM)
+               s = strcat(w, " ", s);
+       return s;
+}
+
+MUTATOR_HOOKFUNCTION(nt, SetStartItems)
+{
+       // rearrange start_weapon_default
+       // apply those bits that are set by start_weapon_defaultmask
+       // same for warmup
+
+       float i, j, k, n;
+
+       WepSet newdefault;
+       WepSet warmup_newdefault;
+
+       newdefault = '0 0 0';
+       warmup_newdefault = '0 0 0';
+
+       for(i = WEP_FIRST; i <= WEP_LAST; ++i)
+       {
+               entity e = get_weaponinfo(i);
+               if(!e.weapon)
+                       continue;
+
+               n = tokenize_console(nt_GetReplacement(e.netname, autocvar_g_new_toys_autoreplace));
+
+               for(j = 0; j < n; ++j)
+                       for(k = WEP_FIRST; k <= WEP_LAST; ++k)
+                               if(get_weaponinfo(k).netname == argv(j))
+                               {
+                                       if(start_weapons & WepSet_FromWeapon(i))
+                                               newdefault |= WepSet_FromWeapon(k);
+                                       if(warmup_start_weapons & WepSet_FromWeapon(i))
+                                               warmup_newdefault |= WepSet_FromWeapon(k);
+                               }
+       }
+
+       newdefault &= start_weapons_defaultmask;
+       start_weapons &= ~start_weapons_defaultmask;
+       start_weapons |= newdefault;
+
+       warmup_newdefault &= warmup_start_weapons_defaultmask;
+       warmup_start_weapons &= ~warmup_start_weapons_defaultmask;
+       warmup_start_weapons |= warmup_newdefault;
+
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(nt, SetWeaponreplace)
+{SELFPARAM();
+       // otherwise, we do replace
+       if(self.new_toys)
+       {
+               // map defined replacement:
+               ret_string = self.new_toys;
+       }
+       else
+       {
+               // auto replacement:
+               ret_string = nt_GetReplacement(other.netname, autocvar_g_new_toys_autoreplace);
+       }
+
+       // apply regular weaponreplace
+       ret_string = W_Apply_Weaponreplace(ret_string);
+
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(nt, FilterItem)
+{SELFPARAM();
+       if(nt_IsNewToy(self.weapon) && autocvar_g_new_toys_use_pickupsound) {
+               self.item_pickupsound = string_null;
+               self.item_pickupsound_ent = SND_WEAPONPICKUP_NEW_TOYS;
+       }
+       return 0;
+}
+#endif
diff --git a/qcsrc/server/mutators/mutator/mutator_nix.qc b/qcsrc/server/mutators/mutator/mutator_nix.qc
new file mode 100644 (file)
index 0000000..259547a
--- /dev/null
@@ -0,0 +1,267 @@
+#ifdef IMPLEMENTATION
+float g_nix_with_blaster;
+// WEAPONTODO
+int nix_weapon;
+float nix_nextchange;
+float nix_nextweapon;
+.float nix_lastchange_id;
+.float nix_lastinfotime;
+.float nix_nextincr;
+
+bool NIX_CanChooseWeapon(int wpn);
+
+REGISTER_MUTATOR(nix, cvar("g_nix") && !cvar("g_instagib") && !cvar("g_overkill"))
+{
+       MUTATOR_ONADD
+       {
+               g_nix_with_blaster = autocvar_g_nix_with_blaster;
+
+               nix_nextchange = 0;
+               nix_nextweapon = 0;
+
+               for (int i = WEP_FIRST; i <= WEP_LAST; ++i)
+                       if (NIX_CanChooseWeapon(i)) {
+                               Weapon w = get_weaponinfo(i);
+                               w.wr_init(w);
+                       }
+       }
+
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               // nothing to roll back
+       }
+
+       MUTATOR_ONREMOVE
+       {
+               // as the PlayerSpawn hook will no longer run, NIX is turned off by this!
+               entity e;
+               FOR_EACH_PLAYER(e) if(e.deadflag == DEAD_NO)
+               {
+                       e.ammo_cells = start_ammo_cells;
+                       e.ammo_plasma = start_ammo_plasma;
+                       e.ammo_shells = start_ammo_shells;
+                       e.ammo_nails = start_ammo_nails;
+                       e.ammo_rockets = start_ammo_rockets;
+                       e.ammo_fuel = start_ammo_fuel;
+                       e.weapons = start_weapons;
+                       if(!client_hasweapon(e, e.weapon, true, false))
+                               e.switchweapon = w_getbestweapon(self);
+               }
+       }
+
+       return 0;
+}
+
+bool NIX_CanChooseWeapon(int wpn)
+{
+       entity e = get_weaponinfo(wpn);
+       if(!e.weapon) // skip dummies
+               return false;
+       if(g_weaponarena)
+       {
+               if(!(g_weaponarena_weapons & WepSet_FromWeapon(wpn)))
+                       return false;
+       }
+       else
+       {
+               if(wpn == WEP_BLASTER.m_id && g_nix_with_blaster)
+                       return false;
+               if(e.spawnflags & WEP_FLAG_MUTATORBLOCKED)
+                       return false;
+               if (!(e.spawnflags & WEP_FLAG_NORMAL))
+                       return false;
+       }
+       return true;
+}
+void NIX_ChooseNextWeapon()
+{
+       float j;
+       RandomSelection_Init();
+       for(j = WEP_FIRST; j <= WEP_LAST; ++j)
+               if(NIX_CanChooseWeapon(j))
+                       RandomSelection_Add(world, j, string_null, 1, (j != nix_weapon));
+       nix_nextweapon = RandomSelection_chosen_float;
+}
+
+void NIX_GiveCurrentWeapon()
+{SELFPARAM();
+       float dt;
+
+       if(!nix_nextweapon)
+               NIX_ChooseNextWeapon();
+
+       dt = ceil(nix_nextchange - time);
+
+       if(dt <= 0)
+       {
+               nix_weapon = nix_nextweapon;
+               nix_nextweapon = 0;
+               if (!nix_nextchange) // no round played yet?
+                       nix_nextchange = time; // start the first round now!
+               else
+                       nix_nextchange = time + autocvar_g_balance_nix_roundtime;
+               // Weapon w = get_weaponinfo(nix_weapon);
+               // w.wr_init(w); // forget it, too slow
+       }
+
+       // get weapon info
+       entity e = get_weaponinfo(nix_weapon);
+
+       if(nix_nextchange != self.nix_lastchange_id) // this shall only be called once per round!
+       {
+               self.ammo_shells = self.ammo_nails = self.ammo_rockets = self.ammo_cells = self.ammo_plasma = self.ammo_fuel = 0;
+
+               if(self.items & IT_UNLIMITED_WEAPON_AMMO)
+               {
+                       switch(e.ammo_field)
+                       {
+                               case ammo_shells:  self.ammo_shells  = autocvar_g_pickup_shells_max;  break;
+                               case ammo_nails:   self.ammo_nails   = autocvar_g_pickup_nails_max;   break;
+                               case ammo_rockets: self.ammo_rockets = autocvar_g_pickup_rockets_max; break;
+                               case ammo_cells:   self.ammo_cells   = autocvar_g_pickup_cells_max;   break;
+                               case ammo_plasma:  self.ammo_plasma  = autocvar_g_pickup_plasma_max;   break;
+                               case ammo_fuel:    self.ammo_fuel    = autocvar_g_pickup_fuel_max;    break;
+                       }
+               }
+               else
+               {
+                       switch(e.ammo_field)
+                       {
+                               case ammo_shells:  self.ammo_shells  = autocvar_g_balance_nix_ammo_shells;  break;
+                               case ammo_nails:   self.ammo_nails   = autocvar_g_balance_nix_ammo_nails;   break;
+                               case ammo_rockets: self.ammo_rockets = autocvar_g_balance_nix_ammo_rockets; break;
+                               case ammo_cells:   self.ammo_cells   = autocvar_g_balance_nix_ammo_cells;   break;
+                               case ammo_plasma:  self.ammo_plasma  = autocvar_g_balance_nix_ammo_plasma;   break;
+                               case ammo_fuel:    self.ammo_fuel    = autocvar_g_balance_nix_ammo_fuel;    break;
+                       }
+               }
+
+               self.nix_nextincr = time + autocvar_g_balance_nix_incrtime;
+               if(dt >= 1 && dt <= 5)
+                       self.nix_lastinfotime = -42;
+               else
+                       Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_NIX_NEWWEAPON, nix_weapon);
+
+               Weapon w = get_weaponinfo(nix_weapon);
+               w.wr_resetplayer(w);
+
+               // all weapons must be fully loaded when we spawn
+               if(e.spawnflags & WEP_FLAG_RELOADABLE) // prevent accessing undefined cvars
+                       self.(weapon_load[nix_weapon]) = e.reloading_ammo;
+
+               // vortex too
+               if(WEP_CVAR(vortex, charge))
+               {
+                       if(WEP_CVAR_SEC(vortex, chargepool))
+                               self.vortex_chargepool_ammo = 1;
+                       self.vortex_charge = WEP_CVAR(vortex, charge_start);
+               }
+
+               // set last change info
+               self.nix_lastchange_id = nix_nextchange;
+       }
+       if(self.nix_lastinfotime != dt)
+       {
+               self.nix_lastinfotime = dt; // initial value 0 should count as "not seen"
+               if(dt >= 1 && dt <= 5)
+                       Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_NIX_COUNTDOWN, nix_nextweapon, dt);
+       }
+
+       if(!(self.items & IT_UNLIMITED_WEAPON_AMMO) && time > self.nix_nextincr)
+       {
+               switch(e.ammo_field)
+               {
+                       case ammo_shells:  self.ammo_shells  += autocvar_g_balance_nix_ammoincr_shells;  break;
+                       case ammo_nails:   self.ammo_nails   += autocvar_g_balance_nix_ammoincr_nails;   break;
+                       case ammo_rockets: self.ammo_rockets += autocvar_g_balance_nix_ammoincr_rockets; break;
+                       case ammo_cells:   self.ammo_cells   += autocvar_g_balance_nix_ammoincr_cells;   break;
+                       case ammo_plasma:  self.ammo_plasma  += autocvar_g_balance_nix_ammoincr_plasma;   break;
+                       case ammo_fuel:    self.ammo_fuel    += autocvar_g_balance_nix_ammoincr_fuel;    break;
+               }
+
+               self.nix_nextincr = time + autocvar_g_balance_nix_incrtime;
+       }
+
+       self.weapons = '0 0 0';
+       if(g_nix_with_blaster)
+               self.weapons |= WEPSET(BLASTER);
+       self.weapons |= WepSet_FromWeapon(nix_weapon);
+
+       if(self.switchweapon != nix_weapon)
+               if(!client_hasweapon(self, self.switchweapon, true, false))
+                       if(client_hasweapon(self, nix_weapon, true, false))
+                               W_SwitchWeapon(nix_weapon);
+}
+
+MUTATOR_HOOKFUNCTION(nix, ForbidThrowCurrentWeapon)
+{
+       return 1; // no throwing in NIX
+}
+
+MUTATOR_HOOKFUNCTION(nix, BuildMutatorsString)
+{
+       ret_string = strcat(ret_string, ":NIX");
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(nix, BuildMutatorsPrettyString)
+{
+       ret_string = strcat(ret_string, ", NIX");
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(nix, FilterItem)
+{SELFPARAM();
+       switch (self.items)
+       {
+               case ITEM_HealthSmall.m_itemid:
+               case ITEM_HealthMedium.m_itemid:
+               case ITEM_HealthLarge.m_itemid:
+               case ITEM_HealthMega.m_itemid:
+               case ITEM_ArmorSmall.m_itemid:
+               case ITEM_ArmorMedium.m_itemid:
+               case ITEM_ArmorLarge.m_itemid:
+               case ITEM_ArmorMega.m_itemid:
+                       if (autocvar_g_nix_with_healtharmor)
+                               return 0;
+                       break;
+               case ITEM_Strength.m_itemid:
+               case ITEM_Shield.m_itemid:
+                       if (autocvar_g_nix_with_powerups)
+                               return 0;
+                       break;
+       }
+
+       return 1; // delete all other items
+}
+
+MUTATOR_HOOKFUNCTION(nix, OnEntityPreSpawn)
+{SELFPARAM();
+       if(self.classname == "target_items") // items triggers cannot work in nix (as they change weapons/ammo)
+               return 1;
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(nix, PlayerPreThink)
+{SELFPARAM();
+       if(!intermission_running)
+       if(self.deadflag == DEAD_NO)
+       if(IS_PLAYER(self))
+               NIX_GiveCurrentWeapon();
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(nix, PlayerSpawn)
+{SELFPARAM();
+       self.nix_lastchange_id = -1;
+       NIX_GiveCurrentWeapon(); // overrides the weapons you got when spawning
+       self.items |= IT_UNLIMITED_SUPERWEAPONS;
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(nix, SetModname, CBC_ORDER_LAST)
+{
+       modname = "NIX";
+       return 0;
+}
+#endif
diff --git a/qcsrc/server/mutators/mutator/mutator_overkill.qc b/qcsrc/server/mutators/mutator/mutator_overkill.qc
new file mode 100644 (file)
index 0000000..ea5adbf
--- /dev/null
@@ -0,0 +1,363 @@
+#ifdef IMPLEMENTATION
+.vector ok_deathloc;
+.float ok_spawnsys_timer;
+.float ok_lastwep;
+.float ok_item;
+
+.float ok_notice_time;
+.float ammo_charge[Weapons_MAX];
+.float ok_use_ammocharge;
+.float ok_ammo_charge;
+
+.float ok_pauseregen_finished;
+
+void(entity ent, float wep) ok_DecreaseCharge;
+
+void ok_Initialize();
+
+REGISTER_MUTATOR(ok, cvar("g_overkill") && !cvar("g_instagib") && !g_nexball && cvar_string("g_mod_balance") == "Overkill")
+{
+       MUTATOR_ONADD
+       {
+               ok_Initialize();
+       }
+
+       MUTATOR_ONREMOVE
+       {
+               WEP_RPC.spawnflags |= WEP_FLAG_MUTATORBLOCKED;
+               WEP_HMG.spawnflags |= WEP_FLAG_MUTATORBLOCKED;
+       }
+
+       return false;
+}
+
+void W_Blaster_Attack(entity, float, float, float, float, float, float, float, float, float, float);
+spawnfunc(weapon_hmg);
+spawnfunc(weapon_rpc);
+
+void ok_DecreaseCharge(entity ent, int wep)
+{
+       if(!ent.ok_use_ammocharge) return;
+
+       entity wepent = get_weaponinfo(wep);
+
+       if(wepent.weapon == 0)
+               return; // dummy
+
+       ent.ammo_charge[wep] -= max(0, cvar(sprintf("g_overkill_ammo_decharge_%s", wepent.netname)));
+}
+
+void ok_IncreaseCharge(entity ent, int wep)
+{
+       entity wepent = get_weaponinfo(wep);
+
+       if(wepent.weapon == 0)
+               return; // dummy
+
+       if(ent.ok_use_ammocharge)
+       if(!ent.BUTTON_ATCK) // not while attacking?
+               ent.ammo_charge[wep] = min(autocvar_g_overkill_ammo_charge_limit, ent.ammo_charge[wep] + cvar(sprintf("g_overkill_ammo_charge_rate_%s", wepent.netname)) * frametime / W_TICSPERFRAME);
+}
+
+float ok_CheckWeaponCharge(entity ent, int wep)
+{
+       if(!ent.ok_use_ammocharge) return true;
+
+       entity wepent = get_weaponinfo(wep);
+
+       if(wepent.weapon == 0)
+               return 0; // dummy
+
+       return (ent.ammo_charge[wep] >= cvar(sprintf("g_overkill_ammo_decharge_%s", wepent.netname)));
+}
+
+MUTATOR_HOOKFUNCTION(ok, PlayerDamage_Calculate, CBC_ORDER_LAST)
+{
+       if(IS_PLAYER(frag_attacker) && IS_PLAYER(frag_target))
+       if(DEATH_ISWEAPON(frag_deathtype, WEP_BLASTER))
+       {
+               frag_damage = 0;
+
+               if(frag_attacker != frag_target)
+               if(frag_target.health > 0)
+               if(frag_target.frozen == 0)
+               if(frag_target.deadflag == DEAD_NO)
+               {
+                       Send_Notification(NOTIF_ONE, frag_attacker, MSG_CENTER, CENTER_SECONDARY_NODAMAGE);
+                       frag_force = '0 0 0';
+               }
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ok, PlayerDamage_SplitHealthArmor)
+{SELFPARAM();
+       if(damage_take)
+               self.ok_pauseregen_finished = max(self.ok_pauseregen_finished, time + 2);
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ok, PlayerDies)
+{SELFPARAM();
+       entity targ = ((frag_attacker) ? frag_attacker : frag_target);
+
+       if(IS_MONSTER(self))
+       {
+               remove(other); // remove default item
+               other = world;
+       }
+
+       setself(spawn());
+       self.ok_item = true;
+       self.noalign = true;
+       self.pickup_anyway = true;
+       spawnfunc_item_armor_small(this);
+       self.movetype = MOVETYPE_TOSS;
+       self.gravity = 1;
+       self.reset = SUB_Remove;
+       setorigin(self, frag_target.origin + '0 0 32');
+       self.velocity = '0 0 200' + normalize(targ.origin - self.origin) * 500;
+       self.classname = "droppedweapon"; // hax
+       SUB_SetFade(self, time + 5, 1);
+       setself(this);
+
+       self.ok_lastwep = self.switchweapon;
+
+       return false;
+}
+MUTATOR_HOOKFUNCTION(ok, MonsterDropItem) { ok_PlayerDies(); }
+
+MUTATOR_HOOKFUNCTION(ok, PlayerRegen)
+{SELFPARAM();
+       // overkill's values are different, so use custom regen
+       if(!self.frozen)
+       {
+               self.armorvalue = CalcRotRegen(self.armorvalue, autocvar_g_balance_armor_regenstable, autocvar_g_balance_armor_regen, autocvar_g_balance_armor_regenlinear, 1 * frametime * (time > self.ok_pauseregen_finished), 0, 0, 1, 1 * frametime * (time > self.pauserotarmor_finished), autocvar_g_balance_armor_limit);
+               self.health = CalcRotRegen(self.health, autocvar_g_balance_health_regenstable, 0, 100, 1 * frametime * (time > self.ok_pauseregen_finished), 200, 0, autocvar_g_balance_health_rotlinear, 1 * frametime * (time > self.pauserothealth_finished), autocvar_g_balance_health_limit);
+
+               float minf, maxf, limitf;
+
+               maxf = autocvar_g_balance_fuel_rotstable;
+               minf = autocvar_g_balance_fuel_regenstable;
+               limitf = autocvar_g_balance_fuel_limit;
+
+               self.ammo_fuel = CalcRotRegen(self.ammo_fuel, minf, autocvar_g_balance_fuel_regen, autocvar_g_balance_fuel_regenlinear, frametime * (time > self.pauseregen_finished) * ((self.items & ITEM_JetpackRegen.m_itemid) != 0), maxf, autocvar_g_balance_fuel_rot, autocvar_g_balance_fuel_rotlinear, frametime * (time > self.pauserotfuel_finished), limitf);
+       }
+       return true; // return true anyway, as frozen uses no regen
+}
+
+MUTATOR_HOOKFUNCTION(ok, ForbidThrowCurrentWeapon)
+{
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(ok, PlayerPreThink)
+{SELFPARAM();
+       if(intermission_running || gameover)
+               return false;
+
+       if(self.deadflag != DEAD_NO || !IS_PLAYER(self) || self.frozen)
+               return false;
+
+       if(self.ok_lastwep)
+       {
+               self.switchweapon = self.ok_lastwep;
+               self.ok_lastwep = 0;
+       }
+
+       ok_IncreaseCharge(self, self.weapon);
+
+       if(self.BUTTON_ATCK2)
+       if(!forbidWeaponUse(self) || self.weapon_blocked) // allow if weapon is blocked
+       if(time >= self.jump_interval)
+       {
+               self.jump_interval = time + WEP_CVAR_PRI(blaster, refire) * W_WeaponRateFactor();
+               makevectors(self.v_angle);
+
+               int oldwep = self.weapon;
+               self.weapon = WEP_BLASTER.m_id;
+               W_Blaster_Attack(
+                       self,
+                       WEP_BLASTER.m_id | HITTYPE_SECONDARY,
+                       WEP_CVAR_SEC(vaporizer, shotangle),
+                       WEP_CVAR_SEC(vaporizer, damage),
+                       WEP_CVAR_SEC(vaporizer, edgedamage),
+                       WEP_CVAR_SEC(vaporizer, radius),
+                       WEP_CVAR_SEC(vaporizer, force),
+                       WEP_CVAR_SEC(vaporizer, speed),
+                       WEP_CVAR_SEC(vaporizer, spread),
+                       WEP_CVAR_SEC(vaporizer, delay),
+                       WEP_CVAR_SEC(vaporizer, lifetime)
+               );
+               self.weapon = oldwep;
+       }
+
+       self.weapon_blocked = false;
+
+       self.ok_ammo_charge = self.ammo_charge[self.weapon];
+
+       if(self.ok_use_ammocharge)
+       if(!ok_CheckWeaponCharge(self, self.weapon))
+       {
+               if(autocvar_g_overkill_ammo_charge_notice && time > self.ok_notice_time && self.BUTTON_ATCK && IS_REAL_CLIENT(self) && self.weapon == self.switchweapon)
+               {
+                       //Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_OVERKILL_CHARGE);
+                       self.ok_notice_time = time + 2;
+                       play2(self, SND(DRYFIRE));
+               }
+               Weapon wpn = get_weaponinfo(self.weapon);
+               if(self.weaponentity.state != WS_CLEAR)
+                       w_ready(wpn, self, self.BUTTON_ATCK, self.BUTTON_ATCK2);
+
+               self.weapon_blocked = true;
+       }
+
+       self.BUTTON_ATCK2 = 0;
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ok, PlayerSpawn)
+{SELFPARAM();
+       if(autocvar_g_overkill_ammo_charge)
+       {
+               for(int i = WEP_FIRST; i <= WEP_LAST; ++i)
+                       self.ammo_charge[i] = autocvar_g_overkill_ammo_charge_limit;
+
+               self.ok_use_ammocharge = 1;
+               self.ok_notice_time = time;
+       }
+       else
+               self.ok_use_ammocharge = 0;
+
+       self.ok_pauseregen_finished = time + 2;
+
+       return false;
+}
+
+void _spawnfunc_weapon_hmg() { SELFPARAM(); spawnfunc_weapon_hmg(this); }
+void _spawnfunc_weapon_rpc() { SELFPARAM(); spawnfunc_weapon_rpc(this); }
+
+MUTATOR_HOOKFUNCTION(ok, OnEntityPreSpawn)
+{SELFPARAM();
+       if(autocvar_g_powerups)
+       if(autocvar_g_overkill_powerups_replace)
+       {
+               if(self.classname == "item_strength")
+               {
+                       entity wep = spawn();
+                       setorigin(wep, self.origin);
+                       setmodel(wep, MDL_OK_HMG);
+                       wep.classname = "weapon_hmg";
+                       wep.ok_item = true;
+                       wep.noalign = self.noalign;
+                       wep.cnt = self.cnt;
+                       wep.team = self.team;
+                       wep.respawntime = autocvar_g_overkill_superguns_respawn_time;
+                       wep.pickup_anyway = true;
+                       wep.think = _spawnfunc_weapon_hmg;
+                       wep.nextthink = time + 0.1;
+                       return true;
+               }
+
+               if(self.classname == "item_invincible")
+               {
+                       entity wep = spawn();
+                       setorigin(wep, self.origin);
+                       setmodel(wep, MDL_OK_RPC);
+                       wep.classname = "weapon_rpc";
+                       wep.ok_item = true;
+                       wep.noalign = self.noalign;
+                       wep.cnt = self.cnt;
+                       wep.team = self.team;
+                       wep.respawntime = autocvar_g_overkill_superguns_respawn_time;
+                       wep.pickup_anyway = true;
+                       wep.think = _spawnfunc_weapon_rpc;
+                       wep.nextthink = time + 0.1;
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ok, FilterItem)
+{SELFPARAM();
+       if(self.ok_item)
+               return false;
+
+       switch(self.items)
+       {
+               case ITEM_HealthMega.m_itemid: return !(autocvar_g_overkill_100h_anyway);
+               case ITEM_ArmorMega.m_itemid: return !(autocvar_g_overkill_100a_anyway);
+       }
+
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(ok, SpectateCopy)
+{SELFPARAM();
+       self.ammo_charge[self.weapon] = other.ammo_charge[other.weapon];
+       self.ok_use_ammocharge = other.ok_use_ammocharge;
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ok, SetStartItems)
+{
+       WepSet ok_start_items = (WEPSET(MACHINEGUN) | WEPSET(VORTEX) | WEPSET(SHOTGUN));
+
+       if(WEP_RPC.weaponstart > 0) { ok_start_items |= WEPSET(RPC); }
+       if(WEP_HMG.weaponstart > 0) { ok_start_items |= WEPSET(HMG); }
+
+       start_items |= IT_UNLIMITED_WEAPON_AMMO;
+       start_weapons = warmup_start_weapons = ok_start_items;
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ok, BuildMutatorsString)
+{
+       ret_string = strcat(ret_string, ":OK");
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ok, BuildMutatorsPrettyString)
+{
+       ret_string = strcat(ret_string, ", Overkill");
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(ok, SetModname)
+{
+       modname = "Overkill";
+       return true;
+}
+
+void ok_SetCvars()
+{
+       // hack to force overkill playermodels
+       cvar_settemp("sv_defaultcharacter", "1");
+       cvar_settemp("sv_defaultplayermodel", "models/ok_player/okrobot1.dpm models/ok_player/okrobot2.dpm models/ok_player/okrobot3.dpm models/ok_player/okrobot4.dpm models/ok_player/okmale1.dpm models/ok_player/okmale2.dpm models/ok_player/okmale3.dpm models/ok_player/okmale4.dpm");
+       cvar_settemp("sv_defaultplayermodel_red", "models/ok_player/okrobot1.dpm models/ok_player/okrobot2.dpm models/ok_player/okrobot3.dpm models/ok_player/okrobot4.dpm");
+       cvar_settemp("sv_defaultplayermodel_blue", "models/ok_player/okmale1.dpm models/ok_player/okmale2.dpm models/ok_player/okmale3.dpm models/ok_player/okmale4.dpm");
+}
+
+void ok_Initialize()
+{
+       ok_SetCvars();
+
+       precache_all_playermodels("models/ok_player/*.dpm");
+
+       addstat(STAT_OK_AMMO_CHARGE, AS_FLOAT, ok_use_ammocharge);
+       addstat(STAT_OK_AMMO_CHARGEPOOL, AS_FLOAT, ok_ammo_charge);
+
+       WEP_RPC.spawnflags &= ~WEP_FLAG_MUTATORBLOCKED;
+       WEP_HMG.spawnflags &= ~WEP_FLAG_MUTATORBLOCKED;
+
+       WEP_SHOTGUN.mdl = "ok_shotgun";
+       WEP_MACHINEGUN.mdl = "ok_mg";
+       WEP_VORTEX.mdl = "ok_sniper";
+}
+#endif
diff --git a/qcsrc/server/mutators/mutator/mutator_physical_items.qc b/qcsrc/server/mutators/mutator/mutator_physical_items.qc
new file mode 100644 (file)
index 0000000..58a01ca
--- /dev/null
@@ -0,0 +1,139 @@
+#ifdef IMPLEMENTATION
+REGISTER_MUTATOR(physical_items, cvar("g_physical_items"))
+{
+       // check if we have a physics engine
+       MUTATOR_ONADD
+       {
+               if (!(autocvar_physics_ode && checkextension("DP_PHYSICS_ODE")))
+               {
+                       LOG_TRACE("Warning: Physical items are enabled but no physics engine can be used. Reverting to old items.\n");
+                       return -1;
+               }
+       }
+
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               // nothing to roll back
+       }
+
+       MUTATOR_ONREMOVE
+       {
+               LOG_INFO("This cannot be removed at runtime\n");
+               return -1;
+       }
+
+       return 0;
+}
+
+.vector spawn_origin, spawn_angles;
+
+void physical_item_think()
+{SELFPARAM();
+       self.nextthink = time;
+
+       self.alpha = self.owner.alpha; // apply fading and ghosting
+
+       if(!self.cnt) // map item, not dropped
+       {
+               // copy ghost item properties
+               self.colormap = self.owner.colormap;
+               self.colormod = self.owner.colormod;
+               self.glowmod = self.owner.glowmod;
+
+               // if the item is not spawned, make sure the invisible / ghost item returns to its origin and stays there
+               if(autocvar_g_physical_items_reset)
+               {
+                       if(self.owner.wait > time) // awaiting respawn
+                       {
+                               setorigin(self, self.spawn_origin);
+                               self.angles = self.spawn_angles;
+                               self.solid = SOLID_NOT;
+                               self.alpha = -1;
+                               self.movetype = MOVETYPE_NONE;
+                       }
+                       else
+                       {
+                               self.alpha = 1;
+                               self.solid = SOLID_CORPSE;
+                               self.movetype = MOVETYPE_PHYSICS;
+                       }
+               }
+       }
+
+       if(!self.owner.modelindex)
+               remove(self); // the real item is gone, remove this
+}
+
+void physical_item_touch()
+{SELFPARAM();
+       if(!self.cnt) // not for dropped items
+       if (ITEM_TOUCH_NEEDKILL())
+       {
+               setorigin(self, self.spawn_origin);
+               self.angles = self.spawn_angles;
+       }
+}
+
+void physical_item_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
+{SELFPARAM();
+       if(!self.cnt) // not for dropped items
+       if(ITEM_DAMAGE_NEEDKILL(deathtype))
+       {
+               setorigin(self, self.spawn_origin);
+               self.angles = self.spawn_angles;
+       }
+}
+
+MUTATOR_HOOKFUNCTION(physical_items, Item_Spawn)
+{SELFPARAM();
+       if(self.owner == world && autocvar_g_physical_items <= 1)
+               return false;
+       if (self.spawnflags & 1) // floating item
+               return false;
+
+       // The actual item can't be physical and trigger at the same time, so make it invisible and use a second entity for physics.
+       // Ugly hack, but unless SOLID_TRIGGER is gotten to work with MOVETYPE_PHYSICS in the engine it can't be fixed.
+       entity wep;
+       wep = spawn();
+       _setmodel(wep, self.model);
+       setsize(wep, self.mins, self.maxs);
+       setorigin(wep, self.origin);
+       wep.angles = self.angles;
+       wep.velocity = self.velocity;
+
+       wep.owner = self;
+       wep.solid = SOLID_CORPSE;
+       wep.movetype = MOVETYPE_PHYSICS;
+       wep.takedamage = DAMAGE_AIM;
+       wep.effects |= EF_NOMODELFLAGS; // disable the spinning
+       wep.colormap = self.owner.colormap;
+       wep.glowmod = self.owner.glowmod;
+       wep.damageforcescale = autocvar_g_physical_items_damageforcescale;
+       wep.dphitcontentsmask = self.dphitcontentsmask;
+       wep.cnt = (self.owner != world);
+
+       wep.think = physical_item_think;
+       wep.nextthink = time;
+       wep.touch = physical_item_touch;
+       wep.event_damage = physical_item_damage;
+
+       if(!wep.cnt)
+       {
+               // fix the spawn origin
+               setorigin(wep, wep.origin + '0 0 1');
+               entity oldself;
+               oldself = self;
+               WITH(entity, self, wep, builtin_droptofloor());
+       }
+
+       wep.spawn_origin = wep.origin;
+       wep.spawn_angles = self.angles;
+
+       self.effects |= EF_NODRAW; // hide the original weapon
+       self.movetype = MOVETYPE_FOLLOW;
+       self.aiment = wep; // attach the original weapon
+       self.SendEntity = func_null;
+
+       return false;
+}
+#endif
diff --git a/qcsrc/server/mutators/mutator/mutator_pinata.qc b/qcsrc/server/mutators/mutator/mutator_pinata.qc
new file mode 100644 (file)
index 0000000..a806b29
--- /dev/null
@@ -0,0 +1,27 @@
+#ifdef IMPLEMENTATION
+REGISTER_MUTATOR(pinata, cvar("g_pinata") && !cvar("g_instagib") && !cvar("g_overkill"));
+
+MUTATOR_HOOKFUNCTION(pinata, PlayerDies)
+{SELFPARAM();
+       for(int j = WEP_FIRST; j <= WEP_LAST; ++j)
+       if(self.weapons & WepSet_FromWeapon(j))
+       if(self.switchweapon != j)
+       if(W_IsWeaponThrowable(j))
+               W_ThrowNewWeapon(self, j, false, self.origin + (self.mins + self.maxs) * 0.5, randomvec() * 175 + '0 0 325');
+
+       return true;
+}
+
+MUTATOR_HOOKFUNCTION(pinata, BuildMutatorsString)
+{
+       ret_string = strcat(ret_string, ":Pinata");
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(pinata, BuildMutatorsPrettyString)
+{
+       ret_string = strcat(ret_string, ", Piñata");
+       return false;
+}
+
+#endif
diff --git a/qcsrc/server/mutators/mutator/mutator_random_gravity.qc b/qcsrc/server/mutators/mutator/mutator_random_gravity.qc
new file mode 100644 (file)
index 0000000..1b17c9f
--- /dev/null
@@ -0,0 +1,49 @@
+#ifdef IMPLEMENTATION
+// Random Gravity
+//
+// Mutator by Mario
+// Inspired by Player 2
+
+REGISTER_MUTATOR(random_gravity, cvar("g_random_gravity"))
+{
+       MUTATOR_ONADD
+       {
+               cvar_settemp("sv_gravity", cvar_string("sv_gravity")); // settemp current gravity so it's restored on match end
+       }
+
+       return false;
+}
+
+float gravity_delay;
+
+MUTATOR_HOOKFUNCTION(random_gravity, SV_StartFrame)
+{
+       if(gameover || !cvar("g_random_gravity")) return false;
+       if(time < gravity_delay) return false;
+       if(time < game_starttime) return false;
+       if(round_handler_IsActive() && !round_handler_IsRoundStarted()) return false;
+
+    if(random() >= autocvar_g_random_gravity_negative_chance)
+        cvar_set("sv_gravity", ftos(bound(autocvar_g_random_gravity_min, random() - random() * -autocvar_g_random_gravity_negative, autocvar_g_random_gravity_max)));
+    else
+        cvar_set("sv_gravity", ftos(bound(autocvar_g_random_gravity_min, random() * autocvar_g_random_gravity_positive, autocvar_g_random_gravity_max)));
+
+       gravity_delay = time + autocvar_g_random_gravity_delay;
+
+       LOG_TRACE("Gravity is now: ", ftos(autocvar_sv_gravity), "\n");
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(random_gravity, BuildMutatorsString)
+{
+       ret_string = strcat(ret_string, ":RandomGravity");
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(random_gravity, BuildMutatorsPrettyString)
+{
+       ret_string = strcat(ret_string, ", Random gravity");
+       return 0;
+}
+#endif
diff --git a/qcsrc/server/mutators/mutator/mutator_rocketflying.qc b/qcsrc/server/mutators/mutator/mutator_rocketflying.qc
new file mode 100644 (file)
index 0000000..f23d991
--- /dev/null
@@ -0,0 +1,25 @@
+#ifdef IMPLEMENTATION
+REGISTER_MUTATOR(rocketflying, cvar("g_rocket_flying"));
+
+MUTATOR_HOOKFUNCTION(rocketflying, EditProjectile)
+{
+       if(other.classname == "rocket" || other.classname == "mine")
+       {
+               // kill detonate delay of rockets
+               other.spawnshieldtime = time;
+       }
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(rocketflying, BuildMutatorsString)
+{
+       ret_string = strcat(ret_string, ":RocketFlying");
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(rocketflying, BuildMutatorsPrettyString)
+{
+       ret_string = strcat(ret_string, ", Rocket Flying");
+       return 0;
+}
+#endif
diff --git a/qcsrc/server/mutators/mutator/mutator_rocketminsta.qc b/qcsrc/server/mutators/mutator/mutator_rocketminsta.qc
new file mode 100644 (file)
index 0000000..f8a1709
--- /dev/null
@@ -0,0 +1,35 @@
+#ifdef IMPLEMENTATION
+#include "../../../common/deathtypes/all.qh"
+#include "../../round_handler.qh"
+
+REGISTER_MUTATOR(rm, cvar("g_instagib"));
+
+MUTATOR_HOOKFUNCTION(rm, PlayerDamage_Calculate)
+{
+       // we do it this way, so rm can be toggled during the match
+       if(!autocvar_g_rm) { return false; }
+
+       if(DEATH_ISWEAPON(frag_deathtype, WEP_DEVASTATOR))
+       if(frag_attacker == frag_target || frag_target.classname == "nade")
+               frag_damage = 0;
+
+       if(autocvar_g_rm_laser)
+       if(DEATH_ISWEAPON(frag_deathtype, WEP_ELECTRO))
+       if(frag_attacker == frag_target || (round_handler_IsActive() && !round_handler_IsRoundStarted()))
+               frag_damage = 0;
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(rm, PlayerDies)
+{
+       // we do it this way, so rm can be toggled during the match
+       if(!autocvar_g_rm) { return false; }
+
+       if(DEATH_ISWEAPON(frag_deathtype, WEP_DEVASTATOR) || DEATH_ISWEAPON(frag_deathtype, WEP_ELECTRO))
+               frag_damage = 1000; // always gib if it was a vaporizer death
+
+       return false;
+}
+
+#endif
diff --git a/qcsrc/server/mutators/mutator/mutator_spawn_near_teammate.qc b/qcsrc/server/mutators/mutator/mutator_spawn_near_teammate.qc
new file mode 100644 (file)
index 0000000..24147b2
--- /dev/null
@@ -0,0 +1,167 @@
+#ifdef IMPLEMENTATION
+REGISTER_MUTATOR(spawn_near_teammate, cvar("g_spawn_near_teammate") && teamplay);
+
+.entity msnt_lookat;
+
+.float msnt_timer;
+.vector msnt_deathloc;
+
+.float cvar_cl_spawn_near_teammate;
+
+MUTATOR_HOOKFUNCTION(spawn_near_teammate, Spawn_Score)
+{SELFPARAM();
+       if(autocvar_g_spawn_near_teammate_ignore_spawnpoint == 1 || (autocvar_g_spawn_near_teammate_ignore_spawnpoint == 2 && self.cvar_cl_spawn_near_teammate))
+               return 0;
+
+       entity p;
+
+       spawn_spot.msnt_lookat = world;
+
+       if(!teamplay)
+               return 0;
+
+       RandomSelection_Init();
+       FOR_EACH_PLAYER(p) if(p != self) if(p.team == self.team) if(!p.deadflag)
+       {
+               float l = vlen(spawn_spot.origin - p.origin);
+               if(l > autocvar_g_spawn_near_teammate_distance)
+                       continue;
+               if(l < 48)
+                       continue;
+               if(!checkpvs(spawn_spot.origin, p))
+                       continue;
+               RandomSelection_Add(p, 0, string_null, 1, 1);
+       }
+
+       if(RandomSelection_chosen_ent)
+       {
+               spawn_spot.msnt_lookat = RandomSelection_chosen_ent;
+               spawn_score.x += SPAWN_PRIO_NEAR_TEAMMATE_FOUND;
+       }
+       else if(self.team == spawn_spot.team)
+               spawn_score.x += SPAWN_PRIO_NEAR_TEAMMATE_SAMETEAM; // prefer same team, if we can't find a spawn near teammate
+
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(spawn_near_teammate, PlayerSpawn)
+{SELFPARAM();
+       // Note: when entering this, fixangle is already set.
+       if(autocvar_g_spawn_near_teammate_ignore_spawnpoint == 1 || (autocvar_g_spawn_near_teammate_ignore_spawnpoint == 2 && self.cvar_cl_spawn_near_teammate))
+       {
+               if(autocvar_g_spawn_near_teammate_ignore_spawnpoint_delay_death)
+                       self.msnt_timer = time + autocvar_g_spawn_near_teammate_ignore_spawnpoint_delay_death;
+
+               entity team_mate, best_mate = world;
+               vector best_spot = '0 0 0';
+               float pc = 0, best_dist = 0, dist = 0;
+               FOR_EACH_PLAYER(team_mate)
+               {
+                       if((autocvar_g_spawn_near_teammate_ignore_spawnpoint_check_health >= 0 && team_mate.health >= autocvar_g_balance_health_regenstable) || autocvar_g_spawn_near_teammate_ignore_spawnpoint_check_health == 0)
+                       if(team_mate.deadflag == DEAD_NO)
+                       if(team_mate.msnt_timer < time)
+                       if(SAME_TEAM(self, team_mate))
+                       if(time > team_mate.spawnshieldtime) // spawn shielding
+                       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);
+                               if(trace_fraction != 1.0)
+                               if(!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY))
+                               {
+                                       pc = pointcontents(trace_endpos + '0 0 1');
+                                       if(pc == CONTENT_EMPTY)
+                                       {
+                                               if(vlen(team_mate.velocity) > 5)
+                                                       fixedmakevectors(vectoangles(team_mate.velocity));
+                                               else
+                                                       fixedmakevectors(team_mate.angles);
+
+                                               for(pc = 0; pc != 5; ++pc) // test 5 diffrent spots close to mate
+                                               {
+                                                       switch(pc)
+                                                       {
+                                                               case 0:
+                                                                       tracebox(team_mate.origin , PL_MIN, PL_MAX, team_mate.origin + v_right * 128, MOVE_NORMAL, team_mate);
+                                                                       break;
+                                                               case 1:
+                                                                       tracebox(team_mate.origin , PL_MIN, PL_MAX, team_mate.origin - v_right * 128 , MOVE_NORMAL, team_mate);
+                                                                       break;
+                                                               case 2:
+                                                                       tracebox(team_mate.origin , PL_MIN, PL_MAX, team_mate.origin + v_right * 64 - v_forward * 64, MOVE_NORMAL, team_mate);
+                                                                       break;
+                                                               case 3:
+                                                                       tracebox(team_mate.origin , PL_MIN, PL_MAX, team_mate.origin - v_right * 64 - v_forward * 64, MOVE_NORMAL, team_mate);
+                                                                       break;
+                                                               case 4:
+                                                                       tracebox(team_mate.origin , PL_MIN, PL_MAX, team_mate.origin - v_forward * 128, MOVE_NORMAL, team_mate);
+                                                                       break;
+                                                       }
+
+                                                       if(trace_fraction == 1.0)
+                                                       {
+                                                               traceline(trace_endpos + '0 0 4', trace_endpos - '0 0 100', MOVE_NORMAL, team_mate);
+                                                               if(trace_fraction != 1.0)
+                                                               {
+                                                                       if(autocvar_g_spawn_near_teammate_ignore_spawnpoint_closetodeath)
+                                                                       {
+                                                                               dist = vlen(trace_endpos - self.msnt_deathloc);
+                                                                               if(dist < best_dist || best_dist == 0)
+                                                                               {
+                                                                                       best_dist = dist;
+                                                                                       best_spot = trace_endpos;
+                                                                                       best_mate = team_mate;
+                                                                               }
+                                                                       }
+                                                                       else
+                                                                       {
+                                                                               setorigin(self, trace_endpos);
+                                                                               self.angles = team_mate.angles;
+                                                                               self.angles_z = 0; // never spawn tilted even if the spot says to
+                                                                               team_mate.msnt_timer = time + autocvar_g_spawn_near_teammate_ignore_spawnpoint_delay;
+                                                                               return 0;
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               if(autocvar_g_spawn_near_teammate_ignore_spawnpoint_closetodeath)
+               if(best_dist)
+               {
+                       setorigin(self, best_spot);
+                       self.angles = best_mate.angles;
+                       self.angles_z = 0; // never spawn tilted even if the spot says to
+                       best_mate.msnt_timer = time + autocvar_g_spawn_near_teammate_ignore_spawnpoint_delay;
+               }
+       }
+       else if(spawn_spot.msnt_lookat)
+       {
+               self.angles = vectoangles(spawn_spot.msnt_lookat.origin - self.origin);
+               self.angles_x = -self.angles.x;
+               self.angles_z = 0; // never spawn tilted even if the spot says to
+               /*
+               sprint(self, "You should be looking at ", spawn_spot.msnt_lookat.netname, "^7.\n");
+               sprint(self, "distance: ", vtos(spawn_spot.msnt_lookat.origin - self.origin), "\n");
+               sprint(self, "angles: ", vtos(self.angles), "\n");
+               */
+       }
+
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(spawn_near_teammate, PlayerDies)
+{SELFPARAM();
+       self.msnt_deathloc = self.origin;
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(spawn_near_teammate, GetCvars)
+{
+       GetCvars_handleFloat(get_cvars_s, get_cvars_f, cvar_cl_spawn_near_teammate, "cl_spawn_near_teammate");
+       return false;
+}
+#endif
diff --git a/qcsrc/server/mutators/mutator/mutator_superspec.qc b/qcsrc/server/mutators/mutator/mutator_superspec.qc
new file mode 100644 (file)
index 0000000..f24b323
--- /dev/null
@@ -0,0 +1,480 @@
+#ifdef IMPLEMENTATION
+REGISTER_MUTATOR(superspec, cvar("g_superspectate"));
+
+#define _SSMAGIX "SUPERSPEC_OPTIONSFILE_V1"
+#define _ISLOCAL ((edict_num(1) == self) ? true : false)
+
+const float ASF_STRENGTH               = 1;
+const float ASF_SHIELD                         = 2;
+const float ASF_MEGA_AR                = 4;
+const float ASF_MEGA_HP                = 8;
+const float ASF_FLAG_GRAB              = 16;
+const float ASF_OBSERVER_ONLY  = 32;
+const float ASF_SHOWWHAT               = 64;
+const float ASF_SSIM                   = 128;
+const float ASF_FOLLOWKILLER   = 256;
+const float ASF_ALL                    = 0xFFFFFF;
+.float autospec_flags;
+
+const float SSF_SILENT = 1;
+const float SSF_VERBOSE = 2;
+const float SSF_ITEMMSG = 4;
+.float superspec_flags;
+
+.string superspec_itemfilter; //"classname1 classname2 ..."
+
+bool superspec_Spectate(entity _player)
+{SELFPARAM();
+       if(Spectate(_player) == 1)
+               self.classname = "spectator";
+
+       return true;
+}
+
+void superspec_save_client_conf()
+{SELFPARAM();
+       string fn = "superspec-local.options";
+       float fh;
+
+       if (!_ISLOCAL)
+       {
+               if(self.crypto_idfp == "")
+                       return;
+
+               fn = sprintf("superspec-%s.options", uri_escape(self.crypto_idfp));
+       }
+
+       fh = fopen(fn, FILE_WRITE);
+       if(fh < 0)
+       {
+               LOG_TRACE("^1ERROR: ^7 superspec can not open ", fn, " for writing.\n");
+       }
+       else
+       {
+               fputs(fh, _SSMAGIX);
+               fputs(fh, "\n");
+               fputs(fh, ftos(self.autospec_flags));
+               fputs(fh, "\n");
+               fputs(fh, ftos(self.superspec_flags));
+               fputs(fh, "\n");
+               fputs(fh, self.superspec_itemfilter);
+               fputs(fh, "\n");
+               fclose(fh);
+       }
+}
+
+void superspec_msg(string _center_title, string _con_title, entity _to, string _msg, float _spamlevel)
+{
+       sprint(_to, strcat(_con_title, _msg));
+
+       if(_to.superspec_flags & SSF_SILENT)
+               return;
+
+       if(_spamlevel > 1)
+               if (!(_to.superspec_flags & SSF_VERBOSE))
+                       return;
+
+       centerprint(_to, strcat(_center_title, _msg));
+}
+
+float superspec_filteritem(entity _for, entity _item)
+{
+       float i;
+
+       if(_for.superspec_itemfilter == "")
+               return true;
+
+       if(_for.superspec_itemfilter == "")
+               return true;
+
+       float l = tokenize_console(_for.superspec_itemfilter);
+       for(i = 0; i < l; ++i)
+       {
+               if(argv(i) == _item.classname)
+                       return true;
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(superspec, ItemTouch)
+{SELFPARAM();
+       entity _item = self;
+
+       entity e;
+       FOR_EACH_SPEC(e)
+       {
+               setself(e);
+               if(self.superspec_flags & SSF_ITEMMSG)
+                       if(superspec_filteritem(self, _item))
+                       {
+                               if(self.superspec_flags & SSF_VERBOSE)
+                                       superspec_msg("", "", self, sprintf("Player %s^7 just picked up ^3%s\n", other.netname, _item.netname), 1);
+                               else
+                                       superspec_msg("", "", self, sprintf("Player %s^7 just picked up ^3%s\n^8(%s^8)\n", other.netname, _item.netname, _item.classname), 1);
+                               if((self.autospec_flags & ASF_SSIM) && self.enemy != other)
+                               {
+                                       superspec_Spectate(other);
+
+                                       setself(this);
+                                       return MUT_ITEMTOUCH_CONTINUE;
+                               }
+                       }
+
+               if((self.autospec_flags & ASF_SHIELD && _item.invincible_finished) ||
+                       (self.autospec_flags & ASF_STRENGTH && _item.strength_finished) ||
+                       (self.autospec_flags & ASF_MEGA_AR && _item.itemdef == ITEM_ArmorMega) ||
+                       (self.autospec_flags & ASF_MEGA_HP && _item.itemdef == ITEM_HealthMega) ||
+                       (self.autospec_flags & ASF_FLAG_GRAB && _item.classname == "item_flag_team"))
+               {
+
+                       if((self.enemy != other) || IS_OBSERVER(self))
+                       {
+                               if(self.autospec_flags & ASF_OBSERVER_ONLY && !IS_OBSERVER(self))
+                               {
+                                       if(self.superspec_flags & SSF_VERBOSE)
+                                               superspec_msg("", "", self, sprintf("^8Ignored that ^7%s^8 grabbed %s^8 since the observer_only option is ON\n", other.netname, _item.netname), 2);
+                               }
+                               else
+                               {
+                                       if(self.autospec_flags & ASF_SHOWWHAT)
+                                               superspec_msg("", "", self, sprintf("^7Following %s^7 due to picking up %s\n", other.netname, _item.netname), 2);
+
+                                       superspec_Spectate(other);
+                               }
+                       }
+               }
+       }
+
+       setself(this);
+
+       return MUT_ITEMTOUCH_CONTINUE;
+}
+
+MUTATOR_HOOKFUNCTION(superspec, SV_ParseClientCommand)
+{SELFPARAM();
+#define OPTIONINFO(flag,var,test,text,long,short) \
+    var = strcat(var, ((flag & test) ? "^2[ON]  ^7" : "^1[OFF] ^7")); \
+    var = strcat(var, text," ^7(^3 ", long, "^7 | ^3", short, " ^7)\n")
+
+       if(MUTATOR_RETURNVALUE) // command was already handled?
+               return false;
+
+       if(IS_PLAYER(self))
+               return false;
+
+       if(cmd_name == "superspec_itemfilter")
+       {
+               if(argv(1) == "help")
+               {
+                       string _aspeco;
+                       _aspeco = "^7 superspec_itemfilter ^3\"item_classname1 item_classname2\"^7 only show thise items when ^2superspec ^3item_message^7 is on\n";
+                       _aspeco = strcat(_aspeco, "^3 clear^7 Remove the filter (show all pickups)\n");
+                       _aspeco = strcat(_aspeco, "^3 show ^7 Display current filter\n");
+                       superspec_msg("^3superspec_itemfilter help:\n\n\n", "\n^3superspec_itemfilter help:\n", self, _aspeco, 1);
+               }
+               else if(argv(1) == "clear")
+               {
+                       if(self.superspec_itemfilter != "")
+                               strunzone(self.superspec_itemfilter);
+
+                       self.superspec_itemfilter = "";
+               }
+               else if(argv(1) == "show" || argv(1) == "")
+               {
+                       if(self.superspec_itemfilter == "")
+                       {
+                               superspec_msg("^3superspec_itemfilter^7 is ^1not^7 set", "\n^3superspec_itemfilter^7 is ^1not^7 set\n", self, "", 1);
+                               return true;
+                       }
+                       float i;
+                       float l = tokenize_console(self.superspec_itemfilter);
+                       string _msg = "";
+                       for(i = 0; i < l; ++i)
+                               _msg = strcat(_msg, "^3#", ftos(i), " ^7", argv(i), "\n");
+                               //_msg = sprintf("^3#%d^7 %s\n%s", i, _msg, argv(i));
+
+                       _msg = strcat(_msg,"\n");
+
+                       superspec_msg("^3superspec_itemfilter is:\n\n\n", "\n^3superspec_itemfilter is:\n", self, _msg, 1);
+               }
+               else
+               {
+                       if(self.superspec_itemfilter != "")
+                               strunzone(self.superspec_itemfilter);
+
+                       self.superspec_itemfilter = strzone(argv(1));
+               }
+
+               return true;
+       }
+
+       if(cmd_name == "superspec")
+       {
+               string _aspeco;
+
+               if(cmd_argc > 1)
+               {
+                       float i, _bits = 0, _start = 1;
+                       if(argv(1) == "help")
+                       {
+                               _aspeco = "use cmd superspec [option] [on|off] to set options\n\n";
+                               _aspeco = strcat(_aspeco, "^3 silent ^7(short^5 si^7) supresses ALL messages from superspectate.\n");
+                               _aspeco = strcat(_aspeco, "^3 verbose ^7(short^5 ve^7) makes superspectate print some additional information.\n");
+                               _aspeco = strcat(_aspeco, "^3 item_message ^7(short^5 im^7) makes superspectate print items that were picked up.\n");
+                               _aspeco = strcat(_aspeco, "^7    Use cmd superspec_itemfilter \"item_class1 item_class2\" to set up a filter of what to show with ^3item_message.\n");
+                               superspec_msg("^2Available Super Spectate ^3options:\n\n\n", "\n^2Available Super Spectate ^3options:\n", self, _aspeco, 1);
+                               return true;
+                       }
+
+                       if(argv(1) == "clear")
+                       {
+                               self.superspec_flags = 0;
+                               _start = 2;
+                       }
+
+                       for(i = _start; i < cmd_argc; ++i)
+                       {
+                               if(argv(i) == "on" || argv(i) == "1")
+                               {
+                                       self.superspec_flags |= _bits;
+                                       _bits = 0;
+                               }
+                               else if(argv(i) == "off" || argv(i) == "0")
+                               {
+                                       if(_start == 1)
+                                               self.superspec_flags &= ~_bits;
+
+                                       _bits = 0;
+                               }
+                               else
+                               {
+                                       if((argv(i) == "silent") || (argv(i) == "si")) _bits |= SSF_SILENT ;
+                                       if((argv(i) == "verbose") || (argv(i) == "ve")) _bits |= SSF_VERBOSE;
+                                       if((argv(i) == "item_message") || (argv(i) == "im")) _bits |= SSF_ITEMMSG;
+                               }
+                       }
+               }
+
+               _aspeco = "";
+               OPTIONINFO(self.superspec_flags, _aspeco, SSF_SILENT, "Silent", "silent", "si");
+               OPTIONINFO(self.superspec_flags, _aspeco, SSF_VERBOSE, "Verbose", "verbose", "ve");
+               OPTIONINFO(self.superspec_flags, _aspeco, SSF_ITEMMSG, "Item pickup messages", "item_message", "im");
+
+               superspec_msg("^3Current Super Spectate options are:\n\n\n\n\n", "\n^3Current Super Spectate options are:\n", self, _aspeco, 1);
+
+               return true;
+       }
+
+/////////////////////
+
+       if(cmd_name == "autospec")
+       {
+               string _aspeco;
+               if(cmd_argc > 1)
+               {
+                       if(argv(1) == "help")
+                       {
+                               _aspeco = "use cmd autospec [option] [on|off] to set options\n\n";
+                               _aspeco = strcat(_aspeco, "^3 strength ^7(short^5 st^7) for automatic spectate on strength powerup\n");
+                               _aspeco = strcat(_aspeco, "^3 shield ^7(short^5 sh^7) for automatic spectate on shield powerup\n");
+                               _aspeco = strcat(_aspeco, "^3 mega_health ^7(short^5 mh^7) for automatic spectate on mega health\n");
+                               _aspeco = strcat(_aspeco, "^3 mega_armor ^7(short^5 ma^7) for automatic spectate on mega armor\n");
+                               _aspeco = strcat(_aspeco, "^3 flag_grab ^7(short^5 fg^7) for automatic spectate on CTF flag grab\n");
+                               _aspeco = strcat(_aspeco, "^3 observer_only ^7(short^5 oo^7) for automatic spectate only if in observer mode\n");
+                               _aspeco = strcat(_aspeco, "^3 show_what ^7(short^5 sw^7) to display what event triggered autospectate\n");
+                               _aspeco = strcat(_aspeco, "^3 item_msg ^7(short^5 im^7) to autospec when item_message in superspectate is triggered\n");
+                               _aspeco = strcat(_aspeco, "^3 followkiller ^7(short ^5fk^7) to autospec the killer/off\n");
+                               _aspeco = strcat(_aspeco, "^3 all ^7(short ^5aa^7) to turn everything on/off\n");
+                               superspec_msg("^2Available Auto Spectate ^3options:\n\n\n", "\n^2Available Auto Spectate ^3options:\n", self, _aspeco, 1);
+                               return true;
+                       }
+
+                       float i, _bits = 0, _start = 1;
+                       if(argv(1) == "clear")
+                       {
+                               self.autospec_flags = 0;
+                               _start = 2;
+                       }
+
+                       for(i = _start; i < cmd_argc; ++i)
+                       {
+                               if(argv(i) == "on" || argv(i) == "1")
+                               {
+                                       self.autospec_flags |= _bits;
+                                       _bits = 0;
+                               }
+                               else if(argv(i) == "off" || argv(i) == "0")
+                               {
+                                       if(_start == 1)
+                                               self.autospec_flags &= ~_bits;
+
+                                       _bits = 0;
+                               }
+                               else
+                               {
+                                       if((argv(i) == "strength") || (argv(i) == "st")) _bits |= ASF_STRENGTH;
+                                       if((argv(i) == "shield") || (argv(i) == "sh")) _bits |= ASF_SHIELD;
+                                       if((argv(i) == "mega_health") || (argv(i) == "mh")) _bits |= ASF_MEGA_HP;
+                                       if((argv(i) == "mega_armor") || (argv(i) == "ma")) _bits |= ASF_MEGA_AR;
+                                       if((argv(i) == "flag_grab") || (argv(i) == "fg")) _bits |= ASF_FLAG_GRAB;
+                                       if((argv(i) == "observer_only") || (argv(i) == "oo")) _bits |= ASF_OBSERVER_ONLY;
+                                       if((argv(i) == "show_what") || (argv(i) == "sw")) _bits |= ASF_SHOWWHAT;
+                                       if((argv(i) == "item_msg") || (argv(i) == "im")) _bits |= ASF_SSIM;
+                                       if((argv(i) == "followkiller") || (argv(i) == "fk")) _bits |= ASF_FOLLOWKILLER;
+                                       if((argv(i) == "all") || (argv(i) == "aa")) _bits |= ASF_ALL;
+                               }
+                       }
+               }
+
+               _aspeco = "";
+               OPTIONINFO(self.autospec_flags, _aspeco, ASF_STRENGTH, "Strength", "strength", "st");
+               OPTIONINFO(self.autospec_flags, _aspeco, ASF_SHIELD, "Shield", "shield", "sh");
+               OPTIONINFO(self.autospec_flags, _aspeco, ASF_MEGA_HP, "Mega Health", "mega_health", "mh");
+               OPTIONINFO(self.autospec_flags, _aspeco, ASF_MEGA_AR, "Mega Armor", "mega_armor", "ma");
+               OPTIONINFO(self.autospec_flags, _aspeco, ASF_FLAG_GRAB, "Flag grab", "flag_grab","fg");
+               OPTIONINFO(self.autospec_flags, _aspeco, ASF_OBSERVER_ONLY, "Only switch if observer", "observer_only", "oo");
+               OPTIONINFO(self.autospec_flags, _aspeco, ASF_SHOWWHAT, "Show what item triggered spectate", "show_what", "sw");
+               OPTIONINFO(self.autospec_flags, _aspeco, ASF_SSIM, "Switch on superspec item message", "item_msg", "im");
+               OPTIONINFO(self.autospec_flags, _aspeco, ASF_FOLLOWKILLER, "Followkiller", "followkiller", "fk");
+
+               superspec_msg("^3Current auto spectate options are:\n\n\n\n\n", "\n^3Current auto spectate options are:\n", self, _aspeco, 1);
+               return true;
+       }
+
+       if(cmd_name == "followpowerup")
+       {
+               entity _player;
+               FOR_EACH_PLAYER(_player)
+               {
+                       if(_player.strength_finished > time || _player.invincible_finished > time)
+                               return superspec_Spectate(_player);
+               }
+
+               superspec_msg("", "", self, "No active powerup\n", 1);
+               return true;
+       }
+
+       if(cmd_name == "followstrength")
+       {
+               entity _player;
+               FOR_EACH_PLAYER(_player)
+               {
+                       if(_player.strength_finished > time)
+                               return superspec_Spectate(_player);
+               }
+
+               superspec_msg("", "", self, "No active Strength\n", 1);
+               return true;
+       }
+
+       if(cmd_name == "followshield")
+       {
+               entity _player;
+               FOR_EACH_PLAYER(_player)
+               {
+                       if(_player.invincible_finished > time)
+                               return superspec_Spectate(_player);
+               }
+
+               superspec_msg("", "", self, "No active Shield\n", 1);
+               return true;
+       }
+
+       return false;
+#undef OPTIONINFO
+}
+
+MUTATOR_HOOKFUNCTION(superspec, BuildMutatorsString)
+{
+       ret_string = strcat(ret_string, ":SS");
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(superspec, BuildMutatorsPrettyString)
+{
+       ret_string = strcat(ret_string, ", Super Spectators");
+       return 0;
+}
+
+void superspec_hello()
+{SELFPARAM();
+       if(self.enemy.crypto_idfp == "")
+               Send_Notification(NOTIF_ONE_ONLY, self.enemy, MSG_INFO, INFO_SUPERSPEC_MISSING_UID);
+
+       remove(self);
+}
+
+MUTATOR_HOOKFUNCTION(superspec, ClientConnect)
+{SELFPARAM();
+       if(!IS_REAL_CLIENT(self))
+               return false;
+
+       string fn = "superspec-local.options";
+       float fh;
+
+       self.superspec_flags = SSF_VERBOSE;
+       self.superspec_itemfilter = "";
+
+       entity _hello = spawn();
+       _hello.enemy = self;
+       _hello.think = superspec_hello;
+       _hello.nextthink = time + 5;
+
+       if (!_ISLOCAL)
+       {
+               if(self.crypto_idfp == "")
+                       return false;
+
+               fn = sprintf("superspec-%s.options", uri_escape(self.crypto_idfp));
+       }
+
+       fh = fopen(fn, FILE_READ);
+       if(fh < 0)
+       {
+               LOG_TRACE("^1ERROR: ^7 superspec can not open ", fn, " for reading.\n");
+       }
+       else
+       {
+               string _magic = fgets(fh);
+               if(_magic != _SSMAGIX)
+               {
+                       LOG_TRACE("^1ERROR^7 While reading superspec options file: unknown magic\n");
+               }
+               else
+               {
+                       self.autospec_flags = stof(fgets(fh));
+                       self.superspec_flags = stof(fgets(fh));
+                       self.superspec_itemfilter = strzone(fgets(fh));
+               }
+               fclose(fh);
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(superspec, PlayerDies)
+{SELFPARAM();
+       entity e;
+       FOR_EACH_SPEC(e)
+       {
+               setself(e);
+               if(self.autospec_flags & ASF_FOLLOWKILLER && IS_PLAYER(frag_attacker) && self.enemy == this)
+               {
+                       if(self.autospec_flags & ASF_SHOWWHAT)
+                               superspec_msg("", "", self, sprintf("^7Following %s^7 due to followkiller\n", frag_attacker.netname), 2);
+
+                       superspec_Spectate(frag_attacker);
+               }
+       }
+
+       setself(this);
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(superspec, ClientDisconnect)
+{
+       superspec_save_client_conf();
+       return false;
+}
+#endif
diff --git a/qcsrc/server/mutators/mutator/mutator_touchexplode.qc b/qcsrc/server/mutators/mutator/mutator_touchexplode.qc
new file mode 100644 (file)
index 0000000..29d9a2c
--- /dev/null
@@ -0,0 +1,43 @@
+#ifdef IMPLEMENTATION
+REGISTER_MUTATOR(touchexplode, cvar("g_touchexplode"));
+
+.float touchexplode_time;
+
+void PlayerTouchExplode(entity p1, entity p2)
+{SELFPARAM();
+       vector org = (p1.origin + p2.origin) * 0.5;
+       org.z += (p1.mins.z + p2.mins.z) * 0.5;
+
+       sound(self, CH_TRIGGER, SND_GRENADE_IMPACT, VOL_BASE, ATTEN_NORM);
+       Send_Effect(EFFECT_EXPLOSION_SMALL, org, '0 0 0', 1);
+
+       entity e = spawn();
+       setorigin(e, org);
+       RadiusDamage(e, world, autocvar_g_touchexplode_damage, autocvar_g_touchexplode_edgedamage, autocvar_g_touchexplode_radius, world, world, autocvar_g_touchexplode_force, DEATH_TOUCHEXPLODE.m_id, world);
+       remove(e);
+}
+
+MUTATOR_HOOKFUNCTION(touchexplode, PlayerPreThink)
+{SELFPARAM();
+       if(time > self.touchexplode_time)
+       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))
+               {
+                       PlayerTouchExplode(self, other);
+                       self.touchexplode_time = other.touchexplode_time = time + 0.2;
+               }
+       }
+
+       return false;
+}
+#endif
diff --git a/qcsrc/server/mutators/mutator/mutator_vampire.qc b/qcsrc/server/mutators/mutator/mutator_vampire.qc
new file mode 100644 (file)
index 0000000..315da7d
--- /dev/null
@@ -0,0 +1,28 @@
+#ifdef IMPLEMENTATION
+REGISTER_MUTATOR(vampire, cvar("g_vampire") && !cvar("g_instagib"));
+
+MUTATOR_HOOKFUNCTION(vampire, PlayerDamage_SplitHealthArmor)
+{
+       if(time >= frag_target.spawnshieldtime)
+       if(frag_target != frag_attacker)
+       if(frag_target.deadflag == DEAD_NO)
+       {
+               frag_attacker.health += bound(0, damage_take, frag_target.health);
+               frag_attacker.health = bound(0, frag_attacker.health, autocvar_g_balance_health_limit);
+       }
+
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(vampire, BuildMutatorsString)
+{
+       ret_string = strcat(ret_string, ":Vampire");
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(vampire, BuildMutatorsPrettyString)
+{
+       ret_string = strcat(ret_string, ", Vampire");
+       return 0;
+}
+#endif
diff --git a/qcsrc/server/mutators/mutator/mutator_vampirehook.qc b/qcsrc/server/mutators/mutator/mutator_vampirehook.qc
new file mode 100644 (file)
index 0000000..f669f6a
--- /dev/null
@@ -0,0 +1,38 @@
+#ifdef IMPLEMENTATION
+REGISTER_MUTATOR(vh, cvar("g_vampirehook"));
+
+bool autocvar_g_vampirehook_teamheal;
+float autocvar_g_vampirehook_damage;
+float autocvar_g_vampirehook_damagerate;
+float autocvar_g_vampirehook_health_steal;
+
+.float last_dmg;
+
+MUTATOR_HOOKFUNCTION(vh, GrappleHookThink)
+{SELFPARAM();
+       entity dmgent = ((SAME_TEAM(self.owner, self.aiment) && autocvar_g_vampirehook_teamheal) ? self.owner : self.aiment);
+
+       if(IS_PLAYER(self.aiment))
+       if(self.last_dmg < time)
+       if(!self.aiment.frozen)
+       if(time >= game_starttime)
+       if(DIFF_TEAM(self.owner, self.aiment) || autocvar_g_vampirehook_teamheal)
+       if(self.aiment.health > 0)
+       if(autocvar_g_vampirehook_damage)
+       {
+               self.last_dmg = time + autocvar_g_vampirehook_damagerate;
+               self.owner.damage_dealt += autocvar_g_vampirehook_damage;
+               Damage(dmgent, self, self.owner, autocvar_g_vampirehook_damage, WEP_HOOK.m_id, self.origin, '0 0 0');
+               if(SAME_TEAM(self.owner, self.aiment))
+                       self.aiment.health = min(self.aiment.health + autocvar_g_vampirehook_health_steal, g_pickup_healthsmall_max);
+               else
+                       self.owner.health = min(self.owner.health + autocvar_g_vampirehook_health_steal, g_pickup_healthsmall_max);
+
+               if(dmgent == self.owner)
+                       dmgent.health -= autocvar_g_vampirehook_damage; // FIXME: friendly fire?!
+       }
+
+       return false;
+}
+
+#endif
diff --git a/qcsrc/server/mutators/mutator/sandbox.qc b/qcsrc/server/mutators/mutator/sandbox.qc
new file mode 100644 (file)
index 0000000..dbee6a1
--- /dev/null
@@ -0,0 +1,828 @@
+#ifdef IMPLEMENTATION
+float autosave_time;
+void sandbox_Database_Load();
+
+REGISTER_MUTATOR(sandbox, cvar("g_sandbox"))
+{
+       MUTATOR_ONADD
+       {
+               autosave_time = time + autocvar_g_sandbox_storage_autosave; // don't save the first server frame
+               if(autocvar_g_sandbox_storage_autoload)
+                       sandbox_Database_Load();
+       }
+
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               // nothing to roll back
+       }
+
+       MUTATOR_ONREMOVE
+       {
+               // nothing to remove
+       }
+
+       return false;
+}
+
+const float MAX_STORAGE_ATTACHMENTS = 16;
+float object_count;
+.float object_flood;
+.entity object_attach;
+.string material;
+
+.float touch_timer;
+void sandbox_ObjectFunction_Touch()
+{SELFPARAM();
+       // apply material impact effects
+
+       if(!self.material)
+               return;
+       if(self.touch_timer > time)
+               return; // don't execute each frame
+       self.touch_timer = time + 0.1;
+
+       // make particle count and sound volume depend on impact speed
+       float intensity;
+       intensity = vlen(self.velocity) + vlen(other.velocity);
+       if(intensity) // avoid divisions by 0
+               intensity /= 2; // average the two velocities
+       if (!(intensity >= autocvar_g_sandbox_object_material_velocity_min))
+               return; // impact not strong enough to do anything
+       // now offset intensity and apply it to the effects
+       intensity -= autocvar_g_sandbox_object_material_velocity_min; // start from minimum velocity, not actual velocity
+       intensity = bound(0, intensity * autocvar_g_sandbox_object_material_velocity_factor, 1);
+
+       _sound(self, CH_TRIGGER, strcat("object/impact_", self.material, "_", ftos(ceil(random() * 5)) , ".wav"), VOL_BASE * intensity, ATTEN_NORM);
+       Send_Effect_(strcat("impact_", self.material), self.origin, '0 0 0', ceil(intensity * 10)); // allow a count from 1 to 10
+}
+
+void sandbox_ObjectFunction_Think()
+{SELFPARAM();
+       entity e;
+
+       // decide if and how this object can be grabbed
+       if(autocvar_g_sandbox_readonly)
+               self.grab = 0; // no grabbing
+       else if(autocvar_g_sandbox_editor_free < 2 && self.crypto_idfp)
+               self.grab = 1; // owner only
+       else
+               self.grab = 3; // anyone
+
+       // Object owner is stored via player UID, but we also need the owner as an entity (if the player is available on the server).
+       // Therefore, scan for all players, and update the owner as long as the player is present. We must always do this,
+       // since if the owning player disconnects, the object's owner should also be reset.
+       FOR_EACH_REALPLAYER(e) // bots can't have objects
+       {
+               if(self.crypto_idfp == e.crypto_idfp)
+               {
+                       self.realowner = e;
+                       break;
+               }
+               self.realowner = world;
+       }
+
+       self.nextthink = time;
+
+       CSQCMODEL_AUTOUPDATE(self);
+}
+
+.float old_solid, old_movetype;
+entity sandbox_ObjectEdit_Get(float permissions)
+{SELFPARAM();
+       // Returns the traced entity if the player can edit it, and world if not.
+       // If permissions if false, the object is returned regardless of editing rights.
+       // Attached objects are SOLID_NOT and do not get traced.
+
+       crosshair_trace_plusvisibletriggers(self);
+       if(vlen(self.origin - trace_ent.origin) > autocvar_g_sandbox_editor_distance_edit)
+               return world; // out of trace range
+       if(trace_ent.classname != "object")
+               return world; // entity is not an object
+       if(!permissions)
+               return trace_ent; // don't check permissions, anyone can edit this object
+       if(trace_ent.crypto_idfp == "")
+               return trace_ent; // the player who spawned this object did not have an UID, so anyone can edit it
+       if (!(trace_ent.realowner != self && autocvar_g_sandbox_editor_free < 2))
+               return trace_ent; // object does not belong to the player, and players can only edit their own objects on this server
+       return world;
+}
+
+void sandbox_ObjectEdit_Scale(entity e, float f)
+{
+       e.scale = f;
+       if(e.scale)
+       {
+               e.scale = bound(autocvar_g_sandbox_object_scale_min, e.scale, autocvar_g_sandbox_object_scale_max);
+               _setmodel(e, e.model); // reset mins and maxs based on mesh
+               setsize(e, e.mins * e.scale, e.maxs * e.scale); // adapt bounding box size to model size
+       }
+}
+
+void sandbox_ObjectAttach_Remove(entity e);
+void sandbox_ObjectAttach_Set(entity e, entity parent, string s)
+{
+       // attaches e to parent on string s
+
+       // we can't attach to an attachment, for obvious reasons
+       sandbox_ObjectAttach_Remove(e);
+
+       e.old_solid = e.solid; // persist solidity
+       e.old_movetype = e.movetype; // persist physics
+       e.movetype = MOVETYPE_FOLLOW;
+       e.solid = SOLID_NOT;
+       e.takedamage = DAMAGE_NO;
+
+       setattachment(e, parent, s);
+       e.owner = parent;
+}
+
+void sandbox_ObjectAttach_Remove(entity e)
+{
+       // detaches any object attached to e
+
+       entity head;
+       for(head = world; (head = find(head, classname, "object")); )
+       {
+               if(head.owner == e)
+               {
+                       vector org;
+                       org = gettaginfo(head, 0);
+                       setattachment(head, world, "");
+                       head.owner = world;
+
+                       // objects change origin and angles when detached, so apply previous position
+                       setorigin(head, org);
+                       head.angles = e.angles; // don't allow detached objects to spin or roll
+
+                       head.solid = head.old_solid; // restore persisted solidity
+                       head.movetype = head.old_movetype; // restore persisted physics
+                       head.takedamage = DAMAGE_AIM;
+               }
+       }
+}
+
+entity sandbox_ObjectSpawn(float database)
+{SELFPARAM();
+       // spawn a new object with default properties
+
+       entity e = spawn();
+       e.classname = "object";
+       e.takedamage = DAMAGE_AIM;
+       e.damageforcescale = 1;
+       e.solid = SOLID_BBOX; // SOLID_BSP would be best, but can lag the server badly
+       e.movetype = MOVETYPE_TOSS;
+       e.frame = 0;
+       e.skin = 0;
+       e.material = string_null;
+       e.touch = sandbox_ObjectFunction_Touch;
+       e.think = sandbox_ObjectFunction_Think;
+       e.nextthink = time;
+       //e.effects |= EF_SELECTABLE; // don't do this all the time, maybe just when editing objects?
+
+       if(!database)
+       {
+               // set the object's owner via player UID
+               // if the player does not have an UID, the owner cannot be stored and his objects may be edited by anyone
+               if(self.crypto_idfp != "")
+                       e.crypto_idfp = strzone(self.crypto_idfp);
+               else
+                       print_to(self, "^1SANDBOX - WARNING: ^7You spawned an object, but lack a player UID. ^1Your objects are not secured and can be edited by any player!");
+
+               // set public object information
+               e.netname = strzone(self.netname); // name of the owner
+               e.message = strzone(strftime(true, "%d-%m-%Y %H:%M:%S")); // creation time
+               e.message2 = strzone(strftime(true, "%d-%m-%Y %H:%M:%S")); // last editing time
+
+               // set origin and direction based on player position and view angle
+               makevectors(self.v_angle);
+               WarpZone_TraceLine(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * autocvar_g_sandbox_editor_distance_spawn, MOVE_NORMAL, self);
+               setorigin(e, trace_endpos);
+               e.angles_y = self.v_angle.y;
+       }
+
+       WITH(entity, self, e, CSQCMODEL_AUTOINIT(e));
+
+       object_count += 1;
+       return e;
+}
+
+void sandbox_ObjectRemove(entity e)
+{
+       sandbox_ObjectAttach_Remove(e); // detach child objects
+
+       // if the object being removed has been selected for attachment by a player, unset it
+       entity head;
+       FOR_EACH_REALPLAYER(head) // bots can't have objects
+       {
+               if(head.object_attach == e)
+                       head.object_attach = world;
+       }
+
+       if(e.material)  {       strunzone(e.material);  e.material = string_null;       }
+       if(e.crypto_idfp)       {       strunzone(e.crypto_idfp);       e.crypto_idfp = string_null;    }
+       if(e.netname)   {       strunzone(e.netname);   e.netname = string_null;        }
+       if(e.message)   {       strunzone(e.message);   e.message = string_null;        }
+       if(e.message2)  {       strunzone(e.message2);  e.message2 = string_null;       }
+       remove(e);
+       e = world;
+
+       object_count -= 1;
+}
+
+string port_string[MAX_STORAGE_ATTACHMENTS]; // fteqcc crashes if this isn't defined as a global
+
+string sandbox_ObjectPort_Save(entity e, float database)
+{
+       // save object properties, and return them as a string
+       float i = 0;
+       string s;
+       entity head;
+
+       for(head = world; (head = find(head, classname, "object")); )
+       {
+               // the main object needs to be first in the array [0] with attached objects following
+               float slot, physics, solidity;
+               if(head == e) // this is the main object, place it first
+               {
+                       slot = 0;
+                       solidity = head.solid; // applied solidity is normal solidity for children
+                       physics = head.movetype; // applied physics are normal physics for parents
+               }
+               else if(head.owner == e) // child object, list them in order
+               {
+                       i += 1; // children start from 1
+                       slot = i;
+                       solidity = head.old_solid; // persisted solidity is normal solidity for children
+                       physics = head.old_movetype; // persisted physics are normal physics for children
+                       gettaginfo(head.owner, head.tag_index); // get the name of the tag our object is attached to, used further below
+               }
+               else
+                       continue;
+
+               // ---------------- OBJECT PROPERTY STORAGE: SAVE ----------------
+               if(slot)
+               {
+                       // properties stored only for child objects
+                       if(gettaginfo_name)     port_string[slot] = strcat(port_string[slot], "\"", gettaginfo_name, "\" ");    else    port_string[slot] = strcat(port_string[slot], "\"\" "); // none
+               }
+               else
+               {
+                       // properties stored only for parent objects
+                       if(database)
+                       {
+                               port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", head.origin), " ");
+                               port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", head.angles), " ");
+                       }
+               }
+               // properties stored for all objects
+               port_string[slot] = strcat(port_string[slot], "\"", head.model, "\" ");
+               port_string[slot] = strcat(port_string[slot], ftos(head.skin), " ");
+               port_string[slot] = strcat(port_string[slot], ftos(head.alpha), " ");
+               port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", head.colormod), " ");
+               port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", head.glowmod), " ");
+               port_string[slot] = strcat(port_string[slot], ftos(head.frame), " ");
+               port_string[slot] = strcat(port_string[slot], ftos(head.scale), " ");
+               port_string[slot] = strcat(port_string[slot], ftos(solidity), " ");
+               port_string[slot] = strcat(port_string[slot], ftos(physics), " ");
+               port_string[slot] = strcat(port_string[slot], ftos(head.damageforcescale), " ");
+               if(head.material)       port_string[slot] = strcat(port_string[slot], "\"", head.material, "\" ");      else    port_string[slot] = strcat(port_string[slot], "\"\" "); // none
+               if(database)
+               {
+                       // properties stored only for the database
+                       if(head.crypto_idfp)    port_string[slot] = strcat(port_string[slot], "\"", head.crypto_idfp, "\" ");   else    port_string[slot] = strcat(port_string[slot], "\"\" "); // none
+                       port_string[slot] = strcat(port_string[slot], "\"", e.netname, "\" ");
+                       port_string[slot] = strcat(port_string[slot], "\"", e.message, "\" ");
+                       port_string[slot] = strcat(port_string[slot], "\"", e.message2, "\" ");
+               }
+       }
+
+       // now apply the array to a simple string, with the ; symbol separating objects
+       s = "";
+       for(i = 0; i <= MAX_STORAGE_ATTACHMENTS; ++i)
+       {
+               if(port_string[i])
+                       s = strcat(s, port_string[i], "; ");
+               port_string[i] = string_null; // fully clear the string
+       }
+
+       return s;
+}
+
+entity sandbox_ObjectPort_Load(string s, float database)
+{
+       // load object properties, and spawn a new object with them
+       float n, i;
+       entity e = world, parent = world;
+
+       // separate objects between the ; symbols
+       n = tokenizebyseparator(s, "; ");
+       for(i = 0; i < n; ++i)
+               port_string[i] = argv(i);
+
+       // now separate and apply the properties of each object
+       for(i = 0; i < n; ++i)
+       {
+               float argv_num;
+               string tagname = string_null;
+               argv_num = 0;
+               tokenize_console(port_string[i]);
+               e = sandbox_ObjectSpawn(database);
+
+               // ---------------- OBJECT PROPERTY STORAGE: LOAD ----------------
+               if(i)
+               {
+                       // properties stored only for child objects
+                       if(argv(argv_num) != "")        tagname = argv(argv_num);       else tagname = string_null;     ++argv_num;
+               }
+               else
+               {
+                       // properties stored only for parent objects
+                       if(database)
+                       {
+                               setorigin(e, stov(argv(argv_num)));     ++argv_num;
+                               e.angles = stov(argv(argv_num));        ++argv_num;
+                       }
+                       parent = e; // mark parent objects as such
+               }
+               // properties stored for all objects
+               _setmodel(e, argv(argv_num));   ++argv_num;
+               e.skin = stof(argv(argv_num));  ++argv_num;
+               e.alpha = stof(argv(argv_num)); ++argv_num;
+               e.colormod = stov(argv(argv_num));      ++argv_num;
+               e.glowmod = stov(argv(argv_num));       ++argv_num;
+               e.frame = stof(argv(argv_num)); ++argv_num;
+               sandbox_ObjectEdit_Scale(e, stof(argv(argv_num)));      ++argv_num;
+               e.solid = e.old_solid = stof(argv(argv_num));   ++argv_num;
+               e.movetype = e.old_movetype = stof(argv(argv_num));     ++argv_num;
+               e.damageforcescale = stof(argv(argv_num));      ++argv_num;
+               if(e.material)  strunzone(e.material);  if(argv(argv_num) != "")        e.material = strzone(argv(argv_num));   else    e.material = string_null;       ++argv_num;
+               if(database)
+               {
+                       // properties stored only for the database
+                       if(e.crypto_idfp)       strunzone(e.crypto_idfp);       if(argv(argv_num) != "")        e.crypto_idfp = strzone(argv(argv_num));        else    e.crypto_idfp = string_null;    ++argv_num;
+                       if(e.netname)   strunzone(e.netname);   e.netname = strzone(argv(argv_num));    ++argv_num;
+                       if(e.message)   strunzone(e.message);   e.message = strzone(argv(argv_num));    ++argv_num;
+                       if(e.message2)  strunzone(e.message2);  e.message2 = strzone(argv(argv_num));   ++argv_num;
+               }
+
+               // attach last
+               if(i)
+                       sandbox_ObjectAttach_Set(e, parent, tagname);
+       }
+
+       for(i = 0; i <= MAX_STORAGE_ATTACHMENTS; ++i)
+               port_string[i] = string_null; // fully clear the string
+
+       return e;
+}
+
+void sandbox_Database_Save()
+{
+       // saves all objects to the database file
+       entity head;
+       string file_name;
+       float file_get;
+
+       file_name = strcat("sandbox/storage_", autocvar_g_sandbox_storage_name, "_", GetMapname(), ".txt");
+       file_get = fopen(file_name, FILE_WRITE);
+       fputs(file_get, strcat("// sandbox storage \"", autocvar_g_sandbox_storage_name, "\" for map \"", GetMapname(), "\" last updated ", strftime(true, "%d-%m-%Y %H:%M:%S")));
+       fputs(file_get, strcat(" containing ", ftos(object_count), " objects\n"));
+
+       for(head = world; (head = find(head, classname, "object")); )
+       {
+               // attached objects are persisted separately, ignore them here
+               if(head.owner != world)
+                       continue;
+
+               // use a line of text for each object, listing all properties
+               fputs(file_get, strcat(sandbox_ObjectPort_Save(head, true), "\n"));
+       }
+       fclose(file_get);
+}
+
+void sandbox_Database_Load()
+{
+       // loads all objects from the database file
+       string file_read, file_name;
+       float file_get, i;
+
+       file_name = strcat("sandbox/storage_", autocvar_g_sandbox_storage_name, "_", GetMapname(), ".txt");
+       file_get = fopen(file_name, FILE_READ);
+       if(file_get < 0)
+       {
+               if(autocvar_g_sandbox_info > 0)
+                       LOG_INFO(strcat("^3SANDBOX - SERVER: ^7could not find storage file ^3", file_name, "^7, no objects were loaded\n"));
+       }
+       else
+       {
+               for (;;)
+               {
+                       file_read = fgets(file_get);
+                       if(file_read == "")
+                               break;
+                       if(substring(file_read, 0, 2) == "//")
+                               continue;
+                       if(substring(file_read, 0, 1) == "#")
+                               continue;
+
+                       entity e;
+                       e = sandbox_ObjectPort_Load(file_read, true);
+
+                       if(e.material)
+                       {
+                               // since objects are being loaded for the first time, precache material sounds for each
+                               for (i = 1; i <= 5; i++) // 5 sounds in total
+                                       precache_sound(strcat("object/impact_", e.material, "_", ftos(i), ".wav"));
+                       }
+               }
+               if(autocvar_g_sandbox_info > 0)
+                       LOG_INFO(strcat("^3SANDBOX - SERVER: ^7successfully loaded storage file ^3", file_name, "\n"));
+       }
+       fclose(file_get);
+}
+
+MUTATOR_HOOKFUNCTION(sandbox, SV_ParseClientCommand)
+{SELFPARAM();
+       if(MUTATOR_RETURNVALUE) // command was already handled?
+               return false;
+       if(cmd_name == "g_sandbox")
+       {
+               if(autocvar_g_sandbox_readonly)
+               {
+                       print_to(self, "^2SANDBOX - INFO: ^7Sandbox mode is active, but in read-only mode. Sandbox commands cannot be used");
+                       return true;
+               }
+               if(cmd_argc < 2)
+               {
+                       print_to(self, "^2SANDBOX - INFO: ^7Sandbox mode is active. For usage information, type 'sandbox help'");
+                       return true;
+               }
+
+               switch(argv(1))
+               {
+                       entity e;
+                       float i;
+                       string s;
+
+                       // ---------------- COMMAND: HELP ----------------
+                       case "help":
+                               print_to(self, "You can use the following sandbox commands:");
+                               print_to(self, "^7\"^2object_spawn ^3models/foo/bar.md3^7\" spawns a new object in front of the player, and gives it the specified model");
+                               print_to(self, "^7\"^2object_remove^7\" removes the object the player is looking at. Players can only remove their own objects");
+                               print_to(self, "^7\"^2object_duplicate ^3value^7\" duplicates the object, if the player has copying rights over the original");
+                               print_to(self, "^3copy value ^7- copies the properties of the object to the specified client cvar");
+                               print_to(self, "^3paste value ^7- spawns an object with the given properties. Properties or cvars must be specified as follows; eg1: \"0 1 2 ...\", eg2: \"$cl_cvar\"");
+                               print_to(self, "^7\"^2object_attach ^3property value^7\" attaches one object to another. Players can only attach their own objects");
+                               print_to(self, "^3get ^7- selects the object you are facing as the object to be attached");
+                               print_to(self, "^3set value ^7- attaches the previously selected object to the object you are facing, on the specified bone");
+                               print_to(self, "^3remove ^7- detaches all objects from the object you are facing");
+                               print_to(self, "^7\"^2object_edit ^3property value^7\" edits the given property of the object. Players can only edit their own objects");
+                               print_to(self, "^3skin value ^7- changes the skin of the object");
+                               print_to(self, "^3alpha value ^7- sets object transparency");
+                               print_to(self, "^3colormod \"value_x value_y value_z\" ^7- main object color");
+                               print_to(self, "^3glowmod \"value_x value_y value_z\" ^7- glow object color");
+                               print_to(self, "^3frame value ^7- object animation frame, for self-animated models");
+                               print_to(self, "^3scale value ^7- changes object scale. 0.5 is half size and 2 is double size");
+                               print_to(self, "^3solidity value ^7- object collisions, 0 = non-solid, 1 = solid");
+                               print_to(self, "^3physics value ^7- object physics, 0 = static, 1 = movable, 2 = physical");
+                               print_to(self, "^3force value ^7- amount of force applied to objects that are shot");
+                               print_to(self, "^3material value ^7- sets the material of the object. Default materials are: metal, stone, wood, flesh");
+                               print_to(self, "^7\"^2object_claim^7\" sets the player as the owner of the object, if he has the right to edit it");
+                               print_to(self, "^7\"^2object_info ^3value^7\" shows public information about the object");
+                               print_to(self, "^3object ^7- prints general information about the object, such as owner and creation / editing date");
+                               print_to(self, "^3mesh ^7- prints information about the object's mesh, including skeletal bones");
+                               print_to(self, "^3attachments ^7- prints information about the object's attachments");
+                               print_to(self, "^7The ^1drag object ^7key can be used to grab and carry objects. Players can only grab their own objects");
+                               return true;
+
+                       // ---------------- COMMAND: OBJECT, SPAWN ----------------
+                       case "object_spawn":
+                               if(time < self.object_flood)
+                               {
+                                       print_to(self, strcat("^1SANDBOX - WARNING: ^7Flood protection active. Please wait ^3", ftos(self.object_flood - time), " ^7seconds beofore spawning another object"));
+                                       return true;
+                               }
+                               self.object_flood = time + autocvar_g_sandbox_editor_flood;
+                               if(object_count >= autocvar_g_sandbox_editor_maxobjects)
+                               {
+                                       print_to(self, strcat("^1SANDBOX - WARNING: ^7Cannot spawn any more objects. Up to ^3", ftos(autocvar_g_sandbox_editor_maxobjects), " ^7objects may exist at a time"));
+                                       return true;
+                               }
+                               if(cmd_argc < 3)
+                               {
+                                       print_to(self, "^1SANDBOX - WARNING: ^7Attempted to spawn an object without specifying a model. Please specify the path to your model file after the 'object_spawn' command");
+                                       return true;
+                               }
+                               if (!(fexists(argv(2))))
+                               {
+                                       print_to(self, "^1SANDBOX - WARNING: ^7Attempted to spawn an object with a non-existent model. Make sure the path to your model file is correct");
+                                       return true;
+                               }
+
+                               e = sandbox_ObjectSpawn(false);
+                               _setmodel(e, argv(2));
+
+                               if(autocvar_g_sandbox_info > 0)
+                                       LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", self.netname, " spawned an object at origin ^3", vtos(e.origin), "\n"));
+                               return true;
+
+                       // ---------------- COMMAND: OBJECT, REMOVE ----------------
+                       case "object_remove":
+                               e = sandbox_ObjectEdit_Get(true);
+                               if(e != world)
+                               {
+                                       if(autocvar_g_sandbox_info > 0)
+                                               LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", self.netname, " removed an object at origin ^3", vtos(e.origin), "\n"));
+                                       sandbox_ObjectRemove(e);
+                                       return true;
+                               }
+
+                               print_to(self, "^1SANDBOX - WARNING: ^7Object could not be removed. Make sure you are facing an object that you have edit rights over");
+                               return true;
+
+                       // ---------------- COMMAND: OBJECT, DUPLICATE ----------------
+                       case "object_duplicate":
+                               switch(argv(2))
+                               {
+                                       case "copy":
+                                               // copies customizable properties of the selected object to the clipboard cvar
+                                               e = sandbox_ObjectEdit_Get(autocvar_g_sandbox_editor_free); // can we copy objects we can't edit?
+                                               if(e != world)
+                                               {
+                                                       s = sandbox_ObjectPort_Save(e, false);
+                                                       s = strreplace("\"", "\\\"", s);
+                                                       stuffcmd(self, strcat("set ", argv(3), " \"", s, "\""));
+
+                                                       print_to(self, "^2SANDBOX - INFO: ^7Object copied to clipboard");
+                                                       return true;
+                                               }
+                                               print_to(self, "^1SANDBOX - WARNING: ^7Object could not be copied. Make sure you are facing an object that you have copy rights over");
+                                               return true;
+
+                                       case "paste":
+                                               // spawns a new object using the properties in the player's clipboard cvar
+                                               if(time < self.object_flood)
+                                               {
+                                                       print_to(self, strcat("^1SANDBOX - WARNING: ^7Flood protection active. Please wait ^3", ftos(self.object_flood - time), " ^7seconds beofore spawning another object"));
+                                                       return true;
+                                               }
+                                               self.object_flood = time + autocvar_g_sandbox_editor_flood;
+                                               if(argv(3) == "") // no object in clipboard
+                                               {
+                                                       print_to(self, "^1SANDBOX - WARNING: ^7No object in clipboard. You must copy an object before you can paste it");
+                                                       return true;
+                                               }
+                                               if(object_count >= autocvar_g_sandbox_editor_maxobjects)
+                                               {
+                                                       print_to(self, strcat("^1SANDBOX - WARNING: ^7Cannot spawn any more objects. Up to ^3", ftos(autocvar_g_sandbox_editor_maxobjects), " ^7objects may exist at a time"));
+                                                       return true;
+                                               }
+                                               e = sandbox_ObjectPort_Load(argv(3), false);
+
+                                               print_to(self, "^2SANDBOX - INFO: ^7Object pasted successfully");
+                                               if(autocvar_g_sandbox_info > 0)
+                                                       LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", self.netname, " pasted an object at origin ^3", vtos(e.origin), "\n"));
+                                               return true;
+                               }
+                               return true;
+
+                       // ---------------- COMMAND: OBJECT, ATTACH ----------------
+                       case "object_attach":
+                               switch(argv(2))
+                               {
+                                       case "get":
+                                               // select e as the object as meant to be attached
+                                               e = sandbox_ObjectEdit_Get(true);
+                                               if(e != world)
+                                               {
+                                                       self.object_attach = e;
+                                                       print_to(self, "^2SANDBOX - INFO: ^7Object selected for attachment");
+                                                       return true;
+                                               }
+                                               print_to(self, "^1SANDBOX - WARNING: ^7Object could not be selected for attachment. Make sure you are facing an object that you have edit rights over");
+                                               return true;
+                                       case "set":
+                                               if(self.object_attach == world)
+                                               {
+                                                       print_to(self, "^1SANDBOX - WARNING: ^7No object selected for attachment. Please select an object to be attached first.");
+                                                       return true;
+                                               }
+
+                                               // attaches the previously selected object to e
+                                               e = sandbox_ObjectEdit_Get(true);
+                                               if(e != world)
+                                               {
+                                                       sandbox_ObjectAttach_Set(self.object_attach, e, argv(3));
+                                                       self.object_attach = world; // object was attached, no longer keep it scheduled for attachment
+                                                       print_to(self, "^2SANDBOX - INFO: ^7Object attached successfully");
+                                                       if(autocvar_g_sandbox_info > 1)
+                                                               LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", self.netname, " attached objects at origin ^3", vtos(e.origin), "\n"));
+                                                       return true;
+                                               }
+                                               print_to(self, "^1SANDBOX - WARNING: ^7Object could not be attached to the parent. Make sure you are facing an object that you have edit rights over");
+                                               return true;
+                                       case "remove":
+                                               // removes e if it was attached
+                                               e = sandbox_ObjectEdit_Get(true);
+                                               if(e != world)
+                                               {
+                                                       sandbox_ObjectAttach_Remove(e);
+                                                       print_to(self, "^2SANDBOX - INFO: ^7Child objects detached successfully");
+                                                       if(autocvar_g_sandbox_info > 1)
+                                                               LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", self.netname, " detached objects at origin ^3", vtos(e.origin), "\n"));
+                                                       return true;
+                                               }
+                                               print_to(self, "^1SANDBOX - WARNING: ^7Child objects could not be detached. Make sure you are facing an object that you have edit rights over");
+                                               return true;
+                               }
+                               return true;
+
+                       // ---------------- COMMAND: OBJECT, EDIT ----------------
+                       case "object_edit":
+                               if(argv(2) == "")
+                               {
+                                       print_to(self, "^1SANDBOX - WARNING: ^7Too few parameters. You must specify a property to edit");
+                                       return true;
+                               }
+
+                               e = sandbox_ObjectEdit_Get(true);
+                               if(e != world)
+                               {
+                                       switch(argv(2))
+                                       {
+                                               case "skin":
+                                                       e.skin = stof(argv(3));
+                                                       break;
+                                               case "alpha":
+                                                       e.alpha = stof(argv(3));
+                                                       break;
+                                               case "color_main":
+                                                       e.colormod = stov(argv(3));
+                                                       break;
+                                               case "color_glow":
+                                                       e.glowmod = stov(argv(3));
+                                                       break;
+                                               case "frame":
+                                                       e.frame = stof(argv(3));
+                                                       break;
+                                               case "scale":
+                                                       sandbox_ObjectEdit_Scale(e, stof(argv(3)));
+                                                       break;
+                                               case "solidity":
+                                                       switch(argv(3))
+                                                       {
+                                                               case "0": // non-solid
+                                                                       e.solid = SOLID_TRIGGER;
+                                                                       break;
+                                                               case "1": // solid
+                                                                       e.solid = SOLID_BBOX;
+                                                                       break;
+                                                               default:
+                                                                       break;
+                                                       }
+                                               case "physics":
+                                                       switch(argv(3))
+                                                       {
+                                                               case "0": // static
+                                                                       e.movetype = MOVETYPE_NONE;
+                                                                       break;
+                                                               case "1": // movable
+                                                                       e.movetype = MOVETYPE_TOSS;
+                                                                       break;
+                                                               case "2": // physical
+                                                                       e.movetype = MOVETYPE_PHYSICS;
+                                                                       break;
+                                                               default:
+                                                                       break;
+                                                       }
+                                                       break;
+                                               case "force":
+                                                       e.damageforcescale = stof(argv(3));
+                                                       break;
+                                               case "material":
+                                                       if(e.material)  strunzone(e.material);
+                                                       if(argv(3))
+                                                       {
+                                                               for (i = 1; i <= 5; i++) // precache material sounds, 5 in total
+                                                                       precache_sound(strcat("object/impact_", argv(3), "_", ftos(i), ".wav"));
+                                                               e.material = strzone(argv(3));
+                                                       }
+                                                       else
+                                                               e.material = string_null; // no material
+                                                       break;
+                                               default:
+                                                       print_to(self, "^1SANDBOX - WARNING: ^7Invalid object property. For usage information, type 'sandbox help'");
+                                                       return true;
+                                       }
+
+                                       // update last editing time
+                                       if(e.message2)  strunzone(e.message2);
+                                       e.message2 = strzone(strftime(true, "%d-%m-%Y %H:%M:%S"));
+
+                                       if(autocvar_g_sandbox_info > 1)
+                                               LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", self.netname, " edited property ^3", argv(2), " ^7of an object at origin ^3", vtos(e.origin), "\n"));
+                                       return true;
+                               }
+
+                               print_to(self, "^1SANDBOX - WARNING: ^7Object could not be edited. Make sure you are facing an object that you have edit rights over");
+                               return true;
+
+                       // ---------------- COMMAND: OBJECT, CLAIM ----------------
+                       case "object_claim":
+                               // if the player can edit an object but is not its owner, this can be used to claim that object
+                               if(self.crypto_idfp == "")
+                               {
+                                       print_to(self, "^1SANDBOX - WARNING: ^7You do not have a player UID, and cannot claim objects");
+                                       return true;
+                               }
+                               e = sandbox_ObjectEdit_Get(true);
+                               if(e != world)
+                               {
+                                       // update the owner's name
+                                       // Do this before checking if you're already the owner and skipping if such, so we
+                                       // also update the player's nickname if he changed it (but has the same player UID)
+                                       if(e.netname != self.netname)
+                                       {
+                                               if(e.netname)   strunzone(e.netname);
+                                               e.netname = strzone(self.netname);
+                                               print_to(self, "^2SANDBOX - INFO: ^7Object owner name updated");
+                                       }
+
+                                       if(e.crypto_idfp == self.crypto_idfp)
+                                       {
+                                               print_to(self, "^2SANDBOX - INFO: ^7Object is already yours, nothing to claim");
+                                               return true;
+                                       }
+
+                                       if(e.crypto_idfp)       strunzone(e.crypto_idfp);
+                                       e.crypto_idfp = strzone(self.crypto_idfp);
+
+                                       print_to(self, "^2SANDBOX - INFO: ^7Object claimed successfully");
+                               }
+                               print_to(self, "^1SANDBOX - WARNING: ^7Object could not be claimed. Make sure you are facing an object that you have edit rights over");
+                               return true;
+
+                       // ---------------- COMMAND: OBJECT, INFO ----------------
+                       case "object_info":
+                               // prints public information about the object to the player
+                               e = sandbox_ObjectEdit_Get(false);
+                               if(e != world)
+                               {
+                                       switch(argv(2))
+                                       {
+                                               case "object":
+                                                       print_to(self, strcat("^2SANDBOX - INFO: ^7Object is owned by \"^7", e.netname, "^7\", created \"^3", e.message, "^7\", last edited \"^3", e.message2, "^7\""));
+                                                       return true;
+                                               case "mesh":
+                                                       s = "";
+                                                       FOR_EACH_TAG(e)
+                                                               s = strcat(s, "^7\"^5", gettaginfo_name, "^7\", ");
+                                                       print_to(self, strcat("^2SANDBOX - INFO: ^7Object mesh is \"^3", e.model, "^7\" at animation frame ^3", ftos(e.frame), " ^7containing the following tags: ", s));
+                                                       return true;
+                                               case "attachments":
+                                                       // this should show the same info as 'mesh' but for attachments
+                                                       s = "";
+                                                       entity head;
+                                                       i = 0;
+                                                       for(head = world; (head = find(head, classname, "object")); )
+                                                       {
+                                                               if(head.owner == e)
+                                                               {
+                                                                       ++i; // start from 1
+                                                                       gettaginfo(e, head.tag_index);
+                                                                       s = strcat(s, "^1attachment ", ftos(i), "^7 has mesh \"^3", head.model, "^7\" at animation frame ^3", ftos(head.frame));
+                                                                       s = strcat(s, "^7 and is attached to bone \"^5", gettaginfo_name, "^7\", ");
+                                                               }
+                                                       }
+                                                       if(i) // object contains attachments
+                                                               print_to(self, strcat("^2SANDBOX - INFO: ^7Object contains the following ^1", ftos(i), "^7 attachment(s): ", s));
+                                                       else
+                                                               print_to(self, "^2SANDBOX - INFO: ^7Object contains no attachments");
+                                                       return true;
+                                       }
+                               }
+                               print_to(self, "^1SANDBOX - WARNING: ^7No information could be found. Make sure you are facing an object");
+                               return true;
+
+                       // ---------------- COMMAND: DEFAULT ----------------
+                       default:
+                               print_to(self, "Invalid command. For usage information, type 'sandbox help'");
+                               return true;
+               }
+       }
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(sandbox, SV_StartFrame)
+{
+       if(!autocvar_g_sandbox_storage_autosave)
+               return false;
+       if(time < autosave_time)
+               return false;
+       autosave_time = time + autocvar_g_sandbox_storage_autosave;
+
+       sandbox_Database_Save();
+
+       return true;
+}
+#endif
diff --git a/qcsrc/server/mutators/mutator_bloodloss.qc b/qcsrc/server/mutators/mutator_bloodloss.qc
deleted file mode 100644 (file)
index 1e54218..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-
-#include "mutator.qh"
-
-.float bloodloss_timer;
-
-MUTATOR_HOOKFUNCTION(bloodloss_PlayerThink)
-{SELFPARAM();
-       if(IS_PLAYER(self))
-       if(self.health <= autocvar_g_bloodloss && self.deadflag == DEAD_NO)
-       {
-               self.BUTTON_CROUCH = true;
-
-               if(time >= self.bloodloss_timer)
-               {
-                       if(self.vehicle)
-                               vehicles_exit(VHEF_RELEASE);
-                       if(self.event_damage)
-                               self.event_damage(self, self, 1, DEATH_ROT.m_id, self.origin, '0 0 0');
-                       self.bloodloss_timer = time + 0.5 + random() * 0.5;
-               }
-       }
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(bloodloss_PlayerJump)
-{SELFPARAM();
-       if(self.health <= autocvar_g_bloodloss)
-               return true;
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(bloodloss_BuildMutatorsString)
-{
-       ret_string = strcat(ret_string, ":bloodloss");
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(bloodloss_BuildMutatorsPrettyString)
-{
-       ret_string = strcat(ret_string, ", Blood loss");
-       return false;
-}
-
-MUTATOR_DEFINITION(mutator_bloodloss)
-{
-       MUTATOR_HOOK(PlayerPreThink, bloodloss_PlayerThink, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerJump, bloodloss_PlayerJump, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BuildMutatorsString, bloodloss_BuildMutatorsString, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BuildMutatorsPrettyString, bloodloss_BuildMutatorsPrettyString, CBC_ORDER_ANY);
-
-       return false;
-}
diff --git a/qcsrc/server/mutators/mutator_breakablehook.qc b/qcsrc/server/mutators/mutator_breakablehook.qc
deleted file mode 100644 (file)
index 3f75e3f..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-#include "../../common/deathtypes/all.qh"
-#include "../g_hook.qh"
-
-REGISTER_MUTATOR(bh, cvar("g_breakablehook"));
-
-bool autocvar_g_breakablehook; // allow toggling mid match?
-bool autocvar_g_breakablehook_owner;
-
-MUTATOR_HOOKFUNCTION(bh, PlayerDamage_Calculate)
-{
-       if(frag_target.classname == "grapplinghook")
-       {
-               if((!autocvar_g_breakablehook)
-               || (!autocvar_g_breakablehook_owner && frag_attacker == frag_target.realowner)
-                       ) { frag_damage = 0; }
-
-               // hurt the owner of the hook
-               if(DIFF_TEAM(frag_attacker, frag_target.realowner))
-               {
-                       Damage (frag_target.realowner, frag_attacker, frag_attacker, 5, WEP_HOOK.m_id | HITTYPE_SPLASH, frag_target.realowner.origin, '0 0 0');
-                       RemoveGrapplingHook(frag_target.realowner);
-                       return false; // dead
-               }
-       }
-
-       return false;
-}
diff --git a/qcsrc/server/mutators/mutator_buffs.qc b/qcsrc/server/mutators/mutator_buffs.qc
deleted file mode 100644 (file)
index 7c24ea1..0000000
+++ /dev/null
@@ -1,1002 +0,0 @@
-#include "../../common/triggers/target/music.qh"
-#include "mutator_buffs.qh"
-
-#include "mutator.qh"
-
-#include "../../common/gamemodes/all.qh"
-#include "../../common/buffs/all.qh"
-
-entity buff_FirstFromFlags(int _buffs)
-{
-       if (flags)
-       {
-               FOREACH(Buffs, it.m_itemid & _buffs, LAMBDA(return it));
-       }
-       return BUFF_Null;
-}
-
-bool buffs_BuffModel_Customize()
-{SELFPARAM();
-       entity player, myowner;
-       bool 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(MUTATOR_CALLHOOK(BuffModel_Customize, self, player))
-               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;
-}
-
-void buffs_BuffModel_Spawn(entity player)
-{
-       player.buff_model = spawn();
-       setmodel(player.buff_model, MDL_BUFF);
-       setsize(player.buff_model, '0 0 -40', '0 0 40');
-       setattachment(player.buff_model, player, "");
-       setorigin(player.buff_model, '0 0 1' * (player.buff_model.maxs.z * 1));
-       player.buff_model.owner = player;
-       player.buff_model.scale = 0.7;
-       player.buff_model.pflags = PFLAGS_FULLDYNAMIC;
-       player.buff_model.light_lev = 200;
-       player.buff_model.customizeentityforclient = buffs_BuffModel_Customize;
-}
-
-vector buff_GlowColor(entity buff)
-{
-       //if(buff.team) { return Team_ColorRGB(buff.team); }
-       return buff.m_color;
-}
-
-void buff_Effect(entity player, string eff)
-{SELFPARAM();
-       if(!autocvar_g_buffs_effects) { return; }
-
-       if(time >= self.buff_effect_delay)
-       {
-               Send_Effect_(eff, player.origin + ((player.mins + player.maxs) * 0.5), '0 0 0', 1);
-               self.buff_effect_delay = time + 0.05; // prevent spam
-       }
-}
-
-// buff item
-float buff_Waypoint_visible_for_player(entity plr)
-{SELFPARAM();
-       if(!self.owner.buff_active && !self.owner.buff_activetime)
-               return false;
-
-       if (plr.buffs)
-       {
-               return plr.cvar_cl_buffs_autoreplace == false || plr.buffs != self.owner.buffs;
-       }
-
-       return WaypointSprite_visible_for_player(plr);
-}
-
-void buff_Waypoint_Spawn(entity e)
-{
-       entity buff = buff_FirstFromFlags(e.buffs);
-       entity wp = WaypointSprite_Spawn(WP_Buff, 0, autocvar_g_buffs_waypoint_distance, e, '0 0 1' * e.maxs.z, world, e.team, e, buff_waypoint, true, RADARICON_Buff);
-       wp.wp_extra = buff.m_id;
-       WaypointSprite_UpdateTeamRadar(e.buff_waypoint, RADARICON_Buff, e.glowmod);
-       e.buff_waypoint.waypointsprite_visible_for_player = buff_Waypoint_visible_for_player;
-}
-
-void buff_SetCooldown(float cd)
-{SELFPARAM();
-       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)
-{SELFPARAM();
-       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;
-
-       Send_Effect(EFFECT_ELECTRO_COMBO, oldbufforigin + ((ent.mins + ent.maxs) * 0.5), '0 0 0', 1);
-       Send_Effect(EFFECT_ELECTRO_COMBO, CENTER_OR_VIEWOFS(ent), '0 0 0', 1);
-
-       WaypointSprite_Ping(ent.buff_waypoint);
-
-       sound(ent, CH_TRIGGER, SND_KA_RESPAWN, VOL_BASE, ATTEN_NONE); // ATTEN_NONE (it's a sound intended to be heard anywhere)
-}
-
-void buff_Touch()
-{SELFPARAM();
-       if(gameover) { return; }
-
-       if(ITEM_TOUCH_NEEDKILL())
-       {
-               buff_Respawn(self);
-               return;
-       }
-
-       if((self.team && DIFF_TEAM(other, self))
-       || (other.frozen)
-       || (other.vehicle)
-       || (!self.buff_active)
-       )
-       {
-               // can't touch this
-               return;
-       }
-
-       if(MUTATOR_CALLHOOK(BuffTouch, self, other))
-               return;
-
-       if(!IS_PLAYER(other))
-               return; // incase mutator changed other
-
-       if (other.buffs)
-       {
-               if (other.cvar_cl_buffs_autoreplace && other.buffs != self.buffs)
-               {
-                       int buffid = buff_FirstFromFlags(other.buffs).m_id;
-                       //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, buffid);
-
-                       other.buffs = 0;
-                       //sound(other, CH_TRIGGER, SND_BUFF_LOST, VOL_BASE, ATTN_NORM);
-               }
-               else { return; } // do nothing
-       }
-
-       self.owner = other;
-       self.buff_active = false;
-       self.lifetime = 0;
-       int buffid = buff_FirstFromFlags(self.buffs).m_id;
-       Send_Notification(NOTIF_ONE, other, MSG_MULTI, ITEM_BUFF_GOT, buffid);
-       Send_Notification(NOTIF_ALL_EXCEPT, other, MSG_INFO, INFO_ITEM_BUFF, other.netname, buffid);
-
-       Send_Effect(EFFECT_ITEM_PICKUP, CENTER_OR_VIEWOFS(self), '0 0 0', 1);
-       sound(other, CH_TRIGGER, SND_SHIELD_RESPAWN, VOL_BASE, ATTN_NORM);
-       other.buffs |= (self.buffs);
-}
-
-float buff_Available(entity buff)
-{
-       if (buff == BUFF_Null)
-               return false;
-       if (buff == BUFF_AMMO && ((start_items & IT_UNLIMITED_WEAPON_AMMO) || (start_items & IT_UNLIMITED_AMMO) || (cvar("g_melee_only"))))
-               return false;
-       if (buff == BUFF_VAMPIRE && cvar("g_vampire"))
-               return false;
-       return cvar(strcat("g_buffs_", buff.m_name));
-}
-
-.int buff_seencount;
-
-void buff_NewType(entity ent, float cb)
-{
-       RandomSelection_Init();
-       FOREACH(Buffs, buff_Available(it), LAMBDA(
-               it.buff_seencount += 1;
-               // if it's already been chosen, give it a lower priority
-               RandomSelection_Add(world, it.m_itemid, string_null, 1, max(0.2, 1 / it.buff_seencount));
-       ));
-       ent.buffs = RandomSelection_chosen_float;
-}
-
-void buff_Think()
-{SELFPARAM();
-       if(self.buffs != self.oldbuffs)
-       {
-               entity buff = buff_FirstFromFlags(self.buffs);
-               self.color = buff.m_color;
-               self.glowmod = buff_GlowColor(buff);
-               self.skin = buff.m_skin;
-
-               setmodel(self, MDL_BUFF);
-
-               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 & 64))
-                       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, SND_STRENGTH_RESPAWN, VOL_BASE, ATTN_NORM);
-                       Send_Effect(EFFECT_ITEM_RESPAWN, CENTER_OR_VIEWOFS(self), '0 0 0', 1);
-               }
-       }
-
-       if(self.buff_active)
-       {
-               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()
-{SELFPARAM();
-       WaypointSprite_Kill(self.buff_waypoint);
-
-       if(self.buff_activetime) { buff_Waypoint_Spawn(self); }
-}
-
-void buff_Reset()
-{SELFPARAM();
-       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 & 64))
-               buff_Respawn(self);
-}
-
-float buff_Customize()
-{SELFPARAM();
-       entity player = WaypointSprite_getviewentity(other);
-       if(!self.buff_active || (self.team && DIFF_TEAM(player, self)))
-       {
-               self.alpha = 0.3;
-               if(self.effects & EF_FULLBRIGHT) { self.effects &= ~(EF_FULLBRIGHT); }
-               self.pflags = 0;
-       }
-       else
-       {
-               self.alpha = 1;
-               if(!(self.effects & EF_FULLBRIGHT)) { self.effects |= EF_FULLBRIGHT; }
-               self.light_lev = 220 + 36 * sin(time);
-               self.pflags = PFLAGS_FULLDYNAMIC;
-       }
-       return true;
-}
-
-void buff_Init(entity ent)
-{SELFPARAM();
-       if(!cvar("g_buffs")) { remove(ent); return; }
-
-       if(!teamplay && ent.team) { ent.team = 0; }
-
-       entity buff = buff_FirstFromFlags(self.buffs);
-
-       setself(ent);
-       if(!self.buffs || buff_Available(buff))
-               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.m_skin;
-       self.effects = EF_FULLBRIGHT | EF_STARDUST | EF_NOSHADOW;
-       self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY;
-       self.customizeentityforclient = buff_Customize;
-       //self.gravity = 100;
-       self.color = buff.m_color;
-       self.glowmod = buff_GlowColor(self);
-       buff_SetCooldown(autocvar_g_buffs_cooldown_activate + game_starttime);
-       self.buff_active = !self.buff_activetime;
-       self.pflags = PFLAGS_FULLDYNAMIC;
-
-       if(self.spawnflags & 1)
-               self.noalign = true;
-
-       if(self.noalign)
-               self.movetype = MOVETYPE_NONE; // reset by random location
-
-       setmodel(self, MDL_BUFF);
-       setsize(self, BUFF_MIN, BUFF_MAX);
-
-       if(cvar("g_buffs_random_location") || (self.spawnflags & 64))
-               buff_Respawn(self);
-
-       setself(this);
-}
-
-void buff_Init_Compat(entity ent, entity replacement)
-{
-       if (ent.spawnflags & 2)
-               ent.team = NUM_TEAM_1;
-       else if (ent.spawnflags & 4)
-               ent.team = NUM_TEAM_2;
-
-       ent.buffs = replacement.m_itemid;
-
-       buff_Init(ent);
-}
-
-void buff_SpawnReplacement(entity ent, entity old)
-{
-       setorigin(ent, old.origin);
-       ent.angles = old.angles;
-       ent.noalign = (old.noalign || (old.spawnflags & 1));
-
-       buff_Init(ent);
-}
-
-void buff_Vengeance_DelayedDamage()
-{SELFPARAM();
-       if(self.enemy)
-               Damage(self.enemy, self.owner, self.owner, self.dmg, DEATH_BUFF.m_id, self.enemy.origin, '0 0 0');
-
-       remove(self);
-       return;
-}
-
-float buff_Inferno_CalculateTime(float x, float offset_x, float offset_y, float intersect_x, float intersect_y, float base)
-{
-       return offset_y + (intersect_y - offset_y) * logn(((x - offset_x) * ((base - 1) / intersect_x)) + 1, base);
-}
-
-// mutator hooks
-MUTATOR_HOOKFUNCTION(buffs_PlayerDamage_SplitHealthArmor)
-{
-       if(frag_deathtype == DEATH_BUFF.m_id) { return false; }
-
-       if(frag_target.buffs & BUFF_RESISTANCE.m_itemid)
-       {
-               vector v = healtharmor_applydamage(50, autocvar_g_buffs_resistance_blockpercent, frag_deathtype, frag_damage);
-               damage_take = v.x;
-               damage_save = v.y;
-       }
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(buffs_PlayerDamage_Calculate)
-{
-       if(frag_deathtype == DEATH_BUFF.m_id) { return false; }
-
-       if(frag_target.buffs & BUFF_SPEED.m_itemid)
-       if(frag_target != frag_attacker)
-               frag_damage *= autocvar_g_buffs_speed_damage_take;
-
-       if(frag_target.buffs & BUFF_MEDIC.m_itemid)
-       if((frag_target.health - frag_damage) <= 0)
-       if(!ITEM_DAMAGE_NEEDKILL(frag_deathtype))
-       if(frag_attacker)
-       if(random() <= autocvar_g_buffs_medic_survive_chance)
-               frag_damage = max(5, frag_target.health - autocvar_g_buffs_medic_survive_health);
-
-       if(frag_target.buffs & BUFF_JUMP.m_itemid)
-       if(frag_deathtype == DEATH_FALL.m_id)
-               frag_damage = 0;
-
-       if(frag_target.buffs & BUFF_VENGEANCE.m_itemid)
-       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.m_itemid)
-       if(frag_attacker != frag_target)
-       if(vlen(frag_force))
-               frag_force = '0 0 0';
-
-       if(frag_attacker.buffs & BUFF_BASH.m_itemid)
-       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.m_itemid)
-       if(frag_target != frag_attacker)
-               frag_target.buff_disability_time = time + autocvar_g_buffs_disability_slowtime;
-
-       if(frag_attacker.buffs & BUFF_MEDIC.m_itemid)
-       if(DEATH_WEAPONOF(frag_deathtype) != WEP_ARC)
-       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;
-       }
-
-       if(frag_attacker.buffs & BUFF_INFERNO.m_itemid)
-       if(frag_target != frag_attacker) {
-               float time = buff_Inferno_CalculateTime(
-                       frag_damage,
-                       0,
-                       autocvar_g_buffs_inferno_burntime_min_time,
-                       autocvar_g_buffs_inferno_burntime_target_damage,
-                       autocvar_g_buffs_inferno_burntime_target_time,
-                       autocvar_g_buffs_inferno_burntime_factor
-               );
-               Fire_AddDamage(frag_target, frag_attacker, (frag_damage * autocvar_g_buffs_inferno_damagemultiplier) * time, time, DEATH_BUFF.m_id);
-       }
-
-       // this... is ridiculous (TODO: fix!)
-       if(frag_attacker.buffs & BUFF_VAMPIRE.m_itemid)
-       if(!frag_target.vehicle)
-       if(DEATH_WEAPONOF(frag_deathtype) != WEP_ARC)
-       if(!ITEM_DAMAGE_NEEDKILL(frag_deathtype))
-       if(frag_target.deadflag == DEAD_NO)
-       if(IS_PLAYER(frag_target) || IS_MONSTER(frag_target))
-       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);
-               if(frag_target.armorvalue)
-                       frag_attacker.armorvalue = bound(0, frag_attacker.armorvalue + bound(0, frag_damage * autocvar_g_buffs_vampire_damage_steal, frag_target.armorvalue), g_pickup_armorsmall_max);
-       }
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(buffs_PlayerSpawn)
-{SELFPARAM();
-       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;
-}
-
-.float stat_sv_maxspeed;
-.float stat_sv_airspeedlimit_nonqw;
-.float stat_sv_jumpvelocity;
-
-MUTATOR_HOOKFUNCTION(buffs_PlayerPhysics)
-{SELFPARAM();
-       if(self.buffs & BUFF_SPEED.m_itemid)
-       {
-               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;
-       }
-
-       if(self.buffs & BUFF_JUMP.m_itemid)
-       {
-               // automatically reset, no need to worry
-               self.stat_sv_jumpvelocity = autocvar_g_buffs_jump_height;
-       }
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(buffs_PlayerJump)
-{SELFPARAM();
-       if(self.buffs & BUFF_JUMP.m_itemid)
-               player_jumpheight = autocvar_g_buffs_jump_height;
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(buffs_MonsterMove)
-{SELFPARAM();
-       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)
-{SELFPARAM();
-       if(self.buffs)
-       {
-               int buffid = buff_FirstFromFlags(self.buffs).m_id;
-               Send_Notification(NOTIF_ALL_EXCEPT, self, MSG_INFO, INFO_ITEM_BUFF_LOST, self.netname, buffid);
-               self.buffs = 0;
-
-               if(self.buff_model)
-               {
-                       remove(self.buff_model);
-                       self.buff_model = world;
-               }
-       }
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(buffs_PlayerUseKey)
-{SELFPARAM();
-       if(MUTATOR_RETURNVALUE || gameover) { return false; }
-       if(self.buffs)
-       {
-               int buffid = buff_FirstFromFlags(self.buffs).m_id;
-               Send_Notification(NOTIF_ONE, self, MSG_MULTI, ITEM_BUFF_DROP, buffid);
-               Send_Notification(NOTIF_ALL_EXCEPT, self, MSG_INFO, INFO_ITEM_BUFF_LOST, self.netname, buffid);
-
-               self.buffs = 0;
-               sound(self, CH_TRIGGER, SND_BUFF_LOST, VOL_BASE, ATTN_NORM);
-               return true;
-       }
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(buffs_PlayerThrowKey)
-{SELFPARAM();
-       if(MUTATOR_RETURNVALUE || gameover) { return false; }
-
-       if(self.buffs & BUFF_SWAPPER.m_itemid)
-       {
-               float best_distance = autocvar_g_buffs_swapper_range;
-               entity closest = world;
-               entity player;
-               FOR_EACH_PLAYER(player)
-               if(DIFF_TEAM(self, player))
-               if(player.deadflag == DEAD_NO && !player.frozen && !player.vehicle)
-               if(vlen(self.origin - player.origin) <= best_distance)
-               {
-                       best_distance = vlen(self.origin - player.origin);
-                       closest = player;
-               }
-
-               if(closest)
-               {
-                       vector my_org, my_vel, my_ang, their_org, their_vel, their_ang;
-
-                       my_org = self.origin;
-                       my_vel = self.velocity;
-                       my_ang = self.angles;
-                       their_org = closest.origin;
-                       their_vel = closest.velocity;
-                       their_ang = closest.angles;
-
-                       if(closest.ballcarried)
-                       if(g_keepaway) { ka_DropEvent(closest); }
-                       else { DropBall(closest.ballcarried, closest.origin, closest.velocity);}
-                       if(closest.flagcarried) { ctf_Handle_Throw(closest, world, DROP_THROW); }
-                       if(closest.nade) { toss_nade(closest, '0 0 0', time + 0.05); }
-
-                       MUTATOR_CALLHOOK(PortalTeleport, self); // initiate flag dropper
-
-                       setorigin(self, their_org);
-                       setorigin(closest, my_org);
-
-                       closest.velocity = my_vel;
-                       closest.angles = my_ang;
-                       closest.fixangle = true;
-                       closest.oldorigin = my_org;
-                       closest.oldvelocity = my_vel;
-                       self.velocity = their_vel;
-                       self.angles = their_ang;
-                       self.fixangle = true;
-                       self.oldorigin = their_org;
-                       self.oldvelocity = their_vel;
-
-                       // set pusher so self gets the kill if they fall into void
-                       closest.pusher = self;
-                       closest.pushltime = time + autocvar_g_maxpushtime;
-                       closest.istypefrag = closest.BUTTON_CHAT;
-
-                       Send_Effect(EFFECT_ELECTRO_COMBO, their_org, '0 0 0', 1);
-                       Send_Effect(EFFECT_ELECTRO_COMBO, my_org, '0 0 0', 1);
-
-                       sound(self, CH_TRIGGER, SND_KA_RESPAWN, VOL_BASE, ATTEN_NORM);
-                       sound(closest, CH_TRIGGER, SND_KA_RESPAWN, VOL_BASE, ATTEN_NORM);
-
-                       // TODO: add a counter to handle how many times one can teleport, and a delay to prevent spam
-                       self.buffs = 0;
-                       return true;
-               }
-       }
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(buffs_RemovePlayer)
-{SELFPARAM();
-       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)
-{SELFPARAM();
-       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.m_itemid) && (e == other))
-       if(DIFF_TEAM(self.owner, e))
-               return true;
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(buffs_OnEntityPreSpawn)
-{SELFPARAM();
-       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)
-{SELFPARAM();
-       if(self.buffs & BUFF_SPEED.m_itemid)
-               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_WeaponSpeed)
-{SELFPARAM();
-       if(self.buffs & BUFF_SPEED.m_itemid)
-               ret_float *= autocvar_g_buffs_speed_weaponspeed;
-
-       if(time < self.buff_disability_time)
-               ret_float *= autocvar_g_buffs_disability_weaponspeed;
-
-       return false;
-}
-
-.float buff_time;
-
-MUTATOR_HOOKFUNCTION(buffs_PlayerThink)
-{SELFPARAM();
-       if(gameover || self.deadflag != DEAD_NO) { return false; }
-
-       if(time < self.buff_disability_time)
-       if(time >= self.buff_disability_effect_time)
-       {
-               Send_Effect(EFFECT_SMOKING, self.origin + ((self.mins + self.maxs) * 0.5), '0 0 0', 1);
-               self.buff_disability_effect_time = time + 0.5;
-       }
-
-       // handle buff lost status
-       // 1: notify everyone else
-       // 2: notify carrier as well
-       int buff_lost = 0;
-
-       if(self.buff_time)
-       if(time >= self.buff_time)
-               buff_lost = 2;
-
-       if(self.frozen) { buff_lost = 1; }
-
-       if(buff_lost)
-       {
-               if(self.buffs)
-               {
-                       int buffid = buff_FirstFromFlags(self.buffs).m_id;
-                       Send_Notification(NOTIF_ALL_EXCEPT, self, MSG_INFO, INFO_ITEM_BUFF_LOST, self.netname, buffid);
-                       if(buff_lost >= 2)
-                       {
-                               Send_Notification(NOTIF_ONE, self, MSG_MULTI, ITEM_BUFF_DROP, buffid); // TODO: special timeout message?
-                               sound(self, CH_TRIGGER, SND_BUFF_LOST, VOL_BASE, ATTN_NORM);
-                       }
-                       self.buffs = 0;
-               }
-       }
-
-       if(self.buffs & BUFF_MAGNET.m_itemid)
-       {
-               vector pickup_size = '1 1 1' * autocvar_g_buffs_magnet_range_item;
-               for(other = world; (other = findflags(other, flags, FL_ITEM)); )
-               if(boxesoverlap(self.absmin - pickup_size, self.absmax + pickup_size, other.absmin, other.absmax))
-               {
-                       setself(other);
-                       other = this;
-                       if(self.touch)
-                               self.touch();
-                       other = self;
-                       setself(this);
-               }
-       }
-
-       if(self.buffs & BUFF_AMMO.m_itemid)
-       if(self.clip_size)
-               self.clip_load = self.(weapon_load[self.switchweapon]) = self.clip_size;
-
-       if((self.buffs & BUFF_INVISIBLE.m_itemid) && (self.oldbuffs & BUFF_INVISIBLE.m_itemid))
-       if(self.alpha != autocvar_g_buffs_invisible_alpha)
-               self.alpha = autocvar_g_buffs_invisible_alpha; // powerups reset alpha, so we must enforce this (TODO)
-
-#define BUFF_ONADD(b) if ( (self.buffs & (b).m_itemid) && !(self.oldbuffs & (b).m_itemid))
-#define BUFF_ONREM(b) if (!(self.buffs & (b).m_itemid) &&  (self.oldbuffs & (b).m_itemid))
-
-       if(self.buffs != self.oldbuffs)
-       {
-               entity buff = buff_FirstFromFlags(self.buffs);
-               float bufftime = buff != BUFF_Null ? buff.m_time(buff) : 0;
-               self.buff_time = (bufftime) ? time + bufftime : 0;
-
-               BUFF_ONADD(BUFF_AMMO)
-               {
-                       self.buff_ammo_prev_infitems = (self.items & IT_UNLIMITED_WEAPON_AMMO);
-                       self.items |= IT_UNLIMITED_WEAPON_AMMO;
-
-                       if(self.clip_load)
-                               self.buff_ammo_prev_clipload = self.clip_load;
-                       self.clip_load = self.(weapon_load[self.switchweapon]) = self.clip_size;
-               }
-
-               BUFF_ONREM(BUFF_AMMO)
-               {
-                       if(self.buff_ammo_prev_infitems)
-                               self.items |= IT_UNLIMITED_WEAPON_AMMO;
-                       else
-                               self.items &= ~IT_UNLIMITED_WEAPON_AMMO;
-
-                       if(self.buff_ammo_prev_clipload)
-                               self.clip_load = self.buff_ammo_prev_clipload;
-               }
-
-               BUFF_ONADD(BUFF_INVISIBLE)
-               {
-                       if(time < self.strength_finished && g_instagib)
-                               self.alpha = autocvar_g_instagib_invis_alpha;
-                       else
-                               self.alpha = self.buff_invisible_prev_alpha;
-                       self.alpha = autocvar_g_buffs_invisible_alpha;
-               }
-
-               BUFF_ONREM(BUFF_INVISIBLE)
-                       self.alpha = self.buff_invisible_prev_alpha;
-
-               BUFF_ONADD(BUFF_FLIGHT)
-               {
-                       self.buff_flight_prev_gravity = self.gravity;
-                       self.gravity = autocvar_g_buffs_flight_gravity;
-               }
-
-               BUFF_ONREM(BUFF_FLIGHT)
-                       self.gravity = self.buff_flight_prev_gravity;
-
-               self.oldbuffs = self.buffs;
-               if(self.buffs)
-               {
-                       if(!self.buff_model)
-                               buffs_BuffModel_Spawn(self);
-
-                       self.buff_model.color = buff.m_color;
-                       self.buff_model.glowmod = buff_GlowColor(self.buff_model);
-                       self.buff_model.skin = buff.m_skin;
-
-                       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;
-       }
-
-#undef BUFF_ONADD
-#undef BUFF_ONREM
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(buffs_SpectateCopy)
-{SELFPARAM();
-       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)
-{SELFPARAM();
-       if(self.buffs & BUFF_MEDIC.m_itemid)
-       {
-               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.m_itemid)
-               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 |= 64; // always randomize
-                       e.velocity = randomvec() * 250; // this gets reset anyway if random location works
-                       buff_Init(e);
-               }
-       }
-}
-
-void buffs_Initialize()
-{
-       addstat(STAT_BUFFS, AS_INT, buffs);
-       addstat(STAT_BUFF_TIME, AS_FLOAT, buff_time);
-
-       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_FIRST);
-       MUTATOR_HOOK(ForbidThrowCurrentWeapon, buffs_PlayerThrowKey, 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_LAST);
-       MUTATOR_HOOK(CustomizeWaypoint, buffs_CustomizeWaypoint, CBC_ORDER_ANY);
-       MUTATOR_HOOK(WeaponRateFactor, buffs_WeaponRate, CBC_ORDER_ANY);
-       MUTATOR_HOOK(WeaponSpeedFactor, buffs_WeaponSpeed, 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
deleted file mode 100644 (file)
index 10d84ef..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef MUTATOR_BUFFS_H
-#define MUTATOR_BUFFS_H
-
-// buff specific variables \\
-//
-// ammo
-.float buff_ammo_prev_infitems;
-.int buff_ammo_prev_clipload;
-// invisible
-.float buff_invisible_prev_alpha;
-// flight
-.float buff_flight_prev_gravity;
-// disability
-.float buff_disability_time;
-.float buff_disability_effect_time;
-// common buff variables
-.float buff_effect_delay;
-
-// buff definitions
-.float buff_active;
-.float buff_activetime;
-.float buff_activetime_updated;
-.entity buff_waypoint;
-.int oldbuffs; // for updating effects
-.entity buff_model; // controls effects (TODO: make csqc)
-
-const vector BUFF_MIN = ('-16 -16 -20');
-const vector BUFF_MAX = ('16 16 20');
-
-// client side options
-.float cvar_cl_buffs_autoreplace;
-#endif
diff --git a/qcsrc/server/mutators/mutator_campcheck.qc b/qcsrc/server/mutators/mutator_campcheck.qc
deleted file mode 100644 (file)
index 4acc754..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-
-#include "mutator.qh"
-
-#include "../campaign.qh"
-
-.float campcheck_nextcheck;
-.float campcheck_traveled_distance;
-
-MUTATOR_HOOKFUNCTION(campcheck_PlayerDies)
-{SELFPARAM();
-       Kill_Notification(NOTIF_ONE, self, MSG_CENTER_CPID, CPID_CAMPCHECK);
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(campcheck_PlayerDamage)
-{
-       if(IS_PLAYER(frag_target))
-       if(IS_PLAYER(frag_attacker))
-       if(frag_attacker != frag_target)
-       {
-               frag_target.campcheck_traveled_distance = autocvar_g_campcheck_distance;
-               frag_attacker.campcheck_traveled_distance = autocvar_g_campcheck_distance;
-       }
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(campcheck_PlayerThink)
-{SELFPARAM();
-       if(!gameover)
-       if(!warmup_stage) // don't consider it camping during warmup?
-       if(time >= game_starttime)
-       if(IS_PLAYER(self))
-       if(IS_REAL_CLIENT(self)) // bots may camp, but that's no reason to constantly kill them
-       if(self.deadflag == DEAD_NO)
-       if(!self.frozen)
-       if(!self.BUTTON_CHAT)
-       if(autocvar_g_campcheck_interval)
-       {
-               vector dist;
-
-               // calculate player movement (in 2 dimensions only, so jumping on one spot doesn't count as movement)
-               dist = self.prevorigin - self.origin;
-               dist.z = 0;
-               self.campcheck_traveled_distance += fabs(vlen(dist));
-
-               if((autocvar_g_campaign && !campaign_bots_may_start) || (time < game_starttime) || (round_handler_IsActive() && !round_handler_IsRoundStarted()))
-               {
-                       self.campcheck_nextcheck = time + autocvar_g_campcheck_interval * 2;
-                       self.campcheck_traveled_distance = 0;
-               }
-
-               if(time > self.campcheck_nextcheck)
-               {
-                       if(self.campcheck_traveled_distance < autocvar_g_campcheck_distance)
-                       {
-                               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_CAMPCHECK);
-                               if(self.vehicle)
-                                       Damage(self.vehicle, self, self, autocvar_g_campcheck_damage * 2, DEATH_CAMP.m_id, self.vehicle.origin, '0 0 0');
-                               else
-                                       Damage(self, self, self, bound(0, autocvar_g_campcheck_damage, self.health + self.armorvalue * autocvar_g_balance_armor_blockpercent + 5), DEATH_CAMP.m_id, self.origin, '0 0 0');
-                       }
-                       self.campcheck_nextcheck = time + autocvar_g_campcheck_interval;
-                       self.campcheck_traveled_distance = 0;
-               }
-
-               return false;
-       }
-
-       self.campcheck_nextcheck = time + autocvar_g_campcheck_interval; // one of the above checks failed, so keep the timer up to date
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(campcheck_PlayerSpawn)
-{SELFPARAM();
-       self.campcheck_nextcheck = time + autocvar_g_campcheck_interval * 2;
-       self.campcheck_traveled_distance = 0;
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(campcheck_BuildMutatorsString)
-{
-       ret_string = strcat(ret_string, ":CampCheck");
-       return false;
-}
-
-MUTATOR_DEFINITION(mutator_campcheck)
-{
-       MUTATOR_HOOK(PlayerDies, campcheck_PlayerDies, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerDamage_Calculate, campcheck_PlayerDamage, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerPreThink, campcheck_PlayerThink, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerSpawn, campcheck_PlayerSpawn, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BuildMutatorsString, campcheck_BuildMutatorsString, CBC_ORDER_ANY);
-
-       return false;
-}
diff --git a/qcsrc/server/mutators/mutator_dodging.qc b/qcsrc/server/mutators/mutator_dodging.qc
deleted file mode 100644 (file)
index e9dd6fd..0000000
+++ /dev/null
@@ -1,328 +0,0 @@
-#ifdef CSQC
-       #define PHYS_DODGING_FRAMETIME                          (1 / (frametime <= 0 ? 60 : frametime))
-       #define PHYS_DODGING                                            getstati(STAT_DODGING)
-       #define PHYS_DODGING_DELAY                                      getstatf(STAT_DODGING_DELAY)
-       #define PHYS_DODGING_TIMEOUT(s)                         getstatf(STAT_DODGING_TIMEOUT)
-       #define PHYS_DODGING_HORIZ_SPEED_FROZEN         getstatf(STAT_DODGING_HORIZ_SPEED_FROZEN)
-       #define PHYS_DODGING_FROZEN_NODOUBLETAP         getstati(STAT_DODGING_FROZEN_NO_DOUBLETAP)
-       #define PHYS_DODGING_HORIZ_SPEED                        getstatf(STAT_DODGING_HORIZ_SPEED)
-       #define PHYS_DODGING_PRESSED_KEYS(s)            s.pressedkeys
-       #define PHYS_DODGING_HEIGHT_THRESHOLD           getstatf(STAT_DODGING_HEIGHT_THRESHOLD)
-       #define PHYS_DODGING_DISTANCE_THRESHOLD         getstatf(STAT_DODGING_DISTANCE_THRESHOLD)
-       #define PHYS_DODGING_RAMP_TIME                          getstatf(STAT_DODGING_RAMP_TIME)
-       #define PHYS_DODGING_UP_SPEED                           getstatf(STAT_DODGING_UP_SPEED)
-       #define PHYS_DODGING_WALL                                       getstatf(STAT_DODGING_WALL)
-#elif defined(SVQC)
-       #define PHYS_DODGING_FRAMETIME                          sys_frametime
-       #define PHYS_DODGING                                            g_dodging
-       #define PHYS_DODGING_DELAY                                      autocvar_sv_dodging_delay
-       #define PHYS_DODGING_TIMEOUT(s)                         s.cvar_cl_dodging_timeout
-       #define PHYS_DODGING_HORIZ_SPEED_FROZEN         autocvar_sv_dodging_horiz_speed_frozen
-       #define PHYS_DODGING_FROZEN_NODOUBLETAP         autocvar_sv_dodging_frozen_doubletap
-       #define PHYS_DODGING_HORIZ_SPEED                        autocvar_sv_dodging_horiz_speed
-       #define PHYS_DODGING_PRESSED_KEYS(s)            s.pressedkeys
-       #define PHYS_DODGING_HEIGHT_THRESHOLD           autocvar_sv_dodging_height_threshold
-       #define PHYS_DODGING_DISTANCE_THRESHOLD         autocvar_sv_dodging_wall_distance_threshold
-       #define PHYS_DODGING_RAMP_TIME                          autocvar_sv_dodging_ramp_time
-       #define PHYS_DODGING_UP_SPEED                           autocvar_sv_dodging_up_speed
-       #define PHYS_DODGING_WALL                                       autocvar_sv_dodging_wall_dodging
-#endif
-
-#ifdef SVQC
-#include "mutator_dodging.qh"
-
-#include "mutator.qh"
-
-#include "../../common/animdecide.qh"
-#include "../../common/physics.qh"
-
-.float cvar_cl_dodging_timeout;
-
-.float stat_dodging;
-.float stat_dodging_delay;
-.float stat_dodging_horiz_speed_frozen;
-.float stat_dodging_frozen_nodoubletap;
-.float stat_dodging_frozen;
-.float stat_dodging_horiz_speed;
-.float stat_dodging_height_threshold;
-.float stat_dodging_distance_threshold;
-.float stat_dodging_ramp_time;
-.float stat_dodging_up_speed;
-.float stat_dodging_wall;
-
-#endif
-
-// set to 1 to indicate dodging has started.. reset by physics hook after dodge has been done..
-.float dodging_action;
-
-// the jump part of the dodge cannot be ramped
-.float dodging_single_action;
-
-
-// these are used to store the last key press time for each of the keys..
-.float last_FORWARD_KEY_time;
-.float last_BACKWARD_KEY_time;
-.float last_LEFT_KEY_time;
-.float last_RIGHT_KEY_time;
-
-// these store the movement direction at the time of the dodge action happening.
-.vector dodging_direction;
-
-// this indicates the last time a dodge was executed. used to check if another one is allowed
-// and to ramp up the dodge acceleration in the physics hook.
-.float last_dodging_time;
-
-// This is the velocity gain to be added over the ramp time.
-// It will decrease from frame to frame during dodging_action = 1
-// until it's 0.
-.float dodging_velocity_gain;
-
-#ifdef CSQC
-.int pressedkeys;
-
-#elif defined(SVQC)
-
-void dodging_UpdateStats()
-{SELFPARAM();
-       self.stat_dodging = PHYS_DODGING;
-       self.stat_dodging_delay = PHYS_DODGING_DELAY;
-       self.stat_dodging_horiz_speed_frozen = PHYS_DODGING_HORIZ_SPEED_FROZEN;
-       self.stat_dodging_frozen = PHYS_DODGING_FROZEN;
-       self.stat_dodging_frozen_nodoubletap = PHYS_DODGING_FROZEN_NODOUBLETAP;
-       self.stat_dodging_height_threshold = PHYS_DODGING_HEIGHT_THRESHOLD;
-       self.stat_dodging_distance_threshold = PHYS_DODGING_DISTANCE_THRESHOLD;
-       self.stat_dodging_ramp_time = PHYS_DODGING_RAMP_TIME;
-       self.stat_dodging_up_speed = PHYS_DODGING_UP_SPEED;
-       self.stat_dodging_wall = PHYS_DODGING_WALL;
-}
-
-void dodging_Initialize()
-{
-       addstat(STAT_DODGING, AS_INT, stat_dodging);
-       addstat(STAT_DODGING_DELAY, AS_FLOAT, stat_dodging_delay);
-       addstat(STAT_DODGING_TIMEOUT, AS_FLOAT, cvar_cl_dodging_timeout); // we stat this, so it is updated on the client when updated on server (otherwise, chaos)
-       addstat(STAT_DODGING_FROZEN_NO_DOUBLETAP, AS_INT, stat_dodging_frozen_nodoubletap);
-       addstat(STAT_DODGING_HORIZ_SPEED_FROZEN, AS_FLOAT, stat_dodging_horiz_speed_frozen);
-       addstat(STAT_DODGING_FROZEN, AS_INT, stat_dodging_frozen);
-       addstat(STAT_DODGING_HORIZ_SPEED, AS_FLOAT, stat_dodging_horiz_speed);
-       addstat(STAT_DODGING_HEIGHT_THRESHOLD, AS_FLOAT, stat_dodging_height_threshold);
-       addstat(STAT_DODGING_DISTANCE_THRESHOLD, AS_FLOAT, stat_dodging_distance_threshold);
-       addstat(STAT_DODGING_RAMP_TIME, AS_FLOAT, stat_dodging_ramp_time);
-       addstat(STAT_DODGING_UP_SPEED, AS_FLOAT, stat_dodging_up_speed);
-       addstat(STAT_DODGING_WALL, AS_FLOAT, stat_dodging_wall);
-}
-
-#endif
-
-// returns 1 if the player is close to a wall
-bool check_close_to_wall(float threshold)
-{SELFPARAM();
-       if (PHYS_DODGING_WALL == 0) { return false; }
-
-       #define X(OFFSET)                                                                                                                               \
-       tracebox(self.origin, self.mins, self.maxs, self.origin + OFFSET, true, self);  \
-       if (trace_fraction < 1 && vlen (self.origin - trace_endpos) < threshold)                \
-               return true;
-       X(1000*v_right);
-       X(-1000*v_right);
-       X(1000*v_forward);
-       X(-1000*v_forward);
-       #undef X
-
-       return false;
-}
-
-bool check_close_to_ground(float threshold)
-{SELFPARAM();
-       return IS_ONGROUND(self) ? true : false;
-}
-
-float PM_dodging_checkpressedkeys()
-{SELFPARAM();
-       if(!PHYS_DODGING)
-               return false;
-
-       float frozen_dodging = (PHYS_FROZEN(self) && PHYS_DODGING_FROZEN);
-       float frozen_no_doubletap = (frozen_dodging && !PHYS_DODGING_FROZEN_NODOUBLETAP);
-
-       // first check if the last dodge is far enough back in time so we can dodge again
-       if ((time - self.last_dodging_time) < PHYS_DODGING_DELAY)
-               return false;
-
-       makevectors(self.angles);
-
-       if (check_close_to_ground(PHYS_DODGING_HEIGHT_THRESHOLD) != 1
-               && check_close_to_wall(PHYS_DODGING_DISTANCE_THRESHOLD) != 1)
-               return true;
-
-       float tap_direction_x = 0;
-       float tap_direction_y = 0;
-       float dodge_detected = 0;
-
-       #define X(COND,BTN,RESULT)                                                                                                                      \
-       if (self.movement_##COND)                                                                                               \
-               /* is this a state change? */                                                                                                   \
-               if(!(PHYS_DODGING_PRESSED_KEYS(self) & KEY_##BTN) || frozen_no_doubletap) {             \
-                               tap_direction_##RESULT;                                                                                                 \
-                               if ((time - self.last_##BTN##_KEY_time) < PHYS_DODGING_TIMEOUT(self))   \
-                                       dodge_detected = 1;                                                                                                     \
-                               self.last_##BTN##_KEY_time = time;                                                                              \
-               }
-       X(x < 0, BACKWARD,      x--);
-       X(x > 0, FORWARD,       x++);
-       X(y < 0, LEFT,          y--);
-       X(y > 0, RIGHT,         y++);
-       #undef X
-
-       if (dodge_detected == 1)
-       {
-               self.last_dodging_time = time;
-
-               self.dodging_action = 1;
-               self.dodging_single_action = 1;
-
-               self.dodging_velocity_gain = PHYS_DODGING_HORIZ_SPEED;
-
-               self.dodging_direction_x = tap_direction_x;
-               self.dodging_direction_y = tap_direction_y;
-
-               // normalize the dodging_direction vector.. (unlike UT99) XD
-               float length = self.dodging_direction_x * self.dodging_direction_x
-                                       + self.dodging_direction_y * self.dodging_direction_y;
-               length = sqrt(length);
-
-               self.dodging_direction_x = self.dodging_direction_x * 1.0 / length;
-               self.dodging_direction_y = self.dodging_direction_y * 1.0 / length;
-               return true;
-       }
-       return false;
-}
-
-void PM_dodging()
-{SELFPARAM();
-       if (!PHYS_DODGING)
-               return;
-
-#ifdef SVQC
-       dodging_UpdateStats();
-#endif
-
-    if (PHYS_DEAD(self))
-        return;
-
-       // when swimming, no dodging allowed..
-       if (self.waterlevel >= WATERLEVEL_SWIMMING)
-       {
-               self.dodging_action = 0;
-               self.dodging_direction_x = 0;
-               self.dodging_direction_y = 0;
-               return;
-       }
-
-       // make sure v_up, v_right and v_forward are sane
-       makevectors(self.angles);
-
-       // if we have e.g. 0.5 sec ramptime and a frametime of 0.25, then the ramp code
-       // will be called ramp_time/frametime times = 2 times. so, we need to
-       // add 0.5 * the total speed each frame until the dodge action is done..
-       float common_factor = PHYS_DODGING_FRAMETIME / PHYS_DODGING_RAMP_TIME;
-
-       // if ramp time is smaller than frametime we get problems ;D
-       common_factor = min(common_factor, 1);
-
-       float horiz_speed = PHYS_FROZEN(self) ? PHYS_DODGING_HORIZ_SPEED_FROZEN : PHYS_DODGING_HORIZ_SPEED;
-       float new_velocity_gain = self.dodging_velocity_gain - (common_factor * horiz_speed);
-       new_velocity_gain = max(0, new_velocity_gain);
-
-       float velocity_difference = self.dodging_velocity_gain - new_velocity_gain;
-
-       // ramp up dodging speed by adding some velocity each frame.. TODO: do it! :D
-       if (self.dodging_action == 1)
-       {
-               //disable jump key during dodge accel phase
-               if(self.movement_z > 0) { self.movement_z = 0; }
-
-               self.velocity += ((self.dodging_direction_y * velocity_difference) * v_right)
-                                       + ((self.dodging_direction_x * velocity_difference) * v_forward);
-
-               self.dodging_velocity_gain = self.dodging_velocity_gain - velocity_difference;
-       }
-
-       // the up part of the dodge is a single shot action
-       if (self.dodging_single_action == 1)
-       {
-               UNSET_ONGROUND(self);
-
-               self.velocity += PHYS_DODGING_UP_SPEED * v_up;
-
-#ifdef SVQC
-               if (autocvar_sv_dodging_sound)
-                       PlayerSound(playersound_jump, CH_PLAYER, VOICETYPE_PLAYERSOUND);
-
-               animdecide_setaction(self, ANIMACTION_JUMP, true);
-#endif
-
-               self.dodging_single_action = 0;
-       }
-
-       // are we done with the dodging ramp yet?
-       if((self.dodging_action == 1) && ((time - self.last_dodging_time) > PHYS_DODGING_RAMP_TIME))
-       {
-               // reset state so next dodge can be done correctly
-               self.dodging_action = 0;
-               self.dodging_direction_x = 0;
-               self.dodging_direction_y = 0;
-       }
-}
-
-#ifdef SVQC
-
-MUTATOR_HOOKFUNCTION(dodging_GetCvars)
-{
-       GetCvars_handleFloat(get_cvars_s, get_cvars_f, cvar_cl_dodging_timeout, "cl_dodging_timeout");
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(dodging_PlayerPhysics)
-{
-       // print("dodging_PlayerPhysics\n");
-       PM_dodging();
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(dodging_GetPressedKeys)
-{
-       PM_dodging_checkpressedkeys();
-
-       return false;
-}
-
-MUTATOR_DEFINITION(mutator_dodging)
-{
-       // we need to be called before GetPressedKey does its thing so we can
-       // detect state changes and therefore dodging actions..
-       MUTATOR_HOOK(GetPressedKeys, dodging_GetPressedKeys, CBC_ORDER_ANY);
-
-       // in the physics hook we actually implement the dodge..
-       MUTATOR_HOOK(PlayerPhysics, dodging_PlayerPhysics, CBC_ORDER_ANY);
-
-       // get timeout information from the client, so the client can configure it..
-       MUTATOR_HOOK(GetCvars, dodging_GetCvars, CBC_ORDER_ANY);
-
-       // this just turns on the cvar.
-       MUTATOR_ONADD
-       {
-               g_dodging = cvar("g_dodging");
-               dodging_Initialize();
-       }
-
-       // this just turns off the cvar.
-       MUTATOR_ONROLLBACK_OR_REMOVE
-       {
-               g_dodging = 0;
-       }
-
-       return false;
-}
-#endif
diff --git a/qcsrc/server/mutators/mutator_dodging.qh b/qcsrc/server/mutators/mutator_dodging.qh
deleted file mode 100644 (file)
index a8fd665..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef MUTATOR_DODGING_H
-#define MUTATOR_DODGING_H
-
-float g_dodging;
-
-// set to 1 to indicate dodging has started.. reset by physics hook after dodge has been done..
-.float dodging_action;
-
-// the jump part of the dodge cannot be ramped
-.float dodging_single_action;
-#endif
diff --git a/qcsrc/server/mutators/mutator_hook.qc b/qcsrc/server/mutators/mutator_hook.qc
deleted file mode 100644 (file)
index e43848b..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-AUTOCVAR(g_grappling_hook, bool, false, _("let players spawn with the grappling hook which allows them to pull themselves up"));
-#ifdef SVQC
-REGISTER_MUTATOR(hook, autocvar_g_grappling_hook) {
-    MUTATOR_ONADD {
-        g_grappling_hook = true;
-        WEP_HOOK.ammo_factor = 0;
-    }
-    MUTATOR_ONROLLBACK_OR_REMOVE {
-        g_grappling_hook = false;
-        WEP_HOOK.ammo_factor = 1;
-    }
-}
-
-MUTATOR_HOOKFUNCTION(hook, BuildMutatorsString)
-{
-    ret_string = strcat(ret_string, ":grappling_hook");
-}
-
-MUTATOR_HOOKFUNCTION(hook, BuildMutatorsPrettyString)
-{
-    ret_string = strcat(ret_string, ", Hook");
-}
-
-MUTATOR_HOOKFUNCTION(hook, BuildGameplayTipsString)
-{
-    ret_string = strcat(ret_string, "\n\n^3grappling hook^8 is enabled, press 'e' to use it\n");
-}
-
-MUTATOR_HOOKFUNCTION(hook, PlayerSpawn)
-{
-    SELFPARAM();
-    self.offhand = OFFHAND_HOOK;
-}
-
-MUTATOR_HOOKFUNCTION(hook, FilterItem)
-{
-    return self.weapon == WEP_HOOK.m_id;
-}
-
-#endif
diff --git a/qcsrc/server/mutators/mutator_invincibleproj.qc b/qcsrc/server/mutators/mutator_invincibleproj.qc
deleted file mode 100644 (file)
index 2855a07..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-
-#include "mutator.qh"
-
-MUTATOR_HOOKFUNCTION(invincibleprojectiles_EditProjectile)
-{
-       if(other.health)
-       {
-               // disable health which in effect disables damage calculations
-               other.health = 0;
-       }
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(invincibleprojectiles_BuildMutatorsString)
-{
-       ret_string = strcat(ret_string, ":InvincibleProjectiles");
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(invincibleprojectiles_BuildMutatorsPrettyString)
-{
-       ret_string = strcat(ret_string, ", Invincible Projectiles");
-       return 0;
-}
-
-MUTATOR_DEFINITION(mutator_invincibleprojectiles)
-{
-       MUTATOR_HOOK(EditProjectile, invincibleprojectiles_EditProjectile, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BuildMutatorsString, invincibleprojectiles_BuildMutatorsString, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BuildMutatorsPrettyString, invincibleprojectiles_BuildMutatorsPrettyString, CBC_ORDER_ANY);
-
-       return 0;
-}
diff --git a/qcsrc/server/mutators/mutator_melee_only.qc b/qcsrc/server/mutators/mutator_melee_only.qc
deleted file mode 100644 (file)
index 019eeb8..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-
-#include "mutator.qh"
-
-MUTATOR_HOOKFUNCTION(melee_SetStartItems)
-{
-       start_ammo_shells = warmup_start_ammo_shells = 0;
-       start_weapons = warmup_start_weapons = WEPSET(SHOTGUN);
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(melee_ForbidThrowing)
-{
-       return true;
-}
-
-MUTATOR_HOOKFUNCTION(melee_FilterItem)
-{SELFPARAM();
-       switch (self.items)
-       {
-               case ITEM_HealthSmall.m_itemid:
-               case ITEM_ArmorSmall.m_itemid:
-                       return false;
-       }
-
-       return true;
-}
-
-MUTATOR_HOOKFUNCTION(melee_BuildMutatorsString)
-{
-       ret_string = strcat(ret_string, ":MeleeOnly");
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(melee_BuildMutatorsPrettyString)
-{
-       ret_string = strcat(ret_string, ", Melee Only Arena");
-       return false;
-}
-
-MUTATOR_DEFINITION(mutator_melee_only)
-{
-       MUTATOR_HOOK(SetStartItems, melee_SetStartItems, CBC_ORDER_ANY);
-       MUTATOR_HOOK(ForbidThrowCurrentWeapon, melee_ForbidThrowing, CBC_ORDER_ANY);
-       MUTATOR_HOOK(FilterItem, melee_FilterItem, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BuildMutatorsString, melee_BuildMutatorsString, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BuildMutatorsPrettyString, melee_BuildMutatorsPrettyString, CBC_ORDER_ANY);
-
-       return false;
-}
diff --git a/qcsrc/server/mutators/mutator_midair.qc b/qcsrc/server/mutators/mutator_midair.qc
deleted file mode 100644 (file)
index 33ae58f..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-
-#include "mutator.qh"
-
-.float midair_shieldtime;
-
-MUTATOR_HOOKFUNCTION(midair_PlayerDamage)
-{SELFPARAM();
-       if(IS_PLAYER(frag_attacker))
-       if(IS_PLAYER(frag_target))
-       if(time < self.midair_shieldtime)
-               frag_damage = false;
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(midair_PlayerPowerups)
-{SELFPARAM();
-       if(time >= game_starttime)
-       if(self.flags & FL_ONGROUND)
-       {
-               self.effects |= (EF_ADDITIVE | EF_FULLBRIGHT);
-               self.midair_shieldtime = max(self.midair_shieldtime, time + autocvar_g_midair_shieldtime);
-       }
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(midair_PlayerSpawn)
-{SELFPARAM();
-       if(IS_BOT_CLIENT(self))
-               self.bot_moveskill = 0; // disable bunnyhopping
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(midair_BuildMutatorsString)
-{
-       ret_string = strcat(ret_string, ":midair");
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(midair_BuildMutatorsPrettyString)
-{
-       ret_string = strcat(ret_string, ", Midair");
-       return false;
-}
-
-MUTATOR_DEFINITION(mutator_midair)
-{
-       MUTATOR_HOOK(PlayerDamage_Calculate, midair_PlayerDamage, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerPowerups, midair_PlayerPowerups, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerSpawn, midair_PlayerSpawn, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BuildMutatorsString, midair_BuildMutatorsString, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BuildMutatorsPrettyString, midair_BuildMutatorsPrettyString, CBC_ORDER_ANY);
-
-       return false;
-}
diff --git a/qcsrc/server/mutators/mutator_multijump.qc b/qcsrc/server/mutators/mutator_multijump.qc
deleted file mode 100644 (file)
index de6296d..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-#ifdef SVQC
-       #include "mutator.qh"
-       #include "../antilag.qh"
-#endif
-#include "../../common/physics.qh"
-
-.int multijump_count;
-.bool multijump_ready;
-.bool cvar_cl_multijump;
-
-#ifdef CSQC
-
-#define PHYS_MULTIJUMP                                 getstati(STAT_MULTIJUMP)
-#define PHYS_MULTIJUMP_SPEED           getstatf(STAT_MULTIJUMP_SPEED)
-#define PHYS_MULTIJUMP_ADD                     getstati(STAT_MULTIJUMP_ADD)
-#define PHYS_MULTIJUMP_MAXSPEED        getstatf(STAT_MULTIJUMP_MAXSPEED)
-#define PHYS_MULTIJUMP_DODGING                 getstati(STAT_MULTIJUMP_DODGING)
-
-#elif defined(SVQC)
-
-#define PHYS_MULTIJUMP                                 autocvar_g_multijump
-#define PHYS_MULTIJUMP_SPEED           autocvar_g_multijump_speed
-#define PHYS_MULTIJUMP_ADD                     autocvar_g_multijump_add
-#define PHYS_MULTIJUMP_MAXSPEED        autocvar_g_multijump_maxspeed
-#define PHYS_MULTIJUMP_DODGING                 autocvar_g_multijump_dodging
-
-
-.float stat_multijump;
-.float stat_multijump_speed;
-.float stat_multijump_add;
-.float stat_multijump_maxspeed;
-.float stat_multijump_dodging;
-
-void multijump_UpdateStats()
-{SELFPARAM();
-       self.stat_multijump = PHYS_MULTIJUMP;
-       self.stat_multijump_speed = PHYS_MULTIJUMP_SPEED;
-       self.stat_multijump_add = PHYS_MULTIJUMP_ADD;
-       self.stat_multijump_maxspeed = PHYS_MULTIJUMP_MAXSPEED;
-       self.stat_multijump_dodging = PHYS_MULTIJUMP_DODGING;
-}
-
-void multijump_AddStats()
-{
-       addstat(STAT_MULTIJUMP, AS_INT, stat_multijump);
-       addstat(STAT_MULTIJUMP_SPEED, AS_FLOAT, stat_multijump_speed);
-       addstat(STAT_MULTIJUMP_ADD, AS_INT, stat_multijump_add);
-       addstat(STAT_MULTIJUMP_MAXSPEED, AS_FLOAT, stat_multijump_maxspeed);
-       addstat(STAT_MULTIJUMP_DODGING, AS_INT, stat_multijump_dodging);
-}
-
-#endif
-
-void PM_multijump()
-{SELFPARAM();
-       if(!PHYS_MULTIJUMP) { return; }
-
-       if(IS_ONGROUND(self))
-       {
-               self.multijump_count = 0;
-       }
-}
-
-bool PM_multijump_checkjump()
-{SELFPARAM();
-       if(!PHYS_MULTIJUMP) { return false; }
-
-#ifdef SVQC
-       bool client_multijump = self.cvar_cl_multijump;
-#elif defined(CSQC)
-       bool client_multijump = cvar("cl_multijump");
-
-       if(cvar("cl_multijump") > 1)
-               return false; // nope
-#endif
-
-       if (!IS_JUMP_HELD(self) && !IS_ONGROUND(self) && client_multijump) // jump button pressed this frame and we are in midair
-               self.multijump_ready = true;  // this is necessary to check that we released the jump button and pressed it again
-       else
-               self.multijump_ready = false;
-
-       int phys_multijump = PHYS_MULTIJUMP;
-
-#ifdef CSQC
-       phys_multijump = (PHYS_MULTIJUMP) ? -1 : 0;
-#endif
-
-       if(!player_multijump && self.multijump_ready && (self.multijump_count < phys_multijump || phys_multijump == -1) && self.velocity_z > PHYS_MULTIJUMP_SPEED && (!PHYS_MULTIJUMP_MAXSPEED || vlen(self.velocity) <= PHYS_MULTIJUMP_MAXSPEED))
-       {
-               if (PHYS_MULTIJUMP)
-               {
-                       if (!PHYS_MULTIJUMP_ADD) // in this case we make the z velocity == jumpvelocity
-                       {
-                               if (self.velocity_z < PHYS_JUMPVELOCITY)
-                               {
-                                       player_multijump = true;
-                                       self.velocity_z = 0;
-                               }
-                       }
-                       else
-                               player_multijump = true;
-
-                       if(player_multijump)
-                       {
-                               if(PHYS_MULTIJUMP_DODGING)
-                               if(self.movement_x != 0 || self.movement_y != 0) // don't remove all speed if player isnt pressing any movement keys
-                               {
-                                       float curspeed;
-                                       vector wishvel, wishdir;
-
-/*#ifdef SVQC
-                                       curspeed = max(
-                                               vlen(vec2(self.velocity)), // current xy speed
-                                               vlen(vec2(antilag_takebackavgvelocity(self, max(self.lastteleporttime + sys_frametime, time - 0.25), time))) // average xy topspeed over the last 0.25 secs
-                                       );
-#elif defined(CSQC)*/
-                                       curspeed = vlen(vec2(self.velocity));
-//#endif
-
-                                       makevectors(self.v_angle_y * '0 1 0');
-                                       wishvel = v_forward * self.movement_x + v_right * self.movement_y;
-                                       wishdir = normalize(wishvel);
-
-                                       self.velocity_x = wishdir_x * curspeed; // allow "dodging" at a multijump
-                                       self.velocity_y = wishdir_y * curspeed;
-                                       // keep velocity_z unchanged!
-                               }
-                               if (PHYS_MULTIJUMP > 0)
-                               {
-                                       self.multijump_count += 1;
-                               }
-                       }
-               }
-               self.multijump_ready = false; // require releasing and pressing the jump button again for the next jump
-       }
-
-       return false;
-}
-
-#ifdef SVQC
-MUTATOR_HOOKFUNCTION(multijump_PlayerPhysics)
-{
-       multijump_UpdateStats();
-       PM_multijump();
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(multijump_PlayerJump)
-{
-       return PM_multijump_checkjump();
-}
-
-MUTATOR_HOOKFUNCTION(multijump_GetCvars)
-{
-       GetCvars_handleFloat(get_cvars_s, get_cvars_f, cvar_cl_multijump, "cl_multijump");
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(multijump_BuildMutatorsString)
-{
-       ret_string = strcat(ret_string, ":multijump");
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(multijump_BuildMutatorsPrettyString)
-{
-       ret_string = strcat(ret_string, ", Multi jump");
-       return false;
-}
-
-MUTATOR_DEFINITION(mutator_multijump)
-{
-       MUTATOR_HOOK(PlayerPhysics, multijump_PlayerPhysics, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerJump, multijump_PlayerJump, CBC_ORDER_ANY);
-       MUTATOR_HOOK(GetCvars, multijump_GetCvars, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BuildMutatorsString, multijump_BuildMutatorsString, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BuildMutatorsPrettyString, multijump_BuildMutatorsPrettyString, CBC_ORDER_ANY);
-
-       MUTATOR_ONADD
-       {
-               multijump_AddStats();
-       }
-
-       return false;
-}
-#endif
diff --git a/qcsrc/server/mutators/mutator_nades.qc b/qcsrc/server/mutators/mutator_nades.qc
deleted file mode 100644 (file)
index bf55e67..0000000
+++ /dev/null
@@ -1,1220 +0,0 @@
-#include "mutator_nades.qh"
-
-#include "mutator.qh"
-
-#include "gamemode_keyhunt.qh"
-#include "gamemode_freezetag.qh"
-#include "../../common/nades/all.qh"
-#include "../../common/gamemodes/all.qh"
-#include "../../common/monsters/spawn.qh"
-#include "../../common/monsters/sv_monsters.qh"
-#include "../g_subs.qh"
-
-.float nade_time_primed;
-
-.entity nade_spawnloc;
-
-void nade_timer_think()
-{SELFPARAM();
-       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)
-{
-       CSQCProjectile(_nade, true, Nades[_nade.nade_type].m_projectile[true], true);
-}
-
-void nade_spawn(entity _nade)
-{
-       entity timer = spawn();
-       setmodel(timer, MDL_NADE_TIMER);
-       setattachment(timer, _nade, "");
-       timer.classname = "nade_timer";
-       timer.colormap = _nade.colormap;
-       timer.glowmod = _nade.glowmod;
-       timer.think = nade_timer_think;
-       timer.nextthink = time;
-       timer.wait = _nade.wait;
-       timer.owner = _nade;
-       timer.skin = 10;
-
-       _nade.effects |= EF_LOWPRECISION;
-
-       CSQCProjectile(_nade, true, Nades[_nade.nade_type].m_projectile[false], true);
-}
-
-void napalm_damage(float dist, float damage, float edgedamage, float burntime)
-{SELFPARAM();
-       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)
-       {
-               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(EFFECT_FIREBALL_LASER), self.origin, RandomSelection_chosen_ent.fireball_impactvec);
-               Send_Effect(EFFECT_FIREBALL_LASER, self.origin, RandomSelection_chosen_ent.fireball_impactvec - self.origin, 1);
-       }
-}
-
-
-void napalm_ball_think()
-{SELFPARAM();
-       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()
-{SELFPARAM();
-       entity proj;
-       vector kick;
-
-       spamsound(self, CH_SHOTS, SND(FIREBALL_FIRE), 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.m_id;
-       PROJECTILE_MAKETRIGGER(proj);
-       setmodel(proj, MDL_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()
-{SELFPARAM();
-
-       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()
-{SELFPARAM();
-       entity fountain;
-       int 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.m_id;
-       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;
-       Send_Effect(EFFECT_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()
-{SELFPARAM();
-
-       if(round_handler_IsActive())
-       if(!round_handler_IsRoundStarted())
-       {
-               remove(self);
-               return;
-       }
-
-       if(time >= self.ltime)
-       {
-               if ( autocvar_g_nades_ice_explode )
-               {
-                       entity expef = EFFECT_NADE_EXPLODE(self.realowner.team);
-                       Send_Effect(expef, self.origin + '0 0 1', '0 0 0', 1);
-                       sound(self, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM);
-
-                       RadiusDamage(self, self.realowner, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage,
-                               autocvar_g_nades_nade_radius, self, world, 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;
-       Send_Effect(EFFECT_ELECTRO_MUZZLEFLASH, self.origin + randomp, '0 0 0', 1);
-
-       if(time >= self.nade_special_time)
-       {
-               self.nade_special_time = time+0.7;
-
-               Send_Effect(EFFECT_ELECTRO_IMPACT, self.origin, '0 0 0', 1);
-               Send_Effect(EFFECT_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()
-{SELFPARAM();
-       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.m_id;
-       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, MDL_PROJECTILE_GRENADE);
-               entity timer = spawn();
-               setmodel(timer, MDL_NADE_TIMER);
-               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, MDL_Null);
-}
-
-void nade_translocate_boom()
-{SELFPARAM();
-       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);
-
-       MUTATOR_CALLHOOK(PortalTeleport, self.realowner);
-
-       TeleportPlayer(self, self.realowner, locout, self.realowner.angles, v_forward * vlen(self.realowner.velocity), '0 0 0', '0 0 0', TELEPORT_FLAGS_TELEPORTER);
-}
-
-void nade_spawn_boom()
-{SELFPARAM();
-       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()
-{SELFPARAM();
-       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()
-{SELFPARAM();
-       float maxhealth;
-       float health_factor;
-       if(IS_PLAYER(other) || IS_MONSTER(other))
-       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 = (IS_MONSTER(other)) ? other.max_health : g_pickup_healthmega_max;
-                       if ( other.health < maxhealth )
-                       {
-                               if ( self.nade_show_particles )
-                                       Send_Effect(EFFECT_HEALING, 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.m_id,other.origin,'0 0 0');
-               }
-
-       }
-
-       if ( IS_REAL_CLIENT(other) || IS_VEHICLE(other) )
-       {
-               entity show_red = (IS_VEHICLE(other)) ? 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()
-{SELFPARAM();
-       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, MDL_NADE_HEAL);
-       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()
-{SELFPARAM();
-       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()
-{SELFPARAM();
-       entity expef = NULL;
-       bool nade_blast = true;
-
-       switch ( Nades[self.nade_type] )
-       {
-               case NADE_TYPE_NAPALM:
-                       nade_blast = autocvar_g_nades_napalm_blast;
-                       expef = EFFECT_EXPLOSION_MEDIUM;
-                       break;
-               case NADE_TYPE_ICE:
-                       nade_blast = false;
-                       expef = EFFECT_ELECTRO_COMBO; // hookbomb_explode electro_combo bigplasma_impact
-                       break;
-               case NADE_TYPE_TRANSLOCATE:
-                       nade_blast = false;
-                       break;
-               case NADE_TYPE_MONSTER:
-               case NADE_TYPE_SPAWN:
-                       nade_blast = false;
-                       switch(self.realowner.team)
-                       {
-                               case NUM_TEAM_1: expef = EFFECT_SPAWN_RED; break;
-                               case NUM_TEAM_2: expef = EFFECT_SPAWN_BLUE; break;
-                               case NUM_TEAM_3: expef = EFFECT_SPAWN_YELLOW; break;
-                               case NUM_TEAM_4: expef = EFFECT_SPAWN_PINK; break;
-                               default: expef = EFFECT_SPAWN_NEUTRAL; break;
-                       }
-                       break;
-               case NADE_TYPE_HEAL:
-                       nade_blast = false;
-                       expef = EFFECT_SPAWN_RED;
-                       break;
-
-               default:
-               case NADE_TYPE_NORMAL:
-                       expef = EFFECT_NADE_EXPLODE(self.realowner.team);
-                       break;
-       }
-
-       if(expef)
-               Send_Effect(expef, findbetterlocation(self.origin, 8), '0 0 0', 1);
-
-       sound(self, CH_SHOTS_SINGLE, SND_Null, VOL_BASE, ATTEN_NORM);
-       sound(self, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM);
-
-       self.event_damage = func_null; // prevent somehow calling damage in the next call
-
-       if(nade_blast)
-       {
-               RadiusDamage(self, self.realowner, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage,
-                                autocvar_g_nades_nade_radius, self, world, 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);
-       }
-
-       if(self.takedamage)
-       switch ( Nades[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;
-       }
-
-       entity head;
-       for(head = world; (head = find(head, classname, "grapplinghook")); )
-       if(head.aiment == self)
-               RemoveGrapplingHook(head.realowner);
-
-       remove(self);
-}
-
-void nade_touch()
-{SELFPARAM();
-       /*float is_weapclip = 0;
-       if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NODRAW)
-       if (!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NONSOLID))
-       if (!(trace_dphitcontents & DPCONTENTS_OPAQUE))
-               is_weapclip = 1;*/
-       if(ITEM_TOUCH_NEEDKILL()) // || is_weapclip)
-       {
-               entity head;
-               for(head = world; (head = find(head, classname, "grapplinghook")); )
-               if(head.aiment == self)
-                       RemoveGrapplingHook(head.realowner);
-               remove(self);
-               return;
-       }
-
-       PROJECTILE_TOUCH;
-
-       //setsize(self, '-2 -2 -2', '2 2 2');
-       //UpdateCSQCProjectile(self);
-       if(self.health == self.max_health)
-       {
-               spamsound(self, CH_SHOTS, SND(GRENADE_BOUNCE_RANDOM()), VOL_BASE, ATTEN_NORM);
-               return;
-       }
-
-       self.enemy = other;
-       nade_boom();
-}
-
-void nade_beep()
-{SELFPARAM();
-       sound(self, CH_SHOTS_SINGLE, SND_NADE_BEEP, VOL_BASE, 0.5 *(ATTEN_LARGE + ATTEN_MAX));
-       self.think = nade_boom;
-       self.nextthink = max(self.wait, time);
-}
-
-void nade_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
-{SELFPARAM();
-       if(ITEM_DAMAGE_NEEDKILL(deathtype))
-       {
-               self.takedamage = DAMAGE_NO;
-               nade_boom();
-               return;
-       }
-
-       if(self.nade_type == NADE_TYPE_TRANSLOCATE.m_id || self.nade_type == NADE_TYPE_SPAWN.m_id)
-               return;
-
-       if(DEATH_ISWEAPON(deathtype, WEP_BLASTER))
-       {
-               force *= 1.5;
-               damage = 0;
-       }
-
-       if(DEATH_ISWEAPON(deathtype, WEP_VAPORIZER) && (deathtype & HITTYPE_SECONDARY))
-       {
-               force *= 0.5; // too much
-               frag_damage = 0;
-       }
-
-       if(DEATH_ISWEAPON(deathtype, WEP_VORTEX) || DEATH_ISWEAPON(deathtype, WEP_VAPORIZER))
-       {
-               force *= 6;
-               damage = self.max_health * 0.55;
-       }
-
-       if(DEATH_ISWEAPON(deathtype, WEP_MACHINEGUN) || DEATH_ISWEAPON(deathtype, WEP_HMG))
-               damage = self.max_health * 0.1;
-
-       if(DEATH_ISWEAPON(deathtype, WEP_SHOCKWAVE) || DEATH_ISWEAPON(deathtype, WEP_SHOTGUN)) // WEAPONTODO
-       if(deathtype & HITTYPE_SECONDARY)
-       {
-               damage = self.max_health * 0.1;
-               force *= 10;
-       }
-       else
-               damage = self.max_health * 1.15;
-
-       self.velocity += force;
-       UpdateCSQCProjectile(self);
-
-       if(damage <= 0 || ((self.flags & FL_ONGROUND) && IS_PLAYER(attacker)))
-               return;
-
-       if(self.health == self.max_health)
-       {
-               sound(self, CH_SHOTS_SINGLE, SND_Null, VOL_BASE, 0.5 *(ATTEN_LARGE + ATTEN_MAX));
-               self.nextthink = max(time + autocvar_g_nades_nade_lifetime, time);
-               self.think = nade_beep;
-       }
-
-       self.health -= damage;
-
-       if ( self.nade_type != NADE_TYPE_HEAL.m_id || IS_PLAYER(attacker) )
-               self.realowner = attacker;
-
-       if(self.health <= 0)
-               W_PrepareExplosionByDamage(attacker, nade_boom);
-       else
-               nade_burn_spawn(self);
-}
-
-void toss_nade(entity e, vector _velocity, float _time)
-{SELFPARAM();
-       if(e.nade == world)
-               return;
-
-       entity _nade = e.nade;
-       e.nade = world;
-
-       remove(e.fake_nade);
-       e.fake_nade = world;
-
-       makevectors(e.v_angle);
-
-       W_SetupShot(e, false, false, "", CH_WEAPON_A, 0);
-
-       Kill_Notification(NOTIF_ONE_ONLY, e, MSG_CENTER_CPID, CPID_NADES);
-
-       vector offset = (v_forward * autocvar_g_nades_throw_offset.x)
-                                 + (v_right * autocvar_g_nades_throw_offset.y)
-                                 + (v_up * autocvar_g_nades_throw_offset.z);
-       if(autocvar_g_nades_throw_offset == '0 0 0')
-               offset = '0 0 0';
-
-       setorigin(_nade, w_shotorg + offset + (v_right * 25) * -1);
-       //setmodel(_nade, MDL_PROJECTILE_NADE);
-       //setattachment(_nade, world, "");
-       PROJECTILE_MAKETRIGGER(_nade);
-       setsize(_nade, '-16 -16 -16', '16 16 16');
-       _nade.movetype = MOVETYPE_BOUNCE;
-
-       tracebox(_nade.origin, _nade.mins, _nade.maxs, _nade.origin, false, _nade);
-       if (trace_startsolid)
-               setorigin(_nade, e.origin);
-
-       if(self.v_angle.x >= 70 && self.v_angle.x <= 110 && self.BUTTON_CROUCH)
-               _nade.velocity = '0 0 100';
-       else if(autocvar_g_nades_nade_newton_style == 1)
-               _nade.velocity = e.velocity + _velocity;
-       else if(autocvar_g_nades_nade_newton_style == 2)
-               _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.traileffectnum = 0;
-       _nade.teleportable = true;
-       _nade.pushable = true;
-       _nade.gravity = 1;
-       _nade.missile_flags = MIF_SPLASH | MIF_ARC;
-       _nade.damagedbycontents = true;
-       _nade.angles = vectoangles(_nade.velocity);
-       _nade.flags = FL_PROJECTILE;
-       _nade.projectiledeathtype = DEATH_NADE.m_id;
-       _nade.toss_time = time;
-       _nade.solid = SOLID_CORPSE; //((_nade.nade_type == NADE_TYPE_TRANSLOCATE) ? SOLID_CORPSE : SOLID_BBOX);
-
-       if(_nade.nade_type == NADE_TYPE_TRANSLOCATE.m_id || _nade.nade_type == NADE_TYPE_SPAWN.m_id)
-               _nade.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
-       else
-               _nade.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY;
-
-       nade_spawn(_nade);
-
-       if(_time)
-       {
-               _nade.think = nade_boom;
-               _nade.nextthink = _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, SND(KH_ALARM));
-                       player.bonus_nades++;
-                       player.bonus_nade_score -= 1;
-               }
-       }
-}
-
-void nades_RemoveBonus(entity player)
-{
-       player.bonus_nades = player.bonus_nade_score = 0;
-}
-
-float nade_customize()
-{SELFPARAM();
-       //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(Nades[self.nade_type].m_projectile[false], self.team).eent_eff_name);
-               self.alpha = 1;
-       }
-
-       return true;
-}
-
-void nade_prime()
-{SELFPARAM();
-       if(autocvar_g_nades_bonus_only)
-       if(!self.bonus_nades)
-               return; // only allow bonus nades
-
-       if(self.nade)
-               remove(self.nade);
-
-       if(self.fake_nade)
-               remove(self.fake_nade);
-
-       entity n = spawn(), fn = spawn();
-
-       n.classname = "nade";
-       fn.classname = "fake_nade";
-
-       if(self.items & ITEM_Strength.m_itemid && 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, Nades_COUNT);
-
-       setmodel(n, MDL_PROJECTILE_NADE);
-       //setattachment(n, self, "bip01 l hand");
-       n.exteriormodeltoclient = self;
-       n.customizeentityforclient = nade_customize;
-       n.traileffectnum = _particleeffectnum(Nade_TrailEffect(Nades[n.nade_type].m_projectile[false], self.team).eent_eff_name);
-       n.colormod = Nades[n.nade_type].m_color;
-       n.realowner = self;
-       n.colormap = self.colormap;
-       n.glowmod = self.glowmod;
-       n.wait = time + autocvar_g_nades_nade_lifetime;
-       n.nade_time_primed = time;
-       n.think = nade_beep;
-       n.nextthink = max(n.wait - 3, time);
-       n.projectiledeathtype = DEATH_NADE.m_id;
-
-       setmodel(fn, MDL_NADE_VIEW);
-       setattachment(fn, self.weaponentity, "");
-       fn.realowner = fn.owner = self;
-       fn.colormod = Nades[n.nade_type].m_color;
-       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()
-{SELFPARAM();
-       if(self.vehicle)
-               return false;
-
-       if(gameover)
-               return false;
-
-       if(self.deadflag != DEAD_NO)
-               return false;
-
-       if (!autocvar_g_nades)
-               return false; // allow turning them off mid match
-
-       if(forbidWeaponUse(self))
-               return false;
-
-       if (!IS_PLAYER(self))
-               return false;
-
-       return true;
-}
-
-.bool nade_altbutton;
-
-void nades_CheckThrow()
-{SELFPARAM();
-       if(!CanThrowNade())
-               return;
-
-       entity held_nade = self.nade;
-       if (!held_nade)
-       {
-               self.nade_altbutton = true;
-               if(time > self.nade_refire)
-               {
-                       Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_NADE_THROW);
-                       nade_prime();
-                       self.nade_refire = time + autocvar_g_nades_nade_refire;
-               }
-       }
-       else
-       {
-               self.nade_altbutton = false;
-               if (time >= held_nade.nade_time_primed + 1) {
-                       makevectors(self.v_angle);
-                       float _force = time - held_nade.nade_time_primed;
-                       _force /= autocvar_g_nades_nade_lifetime;
-                       _force = autocvar_g_nades_nade_minforce + (_force * (autocvar_g_nades_nade_maxforce - autocvar_g_nades_nade_minforce));
-                       toss_nade(self, (v_forward * 0.75 + v_up * 0.2 + v_right * 0.05) * _force, 0);
-               }
-       }
-}
-
-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_VehicleEnter)
-{
-       if(vh_player.nade)
-               toss_nade(vh_player, '0 0 100', max(vh_player.nade.wait, time + 0.05));
-
-       return false;
-}
-
-CLASS(NadeOffhand, OffhandWeapon)
-    METHOD(NadeOffhand, offhand_think, void(NadeOffhand this, entity player, bool key_pressed))
-    {
-       entity held_nade = player.nade;
-               if (held_nade)
-               {
-                       player.nade_timer = bound(0, (time - held_nade.nade_time_primed) / autocvar_g_nades_nade_lifetime, 1);
-                       // LOG_TRACEF("%d %d\n", player.nade_timer, time - held_nade.nade_time_primed);
-                       makevectors(player.angles);
-                       held_nade.velocity = player.velocity;
-                       setorigin(held_nade, player.origin + player.view_ofs + v_forward * 8 + v_right * -8 + v_up * 0);
-                       held_nade.angles_y = player.angles.y;
-
-                       if (time + 0.1 >= held_nade.wait)
-                               toss_nade(player, '0 0 0', time + 0.05);
-               }
-
-        if (!CanThrowNade()) return;
-        if (!(time > player.nade_refire)) return;
-               if (key_pressed) {
-                       if (!held_nade) {
-                               nade_prime();
-                               held_nade = player.nade;
-                       }
-               } else if (time >= held_nade.nade_time_primed + 1) {
-                       if (held_nade) {
-                               makevectors(player.v_angle);
-                               float _force = time - held_nade.nade_time_primed;
-                               _force /= autocvar_g_nades_nade_lifetime;
-                               _force = autocvar_g_nades_nade_minforce + (_force * (autocvar_g_nades_nade_maxforce - autocvar_g_nades_nade_minforce));
-                               toss_nade(player, (v_forward * 0.7 + v_up * 0.2 + v_right * 0.1) * _force, 0);
-                       }
-               }
-    }
-ENDCLASS(NadeOffhand)
-NadeOffhand OFFHAND_NADE; STATIC_INIT(OFFHAND_NADE) { OFFHAND_NADE = NEW(NadeOffhand); }
-
-MUTATOR_HOOKFUNCTION(nades_CheckThrow)
-{
-       if (self.offhand != OFFHAND_NADE || (self.weapons & WEPSET(HOOK)) || autocvar_g_nades_override_dropweapon) {
-               nades_CheckThrow();
-               return true;
-       }
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(nades_PlayerPreThink)
-{SELFPARAM();
-       if (!IS_PLAYER(self)) { return false; }
-
-       if (self.nade && (self.offhand != OFFHAND_NADE || (self.weapons & WEPSET(HOOK)))) OFFHAND_NADE.offhand_think(OFFHAND_NADE, self, self.nade_altbutton);
-
-       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; }
-
-                       float time_score;
-                       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, Nades_COUNT);
-
-                       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;
-}
-
-MUTATOR_HOOKFUNCTION(nades_PlayerSpawn)
-{SELFPARAM();
-       if(autocvar_g_nades_spawn)
-               self.nade_refire = time + autocvar_g_spawnshieldtime;
-       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.offhand) self.offhand = OFFHAND_NADE;
-
-       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(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.m_id)
-       if(time - frag_inflictor.toss_time <= 0.1)
-       {
-               Unfreeze(frag_target);
-               frag_target.health = autocvar_g_freezetag_revive_nade_health;
-               Send_Effect(EFFECT_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)
-{SELFPARAM();
-       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)
-{SELFPARAM();
-       nades_Clear(self);
-       nades_RemoveBonus(self);
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(nades_SpectateCopy)
-{SELFPARAM();
-       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;
-}
-
-MUTATOR_HOOKFUNCTION(nades_BuildMutatorsString)
-{
-       ret_string = strcat(ret_string, ":Nades");
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(nades_BuildMutatorsPrettyString)
-{
-       ret_string = strcat(ret_string, ", Nades");
-       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);
-}
-
-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_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
-       {
-               nades_Initialize();
-       }
-
-       return false;
-}
diff --git a/qcsrc/server/mutators/mutator_nades.qh b/qcsrc/server/mutators/mutator_nades.qh
deleted file mode 100644 (file)
index 1a0dd52..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef MUTATOR_NADES_H
-#define MUTATOR_NADES_H
-
-.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 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;
-#endif
diff --git a/qcsrc/server/mutators/mutator_new_toys.qc b/qcsrc/server/mutators/mutator_new_toys.qc
deleted file mode 100644 (file)
index 93b64eb..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-
-#include "mutator.qh"
-
-/*
-
-CORE    laser   vortex     lg      rl      cry     gl      elec    hagar   fireb   hook
-                                                                       vaporizer  porto
-                                                                       tuba
-
-NEW             rifle   hlac    minel                           seeker
-IDEAS                                   OPEN    flak    OPEN            FUN FUN FUN FUN
-
-
-
-How this mutator works:
- =======================
-
-When a gun tries to spawn, this mutator is called. It will provide alternate
-weaponreplace lists.
-
-Entity:
-
-{
-"classname" "weapon_vortex"
-"new_toys" "rifle"
-}
--> This will spawn as Rifle in this mutator ONLY, and as Vortex otherwise.
-
-{
-"classname" "weapon_vortext"
-"new_toys" "vortex rifle"
-}
--> This will spawn as either Vortex or Rifle in this mutator ONLY, and as Vortex otherwise.
-
-{
-"classname" "weapon_vortex"
-"new_toys" "vortex"
-}
--> This is always a Vortex.
-
-If the map specifies no "new_toys" argument
-
-There will be two default replacements selectable: "replace all" and "replace random".
-In "replace all" mode, e.g. Vortex will have the default replacement "rifle".
-In "replace random" mode, Vortex will have the default replacement "vortex rifle".
-
-This mutator's replacements run BEFORE regular weaponreplace!
-
-The New Toys guns do NOT get a spawn function, so they can only ever be spawned
-when this mutator is active.
-
-Likewise, warmup, give all, give ALL and impulse 99 will not give them unless
-this mutator is active.
-
-Outside this mutator, they still can be spawned by:
-- setting their start weapon cvar to 1
-- give weaponname
-- weaponreplace
-- weaponarena (but all and most weapons arena again won't include them)
-
-This mutator performs the default replacements on the DEFAULTS of the
-start weapon selection.
-
-These weapons appear in the menu's priority list, BUT get a suffix
-"(Mutator weapon)".
-
-Picking up a "new toys" weapon will not play standard weapon pickup sound, but
-roflsound "New toys, new toys!" sound.
-
-*/
-
-.string new_toys;
-
-float autocvar_g_new_toys_autoreplace;
-bool autocvar_g_new_toys_use_pickupsound = true;
-const float NT_AUTOREPLACE_NEVER = 0;
-const float NT_AUTOREPLACE_ALWAYS = 1;
-const float NT_AUTOREPLACE_RANDOM = 2;
-
-MUTATOR_HOOKFUNCTION(nt_SetModname)
-{
-       modname = "NewToys";
-       return 0;
-}
-
-float nt_IsNewToy(float w)
-{
-       switch(w)
-       {
-               case WEP_SEEKER.m_id:
-               case WEP_MINE_LAYER.m_id:
-               case WEP_HLAC.m_id:
-               case WEP_RIFLE.m_id:
-               case WEP_SHOCKWAVE.m_id:
-                       return true;
-               default:
-                       return false;
-       }
-}
-
-string nt_GetFullReplacement(string w)
-{
-       switch(w)
-       {
-               case "hagar": return "seeker";
-               case "devastator": return "minelayer";
-               case "machinegun": return "hlac";
-               case "vortex": return "rifle";
-               //case "shotgun": return "shockwave";
-               default: return string_null;
-       }
-}
-
-string nt_GetReplacement(string w, float m)
-{
-       if(m == NT_AUTOREPLACE_NEVER)
-               return w;
-       string s = nt_GetFullReplacement(w);
-       if (!s)
-               return w;
-       if(m == NT_AUTOREPLACE_RANDOM)
-               s = strcat(w, " ", s);
-       return s;
-}
-
-MUTATOR_HOOKFUNCTION(nt_SetStartItems)
-{
-       // rearrange start_weapon_default
-       // apply those bits that are set by start_weapon_defaultmask
-       // same for warmup
-
-       float i, j, k, n;
-
-       WepSet newdefault;
-       WepSet warmup_newdefault;
-
-       newdefault = '0 0 0';
-       warmup_newdefault = '0 0 0';
-
-       for(i = WEP_FIRST; i <= WEP_LAST; ++i)
-       {
-               entity e = get_weaponinfo(i);
-               if(!e.weapon)
-                       continue;
-
-               n = tokenize_console(nt_GetReplacement(e.netname, autocvar_g_new_toys_autoreplace));
-
-               for(j = 0; j < n; ++j)
-                       for(k = WEP_FIRST; k <= WEP_LAST; ++k)
-                               if(get_weaponinfo(k).netname == argv(j))
-                               {
-                                       if(start_weapons & WepSet_FromWeapon(i))
-                                               newdefault |= WepSet_FromWeapon(k);
-                                       if(warmup_start_weapons & WepSet_FromWeapon(i))
-                                               warmup_newdefault |= WepSet_FromWeapon(k);
-                               }
-       }
-
-       newdefault &= start_weapons_defaultmask;
-       start_weapons &= ~start_weapons_defaultmask;
-       start_weapons |= newdefault;
-
-       warmup_newdefault &= warmup_start_weapons_defaultmask;
-       warmup_start_weapons &= ~warmup_start_weapons_defaultmask;
-       warmup_start_weapons |= warmup_newdefault;
-
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(nt_SetWeaponreplace)
-{SELFPARAM();
-       // otherwise, we do replace
-       if(self.new_toys)
-       {
-               // map defined replacement:
-               ret_string = self.new_toys;
-       }
-       else
-       {
-               // auto replacement:
-               ret_string = nt_GetReplacement(other.netname, autocvar_g_new_toys_autoreplace);
-       }
-
-       // apply regular weaponreplace
-       ret_string = W_Apply_Weaponreplace(ret_string);
-
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(nt_FilterItem)
-{SELFPARAM();
-       if(nt_IsNewToy(self.weapon) && autocvar_g_new_toys_use_pickupsound) {
-               self.item_pickupsound = string_null;
-               self.item_pickupsound_ent = SND_WEAPONPICKUP_NEW_TOYS;
-       }
-       return 0;
-}
-
-MUTATOR_DEFINITION(mutator_new_toys)
-{
-       MUTATOR_HOOK(SetModname, nt_SetModname, CBC_ORDER_ANY);
-       MUTATOR_HOOK(SetStartItems, nt_SetStartItems, CBC_ORDER_ANY);
-       MUTATOR_HOOK(SetWeaponreplace, nt_SetWeaponreplace, CBC_ORDER_LAST);
-       MUTATOR_HOOK(FilterItem, nt_FilterItem, CBC_ORDER_ANY);
-
-       MUTATOR_ONADD
-       {
-               if(time > 1) // game loads at time 1
-                       error("This cannot be added at runtime\n");
-
-               // mark the guns as ok to use by e.g. impulse 99
-               float i;
-               for(i = WEP_FIRST; i <= WEP_LAST; ++i)
-                       if(nt_IsNewToy(i))
-                               get_weaponinfo(i).spawnflags &= ~WEP_FLAG_MUTATORBLOCKED;
-       }
-
-       MUTATOR_ONROLLBACK_OR_REMOVE
-       {
-               float i;
-               for(i = WEP_FIRST; i <= WEP_LAST; ++i)
-                       if(nt_IsNewToy(i))
-                               get_weaponinfo(i).spawnflags |= WEP_FLAG_MUTATORBLOCKED;
-       }
-
-       MUTATOR_ONREMOVE
-       {
-               LOG_INFO("This cannot be removed at runtime\n");
-               return -1;
-       }
-
-       return 0;
-}
diff --git a/qcsrc/server/mutators/mutator_nix.qc b/qcsrc/server/mutators/mutator_nix.qc
deleted file mode 100644 (file)
index 2a26d93..0000000
+++ /dev/null
@@ -1,284 +0,0 @@
-
-#include "mutator.qh"
-
-float g_nix_with_blaster;
-// WEAPONTODO
-int nix_weapon;
-float nix_nextchange;
-float nix_nextweapon;
-.float nix_lastchange_id;
-.float nix_lastinfotime;
-.float nix_nextincr;
-
-float NIX_CanChooseWeapon(float wpn)
-{
-       entity e;
-       e = get_weaponinfo(wpn);
-       if(!e.weapon) // skip dummies
-               return false;
-       if(g_weaponarena)
-       {
-               if(!(g_weaponarena_weapons & WepSet_FromWeapon(wpn)))
-                       return false;
-       }
-       else
-       {
-               if(wpn == WEP_BLASTER.m_id && g_nix_with_blaster) // WEAPONTODO: rename to g_nix_with_blaster
-                       return false;
-               if(e.spawnflags & WEP_FLAG_MUTATORBLOCKED)
-                       return false;
-               if (!(e.spawnflags & WEP_FLAG_NORMAL))
-                       return false;
-       }
-       return true;
-}
-void NIX_ChooseNextWeapon()
-{
-       float j;
-       RandomSelection_Init();
-       for(j = WEP_FIRST; j <= WEP_LAST; ++j)
-               if(NIX_CanChooseWeapon(j))
-                       RandomSelection_Add(world, j, string_null, 1, (j != nix_weapon));
-       nix_nextweapon = RandomSelection_chosen_float;
-}
-
-void NIX_GiveCurrentWeapon()
-{SELFPARAM();
-       float dt;
-
-       if(!nix_nextweapon)
-               NIX_ChooseNextWeapon();
-
-       dt = ceil(nix_nextchange - time);
-
-       if(dt <= 0)
-       {
-               nix_weapon = nix_nextweapon;
-               nix_nextweapon = 0;
-               if (!nix_nextchange) // no round played yet?
-                       nix_nextchange = time; // start the first round now!
-               else
-                       nix_nextchange = time + autocvar_g_balance_nix_roundtime;
-               // Weapon w = get_weaponinfo(nix_weapon);
-               // w.wr_init(w); // forget it, too slow
-       }
-
-       // get weapon info
-       entity e = get_weaponinfo(nix_weapon);
-
-       if(nix_nextchange != self.nix_lastchange_id) // this shall only be called once per round!
-       {
-               self.ammo_shells = self.ammo_nails = self.ammo_rockets = self.ammo_cells = self.ammo_plasma = self.ammo_fuel = 0;
-
-               if(self.items & IT_UNLIMITED_WEAPON_AMMO)
-               {
-                       switch(e.ammo_field)
-                       {
-                               case ammo_shells:  self.ammo_shells  = autocvar_g_pickup_shells_max;  break;
-                               case ammo_nails:   self.ammo_nails   = autocvar_g_pickup_nails_max;   break;
-                               case ammo_rockets: self.ammo_rockets = autocvar_g_pickup_rockets_max; break;
-                               case ammo_cells:   self.ammo_cells   = autocvar_g_pickup_cells_max;   break;
-                               case ammo_plasma:  self.ammo_plasma  = autocvar_g_pickup_plasma_max;   break;
-                               case ammo_fuel:    self.ammo_fuel    = autocvar_g_pickup_fuel_max;    break;
-                       }
-               }
-               else
-               {
-                       switch(e.ammo_field)
-                       {
-                               case ammo_shells:  self.ammo_shells  = autocvar_g_balance_nix_ammo_shells;  break;
-                               case ammo_nails:   self.ammo_nails   = autocvar_g_balance_nix_ammo_nails;   break;
-                               case ammo_rockets: self.ammo_rockets = autocvar_g_balance_nix_ammo_rockets; break;
-                               case ammo_cells:   self.ammo_cells   = autocvar_g_balance_nix_ammo_cells;   break;
-                               case ammo_plasma:  self.ammo_plasma  = autocvar_g_balance_nix_ammo_plasma;   break;
-                               case ammo_fuel:    self.ammo_fuel    = autocvar_g_balance_nix_ammo_fuel;    break;
-                       }
-               }
-
-               self.nix_nextincr = time + autocvar_g_balance_nix_incrtime;
-               if(dt >= 1 && dt <= 5)
-                       self.nix_lastinfotime = -42;
-               else
-                       Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_NIX_NEWWEAPON, nix_weapon);
-
-               Weapon w = get_weaponinfo(nix_weapon);
-               w.wr_resetplayer(w);
-
-               // all weapons must be fully loaded when we spawn
-               if(e.spawnflags & WEP_FLAG_RELOADABLE) // prevent accessing undefined cvars
-                       self.(weapon_load[nix_weapon]) = e.reloading_ammo;
-
-               // vortex too
-               if(WEP_CVAR(vortex, charge))
-               {
-                       if(WEP_CVAR_SEC(vortex, chargepool))
-                               self.vortex_chargepool_ammo = 1;
-                       self.vortex_charge = WEP_CVAR(vortex, charge_start);
-               }
-
-               // set last change info
-               self.nix_lastchange_id = nix_nextchange;
-       }
-       if(self.nix_lastinfotime != dt)
-       {
-               self.nix_lastinfotime = dt; // initial value 0 should count as "not seen"
-               if(dt >= 1 && dt <= 5)
-                       Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_NIX_COUNTDOWN, nix_nextweapon, dt);
-       }
-
-       if(!(self.items & IT_UNLIMITED_WEAPON_AMMO) && time > self.nix_nextincr)
-       {
-               switch(e.ammo_field)
-               {
-                       case ammo_shells:  self.ammo_shells  += autocvar_g_balance_nix_ammoincr_shells;  break;
-                       case ammo_nails:   self.ammo_nails   += autocvar_g_balance_nix_ammoincr_nails;   break;
-                       case ammo_rockets: self.ammo_rockets += autocvar_g_balance_nix_ammoincr_rockets; break;
-                       case ammo_cells:   self.ammo_cells   += autocvar_g_balance_nix_ammoincr_cells;   break;
-                       case ammo_plasma:  self.ammo_plasma  += autocvar_g_balance_nix_ammoincr_plasma;   break;
-                       case ammo_fuel:    self.ammo_fuel    += autocvar_g_balance_nix_ammoincr_fuel;    break;
-               }
-
-               self.nix_nextincr = time + autocvar_g_balance_nix_incrtime;
-       }
-
-       self.weapons = '0 0 0';
-       if(g_nix_with_blaster)
-               self.weapons |= WEPSET(BLASTER);
-       self.weapons |= WepSet_FromWeapon(nix_weapon);
-
-       if(self.switchweapon != nix_weapon)
-               if(!client_hasweapon(self, self.switchweapon, true, false))
-                       if(client_hasweapon(self, nix_weapon, true, false))
-                               W_SwitchWeapon(nix_weapon);
-}
-
-void NIX_precache()
-{
-       float i;
-       for (i = WEP_FIRST; i <= WEP_LAST; ++i)
-               if (NIX_CanChooseWeapon(i)) {
-                       Weapon w = get_weaponinfo(i);
-                       w.wr_init(w);
-               }
-}
-
-MUTATOR_HOOKFUNCTION(nix_ForbidThrowCurrentWeapon)
-{
-       return 1; // no throwing in NIX
-}
-
-MUTATOR_HOOKFUNCTION(nix_BuildMutatorsString)
-{
-       ret_string = strcat(ret_string, ":NIX");
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(nix_BuildMutatorsPrettyString)
-{
-       ret_string = strcat(ret_string, ", NIX");
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(nix_FilterItem)
-{SELFPARAM();
-       switch (self.items)
-       {
-               case ITEM_HealthSmall.m_itemid:
-               case ITEM_HealthMedium.m_itemid:
-               case ITEM_HealthLarge.m_itemid:
-               case ITEM_HealthMega.m_itemid:
-               case ITEM_ArmorSmall.m_itemid:
-               case ITEM_ArmorMedium.m_itemid:
-               case ITEM_ArmorLarge.m_itemid:
-               case ITEM_ArmorMega.m_itemid:
-                       if (autocvar_g_nix_with_healtharmor)
-                               return 0;
-                       break;
-               case ITEM_Strength.m_itemid:
-               case ITEM_Shield.m_itemid:
-                       if (autocvar_g_nix_with_powerups)
-                               return 0;
-                       break;
-       }
-
-       return 1; // delete all other items
-}
-
-MUTATOR_HOOKFUNCTION(nix_OnEntityPreSpawn)
-{SELFPARAM();
-       if(self.classname == "target_items") // items triggers cannot work in nix (as they change weapons/ammo)
-               return 1;
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(nix_PlayerPreThink)
-{SELFPARAM();
-       if(!intermission_running)
-       if(self.deadflag == DEAD_NO)
-       if(IS_PLAYER(self))
-               NIX_GiveCurrentWeapon();
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(nix_PlayerSpawn)
-{SELFPARAM();
-       self.nix_lastchange_id = -1;
-       NIX_GiveCurrentWeapon(); // overrides the weapons you got when spawning
-       self.items |= IT_UNLIMITED_SUPERWEAPONS;
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(nix_SetModname)
-{
-       modname = "NIX";
-       return 0;
-}
-
-MUTATOR_DEFINITION(mutator_nix)
-{SELFPARAM();
-       entity e;
-
-       MUTATOR_HOOK(ForbidThrowCurrentWeapon, nix_ForbidThrowCurrentWeapon, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BuildMutatorsString, nix_BuildMutatorsString, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BuildMutatorsPrettyString, nix_BuildMutatorsPrettyString, CBC_ORDER_ANY);
-       MUTATOR_HOOK(FilterItem, nix_FilterItem, CBC_ORDER_ANY);
-       MUTATOR_HOOK(OnEntityPreSpawn, nix_OnEntityPreSpawn, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerPreThink, nix_PlayerPreThink, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerSpawn, nix_PlayerSpawn, CBC_ORDER_ANY);
-       MUTATOR_HOOK(SetModname, nix_SetModname, CBC_ORDER_LAST);
-
-       MUTATOR_ONADD
-       {
-               g_nix_with_blaster = autocvar_g_nix_with_blaster;
-
-               nix_nextchange = 0;
-               nix_nextweapon = 0;
-
-               NIX_precache();
-       }
-
-       MUTATOR_ONROLLBACK_OR_REMOVE
-       {
-               // nothing to roll back
-       }
-
-       MUTATOR_ONREMOVE
-       {
-               // as the PlayerSpawn hook will no longer run, NIX is turned off by this!
-
-               FOR_EACH_PLAYER(e) if(e.deadflag == DEAD_NO)
-               {
-                       e.ammo_cells = start_ammo_cells;
-                       e.ammo_plasma = start_ammo_plasma;
-                       e.ammo_shells = start_ammo_shells;
-                       e.ammo_nails = start_ammo_nails;
-                       e.ammo_rockets = start_ammo_rockets;
-                       e.ammo_fuel = start_ammo_fuel;
-                       e.weapons = start_weapons;
-                       if(!client_hasweapon(e, e.weapon, true, false))
-                               e.switchweapon = w_getbestweapon(self);
-               }
-       }
-
-       return 0;
-}
diff --git a/qcsrc/server/mutators/mutator_overkill.qc b/qcsrc/server/mutators/mutator_overkill.qc
deleted file mode 100644 (file)
index 5d1a9cd..0000000
+++ /dev/null
@@ -1,364 +0,0 @@
-#include "mutator_overkill.qh"
-
-#include "mutator.qh"
-
-void W_Blaster_Attack(entity, float, float, float, float, float, float, float, float, float, float);
-spawnfunc(weapon_hmg);
-spawnfunc(weapon_rpc);
-
-void ok_DecreaseCharge(entity ent, int wep)
-{
-       if(!ent.ok_use_ammocharge) return;
-
-       entity wepent = get_weaponinfo(wep);
-
-       if(wepent.weapon == 0)
-               return; // dummy
-
-       ent.ammo_charge[wep] -= max(0, cvar(sprintf("g_overkill_ammo_decharge_%s", wepent.netname)));
-}
-
-void ok_IncreaseCharge(entity ent, int wep)
-{
-       entity wepent = get_weaponinfo(wep);
-
-       if(wepent.weapon == 0)
-               return; // dummy
-
-       if(ent.ok_use_ammocharge)
-       if(!ent.BUTTON_ATCK) // not while attacking?
-               ent.ammo_charge[wep] = min(autocvar_g_overkill_ammo_charge_limit, ent.ammo_charge[wep] + cvar(sprintf("g_overkill_ammo_charge_rate_%s", wepent.netname)) * frametime / W_TICSPERFRAME);
-}
-
-float ok_CheckWeaponCharge(entity ent, int wep)
-{
-       if(!ent.ok_use_ammocharge) return true;
-
-       entity wepent = get_weaponinfo(wep);
-
-       if(wepent.weapon == 0)
-               return 0; // dummy
-
-       return (ent.ammo_charge[wep] >= cvar(sprintf("g_overkill_ammo_decharge_%s", wepent.netname)));
-}
-
-MUTATOR_HOOKFUNCTION(ok_PlayerDamage_Calculate)
-{
-       if(IS_PLAYER(frag_attacker) && IS_PLAYER(frag_target))
-       if(DEATH_ISWEAPON(frag_deathtype, WEP_BLASTER))
-       {
-               frag_damage = 0;
-
-               if(frag_attacker != frag_target)
-               if(frag_target.health > 0)
-               if(frag_target.frozen == 0)
-               if(frag_target.deadflag == DEAD_NO)
-               {
-                       Send_Notification(NOTIF_ONE, frag_attacker, MSG_CENTER, CENTER_SECONDARY_NODAMAGE);
-                       frag_force = '0 0 0';
-               }
-       }
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ok_PlayerDamage_SplitHealthArmor)
-{SELFPARAM();
-       if(damage_take)
-               self.ok_pauseregen_finished = max(self.ok_pauseregen_finished, time + 2);
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ok_PlayerDies)
-{SELFPARAM();
-       entity targ = ((frag_attacker) ? frag_attacker : frag_target);
-
-       if(IS_MONSTER(self))
-       {
-               remove(other); // remove default item
-               other = world;
-       }
-
-       setself(spawn());
-       self.ok_item = true;
-       self.noalign = true;
-       self.pickup_anyway = true;
-       spawnfunc_item_armor_small(this);
-       self.movetype = MOVETYPE_TOSS;
-       self.gravity = 1;
-       self.reset = SUB_Remove;
-       setorigin(self, frag_target.origin + '0 0 32');
-       self.velocity = '0 0 200' + normalize(targ.origin - self.origin) * 500;
-       self.classname = "droppedweapon"; // hax
-       SUB_SetFade(self, time + 5, 1);
-       setself(this);
-
-       self.ok_lastwep = self.switchweapon;
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ok_PlayerRegen)
-{SELFPARAM();
-       // overkill's values are different, so use custom regen
-       if(!self.frozen)
-       {
-               self.armorvalue = CalcRotRegen(self.armorvalue, autocvar_g_balance_armor_regenstable, autocvar_g_balance_armor_regen, autocvar_g_balance_armor_regenlinear, 1 * frametime * (time > self.ok_pauseregen_finished), 0, 0, 1, 1 * frametime * (time > self.pauserotarmor_finished), autocvar_g_balance_armor_limit);
-               self.health = CalcRotRegen(self.health, autocvar_g_balance_health_regenstable, 0, 100, 1 * frametime * (time > self.ok_pauseregen_finished), 200, 0, autocvar_g_balance_health_rotlinear, 1 * frametime * (time > self.pauserothealth_finished), autocvar_g_balance_health_limit);
-
-               float minf, maxf, limitf;
-
-               maxf = autocvar_g_balance_fuel_rotstable;
-               minf = autocvar_g_balance_fuel_regenstable;
-               limitf = autocvar_g_balance_fuel_limit;
-
-               self.ammo_fuel = CalcRotRegen(self.ammo_fuel, minf, autocvar_g_balance_fuel_regen, autocvar_g_balance_fuel_regenlinear, frametime * (time > self.pauseregen_finished) * ((self.items & ITEM_JetpackRegen.m_itemid) != 0), maxf, autocvar_g_balance_fuel_rot, autocvar_g_balance_fuel_rotlinear, frametime * (time > self.pauserotfuel_finished), limitf);
-       }
-       return true; // return true anyway, as frozen uses no regen
-}
-
-MUTATOR_HOOKFUNCTION(ok_ForbidThrowCurrentWeapon)
-{
-       return true;
-}
-
-MUTATOR_HOOKFUNCTION(ok_PlayerPreThink)
-{SELFPARAM();
-       if(intermission_running || gameover)
-               return false;
-
-       if(self.deadflag != DEAD_NO || !IS_PLAYER(self) || self.frozen)
-               return false;
-
-       if(self.ok_lastwep)
-       {
-               self.switchweapon = self.ok_lastwep;
-               self.ok_lastwep = 0;
-       }
-
-       ok_IncreaseCharge(self, self.weapon);
-
-       if(self.BUTTON_ATCK2)
-       if(!forbidWeaponUse(self) || self.weapon_blocked) // allow if weapon is blocked
-       if(time >= self.jump_interval)
-       {
-               self.jump_interval = time + WEP_CVAR_PRI(blaster, refire) * W_WeaponRateFactor();
-               makevectors(self.v_angle);
-
-               int oldwep = self.weapon;
-               self.weapon = WEP_BLASTER.m_id;
-               W_Blaster_Attack(
-                       self,
-                       WEP_BLASTER.m_id | HITTYPE_SECONDARY,
-                       WEP_CVAR_SEC(vaporizer, shotangle),
-                       WEP_CVAR_SEC(vaporizer, damage),
-                       WEP_CVAR_SEC(vaporizer, edgedamage),
-                       WEP_CVAR_SEC(vaporizer, radius),
-                       WEP_CVAR_SEC(vaporizer, force),
-                       WEP_CVAR_SEC(vaporizer, speed),
-                       WEP_CVAR_SEC(vaporizer, spread),
-                       WEP_CVAR_SEC(vaporizer, delay),
-                       WEP_CVAR_SEC(vaporizer, lifetime)
-               );
-               self.weapon = oldwep;
-       }
-
-       self.weapon_blocked = false;
-
-       self.ok_ammo_charge = self.ammo_charge[self.weapon];
-
-       if(self.ok_use_ammocharge)
-       if(!ok_CheckWeaponCharge(self, self.weapon))
-       {
-               if(autocvar_g_overkill_ammo_charge_notice && time > self.ok_notice_time && self.BUTTON_ATCK && IS_REAL_CLIENT(self) && self.weapon == self.switchweapon)
-               {
-                       //Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_OVERKILL_CHARGE);
-                       self.ok_notice_time = time + 2;
-                       play2(self, SND(DRYFIRE));
-               }
-               Weapon wpn = get_weaponinfo(self.weapon);
-               if(self.weaponentity.state != WS_CLEAR)
-                       w_ready(wpn, self, self.BUTTON_ATCK, self.BUTTON_ATCK2);
-
-               self.weapon_blocked = true;
-       }
-
-       self.BUTTON_ATCK2 = 0;
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ok_PlayerSpawn)
-{SELFPARAM();
-       if(autocvar_g_overkill_ammo_charge)
-       {
-               for(int i = WEP_FIRST; i <= WEP_LAST; ++i)
-                       self.ammo_charge[i] = autocvar_g_overkill_ammo_charge_limit;
-
-               self.ok_use_ammocharge = 1;
-               self.ok_notice_time = time;
-       }
-       else
-               self.ok_use_ammocharge = 0;
-
-       self.ok_pauseregen_finished = time + 2;
-
-       return false;
-}
-
-void _spawnfunc_weapon_hmg() { SELFPARAM(); spawnfunc_weapon_hmg(this); }
-void _spawnfunc_weapon_rpc() { SELFPARAM(); spawnfunc_weapon_rpc(this); }
-
-MUTATOR_HOOKFUNCTION(ok_OnEntityPreSpawn)
-{SELFPARAM();
-       if(autocvar_g_powerups)
-       if(autocvar_g_overkill_powerups_replace)
-       {
-               if(self.classname == "item_strength")
-               {
-                       entity wep = spawn();
-                       setorigin(wep, self.origin);
-                       setmodel(wep, MDL_OK_HMG);
-                       wep.classname = "weapon_hmg";
-                       wep.ok_item = true;
-                       wep.noalign = self.noalign;
-                       wep.cnt = self.cnt;
-                       wep.team = self.team;
-                       wep.respawntime = autocvar_g_overkill_superguns_respawn_time;
-                       wep.pickup_anyway = true;
-                       wep.think = _spawnfunc_weapon_hmg;
-                       wep.nextthink = time + 0.1;
-                       return true;
-               }
-
-               if(self.classname == "item_invincible")
-               {
-                       entity wep = spawn();
-                       setorigin(wep, self.origin);
-                       setmodel(wep, MDL_OK_RPC);
-                       wep.classname = "weapon_rpc";
-                       wep.ok_item = true;
-                       wep.noalign = self.noalign;
-                       wep.cnt = self.cnt;
-                       wep.team = self.team;
-                       wep.respawntime = autocvar_g_overkill_superguns_respawn_time;
-                       wep.pickup_anyway = true;
-                       wep.think = _spawnfunc_weapon_rpc;
-                       wep.nextthink = time + 0.1;
-                       return true;
-               }
-       }
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ok_ItemRemove)
-{SELFPARAM();
-       if(self.ok_item)
-               return false;
-
-       switch(self.items)
-       {
-               case ITEM_HealthMega.m_itemid: return !(autocvar_g_overkill_100h_anyway);
-               case ITEM_ArmorMega.m_itemid: return !(autocvar_g_overkill_100a_anyway);
-       }
-
-       return true;
-}
-
-MUTATOR_HOOKFUNCTION(ok_SpectateCopy)
-{SELFPARAM();
-       self.ammo_charge[self.weapon] = other.ammo_charge[other.weapon];
-       self.ok_use_ammocharge = other.ok_use_ammocharge;
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ok_StartItems)
-{
-       WepSet ok_start_items = (WEPSET(MACHINEGUN) | WEPSET(VORTEX) | WEPSET(SHOTGUN));
-
-       if(WEP_RPC.weaponstart > 0) { ok_start_items |= WEPSET(RPC); }
-       if(WEP_HMG.weaponstart > 0) { ok_start_items |= WEPSET(HMG); }
-
-       start_items |= IT_UNLIMITED_WEAPON_AMMO;
-       start_weapons = warmup_start_weapons = ok_start_items;
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ok_BuildMutatorsString)
-{
-       ret_string = strcat(ret_string, ":OK");
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ok_BuildMutatorsPrettyString)
-{
-       ret_string = strcat(ret_string, ", Overkill");
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(ok_SetModname)
-{
-       modname = "Overkill";
-       return true;
-}
-
-void ok_SetCvars()
-{
-       // hack to force overkill playermodels
-       cvar_settemp("sv_defaultcharacter", "1");
-       cvar_settemp("sv_defaultplayermodel", "models/ok_player/okrobot1.dpm models/ok_player/okrobot2.dpm models/ok_player/okrobot3.dpm models/ok_player/okrobot4.dpm models/ok_player/okmale1.dpm models/ok_player/okmale2.dpm models/ok_player/okmale3.dpm models/ok_player/okmale4.dpm");
-       cvar_settemp("sv_defaultplayermodel_red", "models/ok_player/okrobot1.dpm models/ok_player/okrobot2.dpm models/ok_player/okrobot3.dpm models/ok_player/okrobot4.dpm");
-       cvar_settemp("sv_defaultplayermodel_blue", "models/ok_player/okmale1.dpm models/ok_player/okmale2.dpm models/ok_player/okmale3.dpm models/ok_player/okmale4.dpm");
-}
-
-void ok_Initialize()
-{
-       ok_SetCvars();
-
-       precache_all_playermodels("models/ok_player/*.dpm");
-
-       addstat(STAT_OK_AMMO_CHARGE, AS_FLOAT, ok_use_ammocharge);
-       addstat(STAT_OK_AMMO_CHARGEPOOL, AS_FLOAT, ok_ammo_charge);
-
-       WEP_RPC.spawnflags &= ~WEP_FLAG_MUTATORBLOCKED;
-       WEP_HMG.spawnflags &= ~WEP_FLAG_MUTATORBLOCKED;
-
-       WEP_SHOTGUN.mdl = "ok_shotgun";
-       WEP_MACHINEGUN.mdl = "ok_mg";
-       WEP_VORTEX.mdl = "ok_sniper";
-}
-
-MUTATOR_DEFINITION(mutator_overkill)
-{
-       MUTATOR_HOOK(ForbidThrowCurrentWeapon, ok_ForbidThrowCurrentWeapon, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerPreThink, ok_PlayerPreThink, CBC_ORDER_LAST);
-       MUTATOR_HOOK(PlayerSpawn, ok_PlayerSpawn, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerDamage_Calculate, ok_PlayerDamage_Calculate, CBC_ORDER_LAST);
-       MUTATOR_HOOK(PlayerDamage_SplitHealthArmor, ok_PlayerDamage_SplitHealthArmor, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerDies, ok_PlayerDies, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerRegen, ok_PlayerRegen, CBC_ORDER_ANY);
-       MUTATOR_HOOK(OnEntityPreSpawn, ok_OnEntityPreSpawn, CBC_ORDER_ANY);
-       MUTATOR_HOOK(FilterItem, ok_ItemRemove, CBC_ORDER_ANY);
-       MUTATOR_HOOK(MonsterDropItem, ok_PlayerDies, CBC_ORDER_ANY);
-       MUTATOR_HOOK(SpectateCopy, ok_SpectateCopy, CBC_ORDER_ANY);
-       MUTATOR_HOOK(SetStartItems, ok_StartItems, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BuildMutatorsString, ok_BuildMutatorsString, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BuildMutatorsPrettyString, ok_BuildMutatorsPrettyString, CBC_ORDER_ANY);
-       MUTATOR_HOOK(SetModname, ok_SetModname, CBC_ORDER_ANY);
-
-       MUTATOR_ONADD
-       {
-               ok_Initialize();
-       }
-
-       MUTATOR_ONREMOVE
-       {
-               WEP_RPC.spawnflags |= WEP_FLAG_MUTATORBLOCKED;
-               WEP_HMG.spawnflags |= WEP_FLAG_MUTATORBLOCKED;
-       }
-
-       return false;
-}
diff --git a/qcsrc/server/mutators/mutator_overkill.qh b/qcsrc/server/mutators/mutator_overkill.qh
deleted file mode 100644 (file)
index 10f89c0..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef MUTATOR_OVERKILL_H
-#define MUTATOR_OVERKILL_H
-
-.vector ok_deathloc;
-.float ok_spawnsys_timer;
-.float ok_lastwep;
-.float ok_item;
-
-.float ok_notice_time;
-.float ammo_charge[Weapons_MAX];
-.float ok_use_ammocharge;
-.float ok_ammo_charge;
-
-.float ok_pauseregen_finished;
-
-void(entity ent, float wep) ok_DecreaseCharge;
-
-#endif
diff --git a/qcsrc/server/mutators/mutator_physical_items.qc b/qcsrc/server/mutators/mutator_physical_items.qc
deleted file mode 100644 (file)
index d127231..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-
-#include "mutator.qh"
-
-.vector spawn_origin, spawn_angles;
-
-void physical_item_think()
-{SELFPARAM();
-       self.nextthink = time;
-
-       self.alpha = self.owner.alpha; // apply fading and ghosting
-
-       if(!self.cnt) // map item, not dropped
-       {
-               // copy ghost item properties
-               self.colormap = self.owner.colormap;
-               self.colormod = self.owner.colormod;
-               self.glowmod = self.owner.glowmod;
-
-               // if the item is not spawned, make sure the invisible / ghost item returns to its origin and stays there
-               if(autocvar_g_physical_items_reset)
-               {
-                       if(self.owner.wait > time) // awaiting respawn
-                       {
-                               setorigin(self, self.spawn_origin);
-                               self.angles = self.spawn_angles;
-                               self.solid = SOLID_NOT;
-                               self.alpha = -1;
-                               self.movetype = MOVETYPE_NONE;
-                       }
-                       else
-                       {
-                               self.alpha = 1;
-                               self.solid = SOLID_CORPSE;
-                               self.movetype = MOVETYPE_PHYSICS;
-                       }
-               }
-       }
-
-       if(!self.owner.modelindex)
-               remove(self); // the real item is gone, remove this
-}
-
-void physical_item_touch()
-{SELFPARAM();
-       if(!self.cnt) // not for dropped items
-       if (ITEM_TOUCH_NEEDKILL())
-       {
-               setorigin(self, self.spawn_origin);
-               self.angles = self.spawn_angles;
-       }
-}
-
-void physical_item_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
-{SELFPARAM();
-       if(!self.cnt) // not for dropped items
-       if(ITEM_DAMAGE_NEEDKILL(deathtype))
-       {
-               setorigin(self, self.spawn_origin);
-               self.angles = self.spawn_angles;
-       }
-}
-
-MUTATOR_HOOKFUNCTION(item_spawning)
-{SELFPARAM();
-       if(self.owner == world && autocvar_g_physical_items <= 1)
-               return false;
-       if (self.spawnflags & 1) // floating item
-               return false;
-
-       // The actual item can't be physical and trigger at the same time, so make it invisible and use a second entity for physics.
-       // Ugly hack, but unless SOLID_TRIGGER is gotten to work with MOVETYPE_PHYSICS in the engine it can't be fixed.
-       entity wep;
-       wep = spawn();
-       _setmodel(wep, self.model);
-       setsize(wep, self.mins, self.maxs);
-       setorigin(wep, self.origin);
-       wep.angles = self.angles;
-       wep.velocity = self.velocity;
-
-       wep.owner = self;
-       wep.solid = SOLID_CORPSE;
-       wep.movetype = MOVETYPE_PHYSICS;
-       wep.takedamage = DAMAGE_AIM;
-       wep.effects |= EF_NOMODELFLAGS; // disable the spinning
-       wep.colormap = self.owner.colormap;
-       wep.glowmod = self.owner.glowmod;
-       wep.damageforcescale = autocvar_g_physical_items_damageforcescale;
-       wep.dphitcontentsmask = self.dphitcontentsmask;
-       wep.cnt = (self.owner != world);
-
-       wep.think = physical_item_think;
-       wep.nextthink = time;
-       wep.touch = physical_item_touch;
-       wep.event_damage = physical_item_damage;
-
-       if(!wep.cnt)
-       {
-               // fix the spawn origin
-               setorigin(wep, wep.origin + '0 0 1');
-               entity oldself;
-               oldself = self;
-               WITH(entity, self, wep, builtin_droptofloor());
-       }
-
-       wep.spawn_origin = wep.origin;
-       wep.spawn_angles = self.angles;
-
-       self.effects |= EF_NODRAW; // hide the original weapon
-       self.movetype = MOVETYPE_FOLLOW;
-       self.aiment = wep; // attach the original weapon
-       self.SendEntity = func_null;
-
-       return false;
-}
-
-MUTATOR_DEFINITION(mutator_physical_items)
-{
-       MUTATOR_HOOK(Item_Spawn, item_spawning, CBC_ORDER_ANY);
-
-       // check if we have a physics engine
-       MUTATOR_ONADD
-       {
-               if (!(autocvar_physics_ode && checkextension("DP_PHYSICS_ODE")))
-               {
-                       LOG_TRACE("Warning: Physical items are enabled but no physics engine can be used. Reverting to old items.\n");
-                       return -1;
-               }
-       }
-
-       MUTATOR_ONROLLBACK_OR_REMOVE
-       {
-               // nothing to roll back
-       }
-
-       MUTATOR_ONREMOVE
-       {
-               LOG_INFO("This cannot be removed at runtime\n");
-               return -1;
-       }
-
-       return 0;
-}
diff --git a/qcsrc/server/mutators/mutator_pinata.qc b/qcsrc/server/mutators/mutator_pinata.qc
deleted file mode 100644 (file)
index 4c450a8..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-
-#include "mutator.qh"
-
-MUTATOR_HOOKFUNCTION(pinata_PlayerDies)
-{SELFPARAM();
-       float j;
-       for(j = WEP_FIRST; j <= WEP_LAST; ++j)
-       if(self.weapons & WepSet_FromWeapon(j))
-       if(self.switchweapon != j)
-       if(W_IsWeaponThrowable(j))
-               W_ThrowNewWeapon(self, j, false, self.origin + (self.mins + self.maxs) * 0.5, randomvec() * 175 + '0 0 325');
-
-       return true;
-}
-
-MUTATOR_HOOKFUNCTION(pinata_BuildMutatorsString)
-{
-       ret_string = strcat(ret_string, ":Pinata");
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(pinata_BuildMutatorsPrettyString)
-{
-       ret_string = strcat(ret_string, ", Piñata");
-       return false;
-}
-
-MUTATOR_DEFINITION(mutator_pinata)
-{
-       MUTATOR_HOOK(PlayerDies, pinata_PlayerDies, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BuildMutatorsString, pinata_BuildMutatorsString, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BuildMutatorsPrettyString, pinata_BuildMutatorsPrettyString, CBC_ORDER_ANY);
-
-       return false;
-}
diff --git a/qcsrc/server/mutators/mutator_random_gravity.qc b/qcsrc/server/mutators/mutator_random_gravity.qc
deleted file mode 100644 (file)
index ff85f29..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-
-#include "mutator.qh"
-
-// Random Gravity
-//
-// Mutator by Mario
-// Inspired by Player 2
-
-float gravity_delay;
-
-MUTATOR_HOOKFUNCTION(gravity_StartFrame)
-{
-       if(gameover || !cvar("g_random_gravity")) return false;
-       if(time < gravity_delay) return false;
-       if(time < game_starttime) return false;
-       if(round_handler_IsActive() && !round_handler_IsRoundStarted()) return false;
-
-    if(random() >= autocvar_g_random_gravity_negative_chance)
-        cvar_set("sv_gravity", ftos(bound(autocvar_g_random_gravity_min, random() - random() * -autocvar_g_random_gravity_negative, autocvar_g_random_gravity_max)));
-    else
-        cvar_set("sv_gravity", ftos(bound(autocvar_g_random_gravity_min, random() * autocvar_g_random_gravity_positive, autocvar_g_random_gravity_max)));
-
-       gravity_delay = time + autocvar_g_random_gravity_delay;
-
-       LOG_TRACE("Gravity is now: ", ftos(autocvar_sv_gravity), "\n");
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(gravity_BuildMutatorsString)
-{
-       ret_string = strcat(ret_string, ":RandomGravity");
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(gravity_BuildMutatorsPrettyString)
-{
-       ret_string = strcat(ret_string, ", Random gravity");
-       return 0;
-}
-
-MUTATOR_DEFINITION(mutator_random_gravity)
-{
-       MUTATOR_HOOK(SV_StartFrame, gravity_StartFrame, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BuildMutatorsString, gravity_BuildMutatorsString, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BuildMutatorsPrettyString, gravity_BuildMutatorsPrettyString, CBC_ORDER_ANY);
-
-       MUTATOR_ONADD
-       {
-               cvar_settemp("sv_gravity", cvar_string("sv_gravity")); // settemp current gravity so it's restored on match end
-       }
-
-       return false;
-}
diff --git a/qcsrc/server/mutators/mutator_rocketflying.qc b/qcsrc/server/mutators/mutator_rocketflying.qc
deleted file mode 100644 (file)
index c403e9f..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-
-#include "mutator.qh"
-
-MUTATOR_HOOKFUNCTION(rocketflying_EditProjectile)
-{
-       if(other.classname == "rocket" || other.classname == "mine")
-       {
-               // kill detonate delay of rockets
-               other.spawnshieldtime = time;
-       }
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(rocketflying_BuildMutatorsString)
-{
-       ret_string = strcat(ret_string, ":RocketFlying");
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(rocketflying_BuildMutatorsPrettyString)
-{
-       ret_string = strcat(ret_string, ", Rocket Flying");
-       return 0;
-}
-
-MUTATOR_DEFINITION(mutator_rocketflying)
-{
-       MUTATOR_HOOK(EditProjectile, rocketflying_EditProjectile, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BuildMutatorsString, rocketflying_BuildMutatorsString, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BuildMutatorsPrettyString, rocketflying_BuildMutatorsPrettyString, CBC_ORDER_ANY);
-
-       return 0;
-}
diff --git a/qcsrc/server/mutators/mutator_rocketminsta.qc b/qcsrc/server/mutators/mutator_rocketminsta.qc
deleted file mode 100644 (file)
index b7319cf..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-#include "../../common/deathtypes/all.qh"
-#include "../round_handler.qh"
-
-REGISTER_MUTATOR(rm, cvar("g_instagib"));
-
-MUTATOR_HOOKFUNCTION(rm, PlayerDamage_Calculate)
-{
-       // we do it this way, so rm can be toggled during the match
-       if(!autocvar_g_rm) { return false; }
-
-       if(DEATH_ISWEAPON(frag_deathtype, WEP_DEVASTATOR))
-       if(frag_attacker == frag_target || frag_target.classname == "nade")
-               frag_damage = 0;
-
-       if(autocvar_g_rm_laser)
-       if(DEATH_ISWEAPON(frag_deathtype, WEP_ELECTRO))
-       if(frag_attacker == frag_target || (round_handler_IsActive() && !round_handler_IsRoundStarted()))
-               frag_damage = 0;
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(rm, PlayerDies)
-{
-       // we do it this way, so rm can be toggled during the match
-       if(!autocvar_g_rm) { return false; }
-
-       if(DEATH_ISWEAPON(frag_deathtype, WEP_DEVASTATOR) || DEATH_ISWEAPON(frag_deathtype, WEP_ELECTRO))
-               frag_damage = 1000; // always gib if it was a vaporizer death
-
-       return false;
-}
-
diff --git a/qcsrc/server/mutators/mutator_spawn_near_teammate.qc b/qcsrc/server/mutators/mutator_spawn_near_teammate.qc
deleted file mode 100644 (file)
index c996f1a..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-
-#include "mutator.qh"
-
-.entity msnt_lookat;
-
-.float msnt_timer;
-.vector msnt_deathloc;
-
-.float cvar_cl_spawn_near_teammate;
-
-MUTATOR_HOOKFUNCTION(msnt_Spawn_Score)
-{SELFPARAM();
-       if(autocvar_g_spawn_near_teammate_ignore_spawnpoint == 1 || (autocvar_g_spawn_near_teammate_ignore_spawnpoint == 2 && self.cvar_cl_spawn_near_teammate))
-               return 0;
-
-       entity p;
-
-       spawn_spot.msnt_lookat = world;
-
-       if(!teamplay)
-               return 0;
-
-       RandomSelection_Init();
-       FOR_EACH_PLAYER(p) if(p != self) if(p.team == self.team) if(!p.deadflag)
-       {
-               float l = vlen(spawn_spot.origin - p.origin);
-               if(l > autocvar_g_spawn_near_teammate_distance)
-                       continue;
-               if(l < 48)
-                       continue;
-               if(!checkpvs(spawn_spot.origin, p))
-                       continue;
-               RandomSelection_Add(p, 0, string_null, 1, 1);
-       }
-
-       if(RandomSelection_chosen_ent)
-       {
-               spawn_spot.msnt_lookat = RandomSelection_chosen_ent;
-               spawn_score.x += SPAWN_PRIO_NEAR_TEAMMATE_FOUND;
-       }
-       else if(self.team == spawn_spot.team)
-               spawn_score.x += SPAWN_PRIO_NEAR_TEAMMATE_SAMETEAM; // prefer same team, if we can't find a spawn near teammate
-
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(msnt_PlayerSpawn)
-{SELFPARAM();
-       // Note: when entering this, fixangle is already set.
-       if(autocvar_g_spawn_near_teammate_ignore_spawnpoint == 1 || (autocvar_g_spawn_near_teammate_ignore_spawnpoint == 2 && self.cvar_cl_spawn_near_teammate))
-       {
-               if(autocvar_g_spawn_near_teammate_ignore_spawnpoint_delay_death)
-                       self.msnt_timer = time + autocvar_g_spawn_near_teammate_ignore_spawnpoint_delay_death;
-
-               entity team_mate, best_mate = world;
-               vector best_spot = '0 0 0';
-               float pc = 0, best_dist = 0, dist = 0;
-               FOR_EACH_PLAYER(team_mate)
-               {
-                       if((autocvar_g_spawn_near_teammate_ignore_spawnpoint_check_health >= 0 && team_mate.health >= autocvar_g_balance_health_regenstable) || autocvar_g_spawn_near_teammate_ignore_spawnpoint_check_health == 0)
-                       if(team_mate.deadflag == DEAD_NO)
-                       if(team_mate.msnt_timer < time)
-                       if(SAME_TEAM(self, team_mate))
-                       if(time > team_mate.spawnshieldtime) // spawn shielding
-                       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);
-                               if(trace_fraction != 1.0)
-                               if(!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY))
-                               {
-                                       pc = pointcontents(trace_endpos + '0 0 1');
-                                       if(pc == CONTENT_EMPTY)
-                                       {
-                                               if(vlen(team_mate.velocity) > 5)
-                                                       fixedmakevectors(vectoangles(team_mate.velocity));
-                                               else
-                                                       fixedmakevectors(team_mate.angles);
-
-                                               for(pc = 0; pc != 5; ++pc) // test 5 diffrent spots close to mate
-                                               {
-                                                       switch(pc)
-                                                       {
-                                                               case 0:
-                                                                       tracebox(team_mate.origin , PL_MIN, PL_MAX, team_mate.origin + v_right * 128, MOVE_NORMAL, team_mate);
-                                                                       break;
-                                                               case 1:
-                                                                       tracebox(team_mate.origin , PL_MIN, PL_MAX, team_mate.origin - v_right * 128 , MOVE_NORMAL, team_mate);
-                                                                       break;
-                                                               case 2:
-                                                                       tracebox(team_mate.origin , PL_MIN, PL_MAX, team_mate.origin + v_right * 64 - v_forward * 64, MOVE_NORMAL, team_mate);
-                                                                       break;
-                                                               case 3:
-                                                                       tracebox(team_mate.origin , PL_MIN, PL_MAX, team_mate.origin - v_right * 64 - v_forward * 64, MOVE_NORMAL, team_mate);
-                                                                       break;
-                                                               case 4:
-                                                                       tracebox(team_mate.origin , PL_MIN, PL_MAX, team_mate.origin - v_forward * 128, MOVE_NORMAL, team_mate);
-                                                                       break;
-                                                       }
-
-                                                       if(trace_fraction == 1.0)
-                                                       {
-                                                               traceline(trace_endpos + '0 0 4', trace_endpos - '0 0 100', MOVE_NORMAL, team_mate);
-                                                               if(trace_fraction != 1.0)
-                                                               {
-                                                                       if(autocvar_g_spawn_near_teammate_ignore_spawnpoint_closetodeath)
-                                                                       {
-                                                                               dist = vlen(trace_endpos - self.msnt_deathloc);
-                                                                               if(dist < best_dist || best_dist == 0)
-                                                                               {
-                                                                                       best_dist = dist;
-                                                                                       best_spot = trace_endpos;
-                                                                                       best_mate = team_mate;
-                                                                               }
-                                                                       }
-                                                                       else
-                                                                       {
-                                                                               setorigin(self, trace_endpos);
-                                                                               self.angles = team_mate.angles;
-                                                                               self.angles_z = 0; // never spawn tilted even if the spot says to
-                                                                               team_mate.msnt_timer = time + autocvar_g_spawn_near_teammate_ignore_spawnpoint_delay;
-                                                                               return 0;
-                                                                       }
-                                                               }
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-               }
-
-               if(autocvar_g_spawn_near_teammate_ignore_spawnpoint_closetodeath)
-               if(best_dist)
-               {
-                       setorigin(self, best_spot);
-                       self.angles = best_mate.angles;
-                       self.angles_z = 0; // never spawn tilted even if the spot says to
-                       best_mate.msnt_timer = time + autocvar_g_spawn_near_teammate_ignore_spawnpoint_delay;
-               }
-       }
-       else if(spawn_spot.msnt_lookat)
-       {
-               self.angles = vectoangles(spawn_spot.msnt_lookat.origin - self.origin);
-               self.angles_x = -self.angles.x;
-               self.angles_z = 0; // never spawn tilted even if the spot says to
-               /*
-               sprint(self, "You should be looking at ", spawn_spot.msnt_lookat.netname, "^7.\n");
-               sprint(self, "distance: ", vtos(spawn_spot.msnt_lookat.origin - self.origin), "\n");
-               sprint(self, "angles: ", vtos(self.angles), "\n");
-               */
-       }
-
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(msnt_PlayerDies)
-{SELFPARAM();
-       self.msnt_deathloc = self.origin;
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(msnt_GetCvars)
-{
-       GetCvars_handleFloat(get_cvars_s, get_cvars_f, cvar_cl_spawn_near_teammate, "cl_spawn_near_teammate");
-       return false;
-}
-
-MUTATOR_DEFINITION(mutator_spawn_near_teammate)
-{
-       MUTATOR_HOOK(Spawn_Score, msnt_Spawn_Score, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerSpawn, msnt_PlayerSpawn, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerDies, msnt_PlayerDies, CBC_ORDER_ANY);
-       MUTATOR_HOOK(GetCvars, msnt_GetCvars, CBC_ORDER_ANY);
-
-       return 0;
-}
diff --git a/qcsrc/server/mutators/mutator_superspec.qc b/qcsrc/server/mutators/mutator_superspec.qc
deleted file mode 100644 (file)
index e0b5ad3..0000000
+++ /dev/null
@@ -1,529 +0,0 @@
-
-#include "mutator.qh"
-
-#define _SSMAGIX "SUPERSPEC_OPTIONSFILE_V1"
-#define _ISLOCAL ((edict_num(1) == self) ? true : false)
-
-const float ASF_STRENGTH               = 1;
-const float ASF_SHIELD                         = 2;
-const float ASF_MEGA_AR                = 4;
-const float ASF_MEGA_HP                = 8;
-const float ASF_FLAG_GRAB              = 16;
-const float ASF_OBSERVER_ONLY  = 32;
-const float ASF_SHOWWHAT               = 64;
-const float ASF_SSIM                   = 128;
-const float ASF_FOLLOWKILLER   = 256;
-const float ASF_ALL                    = 0xFFFFFF;
-.float autospec_flags;
-
-const float SSF_SILENT = 1;
-const float SSF_VERBOSE = 2;
-const float SSF_ITEMMSG = 4;
-.float superspec_flags;
-
-.string superspec_itemfilter; //"classname1 classname2 ..."
-
-float _spectate(entity _player)
-{SELFPARAM();
-       if(Spectate(_player) == 1)
-               self.classname = "spectator";
-
-       return true;
-}
-
-void superspec_save_client_conf()
-{SELFPARAM();
-       string fn = "superspec-local.options";
-       float fh;
-
-       if (!_ISLOCAL)
-       {
-               if(self.crypto_idfp == "")
-                       return;
-
-               fn = sprintf("superspec-%s.options", uri_escape(self.crypto_idfp));
-       }
-
-       fh = fopen(fn, FILE_WRITE);
-       if(fh < 0)
-       {
-               LOG_TRACE("^1ERROR: ^7 superspec can not open ", fn, " for writing.\n");
-       }
-       else
-       {
-               fputs(fh, _SSMAGIX);
-               fputs(fh, "\n");
-               fputs(fh, ftos(self.autospec_flags));
-               fputs(fh, "\n");
-               fputs(fh, ftos(self.superspec_flags));
-               fputs(fh, "\n");
-               fputs(fh, self.superspec_itemfilter);
-               fputs(fh, "\n");
-               fclose(fh);
-       }
-}
-
-void superspec_msg(string _center_title, string _con_title, entity _to, string _msg, float _spamlevel)
-{
-       sprint(_to, strcat(_con_title, _msg));
-
-       if(_to.superspec_flags & SSF_SILENT)
-               return;
-
-       if(_spamlevel > 1)
-               if (!(_to.superspec_flags & SSF_VERBOSE))
-                       return;
-
-       centerprint(_to, strcat(_center_title, _msg));
-}
-
-float superspec_filteritem(entity _for, entity _item)
-{
-       float i;
-
-       if(_for.superspec_itemfilter == "")
-               return true;
-
-       if(_for.superspec_itemfilter == "")
-               return true;
-
-       float l = tokenize_console(_for.superspec_itemfilter);
-       for(i = 0; i < l; ++i)
-       {
-               if(argv(i) == _item.classname)
-                       return true;
-       }
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(superspec_ItemTouch)
-{SELFPARAM();
-       entity _item = self;
-
-       entity e;
-       FOR_EACH_SPEC(e)
-       {
-               setself(e);
-               if(self.superspec_flags & SSF_ITEMMSG)
-                       if(superspec_filteritem(self, _item))
-                       {
-                               if(self.superspec_flags & SSF_VERBOSE)
-                                       superspec_msg("", "", self, sprintf("Player %s^7 just picked up ^3%s\n", other.netname, _item.netname), 1);
-                               else
-                                       superspec_msg("", "", self, sprintf("Player %s^7 just picked up ^3%s\n^8(%s^8)\n", other.netname, _item.netname, _item.classname), 1);
-                               if((self.autospec_flags & ASF_SSIM) && self.enemy != other)
-                               {
-                                       _spectate(other);
-
-                                       setself(this);
-                                       return MUT_ITEMTOUCH_CONTINUE;
-                               }
-                       }
-
-               if((self.autospec_flags & ASF_SHIELD && _item.invincible_finished) ||
-                       (self.autospec_flags & ASF_STRENGTH && _item.strength_finished) ||
-                       (self.autospec_flags & ASF_MEGA_AR && _item.itemdef == ITEM_ArmorMega) ||
-                       (self.autospec_flags & ASF_MEGA_HP && _item.itemdef == ITEM_HealthMega) ||
-                       (self.autospec_flags & ASF_FLAG_GRAB && _item.classname == "item_flag_team"))
-               {
-
-                       if((self.enemy != other) || IS_OBSERVER(self))
-                       {
-                               if(self.autospec_flags & ASF_OBSERVER_ONLY && !IS_OBSERVER(self))
-                               {
-                                       if(self.superspec_flags & SSF_VERBOSE)
-                                               superspec_msg("", "", self, sprintf("^8Ignored that ^7%s^8 grabbed %s^8 since the observer_only option is ON\n", other.netname, _item.netname), 2);
-                               }
-                               else
-                               {
-                                       if(self.autospec_flags & ASF_SHOWWHAT)
-                                               superspec_msg("", "", self, sprintf("^7Following %s^7 due to picking up %s\n", other.netname, _item.netname), 2);
-
-                                       _spectate(other);
-                               }
-                       }
-               }
-       }
-
-       setself(this);
-
-       return MUT_ITEMTOUCH_CONTINUE;
-}
-
-MUTATOR_HOOKFUNCTION(superspec_SV_ParseClientCommand)
-{SELFPARAM();
-#define OPTIONINFO(flag,var,test,text,long,short) \
-    var = strcat(var, ((flag & test) ? "^2[ON]  ^7" : "^1[OFF] ^7")); \
-    var = strcat(var, text," ^7(^3 ", long, "^7 | ^3", short, " ^7)\n")
-
-       if(MUTATOR_RETURNVALUE) // command was already handled?
-               return false;
-
-       if(IS_PLAYER(self))
-               return false;
-
-       if(cmd_name == "superspec_itemfilter")
-       {
-               if(argv(1) == "help")
-               {
-                       string _aspeco;
-                       _aspeco = "^7 superspec_itemfilter ^3\"item_classname1 item_classname2\"^7 only show thise items when ^2superspec ^3item_message^7 is on\n";
-                       _aspeco = strcat(_aspeco, "^3 clear^7 Remove the filter (show all pickups)\n");
-                       _aspeco = strcat(_aspeco, "^3 show ^7 Display current filter\n");
-                       superspec_msg("^3superspec_itemfilter help:\n\n\n", "\n^3superspec_itemfilter help:\n", self, _aspeco, 1);
-               }
-               else if(argv(1) == "clear")
-               {
-                       if(self.superspec_itemfilter != "")
-                               strunzone(self.superspec_itemfilter);
-
-                       self.superspec_itemfilter = "";
-               }
-               else if(argv(1) == "show" || argv(1) == "")
-               {
-                       if(self.superspec_itemfilter == "")
-                       {
-                               superspec_msg("^3superspec_itemfilter^7 is ^1not^7 set", "\n^3superspec_itemfilter^7 is ^1not^7 set\n", self, "", 1);
-                               return true;
-                       }
-                       float i;
-                       float l = tokenize_console(self.superspec_itemfilter);
-                       string _msg = "";
-                       for(i = 0; i < l; ++i)
-                               _msg = strcat(_msg, "^3#", ftos(i), " ^7", argv(i), "\n");
-                               //_msg = sprintf("^3#%d^7 %s\n%s", i, _msg, argv(i));
-
-                       _msg = strcat(_msg,"\n");
-
-                       superspec_msg("^3superspec_itemfilter is:\n\n\n", "\n^3superspec_itemfilter is:\n", self, _msg, 1);
-               }
-               else
-               {
-                       if(self.superspec_itemfilter != "")
-                               strunzone(self.superspec_itemfilter);
-
-                       self.superspec_itemfilter = strzone(argv(1));
-               }
-
-               return true;
-       }
-
-       if(cmd_name == "superspec")
-       {
-               string _aspeco;
-
-               if(cmd_argc > 1)
-               {
-                       float i, _bits = 0, _start = 1;
-                       if(argv(1) == "help")
-                       {
-                               _aspeco = "use cmd superspec [option] [on|off] to set options\n\n";
-                               _aspeco = strcat(_aspeco, "^3 silent ^7(short^5 si^7) supresses ALL messages from superspectate.\n");
-                               _aspeco = strcat(_aspeco, "^3 verbose ^7(short^5 ve^7) makes superspectate print some additional information.\n");
-                               _aspeco = strcat(_aspeco, "^3 item_message ^7(short^5 im^7) makes superspectate print items that were picked up.\n");
-                               _aspeco = strcat(_aspeco, "^7    Use cmd superspec_itemfilter \"item_class1 item_class2\" to set up a filter of what to show with ^3item_message.\n");
-                               superspec_msg("^2Available Super Spectate ^3options:\n\n\n", "\n^2Available Super Spectate ^3options:\n", self, _aspeco, 1);
-                               return true;
-                       }
-
-                       if(argv(1) == "clear")
-                       {
-                               self.superspec_flags = 0;
-                               _start = 2;
-                       }
-
-                       for(i = _start; i < cmd_argc; ++i)
-                       {
-                               if(argv(i) == "on" || argv(i) == "1")
-                               {
-                                       self.superspec_flags |= _bits;
-                                       _bits = 0;
-                               }
-                               else if(argv(i) == "off" || argv(i) == "0")
-                               {
-                                       if(_start == 1)
-                                               self.superspec_flags &= ~_bits;
-
-                                       _bits = 0;
-                               }
-                               else
-                               {
-                                       if((argv(i) == "silent") || (argv(i) == "si")) _bits |= SSF_SILENT ;
-                                       if((argv(i) == "verbose") || (argv(i) == "ve")) _bits |= SSF_VERBOSE;
-                                       if((argv(i) == "item_message") || (argv(i) == "im")) _bits |= SSF_ITEMMSG;
-                               }
-                       }
-               }
-
-               _aspeco = "";
-               OPTIONINFO(self.superspec_flags, _aspeco, SSF_SILENT, "Silent", "silent", "si");
-               OPTIONINFO(self.superspec_flags, _aspeco, SSF_VERBOSE, "Verbose", "verbose", "ve");
-               OPTIONINFO(self.superspec_flags, _aspeco, SSF_ITEMMSG, "Item pickup messages", "item_message", "im");
-
-               superspec_msg("^3Current Super Spectate options are:\n\n\n\n\n", "\n^3Current Super Spectate options are:\n", self, _aspeco, 1);
-
-               return true;
-       }
-
-/////////////////////
-
-       if(cmd_name == "autospec")
-       {
-               string _aspeco;
-               if(cmd_argc > 1)
-               {
-                       if(argv(1) == "help")
-                       {
-                               _aspeco = "use cmd autospec [option] [on|off] to set options\n\n";
-                               _aspeco = strcat(_aspeco, "^3 strength ^7(short^5 st^7) for automatic spectate on strength powerup\n");
-                               _aspeco = strcat(_aspeco, "^3 shield ^7(short^5 sh^7) for automatic spectate on shield powerup\n");
-                               _aspeco = strcat(_aspeco, "^3 mega_health ^7(short^5 mh^7) for automatic spectate on mega health\n");
-                               _aspeco = strcat(_aspeco, "^3 mega_armor ^7(short^5 ma^7) for automatic spectate on mega armor\n");
-                               _aspeco = strcat(_aspeco, "^3 flag_grab ^7(short^5 fg^7) for automatic spectate on CTF flag grab\n");
-                               _aspeco = strcat(_aspeco, "^3 observer_only ^7(short^5 oo^7) for automatic spectate only if in observer mode\n");
-                               _aspeco = strcat(_aspeco, "^3 show_what ^7(short^5 sw^7) to display what event triggered autospectate\n");
-                               _aspeco = strcat(_aspeco, "^3 item_msg ^7(short^5 im^7) to autospec when item_message in superspectate is triggered\n");
-                               _aspeco = strcat(_aspeco, "^3 followkiller ^7(short ^5fk^7) to autospec the killer/off\n");
-                               _aspeco = strcat(_aspeco, "^3 all ^7(short ^5aa^7) to turn everything on/off\n");
-                               superspec_msg("^2Available Auto Spectate ^3options:\n\n\n", "\n^2Available Auto Spectate ^3options:\n", self, _aspeco, 1);
-                               return true;
-                       }
-
-                       float i, _bits = 0, _start = 1;
-                       if(argv(1) == "clear")
-                       {
-                               self.autospec_flags = 0;
-                               _start = 2;
-                       }
-
-                       for(i = _start; i < cmd_argc; ++i)
-                       {
-                               if(argv(i) == "on" || argv(i) == "1")
-                               {
-                                       self.autospec_flags |= _bits;
-                                       _bits = 0;
-                               }
-                               else if(argv(i) == "off" || argv(i) == "0")
-                               {
-                                       if(_start == 1)
-                                               self.autospec_flags &= ~_bits;
-
-                                       _bits = 0;
-                               }
-                               else
-                               {
-                                       if((argv(i) == "strength") || (argv(i) == "st")) _bits |= ASF_STRENGTH;
-                                       if((argv(i) == "shield") || (argv(i) == "sh")) _bits |= ASF_SHIELD;
-                                       if((argv(i) == "mega_health") || (argv(i) == "mh")) _bits |= ASF_MEGA_HP;
-                                       if((argv(i) == "mega_armor") || (argv(i) == "ma")) _bits |= ASF_MEGA_AR;
-                                       if((argv(i) == "flag_grab") || (argv(i) == "fg")) _bits |= ASF_FLAG_GRAB;
-                                       if((argv(i) == "observer_only") || (argv(i) == "oo")) _bits |= ASF_OBSERVER_ONLY;
-                                       if((argv(i) == "show_what") || (argv(i) == "sw")) _bits |= ASF_SHOWWHAT;
-                                       if((argv(i) == "item_msg") || (argv(i) == "im")) _bits |= ASF_SSIM;
-                                       if((argv(i) == "followkiller") || (argv(i) == "fk")) _bits |= ASF_FOLLOWKILLER;
-                                       if((argv(i) == "all") || (argv(i) == "aa")) _bits |= ASF_ALL;
-                               }
-                       }
-               }
-
-               _aspeco = "";
-               OPTIONINFO(self.autospec_flags, _aspeco, ASF_STRENGTH, "Strength", "strength", "st");
-               OPTIONINFO(self.autospec_flags, _aspeco, ASF_SHIELD, "Shield", "shield", "sh");
-               OPTIONINFO(self.autospec_flags, _aspeco, ASF_MEGA_HP, "Mega Health", "mega_health", "mh");
-               OPTIONINFO(self.autospec_flags, _aspeco, ASF_MEGA_AR, "Mega Armor", "mega_armor", "ma");
-               OPTIONINFO(self.autospec_flags, _aspeco, ASF_FLAG_GRAB, "Flag grab", "flag_grab","fg");
-               OPTIONINFO(self.autospec_flags, _aspeco, ASF_OBSERVER_ONLY, "Only switch if observer", "observer_only", "oo");
-               OPTIONINFO(self.autospec_flags, _aspeco, ASF_SHOWWHAT, "Show what item triggered spectate", "show_what", "sw");
-               OPTIONINFO(self.autospec_flags, _aspeco, ASF_SSIM, "Switch on superspec item message", "item_msg", "im");
-               OPTIONINFO(self.autospec_flags, _aspeco, ASF_FOLLOWKILLER, "Followkiller", "followkiller", "fk");
-
-               superspec_msg("^3Current auto spectate options are:\n\n\n\n\n", "\n^3Current auto spectate options are:\n", self, _aspeco, 1);
-               return true;
-       }
-
-       if(cmd_name == "followpowerup")
-       {
-               entity _player;
-               FOR_EACH_PLAYER(_player)
-               {
-                       if(_player.strength_finished > time || _player.invincible_finished > time)
-                               return _spectate(_player);
-               }
-
-               superspec_msg("", "", self, "No active powerup\n", 1);
-               return true;
-       }
-
-       if(cmd_name == "followstrength")
-       {
-               entity _player;
-               FOR_EACH_PLAYER(_player)
-               {
-                       if(_player.strength_finished > time)
-                               return _spectate(_player);
-               }
-
-               superspec_msg("", "", self, "No active Strength\n", 1);
-               return true;
-       }
-
-       if(cmd_name == "followshield")
-       {
-               entity _player;
-               FOR_EACH_PLAYER(_player)
-               {
-                       if(_player.invincible_finished > time)
-                               return _spectate(_player);
-               }
-
-               superspec_msg("", "", self, "No active Shield\n", 1);
-               return true;
-       }
-
-       if(cmd_name == "followfc")
-       {
-               if(!g_ctf)
-                       return true;
-
-               entity _player;
-               int _team = 0;
-               bool found = false;
-
-               if(cmd_argc == 2)
-               {
-                       switch(argv(1))
-                       {
-                               case "red": _team = NUM_TEAM_1; break;
-                               case "blue": _team = NUM_TEAM_2; break;
-                               case "yellow": if(ctf_teams >= 3) _team = NUM_TEAM_3; break;
-                               case "pink": if(ctf_teams >= 4) _team = NUM_TEAM_4; break;
-                       }
-               }
-
-               FOR_EACH_PLAYER(_player)
-               {
-                       if(_player.flagcarried && (_player.team == _team || _team == 0))
-                       {
-                               found = true;
-                               if(_team == 0 && IS_SPEC(self) && self.enemy == _player)
-                                       continue; // already spectating a fc, try to find the other fc
-                               return _spectate(_player);
-                       }
-               }
-
-               if(!found)
-                       superspec_msg("", "", self, "No active flag carrier\n", 1);
-               return true;
-       }
-
-       return false;
-#undef OPTIONINFO
-}
-
-MUTATOR_HOOKFUNCTION(superspec_BuildMutatorsString)
-{
-       ret_string = strcat(ret_string, ":SS");
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(superspec_BuildMutatorsPrettyString)
-{
-       ret_string = strcat(ret_string, ", Super Spectators");
-       return 0;
-}
-
-void superspec_hello()
-{SELFPARAM();
-       if(self.enemy.crypto_idfp == "")
-               Send_Notification(NOTIF_ONE_ONLY, self.enemy, MSG_INFO, INFO_SUPERSPEC_MISSING_UID);
-
-       remove(self);
-}
-
-MUTATOR_HOOKFUNCTION(superspec_ClientConnect)
-{SELFPARAM();
-       if(!IS_REAL_CLIENT(self))
-               return false;
-
-       string fn = "superspec-local.options";
-       float fh;
-
-       self.superspec_flags = SSF_VERBOSE;
-       self.superspec_itemfilter = "";
-
-       entity _hello = spawn();
-       _hello.enemy = self;
-       _hello.think = superspec_hello;
-       _hello.nextthink = time + 5;
-
-       if (!_ISLOCAL)
-       {
-               if(self.crypto_idfp == "")
-                       return false;
-
-               fn = sprintf("superspec-%s.options", uri_escape(self.crypto_idfp));
-       }
-
-       fh = fopen(fn, FILE_READ);
-       if(fh < 0)
-       {
-               LOG_TRACE("^1ERROR: ^7 superspec can not open ", fn, " for reading.\n");
-       }
-       else
-       {
-               string _magic = fgets(fh);
-               if(_magic != _SSMAGIX)
-               {
-                       LOG_TRACE("^1ERROR^7 While reading superspec options file: unknown magic\n");
-               }
-               else
-               {
-                       self.autospec_flags = stof(fgets(fh));
-                       self.superspec_flags = stof(fgets(fh));
-                       self.superspec_itemfilter = strzone(fgets(fh));
-               }
-               fclose(fh);
-       }
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(superspec_PlayerDies)
-{SELFPARAM();
-       entity e;
-       FOR_EACH_SPEC(e)
-       {
-               setself(e);
-               if(self.autospec_flags & ASF_FOLLOWKILLER && IS_PLAYER(frag_attacker) && self.enemy == this)
-               {
-                       if(self.autospec_flags & ASF_SHOWWHAT)
-                               superspec_msg("", "", self, sprintf("^7Following %s^7 due to followkiller\n", frag_attacker.netname), 2);
-
-                       _spectate(frag_attacker);
-               }
-       }
-
-       setself(this);
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(superspec_ClientDisconnect)
-{
-       superspec_save_client_conf();
-       return false;
-}
-
-MUTATOR_DEFINITION(mutator_superspec)
-{
-
-       MUTATOR_HOOK(BuildMutatorsString, superspec_BuildMutatorsString, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BuildMutatorsPrettyString, superspec_BuildMutatorsPrettyString, CBC_ORDER_ANY);
-       MUTATOR_HOOK(SV_ParseClientCommand, superspec_SV_ParseClientCommand, CBC_ORDER_ANY);
-       MUTATOR_HOOK(ItemTouch, superspec_ItemTouch, CBC_ORDER_ANY);
-       MUTATOR_HOOK(ClientConnect, superspec_ClientConnect, CBC_ORDER_ANY);
-       MUTATOR_HOOK(ClientDisconnect, superspec_ClientDisconnect, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerDies, superspec_PlayerDies, CBC_ORDER_ANY);
-
-       return 0;
-}
diff --git a/qcsrc/server/mutators/mutator_touchexplode.qc b/qcsrc/server/mutators/mutator_touchexplode.qc
deleted file mode 100644 (file)
index e0dd4cd..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-
-#include "mutator.qh"
-
-.float touchexplode_time;
-
-void PlayerTouchExplode(entity p1, entity p2)
-{SELFPARAM();
-       vector org;
-       org = (p1.origin + p2.origin) * 0.5;
-       org.z += (p1.mins.z + p2.mins.z) * 0.5;
-
-       sound(self, CH_TRIGGER, SND_GRENADE_IMPACT, VOL_BASE, ATTEN_NORM);
-       Send_Effect(EFFECT_EXPLOSION_SMALL, org, '0 0 0', 1);
-
-       entity e;
-       e = spawn();
-       setorigin(e, org);
-       RadiusDamage(e, world, autocvar_g_touchexplode_damage, autocvar_g_touchexplode_edgedamage, autocvar_g_touchexplode_radius, world, world, autocvar_g_touchexplode_force, DEATH_TOUCHEXPLODE.m_id, world);
-       remove(e);
-}
-
-MUTATOR_HOOKFUNCTION(touchexplode_PlayerThink)
-{SELFPARAM();
-       if(time > self.touchexplode_time)
-       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))
-               {
-                       PlayerTouchExplode(self, other);
-                       self.touchexplode_time = other.touchexplode_time = time + 0.2;
-               }
-       }
-
-       return false;
-}
-
-MUTATOR_DEFINITION(mutator_touchexplode)
-{
-       MUTATOR_HOOK(PlayerPreThink, touchexplode_PlayerThink, CBC_ORDER_ANY);
-
-       return false;
-}
diff --git a/qcsrc/server/mutators/mutator_vampire.qc b/qcsrc/server/mutators/mutator_vampire.qc
deleted file mode 100644 (file)
index b5cad57..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-
-#include "mutator.qh"
-
-MUTATOR_HOOKFUNCTION(vampire_PlayerDamage)
-{
-       if(time >= frag_target.spawnshieldtime)
-       if(frag_target != frag_attacker)
-       if(frag_target.deadflag == DEAD_NO)
-       {
-               frag_attacker.health += bound(0, damage_take, frag_target.health);
-               frag_attacker.health = bound(0, frag_attacker.health, autocvar_g_balance_health_limit);
-       }
-
-       return false;
-}
-
-MUTATOR_HOOKFUNCTION(vampire_BuildMutatorsString)
-{
-       ret_string = strcat(ret_string, ":Vampire");
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(vampire_BuildMutatorsPrettyString)
-{
-       ret_string = strcat(ret_string, ", Vampire");
-       return 0;
-}
-
-MUTATOR_DEFINITION(mutator_vampire)
-{
-       MUTATOR_HOOK(PlayerDamage_SplitHealthArmor, vampire_PlayerDamage, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BuildMutatorsString, vampire_BuildMutatorsString, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BuildMutatorsPrettyString, vampire_BuildMutatorsPrettyString, CBC_ORDER_ANY);
-
-       return 0;
-}
diff --git a/qcsrc/server/mutators/mutator_vampirehook.qc b/qcsrc/server/mutators/mutator_vampirehook.qc
deleted file mode 100644 (file)
index 3d88a90..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-REGISTER_MUTATOR(vh, cvar("g_vampirehook"));
-
-bool autocvar_g_vampirehook_teamheal;
-float autocvar_g_vampirehook_damage;
-float autocvar_g_vampirehook_damagerate;
-float autocvar_g_vampirehook_health_steal;
-
-.float last_dmg;
-
-MUTATOR_HOOKFUNCTION(vh, GrappleHookThink)
-{SELFPARAM();
-       entity dmgent = ((SAME_TEAM(self.owner, self.aiment) && autocvar_g_vampirehook_teamheal) ? self.owner : self.aiment);
-
-       if(IS_PLAYER(self.aiment))
-       if(self.last_dmg < time)
-       if(!self.aiment.frozen)
-       if(time >= game_starttime)
-       if(DIFF_TEAM(self.owner, self.aiment) || autocvar_g_vampirehook_teamheal)
-       if(self.aiment.health > 0)
-       if(autocvar_g_vampirehook_damage)
-       {
-               self.last_dmg = time + autocvar_g_vampirehook_damagerate;
-               self.owner.damage_dealt += autocvar_g_vampirehook_damage;
-               Damage(dmgent, self, self.owner, autocvar_g_vampirehook_damage, WEP_HOOK.m_id, self.origin, '0 0 0');
-               if(SAME_TEAM(self.owner, self.aiment))
-                       self.aiment.health = min(self.aiment.health + autocvar_g_vampirehook_health_steal, g_pickup_healthsmall_max);
-               else
-                       self.owner.health = min(self.owner.health + autocvar_g_vampirehook_health_steal, g_pickup_healthsmall_max);
-
-               if(dmgent == self.owner)
-                       dmgent.health -= autocvar_g_vampirehook_damage; // FIXME: friendly fire?!
-       }
-
-       return false;
-}
-
diff --git a/qcsrc/server/mutators/mutators.qc b/qcsrc/server/mutators/mutators.qc
deleted file mode 100644 (file)
index 93fc4cf..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-#if defined(CSQC)
-#elif defined(MENUQC)
-#elif defined(SVQC)
-    #include "mutators_include.qh"
-    #include "../../common/mapinfo.qh"
-#endif
-
-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_invincible_projectiles", mutator_invincibleprojectiles, 1);
-       CHECK_MUTATOR_ADD("g_new_toys", mutator_new_toys, !cvar("g_instagib") && !cvar("g_overkill"));
-       CHECK_MUTATOR_ADD("g_nix", mutator_nix, !cvar("g_instagib") && !cvar("g_overkill"));
-       CHECK_MUTATOR_ADD("g_rocket_flying", mutator_rocketflying, 1);
-       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") && !cvar("g_overkill"));
-       CHECK_MUTATOR_ADD("g_midair", mutator_midair, 1);
-       CHECK_MUTATOR_ADD("g_bloodloss", mutator_bloodloss, 1);
-       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_overkill", mutator_overkill, !cvar("g_instagib") && !g_nexball && cvar_string("g_mod_balance") == "Overkill");
-       CHECK_MUTATOR_ADD("g_buffs", mutator_buffs, 1);
-
-       #undef CHECK_MUTATOR_ADD
-}
diff --git a/qcsrc/server/mutators/mutators.qh b/qcsrc/server/mutators/mutators.qh
deleted file mode 100644 (file)
index b65cbd2..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef MUTATORS_H
-#define MUTATORS_H
-
-MUTATOR_DECLARATION(gamemode_assault);
-MUTATOR_DECLARATION(gamemode_ca);
-MUTATOR_DECLARATION(gamemode_keyhunt);
-MUTATOR_DECLARATION(gamemode_freezetag);
-MUTATOR_DECLARATION(gamemode_keepaway);
-MUTATOR_DECLARATION(gamemode_ctf);
-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(gamemode_deathmatch);
-
-MUTATOR_DECLARATION(mutator_dodging);
-MUTATOR_DECLARATION(mutator_invincibleprojectiles);
-MUTATOR_DECLARATION(mutator_new_toys);
-MUTATOR_DECLARATION(mutator_nix);
-MUTATOR_DECLARATION(mutator_rocketflying);
-MUTATOR_DECLARATION(mutator_spawn_near_teammate);
-MUTATOR_DECLARATION(mutator_physical_items);
-MUTATOR_DECLARATION(mutator_vampire);
-MUTATOR_DECLARATION(mutator_superspec);
-MUTATOR_DECLARATION(mutator_touchexplode);
-MUTATOR_DECLARATION(mutator_pinata);
-MUTATOR_DECLARATION(mutator_midair);
-MUTATOR_DECLARATION(mutator_bloodloss);
-MUTATOR_DECLARATION(mutator_random_gravity);
-MUTATOR_DECLARATION(mutator_multijump);
-MUTATOR_DECLARATION(mutator_melee_only);
-MUTATOR_DECLARATION(mutator_nades);
-MUTATOR_DECLARATION(mutator_campcheck);
-MUTATOR_DECLARATION(mutator_buffs);
-
-MUTATOR_DECLARATION(sandbox);
-MUTATOR_DECLARATION(mutator_overkill);
-
-#endif
diff --git a/qcsrc/server/mutators/mutators_include.qc b/qcsrc/server/mutators/mutators_include.qc
deleted file mode 100644 (file)
index d2ea468..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-#if defined(CSQC)
-#elif defined(MENUQC)
-#elif defined(SVQC)
-    #include "../../lib/warpzone/anglestransform.qh"
-    #include "../../lib/warpzone/common.qh"
-    #include "../../lib/warpzone/util_server.qh"
-    #include "../../lib/warpzone/server.qh"
-    #include "../../common/constants.qh"
-    #include "../../common/stats.qh"
-    #include "../../common/teams.qh"
-    #include "../../common/util.qh"
-    #include "../../common/nades/all.qh"
-    #include "../../common/buffs/all.qh"
-    #include "../../common/command/markup.qh"
-    #include "../../common/command/rpn.qh"
-    #include "../../common/command/generic.qh"
-    #include "../../common/command/command.qh"
-    #include "../../common/net_notice.qh"
-    #include "../../common/animdecide.qh"
-    #include "../../common/monsters/all.qh"
-    #include "../../common/monsters/sv_monsters.qh"
-    #include "../../common/monsters/spawn.qh"
-    #include "../../common/weapons/config.qh"
-    #include "../../common/weapons/all.qh"
-    #include "../weapons/accuracy.qh"
-    #include "../weapons/common.qh"
-    #include "../weapons/csqcprojectile.qh"
-    #include "../weapons/hitplot.qh"
-    #include "../weapons/selection.qh"
-    #include "../weapons/spawning.qh"
-    #include "../weapons/throwing.qh"
-    #include "../weapons/tracing.qh"
-    #include "../weapons/weaponstats.qh"
-    #include "../weapons/weaponsystem.qh"
-    #include "../t_items.qh"
-    #include "../autocvars.qh"
-    #include "../constants.qh"
-    #include "../defs.qh"
-    #include "../../common/notifications.qh"
-    #include "../../common/deathtypes/all.qh"
-    #include "mutators_include.qh"
-    #include "../../common/turrets/sv_turrets.qh"
-    #include "../../common/vehicles/all.qh"
-    #include "../campaign.qh"
-    #include "../../common/campaign_common.qh"
-    #include "../../common/mapinfo.qh"
-    #include "../command/common.qh"
-    #include "../command/banning.qh"
-    #include "../command/radarmap.qh"
-    #include "../command/vote.qh"
-    #include "../command/getreplies.qh"
-    #include "../command/cmd.qh"
-    #include "../command/sv_cmd.qh"
-    #include "../../common/csqcmodel_settings.qh"
-    #include "../../lib/csqcmodel/common.qh"
-    #include "../../lib/csqcmodel/sv_model.qh"
-    #include "../anticheat.qh"
-    #include "../cheats.qh"
-    #include "../../common/playerstats.qh"
-    #include "../portals.qh"
-    #include "../g_hook.qh"
-    #include "../scores.qh"
-    #include "../spawnpoints.qh"
-    #include "../mapvoting.qh"
-    #include "../ipban.qh"
-    #include "../race.qh"
-    #include "../antilag.qh"
-    #include "../playerdemo.qh"
-    #include "../round_handler.qh"
-    #include "../item_key.qh"
-    #include "../pathlib/pathlib.qh"
-    #include "../../common/vehicles/all.qh"
-#endif
-
-#include "../../common/mutators/base.qh"
-
-#include "gamemode_assault.qc"
-#include "gamemode_ca.qc"
-#include "gamemode_ctf.qc"
-#include "gamemode_cts.qc"
-#include "gamemode_deathmatch.qc"
-#include "gamemode_domination.qc"
-#include "gamemode_freezetag.qc"
-#include "gamemode_invasion.qc"
-#include "gamemode_keepaway.qc"
-#include "gamemode_keyhunt.qc"
-#include "gamemode_lms.qc"
-#include "gamemode_onslaught.qc"
-#include "gamemode_race.qc"
-#include "gamemode_tdm.qc"
-
-#include "mutator_bloodloss.qc"
-#include "mutator_breakablehook.qc"
-#include "mutator_buffs.qc"
-#include "mutator_campcheck.qc"
-#include "mutator_dodging.qc"
-#include "mutator_hook.qc"
-#include "mutator_invincibleproj.qc"
-#include "mutator_melee_only.qc"
-#include "mutator_midair.qc"
-#include "mutator_multijump.qc"
-#include "mutator_nades.qc"
-#include "mutator_new_toys.qc"
-#include "mutator_nix.qc"
-#include "mutator_overkill.qc"
-#include "mutator_physical_items.qc"
-#include "mutator_pinata.qc"
-#include "mutator_random_gravity.qc"
-#include "mutator_rocketflying.qc"
-#include "mutator_rocketminsta.qc"
-#include "mutator_spawn_near_teammate.qc"
-#include "mutator_superspec.qc"
-#include "mutator_touchexplode.qc"
-#include "mutator_vampirehook.qc"
-#include "mutator_vampire.qc"
-
-#include "sandbox.qc"
diff --git a/qcsrc/server/mutators/mutators_include.qh b/qcsrc/server/mutators/mutators_include.qh
deleted file mode 100644 (file)
index e7144bc..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef MUTATORS_INCLUDE_H
-#define MUTATORS_INCLUDE_H
-
-#include "../../common/mutators/base.qh"
-#include "mutators.qh"
-
-#include "gamemode_assault.qh"
-#include "gamemode_ca.qh"
-#include "gamemode_ctf.qh"
-#include "gamemode_cts.qh"
-#include "gamemode_domination.qh"
-#include "gamemode_invasion.qh"
-#include "gamemode_keepaway.qh"
-#include "gamemode_keyhunt.qh"
-#include "gamemode_lms.qh"
-#include "gamemode_onslaught.qh"
-#include "gamemode_race.qh"
-
-#include "mutator_buffs.qh"
-#include "mutator_dodging.qh"
-#include "mutator_nades.qh"
-#include "mutator_overkill.qh"
-#endif
diff --git a/qcsrc/server/mutators/sandbox.qc b/qcsrc/server/mutators/sandbox.qc
deleted file mode 100644 (file)
index 7a52f0c..0000000
+++ /dev/null
@@ -1,838 +0,0 @@
-
-#include "mutator.qh"
-
-const float MAX_STORAGE_ATTACHMENTS = 16;
-float object_count;
-.float object_flood;
-.entity object_attach;
-.string material;
-
-.float touch_timer;
-void sandbox_ObjectFunction_Touch()
-{SELFPARAM();
-       // apply material impact effects
-
-       if(!self.material)
-               return;
-       if(self.touch_timer > time)
-               return; // don't execute each frame
-       self.touch_timer = time + 0.1;
-
-       // make particle count and sound volume depend on impact speed
-       float intensity;
-       intensity = vlen(self.velocity) + vlen(other.velocity);
-       if(intensity) // avoid divisions by 0
-               intensity /= 2; // average the two velocities
-       if (!(intensity >= autocvar_g_sandbox_object_material_velocity_min))
-               return; // impact not strong enough to do anything
-       // now offset intensity and apply it to the effects
-       intensity -= autocvar_g_sandbox_object_material_velocity_min; // start from minimum velocity, not actual velocity
-       intensity = bound(0, intensity * autocvar_g_sandbox_object_material_velocity_factor, 1);
-
-       _sound(self, CH_TRIGGER, strcat("object/impact_", self.material, "_", ftos(ceil(random() * 5)) , ".wav"), VOL_BASE * intensity, ATTEN_NORM);
-       Send_Effect_(strcat("impact_", self.material), self.origin, '0 0 0', ceil(intensity * 10)); // allow a count from 1 to 10
-}
-
-void sandbox_ObjectFunction_Think()
-{SELFPARAM();
-       entity e;
-
-       // decide if and how this object can be grabbed
-       if(autocvar_g_sandbox_readonly)
-               self.grab = 0; // no grabbing
-       else if(autocvar_g_sandbox_editor_free < 2 && self.crypto_idfp)
-               self.grab = 1; // owner only
-       else
-               self.grab = 3; // anyone
-
-       // Object owner is stored via player UID, but we also need the owner as an entity (if the player is available on the server).
-       // Therefore, scan for all players, and update the owner as long as the player is present. We must always do this,
-       // since if the owning player disconnects, the object's owner should also be reset.
-       FOR_EACH_REALPLAYER(e) // bots can't have objects
-       {
-               if(self.crypto_idfp == e.crypto_idfp)
-               {
-                       self.realowner = e;
-                       break;
-               }
-               self.realowner = world;
-       }
-
-       self.nextthink = time;
-
-       CSQCMODEL_AUTOUPDATE(self);
-}
-
-.float old_solid, old_movetype;
-entity sandbox_ObjectEdit_Get(float permissions)
-{SELFPARAM();
-       // Returns the traced entity if the player can edit it, and world if not.
-       // If permissions if false, the object is returned regardless of editing rights.
-       // Attached objects are SOLID_NOT and do not get traced.
-
-       crosshair_trace_plusvisibletriggers(self);
-       if(vlen(self.origin - trace_ent.origin) > autocvar_g_sandbox_editor_distance_edit)
-               return world; // out of trace range
-       if(trace_ent.classname != "object")
-               return world; // entity is not an object
-       if(!permissions)
-               return trace_ent; // don't check permissions, anyone can edit this object
-       if(trace_ent.crypto_idfp == "")
-               return trace_ent; // the player who spawned this object did not have an UID, so anyone can edit it
-       if (!(trace_ent.realowner != self && autocvar_g_sandbox_editor_free < 2))
-               return trace_ent; // object does not belong to the player, and players can only edit their own objects on this server
-       return world;
-}
-
-void sandbox_ObjectEdit_Scale(entity e, float f)
-{
-       e.scale = f;
-       if(e.scale)
-       {
-               e.scale = bound(autocvar_g_sandbox_object_scale_min, e.scale, autocvar_g_sandbox_object_scale_max);
-               _setmodel(e, e.model); // reset mins and maxs based on mesh
-               setsize(e, e.mins * e.scale, e.maxs * e.scale); // adapt bounding box size to model size
-       }
-}
-
-void sandbox_ObjectAttach_Remove(entity e);
-void sandbox_ObjectAttach_Set(entity e, entity parent, string s)
-{
-       // attaches e to parent on string s
-
-       // we can't attach to an attachment, for obvious reasons
-       sandbox_ObjectAttach_Remove(e);
-
-       e.old_solid = e.solid; // persist solidity
-       e.old_movetype = e.movetype; // persist physics
-       e.movetype = MOVETYPE_FOLLOW;
-       e.solid = SOLID_NOT;
-       e.takedamage = DAMAGE_NO;
-
-       setattachment(e, parent, s);
-       e.owner = parent;
-}
-
-void sandbox_ObjectAttach_Remove(entity e)
-{
-       // detaches any object attached to e
-
-       entity head;
-       for(head = world; (head = find(head, classname, "object")); )
-       {
-               if(head.owner == e)
-               {
-                       vector org;
-                       org = gettaginfo(head, 0);
-                       setattachment(head, world, "");
-                       head.owner = world;
-
-                       // objects change origin and angles when detached, so apply previous position
-                       setorigin(head, org);
-                       head.angles = e.angles; // don't allow detached objects to spin or roll
-
-                       head.solid = head.old_solid; // restore persisted solidity
-                       head.movetype = head.old_movetype; // restore persisted physics
-                       head.takedamage = DAMAGE_AIM;
-               }
-       }
-}
-
-entity sandbox_ObjectSpawn(float database)
-{SELFPARAM();
-       // spawn a new object with default properties
-
-       entity e = spawn();
-       e.classname = "object";
-       e.takedamage = DAMAGE_AIM;
-       e.damageforcescale = 1;
-       e.solid = SOLID_BBOX; // SOLID_BSP would be best, but can lag the server badly
-       e.movetype = MOVETYPE_TOSS;
-       e.frame = 0;
-       e.skin = 0;
-       e.material = string_null;
-       e.touch = sandbox_ObjectFunction_Touch;
-       e.think = sandbox_ObjectFunction_Think;
-       e.nextthink = time;
-       //e.effects |= EF_SELECTABLE; // don't do this all the time, maybe just when editing objects?
-
-       if(!database)
-       {
-               // set the object's owner via player UID
-               // if the player does not have an UID, the owner cannot be stored and his objects may be edited by anyone
-               if(self.crypto_idfp != "")
-                       e.crypto_idfp = strzone(self.crypto_idfp);
-               else
-                       print_to(self, "^1SANDBOX - WARNING: ^7You spawned an object, but lack a player UID. ^1Your objects are not secured and can be edited by any player!");
-
-               // set public object information
-               e.netname = strzone(self.netname); // name of the owner
-               e.message = strzone(strftime(true, "%d-%m-%Y %H:%M:%S")); // creation time
-               e.message2 = strzone(strftime(true, "%d-%m-%Y %H:%M:%S")); // last editing time
-
-               // set origin and direction based on player position and view angle
-               makevectors(self.v_angle);
-               WarpZone_TraceLine(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * autocvar_g_sandbox_editor_distance_spawn, MOVE_NORMAL, self);
-               setorigin(e, trace_endpos);
-               e.angles_y = self.v_angle.y;
-       }
-
-       WITH(entity, self, e, CSQCMODEL_AUTOINIT(e));
-
-       object_count += 1;
-       return e;
-}
-
-void sandbox_ObjectRemove(entity e)
-{
-       sandbox_ObjectAttach_Remove(e); // detach child objects
-
-       // if the object being removed has been selected for attachment by a player, unset it
-       entity head;
-       FOR_EACH_REALPLAYER(head) // bots can't have objects
-       {
-               if(head.object_attach == e)
-                       head.object_attach = world;
-       }
-
-       if(e.material)  {       strunzone(e.material);  e.material = string_null;       }
-       if(e.crypto_idfp)       {       strunzone(e.crypto_idfp);       e.crypto_idfp = string_null;    }
-       if(e.netname)   {       strunzone(e.netname);   e.netname = string_null;        }
-       if(e.message)   {       strunzone(e.message);   e.message = string_null;        }
-       if(e.message2)  {       strunzone(e.message2);  e.message2 = string_null;       }
-       remove(e);
-       e = world;
-
-       object_count -= 1;
-}
-
-string port_string[MAX_STORAGE_ATTACHMENTS]; // fteqcc crashes if this isn't defined as a global
-
-string sandbox_ObjectPort_Save(entity e, float database)
-{
-       // save object properties, and return them as a string
-       float i = 0;
-       string s;
-       entity head;
-
-       for(head = world; (head = find(head, classname, "object")); )
-       {
-               // the main object needs to be first in the array [0] with attached objects following
-               float slot, physics, solidity;
-               if(head == e) // this is the main object, place it first
-               {
-                       slot = 0;
-                       solidity = head.solid; // applied solidity is normal solidity for children
-                       physics = head.movetype; // applied physics are normal physics for parents
-               }
-               else if(head.owner == e) // child object, list them in order
-               {
-                       i += 1; // children start from 1
-                       slot = i;
-                       solidity = head.old_solid; // persisted solidity is normal solidity for children
-                       physics = head.old_movetype; // persisted physics are normal physics for children
-                       gettaginfo(head.owner, head.tag_index); // get the name of the tag our object is attached to, used further below
-               }
-               else
-                       continue;
-
-               // ---------------- OBJECT PROPERTY STORAGE: SAVE ----------------
-               if(slot)
-               {
-                       // properties stored only for child objects
-                       if(gettaginfo_name)     port_string[slot] = strcat(port_string[slot], "\"", gettaginfo_name, "\" ");    else    port_string[slot] = strcat(port_string[slot], "\"\" "); // none
-               }
-               else
-               {
-                       // properties stored only for parent objects
-                       if(database)
-                       {
-                               port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", head.origin), " ");
-                               port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", head.angles), " ");
-                       }
-               }
-               // properties stored for all objects
-               port_string[slot] = strcat(port_string[slot], "\"", head.model, "\" ");
-               port_string[slot] = strcat(port_string[slot], ftos(head.skin), " ");
-               port_string[slot] = strcat(port_string[slot], ftos(head.alpha), " ");
-               port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", head.colormod), " ");
-               port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", head.glowmod), " ");
-               port_string[slot] = strcat(port_string[slot], ftos(head.frame), " ");
-               port_string[slot] = strcat(port_string[slot], ftos(head.scale), " ");
-               port_string[slot] = strcat(port_string[slot], ftos(solidity), " ");
-               port_string[slot] = strcat(port_string[slot], ftos(physics), " ");
-               port_string[slot] = strcat(port_string[slot], ftos(head.damageforcescale), " ");
-               if(head.material)       port_string[slot] = strcat(port_string[slot], "\"", head.material, "\" ");      else    port_string[slot] = strcat(port_string[slot], "\"\" "); // none
-               if(database)
-               {
-                       // properties stored only for the database
-                       if(head.crypto_idfp)    port_string[slot] = strcat(port_string[slot], "\"", head.crypto_idfp, "\" ");   else    port_string[slot] = strcat(port_string[slot], "\"\" "); // none
-                       port_string[slot] = strcat(port_string[slot], "\"", e.netname, "\" ");
-                       port_string[slot] = strcat(port_string[slot], "\"", e.message, "\" ");
-                       port_string[slot] = strcat(port_string[slot], "\"", e.message2, "\" ");
-               }
-       }
-
-       // now apply the array to a simple string, with the ; symbol separating objects
-       s = "";
-       for(i = 0; i <= MAX_STORAGE_ATTACHMENTS; ++i)
-       {
-               if(port_string[i])
-                       s = strcat(s, port_string[i], "; ");
-               port_string[i] = string_null; // fully clear the string
-       }
-
-       return s;
-}
-
-entity sandbox_ObjectPort_Load(string s, float database)
-{
-       // load object properties, and spawn a new object with them
-       float n, i;
-       entity e = world, parent = world;
-
-       // separate objects between the ; symbols
-       n = tokenizebyseparator(s, "; ");
-       for(i = 0; i < n; ++i)
-               port_string[i] = argv(i);
-
-       // now separate and apply the properties of each object
-       for(i = 0; i < n; ++i)
-       {
-               float argv_num;
-               string tagname = string_null;
-               argv_num = 0;
-               tokenize_console(port_string[i]);
-               e = sandbox_ObjectSpawn(database);
-
-               // ---------------- OBJECT PROPERTY STORAGE: LOAD ----------------
-               if(i)
-               {
-                       // properties stored only for child objects
-                       if(argv(argv_num) != "")        tagname = argv(argv_num);       else tagname = string_null;     ++argv_num;
-               }
-               else
-               {
-                       // properties stored only for parent objects
-                       if(database)
-                       {
-                               setorigin(e, stov(argv(argv_num)));     ++argv_num;
-                               e.angles = stov(argv(argv_num));        ++argv_num;
-                       }
-                       parent = e; // mark parent objects as such
-               }
-               // properties stored for all objects
-               _setmodel(e, argv(argv_num));   ++argv_num;
-               e.skin = stof(argv(argv_num));  ++argv_num;
-               e.alpha = stof(argv(argv_num)); ++argv_num;
-               e.colormod = stov(argv(argv_num));      ++argv_num;
-               e.glowmod = stov(argv(argv_num));       ++argv_num;
-               e.frame = stof(argv(argv_num)); ++argv_num;
-               sandbox_ObjectEdit_Scale(e, stof(argv(argv_num)));      ++argv_num;
-               e.solid = e.old_solid = stof(argv(argv_num));   ++argv_num;
-               e.movetype = e.old_movetype = stof(argv(argv_num));     ++argv_num;
-               e.damageforcescale = stof(argv(argv_num));      ++argv_num;
-               if(e.material)  strunzone(e.material);  if(argv(argv_num) != "")        e.material = strzone(argv(argv_num));   else    e.material = string_null;       ++argv_num;
-               if(database)
-               {
-                       // properties stored only for the database
-                       if(e.crypto_idfp)       strunzone(e.crypto_idfp);       if(argv(argv_num) != "")        e.crypto_idfp = strzone(argv(argv_num));        else    e.crypto_idfp = string_null;    ++argv_num;
-                       if(e.netname)   strunzone(e.netname);   e.netname = strzone(argv(argv_num));    ++argv_num;
-                       if(e.message)   strunzone(e.message);   e.message = strzone(argv(argv_num));    ++argv_num;
-                       if(e.message2)  strunzone(e.message2);  e.message2 = strzone(argv(argv_num));   ++argv_num;
-               }
-
-               // attach last
-               if(i)
-                       sandbox_ObjectAttach_Set(e, parent, tagname);
-       }
-
-       for(i = 0; i <= MAX_STORAGE_ATTACHMENTS; ++i)
-               port_string[i] = string_null; // fully clear the string
-
-       return e;
-}
-
-void sandbox_Database_Save()
-{
-       // saves all objects to the database file
-       entity head;
-       string file_name;
-       float file_get;
-
-       file_name = strcat("sandbox/storage_", autocvar_g_sandbox_storage_name, "_", GetMapname(), ".txt");
-       file_get = fopen(file_name, FILE_WRITE);
-       fputs(file_get, strcat("// sandbox storage \"", autocvar_g_sandbox_storage_name, "\" for map \"", GetMapname(), "\" last updated ", strftime(true, "%d-%m-%Y %H:%M:%S")));
-       fputs(file_get, strcat(" containing ", ftos(object_count), " objects\n"));
-
-       for(head = world; (head = find(head, classname, "object")); )
-       {
-               // attached objects are persisted separately, ignore them here
-               if(head.owner != world)
-                       continue;
-
-               // use a line of text for each object, listing all properties
-               fputs(file_get, strcat(sandbox_ObjectPort_Save(head, true), "\n"));
-       }
-       fclose(file_get);
-}
-
-void sandbox_Database_Load()
-{
-       // loads all objects from the database file
-       string file_read, file_name;
-       float file_get, i;
-
-       file_name = strcat("sandbox/storage_", autocvar_g_sandbox_storage_name, "_", GetMapname(), ".txt");
-       file_get = fopen(file_name, FILE_READ);
-       if(file_get < 0)
-       {
-               if(autocvar_g_sandbox_info > 0)
-                       LOG_INFO(strcat("^3SANDBOX - SERVER: ^7could not find storage file ^3", file_name, "^7, no objects were loaded\n"));
-       }
-       else
-       {
-               for (;;)
-               {
-                       file_read = fgets(file_get);
-                       if(file_read == "")
-                               break;
-                       if(substring(file_read, 0, 2) == "//")
-                               continue;
-                       if(substring(file_read, 0, 1) == "#")
-                               continue;
-
-                       entity e;
-                       e = sandbox_ObjectPort_Load(file_read, true);
-
-                       if(e.material)
-                       {
-                               // since objects are being loaded for the first time, precache material sounds for each
-                               for (i = 1; i <= 5; i++) // 5 sounds in total
-                                       precache_sound(strcat("object/impact_", e.material, "_", ftos(i), ".wav"));
-                       }
-               }
-               if(autocvar_g_sandbox_info > 0)
-                       LOG_INFO(strcat("^3SANDBOX - SERVER: ^7successfully loaded storage file ^3", file_name, "\n"));
-       }
-       fclose(file_get);
-}
-
-MUTATOR_HOOKFUNCTION(sandbox_PlayerCommand)
-{SELFPARAM();
-       if(MUTATOR_RETURNVALUE) // command was already handled?
-               return false;
-       if(cmd_name == "g_sandbox")
-       {
-               if(autocvar_g_sandbox_readonly)
-               {
-                       print_to(self, "^2SANDBOX - INFO: ^7Sandbox mode is active, but in read-only mode. Sandbox commands cannot be used");
-                       return true;
-               }
-               if(cmd_argc < 2)
-               {
-                       print_to(self, "^2SANDBOX - INFO: ^7Sandbox mode is active. For usage information, type 'sandbox help'");
-                       return true;
-               }
-
-               switch(argv(1))
-               {
-                       entity e;
-                       float i;
-                       string s;
-
-                       // ---------------- COMMAND: HELP ----------------
-                       case "help":
-                               print_to(self, "You can use the following sandbox commands:");
-                               print_to(self, "^7\"^2object_spawn ^3models/foo/bar.md3^7\" spawns a new object in front of the player, and gives it the specified model");
-                               print_to(self, "^7\"^2object_remove^7\" removes the object the player is looking at. Players can only remove their own objects");
-                               print_to(self, "^7\"^2object_duplicate ^3value^7\" duplicates the object, if the player has copying rights over the original");
-                               print_to(self, "^3copy value ^7- copies the properties of the object to the specified client cvar");
-                               print_to(self, "^3paste value ^7- spawns an object with the given properties. Properties or cvars must be specified as follows; eg1: \"0 1 2 ...\", eg2: \"$cl_cvar\"");
-                               print_to(self, "^7\"^2object_attach ^3property value^7\" attaches one object to another. Players can only attach their own objects");
-                               print_to(self, "^3get ^7- selects the object you are facing as the object to be attached");
-                               print_to(self, "^3set value ^7- attaches the previously selected object to the object you are facing, on the specified bone");
-                               print_to(self, "^3remove ^7- detaches all objects from the object you are facing");
-                               print_to(self, "^7\"^2object_edit ^3property value^7\" edits the given property of the object. Players can only edit their own objects");
-                               print_to(self, "^3skin value ^7- changes the skin of the object");
-                               print_to(self, "^3alpha value ^7- sets object transparency");
-                               print_to(self, "^3colormod \"value_x value_y value_z\" ^7- main object color");
-                               print_to(self, "^3glowmod \"value_x value_y value_z\" ^7- glow object color");
-                               print_to(self, "^3frame value ^7- object animation frame, for self-animated models");
-                               print_to(self, "^3scale value ^7- changes object scale. 0.5 is half size and 2 is double size");
-                               print_to(self, "^3solidity value ^7- object collisions, 0 = non-solid, 1 = solid");
-                               print_to(self, "^3physics value ^7- object physics, 0 = static, 1 = movable, 2 = physical");
-                               print_to(self, "^3force value ^7- amount of force applied to objects that are shot");
-                               print_to(self, "^3material value ^7- sets the material of the object. Default materials are: metal, stone, wood, flesh");
-                               print_to(self, "^7\"^2object_claim^7\" sets the player as the owner of the object, if he has the right to edit it");
-                               print_to(self, "^7\"^2object_info ^3value^7\" shows public information about the object");
-                               print_to(self, "^3object ^7- prints general information about the object, such as owner and creation / editing date");
-                               print_to(self, "^3mesh ^7- prints information about the object's mesh, including skeletal bones");
-                               print_to(self, "^3attachments ^7- prints information about the object's attachments");
-                               print_to(self, "^7The ^1drag object ^7key can be used to grab and carry objects. Players can only grab their own objects");
-                               return true;
-
-                       // ---------------- COMMAND: OBJECT, SPAWN ----------------
-                       case "object_spawn":
-                               if(time < self.object_flood)
-                               {
-                                       print_to(self, strcat("^1SANDBOX - WARNING: ^7Flood protection active. Please wait ^3", ftos(self.object_flood - time), " ^7seconds beofore spawning another object"));
-                                       return true;
-                               }
-                               self.object_flood = time + autocvar_g_sandbox_editor_flood;
-                               if(object_count >= autocvar_g_sandbox_editor_maxobjects)
-                               {
-                                       print_to(self, strcat("^1SANDBOX - WARNING: ^7Cannot spawn any more objects. Up to ^3", ftos(autocvar_g_sandbox_editor_maxobjects), " ^7objects may exist at a time"));
-                                       return true;
-                               }
-                               if(cmd_argc < 3)
-                               {
-                                       print_to(self, "^1SANDBOX - WARNING: ^7Attempted to spawn an object without specifying a model. Please specify the path to your model file after the 'object_spawn' command");
-                                       return true;
-                               }
-                               if (!(fexists(argv(2))))
-                               {
-                                       print_to(self, "^1SANDBOX - WARNING: ^7Attempted to spawn an object with a non-existent model. Make sure the path to your model file is correct");
-                                       return true;
-                               }
-
-                               e = sandbox_ObjectSpawn(false);
-                               _setmodel(e, argv(2));
-
-                               if(autocvar_g_sandbox_info > 0)
-                                       LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", self.netname, " spawned an object at origin ^3", vtos(e.origin), "\n"));
-                               return true;
-
-                       // ---------------- COMMAND: OBJECT, REMOVE ----------------
-                       case "object_remove":
-                               e = sandbox_ObjectEdit_Get(true);
-                               if(e != world)
-                               {
-                                       if(autocvar_g_sandbox_info > 0)
-                                               LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", self.netname, " removed an object at origin ^3", vtos(e.origin), "\n"));
-                                       sandbox_ObjectRemove(e);
-                                       return true;
-                               }
-
-                               print_to(self, "^1SANDBOX - WARNING: ^7Object could not be removed. Make sure you are facing an object that you have edit rights over");
-                               return true;
-
-                       // ---------------- COMMAND: OBJECT, DUPLICATE ----------------
-                       case "object_duplicate":
-                               switch(argv(2))
-                               {
-                                       case "copy":
-                                               // copies customizable properties of the selected object to the clipboard cvar
-                                               e = sandbox_ObjectEdit_Get(autocvar_g_sandbox_editor_free); // can we copy objects we can't edit?
-                                               if(e != world)
-                                               {
-                                                       s = sandbox_ObjectPort_Save(e, false);
-                                                       s = strreplace("\"", "\\\"", s);
-                                                       stuffcmd(self, strcat("set ", argv(3), " \"", s, "\""));
-
-                                                       print_to(self, "^2SANDBOX - INFO: ^7Object copied to clipboard");
-                                                       return true;
-                                               }
-                                               print_to(self, "^1SANDBOX - WARNING: ^7Object could not be copied. Make sure you are facing an object that you have copy rights over");
-                                               return true;
-
-                                       case "paste":
-                                               // spawns a new object using the properties in the player's clipboard cvar
-                                               if(time < self.object_flood)
-                                               {
-                                                       print_to(self, strcat("^1SANDBOX - WARNING: ^7Flood protection active. Please wait ^3", ftos(self.object_flood - time), " ^7seconds beofore spawning another object"));
-                                                       return true;
-                                               }
-                                               self.object_flood = time + autocvar_g_sandbox_editor_flood;
-                                               if(argv(3) == "") // no object in clipboard
-                                               {
-                                                       print_to(self, "^1SANDBOX - WARNING: ^7No object in clipboard. You must copy an object before you can paste it");
-                                                       return true;
-                                               }
-                                               if(object_count >= autocvar_g_sandbox_editor_maxobjects)
-                                               {
-                                                       print_to(self, strcat("^1SANDBOX - WARNING: ^7Cannot spawn any more objects. Up to ^3", ftos(autocvar_g_sandbox_editor_maxobjects), " ^7objects may exist at a time"));
-                                                       return true;
-                                               }
-                                               e = sandbox_ObjectPort_Load(argv(3), false);
-
-                                               print_to(self, "^2SANDBOX - INFO: ^7Object pasted successfully");
-                                               if(autocvar_g_sandbox_info > 0)
-                                                       LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", self.netname, " pasted an object at origin ^3", vtos(e.origin), "\n"));
-                                               return true;
-                               }
-                               return true;
-
-                       // ---------------- COMMAND: OBJECT, ATTACH ----------------
-                       case "object_attach":
-                               switch(argv(2))
-                               {
-                                       case "get":
-                                               // select e as the object as meant to be attached
-                                               e = sandbox_ObjectEdit_Get(true);
-                                               if(e != world)
-                                               {
-                                                       self.object_attach = e;
-                                                       print_to(self, "^2SANDBOX - INFO: ^7Object selected for attachment");
-                                                       return true;
-                                               }
-                                               print_to(self, "^1SANDBOX - WARNING: ^7Object could not be selected for attachment. Make sure you are facing an object that you have edit rights over");
-                                               return true;
-                                       case "set":
-                                               if(self.object_attach == world)
-                                               {
-                                                       print_to(self, "^1SANDBOX - WARNING: ^7No object selected for attachment. Please select an object to be attached first.");
-                                                       return true;
-                                               }
-
-                                               // attaches the previously selected object to e
-                                               e = sandbox_ObjectEdit_Get(true);
-                                               if(e != world)
-                                               {
-                                                       sandbox_ObjectAttach_Set(self.object_attach, e, argv(3));
-                                                       self.object_attach = world; // object was attached, no longer keep it scheduled for attachment
-                                                       print_to(self, "^2SANDBOX - INFO: ^7Object attached successfully");
-                                                       if(autocvar_g_sandbox_info > 1)
-                                                               LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", self.netname, " attached objects at origin ^3", vtos(e.origin), "\n"));
-                                                       return true;
-                                               }
-                                               print_to(self, "^1SANDBOX - WARNING: ^7Object could not be attached to the parent. Make sure you are facing an object that you have edit rights over");
-                                               return true;
-                                       case "remove":
-                                               // removes e if it was attached
-                                               e = sandbox_ObjectEdit_Get(true);
-                                               if(e != world)
-                                               {
-                                                       sandbox_ObjectAttach_Remove(e);
-                                                       print_to(self, "^2SANDBOX - INFO: ^7Child objects detached successfully");
-                                                       if(autocvar_g_sandbox_info > 1)
-                                                               LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", self.netname, " detached objects at origin ^3", vtos(e.origin), "\n"));
-                                                       return true;
-                                               }
-                                               print_to(self, "^1SANDBOX - WARNING: ^7Child objects could not be detached. Make sure you are facing an object that you have edit rights over");
-                                               return true;
-                               }
-                               return true;
-
-                       // ---------------- COMMAND: OBJECT, EDIT ----------------
-                       case "object_edit":
-                               if(argv(2) == "")
-                               {
-                                       print_to(self, "^1SANDBOX - WARNING: ^7Too few parameters. You must specify a property to edit");
-                                       return true;
-                               }
-
-                               e = sandbox_ObjectEdit_Get(true);
-                               if(e != world)
-                               {
-                                       switch(argv(2))
-                                       {
-                                               case "skin":
-                                                       e.skin = stof(argv(3));
-                                                       break;
-                                               case "alpha":
-                                                       e.alpha = stof(argv(3));
-                                                       break;
-                                               case "color_main":
-                                                       e.colormod = stov(argv(3));
-                                                       break;
-                                               case "color_glow":
-                                                       e.glowmod = stov(argv(3));
-                                                       break;
-                                               case "frame":
-                                                       e.frame = stof(argv(3));
-                                                       break;
-                                               case "scale":
-                                                       sandbox_ObjectEdit_Scale(e, stof(argv(3)));
-                                                       break;
-                                               case "solidity":
-                                                       switch(argv(3))
-                                                       {
-                                                               case "0": // non-solid
-                                                                       e.solid = SOLID_TRIGGER;
-                                                                       break;
-                                                               case "1": // solid
-                                                                       e.solid = SOLID_BBOX;
-                                                                       break;
-                                                               default:
-                                                                       break;
-                                                       }
-                                               case "physics":
-                                                       switch(argv(3))
-                                                       {
-                                                               case "0": // static
-                                                                       e.movetype = MOVETYPE_NONE;
-                                                                       break;
-                                                               case "1": // movable
-                                                                       e.movetype = MOVETYPE_TOSS;
-                                                                       break;
-                                                               case "2": // physical
-                                                                       e.movetype = MOVETYPE_PHYSICS;
-                                                                       break;
-                                                               default:
-                                                                       break;
-                                                       }
-                                                       break;
-                                               case "force":
-                                                       e.damageforcescale = stof(argv(3));
-                                                       break;
-                                               case "material":
-                                                       if(e.material)  strunzone(e.material);
-                                                       if(argv(3))
-                                                       {
-                                                               for (i = 1; i <= 5; i++) // precache material sounds, 5 in total
-                                                                       precache_sound(strcat("object/impact_", argv(3), "_", ftos(i), ".wav"));
-                                                               e.material = strzone(argv(3));
-                                                       }
-                                                       else
-                                                               e.material = string_null; // no material
-                                                       break;
-                                               default:
-                                                       print_to(self, "^1SANDBOX - WARNING: ^7Invalid object property. For usage information, type 'sandbox help'");
-                                                       return true;
-                                       }
-
-                                       // update last editing time
-                                       if(e.message2)  strunzone(e.message2);
-                                       e.message2 = strzone(strftime(true, "%d-%m-%Y %H:%M:%S"));
-
-                                       if(autocvar_g_sandbox_info > 1)
-                                               LOG_INFO(strcat("^3SANDBOX - SERVER: ^7", self.netname, " edited property ^3", argv(2), " ^7of an object at origin ^3", vtos(e.origin), "\n"));
-                                       return true;
-                               }
-
-                               print_to(self, "^1SANDBOX - WARNING: ^7Object could not be edited. Make sure you are facing an object that you have edit rights over");
-                               return true;
-
-                       // ---------------- COMMAND: OBJECT, CLAIM ----------------
-                       case "object_claim":
-                               // if the player can edit an object but is not its owner, this can be used to claim that object
-                               if(self.crypto_idfp == "")
-                               {
-                                       print_to(self, "^1SANDBOX - WARNING: ^7You do not have a player UID, and cannot claim objects");
-                                       return true;
-                               }
-                               e = sandbox_ObjectEdit_Get(true);
-                               if(e != world)
-                               {
-                                       // update the owner's name
-                                       // Do this before checking if you're already the owner and skipping if such, so we
-                                       // also update the player's nickname if he changed it (but has the same player UID)
-                                       if(e.netname != self.netname)
-                                       {
-                                               if(e.netname)   strunzone(e.netname);
-                                               e.netname = strzone(self.netname);
-                                               print_to(self, "^2SANDBOX - INFO: ^7Object owner name updated");
-                                       }
-
-                                       if(e.crypto_idfp == self.crypto_idfp)
-                                       {
-                                               print_to(self, "^2SANDBOX - INFO: ^7Object is already yours, nothing to claim");
-                                               return true;
-                                       }
-
-                                       if(e.crypto_idfp)       strunzone(e.crypto_idfp);
-                                       e.crypto_idfp = strzone(self.crypto_idfp);
-
-                                       print_to(self, "^2SANDBOX - INFO: ^7Object claimed successfully");
-                               }
-                               print_to(self, "^1SANDBOX - WARNING: ^7Object could not be claimed. Make sure you are facing an object that you have edit rights over");
-                               return true;
-
-                       // ---------------- COMMAND: OBJECT, INFO ----------------
-                       case "object_info":
-                               // prints public information about the object to the player
-                               e = sandbox_ObjectEdit_Get(false);
-                               if(e != world)
-                               {
-                                       switch(argv(2))
-                                       {
-                                               case "object":
-                                                       print_to(self, strcat("^2SANDBOX - INFO: ^7Object is owned by \"^7", e.netname, "^7\", created \"^3", e.message, "^7\", last edited \"^3", e.message2, "^7\""));
-                                                       return true;
-                                               case "mesh":
-                                                       s = "";
-                                                       FOR_EACH_TAG(e)
-                                                               s = strcat(s, "^7\"^5", gettaginfo_name, "^7\", ");
-                                                       print_to(self, strcat("^2SANDBOX - INFO: ^7Object mesh is \"^3", e.model, "^7\" at animation frame ^3", ftos(e.frame), " ^7containing the following tags: ", s));
-                                                       return true;
-                                               case "attachments":
-                                                       // this should show the same info as 'mesh' but for attachments
-                                                       s = "";
-                                                       entity head;
-                                                       i = 0;
-                                                       for(head = world; (head = find(head, classname, "object")); )
-                                                       {
-                                                               if(head.owner == e)
-                                                               {
-                                                                       ++i; // start from 1
-                                                                       gettaginfo(e, head.tag_index);
-                                                                       s = strcat(s, "^1attachment ", ftos(i), "^7 has mesh \"^3", head.model, "^7\" at animation frame ^3", ftos(head.frame));
-                                                                       s = strcat(s, "^7 and is attached to bone \"^5", gettaginfo_name, "^7\", ");
-                                                               }
-                                                       }
-                                                       if(i) // object contains attachments
-                                                               print_to(self, strcat("^2SANDBOX - INFO: ^7Object contains the following ^1", ftos(i), "^7 attachment(s): ", s));
-                                                       else
-                                                               print_to(self, "^2SANDBOX - INFO: ^7Object contains no attachments");
-                                                       return true;
-                                       }
-                               }
-                               print_to(self, "^1SANDBOX - WARNING: ^7No information could be found. Make sure you are facing an object");
-                               return true;
-
-                       // ---------------- COMMAND: DEFAULT ----------------
-                       default:
-                               print_to(self, "Invalid command. For usage information, type 'sandbox help'");
-                               return true;
-               }
-       }
-       return false;
-}
-
-float autosave_time;
-MUTATOR_HOOKFUNCTION(sandbox_StartFrame)
-{
-       if(!autocvar_g_sandbox_storage_autosave)
-               return false;
-       if(time < autosave_time)
-               return false;
-       autosave_time = time + autocvar_g_sandbox_storage_autosave;
-
-       sandbox_Database_Save();
-
-       return true;
-}
-
-MUTATOR_HOOKFUNCTION(sandbox_SetModname)
-{
-       modname = "Sandbox";
-       return true;
-}
-
-MUTATOR_DEFINITION(sandbox)
-{
-       MUTATOR_HOOK(SV_ParseClientCommand, sandbox_PlayerCommand, CBC_ORDER_ANY);
-       MUTATOR_HOOK(SV_StartFrame, sandbox_StartFrame, CBC_ORDER_ANY);
-       MUTATOR_HOOK(SetModname, sandbox_SetModname, CBC_ORDER_ANY);
-
-       MUTATOR_ONADD
-       {
-               autosave_time = time + autocvar_g_sandbox_storage_autosave; // don't save the first server frame
-               if(autocvar_g_sandbox_storage_autoload)
-                       sandbox_Database_Load();
-       }
-
-       MUTATOR_ONROLLBACK_OR_REMOVE
-       {
-               // nothing to roll back
-       }
-
-       MUTATOR_ONREMOVE
-       {
-               // nothing to remove
-       }
-
-       return false;
-}
-
index ca6442f979dff6515ea38f24018fb89afbdc917f..9b1d7194f9555587bb42fcda6e0d01d589c168fc 100644 (file)
@@ -1,7 +1,7 @@
 #include "portals.qh"
 
 #include "g_hook.qh"
-#include "mutators/mutators_include.qh"
+#include "mutators/all.qh"
 #include "../common/constants.qh"
 #include "../common/deathtypes/all.qh"
 #include "../common/notifications.qh"
index ece94bdbefb6ca0d67a5b29309cbbe976b0108cf..ab94c42bdd4d6215daef510455181d1ac5a8116f 100644 (file)
@@ -43,8 +43,7 @@
 
 #include "command/all.qc"
 
-#include "mutators/mutators_include.qc"
-#include "mutators/mutators.qc"
+#include "mutators/all.qc"
 
 #include "pathlib/_all.inc"
 
index 94f3100a40cb7bd76d9d4f710d5e98586e3573c8..4f8298238fcaf7755799c08ea0af8cd84e56a0d0 100644 (file)
@@ -416,10 +416,7 @@ void race_SendTime(entity e, float cp, float t, float tvalid)
                                if(cp == race_timed_checkpoint)
                                {
                                        race_setTime(GetMapname(), t, e.crypto_idfp, e.netname, e);
-                                       if(g_cts && autocvar_g_cts_finish_kill_delay)
-                                       {
-                                               CTS_ClientKill(e);
-                                       }
+                                       MUTATOR_CALLHOOK(Race_FinalCheckpoint, e);
                                }
                                if(t < recordtime || recordtime == 0)
                                {
@@ -1145,6 +1142,9 @@ void penalty_use()
 
 spawnfunc(trigger_race_penalty)
 {
+       // TODO: find out why this wasnt done:
+       //if(!g_cts && !g_race) { remove(self); return; }
+
        EXACTTRIGGER_INIT;
 
        self.use = penalty_use;
index 47c1db4a3860176672e7e9ad486be8cf06a1f181..03e8a54aba2747e2f04f6f0914d7e23a2717fccb 100644 (file)
@@ -1,6 +1,11 @@
 #ifndef RACE_H
 #define RACE_H
 
+bool g_race_qualifying;
+
+float speedaward_lastsent;
+float speedaward_lastupdate;
+
 float race_spawns;
 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
index bb489f76fc72a2c74073a0ae387f3bd001fd1d37..678baec958aa26d313a297959947fde5cbd5cac3 100644 (file)
@@ -1,7 +1,7 @@
 #include "scores.qh"
 
 #include "command/common.qh"
-#include "mutators/mutators_include.qh"
+#include "mutators/all.qh"
 #include "../common/playerstats.qh"
 #include "../common/teams.qh"
 
@@ -335,14 +335,15 @@ void PlayerScore_Detach(entity player)
 
 float PlayerScore_Add(entity player, float scorefield, float score)
 {
-       entity s;
+       bool mutator_returnvalue = MUTATOR_CALLHOOK(AddPlayerScore, scorefield, score);
+       score = ret_float;
 
        if(gameover)
-       if(!(g_lms && scorefield == SP_LMS_RANK)) // allow writing to this field in intermission as it is needed for newly joining players
+       if(!mutator_returnvalue)
                score = 0;
 
        if(!scores_initialized) return 0; // FIXME remove this when everything uses this system
-       s = player.scorekeeper;
+       entity s = player.scorekeeper;
        if(!s)
        {
                if(gameover)
@@ -536,15 +537,17 @@ void WinningConditionHelper()
                                s = strcat(s, ":human");
                        else
                                s = strcat(s, ":bot");
-                       if(!IS_PLAYER(p) && p.caplayer != 1 && !g_lms)
+                       if(!IS_PLAYER(p) && !MUTATOR_CALLHOOK(GetPlayerStatus, p, s))
                                s = strcat(s, ":spectator");
+                       s = strcat(s, ret_string);
                }
                else
                {
-                       if(IS_PLAYER(p) || p.caplayer == 1 || g_lms)
+                       if(IS_PLAYER(p) || MUTATOR_CALLHOOK(GetPlayerStatus, p, s))
                                s = GetPlayerScoreString(p, 2);
                        else
                                s = "-666";
+                       s = strcat(s, ret_string);
                }
 
                if(p.clientstatus)
index 6980a9e9439d59a0c6a53b72d94065e2244c0ee1..a1abfa58fc2f02e926d6e0de50c264b8aa4fa08c 100644 (file)
@@ -1,6 +1,6 @@
 #include "spawnpoints.qh"
 
-#include "mutators/mutators_include.qh"
+#include "mutators/all.qh"
 #include "g_world.qh"
 #include "race.qh"
 #include "../common/constants.qh"
@@ -46,6 +46,17 @@ bool SpawnEvent_Send(entity this, entity to, int sf)
        return send;
 }
 
+.vector spawnpoint_prevorigin;
+void spawnpoint_think()
+{
+       self.nextthink = time + 0.1;
+       if(self.origin != self.spawnpoint_prevorigin)
+       {
+               self.spawnpoint_prevorigin = self.origin;
+               self.SendFlags |= 1;
+       }
+}
+
 void spawnpoint_use()
 {SELFPARAM();
        if(teamplay)
@@ -91,6 +102,8 @@ void relocate_spawnpoint()
     }
 
     self.use = spawnpoint_use;
+    self.think = spawnpoint_think;
+    self.nextthink = time + 0.5 + random() * 2; // shouldn't need it for a little second
     self.team_saved = self.team;
     if (!self.cnt)
         self.cnt = 1;
@@ -163,8 +176,6 @@ Starting point for a player in team one (Red).
 Keys: "angle" viewing angle when spawning. */
 spawnfunc(info_player_team1)
 {
-       if(g_assault) { remove(this); return; }
-
        this.team = NUM_TEAM_1; // red
        spawnfunc_info_player_deathmatch(this);
 }
@@ -175,8 +186,6 @@ Starting point for a player in team two (Blue).
 Keys: "angle" viewing angle when spawning. */
 spawnfunc(info_player_team2)
 {
-       if(g_assault) { remove(this); return; }
-
        this.team = NUM_TEAM_2; // blue
        spawnfunc_info_player_deathmatch(this);
 }
@@ -186,8 +195,6 @@ Starting point for a player in team three (Yellow).
 Keys: "angle" viewing angle when spawning. */
 spawnfunc(info_player_team3)
 {
-       if(g_assault) { remove(this); return; }
-
        this.team = NUM_TEAM_3; // yellow
        spawnfunc_info_player_deathmatch(this);
 }
@@ -198,8 +205,6 @@ Starting point for a player in team four (Purple).
 Keys: "angle" viewing angle when spawning. */
 spawnfunc(info_player_team4)
 {
-       if(g_assault) { remove(this); return; }
-
        this.team = NUM_TEAM_4; // purple
        spawnfunc_info_player_deathmatch(this);
 }
index 0a9d8f21014dab6571af9b9deb818ae0d7ed1702..5fc3f771aa87aeb449074d16c4e4edba96d9078f 100644 (file)
@@ -8,7 +8,7 @@
 
 #include "command/common.qh"
 
-#include "mutators/mutators_include.qh"
+#include "mutators/all.qh"
 #include "weapons/csqcprojectile.qh"
 
 #include "../common/constants.qh"
index a640cce105a46f39b95d18b90fd6adedc0f860e5..cb76f97f9a9a730cd9f750a3889a68d388ead5e4 100644 (file)
@@ -7,7 +7,7 @@
     #include "bot/bot.qh"
     #include "bot/waypoints.qh"
 
-    #include "mutators/mutators_include.qh"
+    #include "mutators/all.qh"
 
     #include "weapons/common.qh"
     #include "weapons/selection.qh"
@@ -574,7 +574,7 @@ float Item_GiveAmmoTo(entity item, entity player, .float ammotype, float ammomax
 
        if (item.spawnshieldtime)
        {
-               if ((player.(ammotype) < ammomax) || item.pickup_anyway)
+               if ((player.(ammotype) < ammomax) || item.pickup_anyway > 0)
                {
                        player.(ammotype) = bound(player.(ammotype), ammomax, player.(ammotype) + item.(ammotype));
                        goto YEAH;
@@ -645,7 +645,7 @@ float Item_GiveTo(entity item, entity player)
                it = item.weapons;
                it &= ~player.weapons;
 
-               if (it || (item.spawnshieldtime && item.pickup_anyway))
+               if (it || (item.spawnshieldtime && item.pickup_anyway > 0))
                {
                        pickedup = true;
                        for(i = WEP_FIRST; i <= WEP_LAST; ++i)
@@ -1070,12 +1070,12 @@ void StartItem (string itemmodel, string pickupsound, float defaultrespawntime,
                // it's a level item
                if(self.spawnflags & 1)
                        self.noalign = 1;
-               if (self.noalign)
+               if (self.noalign > 0)
                        self.movetype = MOVETYPE_NONE;
                else
                        self.movetype = MOVETYPE_TOSS;
                // do item filtering according to game mode and other things
-               if (!self.noalign)
+               if (self.noalign <= 0)
                {
                        // first nudge it off the floor a little bit to avoid math errors
                        setorigin(self, self.origin + '0 0 1');
@@ -1086,7 +1086,8 @@ void StartItem (string itemmodel, string pickupsound, float defaultrespawntime,
                                setsize (self, '-16 -16 0', '16 16 32');
                        self.SendFlags |= ISF_SIZE;
                        // note droptofloor returns false if stuck/or would fall too far
-                       droptofloor();
+                       if(!self.noalign)
+                               droptofloor();
                        waypoint_spawnforitem(self);
                }
 
@@ -1154,11 +1155,14 @@ void StartItem (string itemmodel, string pickupsound, float defaultrespawntime,
 
        self.SendFlags |= ISF_SIZE;
 
-       if(itemflags & FL_POWERUP)
-               self.ItemStatus |= ITS_ANIMATE1;
+       if(!(self.spawnflags & 1024))
+       {
+               if(itemflags & FL_POWERUP)
+                       self.ItemStatus |= ITS_ANIMATE1;
 
-       if(self.armorvalue || self.health)
-               self.ItemStatus |= ITS_ANIMATE2;
+               if(self.armorvalue || self.health)
+                       self.ItemStatus |= ITS_ANIMATE2;
+       }
 
        if(itemflags & FL_WEAPON)
        {
@@ -1167,7 +1171,8 @@ void StartItem (string itemmodel, string pickupsound, float defaultrespawntime,
                else
                        self.gravity = 1;
 
-               self.ItemStatus |= ITS_ANIMATE1;
+               if(!(self.spawnflags & 1024))
+                       self.ItemStatus |= ITS_ANIMATE1;
                self.ItemStatus |= ISF_COLORMAP;
        }
 
index 5a9d2ee3b999f5989482d0375fad17c4c8ca8502..2f2bf545455a60af2b6a1c4185bd25ce43bda98f 100644 (file)
@@ -9,7 +9,7 @@
 
 #include "command/vote.qh"
 
-#include "mutators/mutators_include.qh"
+#include "mutators/all.qh"
 
 #include "../common/deathtypes/all.qh"
 #include "../common/gamemodes/all.qh"
@@ -44,12 +44,25 @@ void ActivateTeamplay()
        cvar_set("teamplay", "2");  // DP needs this for sending proper getstatus replies.
 }
 
-void InitGameplayMode()
+void SetLimits(int fraglimit_override, int leadlimit_override, float timelimit_override, float qualifying_override)
 {
-       float fraglimit_override, timelimit_override, leadlimit_override, qualifying_override;
-
-       qualifying_override = -1;
+       // enforce the server's universal frag/time limits
+       // set to -1 to not change value
+       if(!autocvar_g_campaign)
+       {
+               if(fraglimit_override >= 0)
+                       cvar_set("fraglimit", ftos(fraglimit_override));
+               if(timelimit_override >= 0)
+                       cvar_set("timelimit", ftos(timelimit_override));
+               if(leadlimit_override >= 0)
+                       cvar_set("leadlimit", ftos(leadlimit_override));
+               if(qualifying_override >= 0)
+                       cvar_set("g_race_qualifying_timelimit", ftos(qualifying_override));
+       }
+}
 
+void InitGameplayMode()
+{
        VoteReset();
 
        // find out good world mins/maxs bounds, either the static bounds found by looking for solid, or the mapinfo specified bounds
@@ -77,192 +90,12 @@ void InitGameplayMode()
        MapInfo_ClearTemps();
 
        // set both here, gamemode can override it later
-       timelimit_override = autocvar_timelimit_override;
-       fraglimit_override = autocvar_fraglimit_override;
-       leadlimit_override = autocvar_leadlimit_override;
+       SetLimits(autocvar_fraglimit_override, autocvar_leadlimit_override, autocvar_timelimit_override, -1);
        gamemode_name = MapInfo_Type_ToText(MapInfo_LoadedGametype);
 
-       if(g_dm)
-       {
-               MUTATOR_ADD(gamemode_deathmatch);
-       }
-
-       if(g_tdm)
-       {
-               ActivateTeamplay();
-               fraglimit_override = autocvar_g_tdm_point_limit;
-               leadlimit_override = autocvar_g_tdm_point_leadlimit;
-               if(autocvar_g_tdm_team_spawns)
-                       have_team_spawns = -1; // request team spawns
-               MUTATOR_ADD(gamemode_tdm);
-       }
-
-       if(g_domination)
-       {
-               ActivateTeamplay();
-               fraglimit_override = autocvar_g_domination_point_limit;
-               leadlimit_override = autocvar_g_domination_point_leadlimit;
-               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
-               MUTATOR_ADD(gamemode_domination);
-       }
-
-       if(g_ctf)
-       {
-               ActivateTeamplay();
-               fraglimit_override = autocvar_capturelimit_override;
-               leadlimit_override = autocvar_captureleadlimit_override;
-               have_team_spawns = -1; // request team spawns
-               MUTATOR_ADD(gamemode_ctf);
-       }
-
-       if(g_lms)
-       {
-               fraglimit_override = autocvar_g_lms_lives_override;
-               leadlimit_override = 0; // not supported by LMS
-               if(fraglimit_override == 0)
-                       fraglimit_override = -1;
-               MUTATOR_ADD(gamemode_lms);
-       }
-
-       if(g_ca)
-       {
-               ActivateTeamplay();
-               fraglimit_override = autocvar_g_ca_point_limit;
-               leadlimit_override = autocvar_g_ca_point_leadlimit;
-               if(autocvar_g_ca_team_spawns)
-                       have_team_spawns = -1; // request team spawns
-               MUTATOR_ADD(gamemode_ca);
-       }
-
-       if(g_keyhunt)
-       {
-               ActivateTeamplay();
-               fraglimit_override = autocvar_g_keyhunt_point_limit;
-               leadlimit_override = autocvar_g_keyhunt_point_leadlimit;
-               if(autocvar_g_keyhunt_team_spawns)
-                       have_team_spawns = -1; // request team spawns
-               MUTATOR_ADD(gamemode_keyhunt);
-       }
-
-       if(g_freezetag)
-       {
-               ActivateTeamplay();
-               fraglimit_override = autocvar_g_freezetag_point_limit;
-               leadlimit_override = autocvar_g_freezetag_point_leadlimit;
-               if(autocvar_g_freezetag_team_spawns)
-                       have_team_spawns = -1; // request team spawns
-               MUTATOR_ADD(gamemode_freezetag);
-       }
-
-       if(g_assault)
-       {
-               ActivateTeamplay();
-               have_team_spawns = -1; // request team spawns
-               MUTATOR_ADD(gamemode_assault);
-       }
-
-       if(g_onslaught)
-       {
-               ActivateTeamplay();
-               fraglimit_override = autocvar_g_onslaught_point_limit;
-               have_team_spawns = -1; // request team spawns
-               MUTATOR_ADD(gamemode_onslaught);
-       }
-
-       if(g_race)
-       {
-               if(autocvar_g_race_teams)
-               {
-                       ActivateTeamplay();
-                       race_teams = bound(2, autocvar_g_race_teams, 4);
-                       have_team_spawns = -1; // request team spawns
-               }
-               else
-                       race_teams = 0;
-               qualifying_override = autocvar_g_race_qualifying_timelimit_override;
-               fraglimit_override = autocvar_g_race_laps_limit;
-               leadlimit_override = 0; // currently not supported by race
-
-               // we need to find out the correct value for g_race_qualifying
-               float want_qualifying = ((qualifying_override >= 0) ? qualifying_override : autocvar_g_race_qualifying_timelimit) > 0;
-
-               if(autocvar_g_campaign)
-               {
-                       g_race_qualifying = 1;
-                       independent_players = 1;
-               }
-               else if(!autocvar_g_campaign && want_qualifying)
-               {
-                       g_race_qualifying = 2;
-                       independent_players = 1;
-                       race_fraglimit = (race_fraglimit >= 0) ? fraglimit_override : autocvar_fraglimit;
-                       race_leadlimit = (race_leadlimit >= 0) ? leadlimit_override : autocvar_leadlimit;
-                       race_timelimit = (race_timelimit >= 0) ? timelimit_override : autocvar_timelimit;
-                       fraglimit_override = 0;
-                       leadlimit_override = 0;
-                       timelimit_override = autocvar_g_race_qualifying_timelimit;
-               }
-               else
-               {
-                       g_race_qualifying = 0;
-               }
-
-               MUTATOR_ADD(gamemode_race);
-       }
-
-       if(g_cts)
-       {
-               g_race_qualifying = 1;
-               fraglimit_override = 0;
-               leadlimit_override = 0;
-               independent_players = 1;
-               MUTATOR_ADD(gamemode_cts);
-       }
-
-       if(g_nexball)
-       {
-               fraglimit_override = autocvar_g_nexball_goallimit;
-               leadlimit_override = autocvar_g_nexball_goalleadlimit;
-               ActivateTeamplay();
-               have_team_spawns = -1; // request team spawns
-               MUTATOR_ADD(gamemode_nexball);
-       }
-
-       if(g_keepaway)
-       {
-               MUTATOR_ADD(gamemode_keepaway);
-       }
-
-       if(g_invasion)
-       {
-               fraglimit_override = autocvar_g_invasion_point_limit;
-               if(autocvar_g_invasion_teams >= 2)
-               {
-                       ActivateTeamplay();
-                       if(autocvar_g_invasion_team_spawns)
-                               have_team_spawns = -1; // request team spawns
-               }
-               MUTATOR_ADD(gamemode_invasion);
-       }
-
        cache_mutatormsg = strzone("");
        cache_lastmutatormsg = strzone("");
 
-       // enforce the server's universal frag/time limits
-       if(!autocvar_g_campaign)
-       {
-               if(fraglimit_override >= 0)
-                       cvar_set("fraglimit", ftos(fraglimit_override));
-               if(timelimit_override >= 0)
-                       cvar_set("timelimit", ftos(timelimit_override));
-               if(leadlimit_override >= 0)
-                       cvar_set("leadlimit", ftos(leadlimit_override));
-               if(qualifying_override >= 0)
-                       cvar_set("g_race_qualifying_timelimit", ftos(qualifying_override));
-       }
-
        InitializeEntity(world, default_delayedinit, INITPRIO_GAMETYPE_FALLBACK);
 }
 
@@ -398,45 +231,19 @@ void SetPlayerTeam(entity pl, float t, float s, float noprint)
 // set c1...c4 to show what teams are allowed
 void CheckAllowedTeams (entity for_whom)
 {SELFPARAM();
-       float dm;
-       entity head;
-       string teament_name;
+       int dm = 0;
 
        c1 = c2 = c3 = c4 = -1;
        cb1 = cb2 = cb3 = cb4 = 0;
 
-       teament_name = string_null;
-       if(g_onslaught)
-       {
-               // onslaught is special
-               head = findchain(classname, "onslaught_generator");
-               while (head)
-               {
-                       if (head.team == NUM_TEAM_1) c1 = 0;
-                       if (head.team == NUM_TEAM_2) c2 = 0;
-                       if (head.team == NUM_TEAM_3) c3 = 0;
-                       if (head.team == NUM_TEAM_4) c4 = 0;
-                       head = head.chain;
-               }
-       }
-       else if(g_domination)
-               teament_name = "dom_team";
-       else if(g_ctf)
-               teament_name = "ctf_team";
-       else if(g_tdm)
-               teament_name = "tdm_team";
-       else if(g_nexball)
-               teament_name = "nexball_team";
-       else if(g_assault)
-               c1 = c2 = 0; // Assault always has 2 teams
-       else
-       {
-               // cover anything else by treating it like tdm with no teams spawned
-               dm = 2;
+       string teament_name = string_null;
 
-               MUTATOR_CALLHOOK(GetTeamCount, dm);
-               dm = ret_float;
+       bool mutator_returnvalue = MUTATOR_CALLHOOK(GetTeamCount, dm, teament_name);
+       teament_name = ret_string;
+       dm = ret_float;
 
+       if(!mutator_returnvalue)
+       {
                if(dm >= 4)
                        c1 = c2 = c3 = c4 = 0;
                else if(dm >= 3)
@@ -448,20 +255,17 @@ void CheckAllowedTeams (entity for_whom)
        // find out what teams are allowed if necessary
        if(teament_name)
        {
-               head = find(world, classname, teament_name);
+               entity head = find(world, classname, teament_name);
                while(head)
                {
-                       if(!(g_domination && head.netname == ""))
+                       switch(head.team)
                        {
-                               if(head.team == NUM_TEAM_1)
-                                       c1 = 0;
-                               else if(head.team == NUM_TEAM_2)
-                                       c2 = 0;
-                               else if(head.team == NUM_TEAM_3)
-                                       c3 = 0;
-                               else if(head.team == NUM_TEAM_4)
-                                       c4 = 0;
+                               case NUM_TEAM_1: c1 = 0; break;
+                               case NUM_TEAM_2: c2 = 0; break;
+                               case NUM_TEAM_3: c3 = 0; break;
+                               case NUM_TEAM_4: c4 = 0; break;
                        }
+
                        head = find(head, classname, teament_name);
                }
        }
index 5664d261daa1a6b26376899369562fe9abc51132..b934993235d4c130ad9b24ad55081922acabdd39 100644 (file)
@@ -21,6 +21,8 @@ void default_delayedinit();
 
 void ActivateTeamplay();
 
+void SetLimits(int fraglimit_override, int leadlimit_override, float timelimit_override, float qualifying_override);
+
 void InitGameplayMode();
 
 string GetClientVersionMessage();
index baa95c64952ffd34b0fcc56d5da4e0bb6062cb21..7d1633f7f34124e6de945eb2fd17657c3b47daec 100644 (file)
@@ -1,6 +1,6 @@
 #include "accuracy.qh"
 
-#include "../mutators/mutators_include.qh"
+#include "../mutators/all.qh"
 #include "../../common/constants.qh"
 #include "../../common/teams.qh"
 #include "../../common/util.qh"
index be2ca6b50f0c6d734d1903aa9470c6d19f1bb291..995154509c11243d148f0f0c90f7aef0287d8892 100644 (file)
@@ -1,7 +1,7 @@
 #include "spawning.qh"
 
 #include "weaponsystem.qh"
-#include "../mutators/mutators_include.qh"
+#include "../mutators/all.qh"
 #include "../t_items.qh"
 #include "../../common/weapons/all.qh"
 
index 83025da9a859869669381fc26167a9fadef66f8b..9e1b3e4dc987de6c4de6472a454e9e73006b2c00 100644 (file)
@@ -1,7 +1,7 @@
 #include "throwing.qh"
 
 #include "weaponsystem.qh"
-#include "../mutators/mutators_include.qh"
+#include "../mutators/all.qh"
 #include "../t_items.qh"
 #include "../g_damage.qh"
 #include "../../common/items/item.qh"
@@ -133,29 +133,29 @@ string W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vecto
        }
 }
 
-float W_IsWeaponThrowable(float w)
+bool W_IsWeaponThrowable(bool w)
 {
+       if (MUTATOR_CALLHOOK(ForbidDropCurrentWeapon))
+               return false;
        if (!autocvar_g_pickup_items)
-               return 0;
+               return false;
        if (g_weaponarena)
                return 0;
        if (g_cts)
                return 0;
-       if (g_nexball && w == WEP_MORTAR.m_id)
-               return 0;
-    if(w == 0)
-        return 0;
+    if(w == WEP_Null.m_id)
+        return false;
 
        #if 0
        if(start_weapons & WepSet_FromWeapon(w))
        {
                // start weapons that take no ammo can't be dropped (this prevents dropping the laser, as long as it continues to use no ammo)
                if(start_items & IT_UNLIMITED_WEAPON_AMMO)
-                       return 0;
+                       return false;
                if((get_weaponinfo(w)).ammo_field == ammo_none)
-                       return 0;
+                       return false;
        }
-       return 1;
+       return true;
        #else
        return (get_weaponinfo(w)).weaponthrowable;
        #endif
@@ -164,11 +164,8 @@ float W_IsWeaponThrowable(float w)
 // toss current weapon
 void W_ThrowWeapon(vector velo, vector delta, float doreduce)
 {SELFPARAM();
-       float w;
-       string a;
-
-       w = self.weapon;
-       if (w == 0)
+       int w = self.weapon;
+       if (w == WEP_Null.m_id)
                return; // just in case
        if(MUTATOR_CALLHOOK(ForbidThrowCurrentWeapon))
                return;
@@ -184,7 +181,7 @@ void W_ThrowWeapon(vector velo, vector delta, float doreduce)
        self.weapons &= ~WepSet_FromWeapon(w);
 
        W_SwitchWeapon_Force(self, w_getbestweapon(self));
-       a = W_ThrowNewWeapon(self, w, doreduce, self.origin + delta, velo);
+       string a = W_ThrowNewWeapon(self, w, doreduce, self.origin + delta, velo);
 
        if(!a) return;
        Send_Notification(NOTIF_ONE, self, MSG_MULTI, ITEM_WEAPON_DROP, a, w);
index dd7e2b59935ceed86ffdc7b24f3d2ac039e774fa..7fa14508688cc50ba50803fbd22e87d98b0a67b4 100644 (file)
@@ -3,7 +3,7 @@
 #include "selection.qh"
 
 #include "../command/common.qh"
-#include "../mutators/mutators_include.qh"
+#include "../mutators/all.qh"
 #include "../round_handler.qh"
 #include "../t_items.qh"
 #include "../../common/animdecide.qh"
 #include "../../common/weapons/all.qh"
 #include "../../lib/csqcmodel/sv_model.qh"
 
-/*
-===========================================================================
+vector shotorg_adjustfromclient(vector vecs, float y_is_right, float algn)
+{
+       switch(algn)
+       {
+               default: case 3: break; // right alignment
+               case 4: vecs.y = -vecs.y; break; // left
+               case 1: case 2: vecs.y = 0; vecs.z -= 2; break; // center
+       }
+
+       return vecs;
+}
+
+vector shotorg_adjust_values(vector vecs, bool y_is_right, bool visual, int algn)
+{
+       string s;
 
-  CLIENT WEAPONSYSTEM CODE
-  Bring back W_Weaponframe
+       if(visual)
+               vecs = shotorg_adjustfromclient(vecs, y_is_right, algn);
+       else if(autocvar_g_shootfromeye)
+               vecs.y = vecs.z = 0;
+       else if(autocvar_g_shootfromcenter)
+       {
+               vecs.y = 0;
+               vecs.z -= 2;
+       }
+       else if((s = autocvar_g_shootfromfixedorigin) != "")
+       {
+               vector v = stov(s);
+               if(y_is_right) { v.y = -v.y; }
+               if(v.x != 0) { vecs.x = v.x; }
+               vecs.y = v.y;
+               vecs.z = v.z;
+       }
+       else // just do the same as top
+               vecs = shotorg_adjustfromclient(vecs, y_is_right, algn);
 
-===========================================================================
-*/
+       return vecs;
+}
+
+vector shotorg_adjust(vector vecs, bool y_is_right, bool visual, int algn)
+{
+       return shotorg_adjust_values(vecs, y_is_right, visual, algn);
+}
 
 .int state;
 
@@ -254,8 +289,8 @@ void CL_WeaponEntity_SetModel(string name)
        {
                vector v0;
                v0 = self.movedir;
-               self.movedir = shotorg_adjust(v0, false, false);
-               self.view_ofs = shotorg_adjust(v0, false, true) - v0;
+               self.movedir = shotorg_adjust(v0, false, false, self.owner.cvar_cl_gunalign);
+               self.view_ofs = shotorg_adjust(v0, false, true, self.owner.cvar_cl_gunalign) - v0;
        }
        self.owner.stat_shotorg = compressShotOrigin(self.movedir);
        self.movedir = decompressShotOrigin(self.owner.stat_shotorg); // make them match perfectly
index e1fc0922d62f53d50ce4b99fbe436b82b1bd20e7..86d31119568c33f7518bfbb7cc01c176f1acc8a5 100644 (file)
@@ -14,6 +14,10 @@ const float WFRAME_FIRE2 = 1;
 const float WFRAME_IDLE = 2;
 const float WFRAME_RELOAD = 3;
 
+vector shotorg_adjust(vector vecs, bool y_is_right, bool visual, int algn);
+
+vector shotorg_adjust_values(vector vecs, bool y_is_right, bool visual, int algn);
+
 void CL_SpawnWeaponentity(entity e);
 
 vector CL_Weapon_GetShotOrg(float wpn);