]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into Mario/q3compat_sanity
authorMario <mario.mario@y7mail.com>
Wed, 5 Aug 2020 01:54:05 +0000 (11:54 +1000)
committerMario <mario.mario@y7mail.com>
Wed, 5 Aug 2020 01:54:05 +0000 (11:54 +1000)
296 files changed:
.tx/merge-base
common.bg.po
common.ca.po
common.da.po [new file with mode: 0644]
common.gl.po [new file with mode: 0644]
common.zh_CN.po
hud_luma.cfg
hud_luminos.cfg
hud_luminos_minimal.cfg
hud_luminos_minimal_xhair.cfg
hud_luminos_old.cfg
hud_nexuiz.cfg
languages.txt
qcsrc/client/_mod.inc
qcsrc/client/_mod.qh
qcsrc/client/autocvars.qh
qcsrc/client/bgmscript.qc
qcsrc/client/bgmscript.qh
qcsrc/client/command/_mod.inc [new file with mode: 0644]
qcsrc/client/command/_mod.qh [new file with mode: 0644]
qcsrc/client/command/cl_cmd.qc [new file with mode: 0644]
qcsrc/client/command/cl_cmd.qh [new file with mode: 0644]
qcsrc/client/commands/_mod.inc [deleted file]
qcsrc/client/commands/_mod.qh [deleted file]
qcsrc/client/commands/cl_cmd.qc [deleted file]
qcsrc/client/commands/cl_cmd.qh [deleted file]
qcsrc/client/csqcmodel_hooks.qc
qcsrc/client/csqcmodel_hooks.qh
qcsrc/client/defs.qh [deleted file]
qcsrc/client/hud/crosshair.qh
qcsrc/client/hud/hud.qc
qcsrc/client/hud/hud_config.qc
qcsrc/client/hud/panel/ammo.qc
qcsrc/client/hud/panel/centerprint.qc
qcsrc/client/hud/panel/chat.qc
qcsrc/client/hud/panel/healtharmor.qc
qcsrc/client/hud/panel/infomessages.qc
qcsrc/client/hud/panel/physics.qc
qcsrc/client/hud/panel/powerups.qc
qcsrc/client/hud/panel/pressedkeys.qc
qcsrc/client/hud/panel/quickmenu.qc
qcsrc/client/hud/panel/racetimer.qc
qcsrc/client/hud/panel/racetimer.qh
qcsrc/client/hud/panel/radar.qc
qcsrc/client/hud/panel/score.qc
qcsrc/client/hud/panel/scoreboard.qc
qcsrc/client/hud/panel/scoreboard.qh
qcsrc/client/hud/panel/timer.qc
qcsrc/client/hud/panel/vote.qc
qcsrc/client/hud/panel/vote.qh
qcsrc/client/hud/panel/weapons.qc
qcsrc/client/items/_mod.inc [new file with mode: 0644]
qcsrc/client/items/_mod.qh [new file with mode: 0644]
qcsrc/client/items/items.qc [new file with mode: 0644]
qcsrc/client/items/items.qh [new file with mode: 0644]
qcsrc/client/main.qc
qcsrc/client/main.qh
qcsrc/client/mapvoting.qc
qcsrc/client/miscfunctions.qc
qcsrc/client/shownames.qc
qcsrc/client/teamradar.qc
qcsrc/client/view.qc
qcsrc/client/view.qh
qcsrc/client/weapons/projectile.qc
qcsrc/client/weapons/projectile.qh
qcsrc/common/_all.inc
qcsrc/common/_mod.inc
qcsrc/common/_mod.qh
qcsrc/common/animdecide.qc
qcsrc/common/command/generic.qc
qcsrc/common/constants.qh
qcsrc/common/csqcmodel_settings.qh
qcsrc/common/effects/qc/casings.qc
qcsrc/common/effects/qc/damageeffects.qc
qcsrc/common/effects/qc/damageeffects.qh
qcsrc/common/effects/qc/globalsound.qc
qcsrc/common/effects/qc/modeleffects.qc
qcsrc/common/ent_cs.qc
qcsrc/common/ent_cs.qh
qcsrc/common/gamemodes/gamemode/assault/sv_assault.qc
qcsrc/common/gamemodes/gamemode/ctf/sv_ctf.qc
qcsrc/common/gamemodes/gamemode/ctf/sv_ctf.qh
qcsrc/common/gamemodes/gamemode/cts/sv_cts.qc
qcsrc/common/gamemodes/gamemode/domination/sv_domination.qc
qcsrc/common/gamemodes/gamemode/invasion/sv_invasion.qc
qcsrc/common/gamemodes/gamemode/keepaway/sv_keepaway.qc
qcsrc/common/gamemodes/gamemode/keyhunt/sv_keyhunt.qc
qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc
qcsrc/common/gamemodes/gamemode/nexball/cl_nexball.qh
qcsrc/common/gamemodes/gamemode/nexball/sv_nexball.qc
qcsrc/common/gamemodes/gamemode/nexball/sv_nexball.qh
qcsrc/common/gamemodes/gamemode/onslaught/onslaught.qc
qcsrc/common/gamemodes/gamemode/onslaught/sv_onslaught.qc
qcsrc/common/gamemodes/gamemode/race/sv_race.qc
qcsrc/common/gamemodes/sv_rules.qc
qcsrc/common/items/item.qh
qcsrc/common/items/item/ammo.qh
qcsrc/common/items/item/armor.qh
qcsrc/common/items/item/health.qh
qcsrc/common/items/item/jetpack.qh
qcsrc/common/items/item/powerup.qh
qcsrc/common/mapinfo.qc
qcsrc/common/mapobjects/_mod.inc
qcsrc/common/mapobjects/_mod.qh
qcsrc/common/mapobjects/bgmscript.qc [new file with mode: 0644]
qcsrc/common/mapobjects/bgmscript.qh [new file with mode: 0644]
qcsrc/common/mapobjects/defs.qh
qcsrc/common/mapobjects/func/breakable.qc
qcsrc/common/mapobjects/func/ladder.qh
qcsrc/common/mapobjects/func/plat.qc
qcsrc/common/mapobjects/func/rotating.qc
qcsrc/common/mapobjects/func/stardust.qc
qcsrc/common/mapobjects/func/train.qc
qcsrc/common/mapobjects/func/train.qh
qcsrc/common/mapobjects/func/vectormamamam.qc
qcsrc/common/mapobjects/func/vectormamamam.qh
qcsrc/common/mapobjects/misc/dynlight.qc
qcsrc/common/mapobjects/misc/laser.qc
qcsrc/common/mapobjects/misc/laser.qh
qcsrc/common/mapobjects/misc/teleport_dest.qc
qcsrc/common/mapobjects/models.qc
qcsrc/common/mapobjects/models.qh
qcsrc/common/mapobjects/platforms.qh
qcsrc/common/mapobjects/target/kill.qc
qcsrc/common/mapobjects/target/location.qh
qcsrc/common/mapobjects/target/music.qc
qcsrc/common/mapobjects/target/spawn.qc
qcsrc/common/mapobjects/teleporters.qc
qcsrc/common/mapobjects/teleporters.qh
qcsrc/common/mapobjects/trigger/counter.qc
qcsrc/common/mapobjects/trigger/counter.qh
qcsrc/common/mapobjects/trigger/delay.qc
qcsrc/common/mapobjects/trigger/flipflop.qc
qcsrc/common/mapobjects/trigger/gamestart.qc
qcsrc/common/mapobjects/trigger/hurt.qh
qcsrc/common/mapobjects/trigger/jumppads.qc
qcsrc/common/mapobjects/trigger/keylock.qc
qcsrc/common/mapobjects/trigger/multi.qc
qcsrc/common/mapobjects/trigger/relay_activators.qc
qcsrc/common/mapobjects/trigger/relay_if.qc
qcsrc/common/mapobjects/trigger/relay_teamcheck.qc
qcsrc/common/mapobjects/trigger/secret.qc
qcsrc/common/mapobjects/trigger/secret.qh
qcsrc/common/mapobjects/trigger/swamp.qc
qcsrc/common/mapobjects/trigger/viewloc.qc
qcsrc/common/mapobjects/triggers.qh
qcsrc/common/monsters/monster.qh
qcsrc/common/monsters/sv_monsters.qc
qcsrc/common/monsters/sv_monsters.qh
qcsrc/common/monsters/sv_spawn.qc
qcsrc/common/monsters/sv_spawner.qc
qcsrc/common/mutators/mutator/breakablehook/sv_breakablehook.qc
qcsrc/common/mutators/mutator/buffs/sv_buffs.qc
qcsrc/common/mutators/mutator/instagib/items.qh
qcsrc/common/mutators/mutator/new_toys/sv_new_toys.qc
qcsrc/common/mutators/mutator/nix/sv_nix.qc
qcsrc/common/mutators/mutator/spawn_near_teammate/sv_spawn_near_teammate.qc
qcsrc/common/notifications/all.qc
qcsrc/common/physics/movetypes/movetypes.qc
qcsrc/common/physics/movetypes/movetypes.qh
qcsrc/common/physics/player.qc
qcsrc/common/physics/player.qh
qcsrc/common/playerstats.qc
qcsrc/common/replicate.qc [new file with mode: 0644]
qcsrc/common/replicate.qh [new file with mode: 0644]
qcsrc/common/stats.qh
qcsrc/common/t_items.qc [deleted file]
qcsrc/common/t_items.qh [deleted file]
qcsrc/common/turrets/cl_turrets.qc
qcsrc/common/turrets/sv_turrets.qc
qcsrc/common/turrets/sv_turrets.qh
qcsrc/common/turrets/turret/flac_weapon.qc
qcsrc/common/vehicles/sv_vehicles.qc
qcsrc/common/vehicles/sv_vehicles.qh
qcsrc/common/vehicles/vehicle/bumblebee.qc
qcsrc/common/vehicles/vehicle/racer.qc
qcsrc/common/vehicles/vehicle/raptor.qc
qcsrc/common/vehicles/vehicle/spiderbot.qc
qcsrc/common/viewloc.qc
qcsrc/common/weapons/all.qc
qcsrc/common/weapons/weapon/arc.qc
qcsrc/common/weapons/weapon/hlac.qc
qcsrc/common/weapons/weapon/minelayer.qh
qcsrc/common/weapons/weapon/porto.qh
qcsrc/common/weapons/weapon/shockwave.qc
qcsrc/common/weapons/weapon/vortex.qh
qcsrc/common/wepent.qc
qcsrc/lib/csqcmodel/cl_player.qc
qcsrc/lib/csqcmodel/cl_player.qh
qcsrc/lib/draw.qh
qcsrc/lib/net.qh
qcsrc/lib/warpzone/common.qc
qcsrc/lib/warpzone/server.qc
qcsrc/menu/xonotic/dialog_settings_game_model.qc
qcsrc/server/_mod.inc
qcsrc/server/_mod.qh
qcsrc/server/anticheat.qc
qcsrc/server/antilag.qc
qcsrc/server/bot/api.qh
qcsrc/server/bot/default/aim.qc
qcsrc/server/bot/default/bot.qc
qcsrc/server/bot/default/havocbot/havocbot.qc
qcsrc/server/bot/default/havocbot/roles.qc
qcsrc/server/bot/default/navigation.qc
qcsrc/server/bot/default/scripting.qc
qcsrc/server/bot/default/waypoints.qc
qcsrc/server/campaign.qc
qcsrc/server/cheats.qc
qcsrc/server/cheats.qh
qcsrc/server/client.qc
qcsrc/server/client.qh
qcsrc/server/clientkill.qc
qcsrc/server/command/banning.qc
qcsrc/server/command/cmd.qc
qcsrc/server/command/common.qc
qcsrc/server/command/common.qh
qcsrc/server/command/getreplies.qc
qcsrc/server/command/getreplies.qh
qcsrc/server/command/radarmap.qc
qcsrc/server/command/sv_cmd.qc
qcsrc/server/command/vote.qc
qcsrc/server/command/vote.qh
qcsrc/server/compat/quake.qc
qcsrc/server/compat/quake3.qc
qcsrc/server/compat/wop.qc
qcsrc/server/constants.qh [deleted file]
qcsrc/server/damage.qc [new file with mode: 0644]
qcsrc/server/damage.qh [new file with mode: 0644]
qcsrc/server/defs.qh [deleted file]
qcsrc/server/g_damage.qc [deleted file]
qcsrc/server/g_damage.qh [deleted file]
qcsrc/server/g_hook.qc [deleted file]
qcsrc/server/g_hook.qh [deleted file]
qcsrc/server/g_world.qc [deleted file]
qcsrc/server/g_world.qh [deleted file]
qcsrc/server/hook.qc [new file with mode: 0644]
qcsrc/server/hook.qh [new file with mode: 0644]
qcsrc/server/impulse.qc
qcsrc/server/ipban.qc
qcsrc/server/items.qc [deleted file]
qcsrc/server/items.qh [deleted file]
qcsrc/server/items/_mod.inc [new file with mode: 0644]
qcsrc/server/items/_mod.qh [new file with mode: 0644]
qcsrc/server/items/items.qc [new file with mode: 0644]
qcsrc/server/items/items.qh [new file with mode: 0644]
qcsrc/server/items/spawning.qc [new file with mode: 0644]
qcsrc/server/items/spawning.qh [new file with mode: 0644]
qcsrc/server/main.qc [new file with mode: 0644]
qcsrc/server/main.qh [new file with mode: 0644]
qcsrc/server/mapvoting.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/miscfunctions.qh
qcsrc/server/mutators/loader.qc
qcsrc/server/pathlib/costs.qc
qcsrc/server/pathlib/expandnode.qc
qcsrc/server/pathlib/main.qc
qcsrc/server/pathlib/movenode.qc
qcsrc/server/pathlib/path_waypoint.qc
qcsrc/server/pathlib/pathlib.qh
qcsrc/server/pathlib/utility.qc
qcsrc/server/player.qc
qcsrc/server/player.qh
qcsrc/server/portals.qc
qcsrc/server/race.qc
qcsrc/server/race.qh
qcsrc/server/round_handler.qc
qcsrc/server/scores.qc
qcsrc/server/scores_rules.qc
qcsrc/server/spawnpoints.qc
qcsrc/server/spawnpoints.qh
qcsrc/server/sv_main.qc [deleted file]
qcsrc/server/sv_main.qh [deleted file]
qcsrc/server/sys-post.qh
qcsrc/server/sys-pre.qh
qcsrc/server/teamplay.qc
qcsrc/server/tests.qh
qcsrc/server/weapons/accuracy.qc
qcsrc/server/weapons/accuracy.qh
qcsrc/server/weapons/common.qc
qcsrc/server/weapons/common.qh
qcsrc/server/weapons/csqcprojectile.qc
qcsrc/server/weapons/hitplot.qc
qcsrc/server/weapons/selection.qc
qcsrc/server/weapons/selection.qh
qcsrc/server/weapons/spawning.qc
qcsrc/server/weapons/spawning.qh
qcsrc/server/weapons/throwing.qc
qcsrc/server/weapons/throwing.qh
qcsrc/server/weapons/tracing.qc
qcsrc/server/weapons/tracing.qh
qcsrc/server/weapons/weaponstats.qc
qcsrc/server/weapons/weaponsystem.qc
qcsrc/server/weapons/weaponsystem.qh
qcsrc/server/world.qc [new file with mode: 0644]
qcsrc/server/world.qh [new file with mode: 0644]
xonotic-client.cfg

index 615dd52c39dba7579f266d74008786fbef6b543b..188907c41507edd6dce4c81d5a790c16d87d3371 100644 (file)
@@ -1 +1 @@
-Sun Jul 26 07:24:53 CEST 2020
+Tue Aug  4 07:23:45 CEST 2020
index 22006b1792e9d70a319a90e925be5ca0983c38d0..6c015f2b603c7b53420033958477a776ca9cffb2 100644 (file)
@@ -5,6 +5,7 @@
 # Translators:
 # 411370735b8ef90fa32c21e58a50941e_d905c03 <7784313cf022f885419b74f26eaf98f3_541595>, 2016-2017
 # set_killer <mettall@abv.bg>, 2014
+# Nik Dim <lilo@abv.bg>, 2020
 # ubone <van_ds_ff@mail.bg>, 2016
 # set_killer <mettall@abv.bg>, 2014
 # ubone <van_ds_ff@mail.bg>, 2016
@@ -13,8 +14,8 @@ msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2020-06-07 07:23+0200\n"
-"PO-Revision-Date: 2020-06-07 05:23+0000\n"
-"Last-Translator: divVerent <divVerent@xonotic.org>\n"
+"PO-Revision-Date: 2020-07-29 08:59+0000\n"
+"Last-Translator: Nik Dim <lilo@abv.bg>\n"
 "Language-Team: Bulgarian (http://www.transifex.com/team-xonotic/xonotic/"
 "language/bg/)\n"
 "Language: bg\n"
@@ -80,7 +81,7 @@ msgstr "^1Натиснете ^3%s^1 за да наблюдавате играч"
 #: qcsrc/client/hud/panel/infomessages.qc:108
 #: qcsrc/menu/xonotic/keybinder.qc:47
 msgid "primary fire"
-msgstr ""
+msgstr "Основна стрелба"
 
 #: qcsrc/client/hud/panel/infomessages.qc:110
 #, c-format
@@ -115,7 +116,7 @@ msgstr "пусни оръжието"
 #: qcsrc/client/hud/panel/infomessages.qc:116
 #: qcsrc/menu/xonotic/keybinder.qc:48
 msgid "secondary fire"
-msgstr ""
+msgstr "Второстепенна стрелба"
 
 #: qcsrc/client/hud/panel/infomessages.qc:119
 #, c-format
@@ -202,11 +203,11 @@ msgstr "отборно меню"
 
 #: qcsrc/client/hud/panel/infomessages.qc:217
 msgid "^1Spectating this player:"
-msgstr ""
+msgstr "^1Наблюдаващи този играч:"
 
 #: qcsrc/client/hud/panel/infomessages.qc:217
 msgid "^1Spectating you:"
-msgstr ""
+msgstr "^1Наблюдаващи теб:"
 
 #: qcsrc/client/hud/panel/infomessages.qc:233
 msgid "^7Press ^3ESC ^7to show HUD options."
@@ -256,7 +257,7 @@ msgstr "Продължи..."
 #: qcsrc/client/hud/panel/quickmenu.qc:787
 #: qcsrc/client/hud/panel/quickmenu.qc:794
 msgid "Chat"
-msgstr ""
+msgstr "Чат"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:788
 msgid "QMCMD^Send public message to"
@@ -272,7 +273,7 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/quickmenu.qc:790
 msgid "QMCMD^good game"
-msgstr ""
+msgstr "QMCMD^добра игра"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:791
 msgid "QMCMD^hi / good luck"
@@ -289,7 +290,7 @@ msgstr ""
 #: qcsrc/client/hud/panel/quickmenu.qc:798
 #: qcsrc/client/hud/panel/quickmenu.qc:814
 msgid "QMCMD^Team chat"
-msgstr ""
+msgstr "QMCMD^Отборен чат"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:799
 msgid "QMCMD^strength soon"
@@ -313,11 +314,11 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/quickmenu.qc:802
 msgid "QMCMD^negative"
-msgstr ""
+msgstr "QMCMD^отрицателен"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:803
 msgid "QMCMD^positive"
-msgstr ""
+msgstr "QMCMD^положителен"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:804
 msgid "QMCMD^need help (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
@@ -402,12 +403,12 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/quickmenu.qc:817
 msgid "QMCMD^Send private message to"
-msgstr ""
+msgstr "QMCMD^Изпрати лично съобщение до"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:819
 #: qcsrc/client/hud/panel/quickmenu.qc:849
 msgid "QMCMD^Settings"
-msgstr ""
+msgstr "QMCMD^Настройки"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:820
 #: qcsrc/client/hud/panel/quickmenu.qc:827
@@ -462,11 +463,11 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/quickmenu.qc:842
 msgid "QMCMD^Increase speed"
-msgstr ""
+msgstr "QMCMD^Увеличи скоростта"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:843
 msgid "QMCMD^Decrease speed"
-msgstr ""
+msgstr "QMCMD^Намали скоростта"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:844
 msgid "QMCMD^Wall collision"
@@ -474,7 +475,7 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/quickmenu.qc:848
 msgid "QMCMD^Fullscreen"
-msgstr ""
+msgstr "QMCMD^Цял екран"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:851
 #: qcsrc/client/hud/panel/quickmenu.qc:861
@@ -483,7 +484,7 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/quickmenu.qc:852
 msgid "QMCMD^Restart the map"
-msgstr ""
+msgstr "QMCMD^Рестартиране на картата"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:853
 msgid "QMCMD^End match"
@@ -539,7 +540,7 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/racetimer.qc:159 qcsrc/client/main.qc:1102
 msgid "missing a checkpoint"
-msgstr ""
+msgstr "пропуснат чекпойнт"
 
 #: qcsrc/client/hud/panel/radar.qc:386
 msgid "Click to select teleport destination"
@@ -583,7 +584,7 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/scoreboard.qc:109
 msgid "Number of deaths"
-msgstr ""
+msgstr "Брой умирания"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:109
 msgid "SCO^deaths"
@@ -603,7 +604,7 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/scoreboard.qc:111
 msgid "The total damage done"
-msgstr ""
+msgstr "Общa нанесена щета"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:112
 msgid "SCO^dmgtaken"
@@ -663,7 +664,7 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/scoreboard.qc:119
 msgid "Number of kills minus suicides"
-msgstr ""
+msgstr "Брой убийства без самоубийствата"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:119
 msgid "SCO^frags"
@@ -705,7 +706,7 @@ msgstr "SCO^kdсъотношение"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:125
 msgid "Number of kills"
-msgstr ""
+msgstr "Брой убийства"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:125
 msgid "SCO^kills"
@@ -729,7 +730,7 @@ msgstr "SCO^животи"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:128
 msgid "Number of times a key was lost"
-msgstr ""
+msgstr "Колко пъти ключа е бил изгубен"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:128
 msgid "SCO^losses"
@@ -738,7 +739,7 @@ msgstr "SCO^загуби"
 #: qcsrc/client/hud/panel/scoreboard.qc:129
 #: qcsrc/client/hud/panel/scoreboard.qc:130
 msgid "Player name"
-msgstr ""
+msgstr "Име на играч"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:129
 msgid "SCO^name"
@@ -750,7 +751,7 @@ msgstr "SCO^прякор"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:131
 msgid "Number of objectives destroyed"
-msgstr ""
+msgstr "Брой унищожени цели"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:131
 msgid "SCO^objectives"
@@ -775,7 +776,7 @@ msgstr "SCO^пинг"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:134
 msgid "Packet loss"
-msgstr ""
+msgstr "Загубени пакети"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:134
 msgid "SCO^pl"
@@ -807,7 +808,7 @@ msgstr "SCO^връщания"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:138
 msgid "Number of revivals"
-msgstr ""
+msgstr "Брой съживявания"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:138
 msgid "SCO^revivals"
@@ -815,11 +816,11 @@ msgstr "SCO^съживявания"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:139
 msgid "Number of rounds won"
-msgstr ""
+msgstr "Брой спечелени рундове"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:139
 msgid "SCO^rounds won"
-msgstr ""
+msgstr "SCO^спечелени рундове"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:140
 msgid "SCO^score"
@@ -827,7 +828,7 @@ msgstr "SCO^резултат"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:140
 msgid "Total score"
-msgstr ""
+msgstr "Общ резултат"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:141
 msgid "Number of suicides"
@@ -884,7 +885,7 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/scoreboard.qc:331
 msgid "Usage:"
-msgstr ""
+msgstr "Употреба:"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:333
 msgid "^2scoreboard_columns_set ^3field1 field2 ..."
@@ -1044,7 +1045,7 @@ msgstr "Мъртав сте, натиснете ^2%s^7 за съживяване
 
 #: qcsrc/client/hud/panel/timer.qc:72
 msgid "WARMUP"
-msgstr ""
+msgstr "ЗАГРЯВКА"
 
 #: qcsrc/client/hud/panel/vote.qc:33
 msgid "^1You must answer before entering hud configure mode"
@@ -1218,35 +1219,35 @@ msgstr ""
 
 #: qcsrc/common/items/item/armor.qh:42
 msgid "Small armor"
-msgstr ""
+msgstr "Малка броня"
 
 #: qcsrc/common/items/item/armor.qh:80
 msgid "Medium armor"
-msgstr ""
+msgstr "Средна броня"
 
 #: qcsrc/common/items/item/armor.qh:118 qcsrc/common/items/item/armor.qh:121
 msgid "Big armor"
-msgstr ""
+msgstr "Голяма броня"
 
 #: qcsrc/common/items/item/armor.qh:158 qcsrc/common/items/item/armor.qh:161
 msgid "Mega armor"
-msgstr ""
+msgstr "Мега броня"
 
 #: qcsrc/common/items/item/health.qh:42
 msgid "Small health"
-msgstr ""
+msgstr "Малка аптечка"
 
 #: qcsrc/common/items/item/health.qh:80
 msgid "Medium health"
-msgstr ""
+msgstr "Средна аптечка"
 
 #: qcsrc/common/items/item/health.qh:118 qcsrc/common/items/item/health.qh:121
 msgid "Big health"
-msgstr ""
+msgstr "Голяма аптечка"
 
 #: qcsrc/common/items/item/health.qh:158 qcsrc/common/items/item/health.qh:161
 msgid "Mega health"
-msgstr ""
+msgstr "Мега аптечка"
 
 #: qcsrc/common/items/item/jetpack.qh:38 qcsrc/common/items/item/jetpack.qh:41
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:91
@@ -1458,7 +1459,7 @@ msgstr ""
 
 #: qcsrc/common/mapinfo.qh:590
 msgid "Duel"
-msgstr ""
+msgstr "Дуел"
 
 #: qcsrc/common/mapinfo.qh:590
 msgid "Fight in a one versus one arena battle to decide the winner"
@@ -1625,7 +1626,7 @@ msgstr ""
 #: qcsrc/common/minigames/minigame/pong.qc:589
 #: qcsrc/common/minigames/minigame/ttt.qc:299
 msgid "AI"
-msgstr ""
+msgstr "ИИ"
 
 #: qcsrc/common/minigames/minigame/pong.qc:606
 msgid "Press ^1Start Match^7 to start the match with the current players"
@@ -1704,7 +1705,7 @@ msgstr ""
 
 #: qcsrc/common/minigames/minigame/ttt.qc:672
 msgid "Single Player"
-msgstr ""
+msgstr "Солова Игра"
 
 #: qcsrc/common/monsters/monster/mage.qh:17
 #: qcsrc/menu/xonotic/dialog_monstertools.qc:18
@@ -1781,7 +1782,7 @@ msgstr ""
 
 #: qcsrc/common/mutators/mutator/buffs/all.inc:87
 msgid "Jump"
-msgstr ""
+msgstr "Скок"
 
 #: qcsrc/common/mutators/mutator/buffs/all.inc:96
 msgid "Invisible"
@@ -1801,7 +1802,7 @@ msgstr ""
 
 #: qcsrc/common/mutators/mutator/buffs/all.inc:129
 msgid "Luck"
-msgstr ""
+msgstr "Късмет"
 
 #: qcsrc/common/mutators/mutator/buffs/all.inc:137
 msgid "Flight"
@@ -1856,11 +1857,11 @@ msgstr "Невидимост"
 
 #: qcsrc/common/mutators/mutator/nades/nades.inc:18
 msgid "Napalm grenade"
-msgstr ""
+msgstr "Напалмова граната"
 
 #: qcsrc/common/mutators/mutator/nades/nades.inc:26
 msgid "Ice grenade"
-msgstr ""
+msgstr "Ледена граната"
 
 #: qcsrc/common/mutators/mutator/nades/nades.inc:34
 msgid "Translocate grenade"
@@ -1888,7 +1889,7 @@ msgstr ""
 
 #: qcsrc/common/mutators/mutator/nades/nades.qh:33
 msgid "Grenade"
-msgstr ""
+msgstr "Граната"
 
 #: qcsrc/common/mutators/mutator/overkill/okhmg.qh:20
 msgid "Overkill Heavy Machine Gun"
@@ -3520,12 +3521,12 @@ msgstr "^BGВие получихте ^TC^TT^BG знаме!"
 
 #: qcsrc/common/notifications/all.inc:561
 msgid "^BGYou got the flag!"
-msgstr ""
+msgstr "^BGТи взе флага!"
 
 #: qcsrc/common/notifications/all.inc:562
 #, c-format
 msgid "^BGYou got your %steam^BG's flag, return it!"
-msgstr ""
+msgstr "^BGТи взе твоя %s team^BG's флаг, върни го!"
 
 #: qcsrc/common/notifications/all.inc:563
 #, c-format
@@ -4318,11 +4319,11 @@ msgstr "вторично"
 
 #: qcsrc/common/notifications/all.qh:419
 msgid "point"
-msgstr ""
+msgstr "точка"
 
 #: qcsrc/common/notifications/all.qh:419
 msgid "points"
-msgstr ""
+msgstr "точки"
 
 #: qcsrc/common/notifications/all.qh:428
 msgid "drop flag"
@@ -4753,22 +4754,22 @@ msgstr ""
 #: qcsrc/common/util.qc:1451 qcsrc/common/util.qc:1508
 #, c-format
 msgid "UPARROW"
-msgstr ""
+msgstr "СТРЕЛКА НАГОРЕ"
 
 #: qcsrc/common/util.qc:1452 qcsrc/common/util.qc:1503
 #, c-format
 msgid "DOWNARROW"
-msgstr ""
+msgstr "СТРЕЛКА НАДОЛУ"
 
 #: qcsrc/common/util.qc:1453 qcsrc/common/util.qc:1505
 #, c-format
 msgid "LEFTARROW"
-msgstr ""
+msgstr "СТРЕЛКА НАЛЯВО"
 
 #: qcsrc/common/util.qc:1454 qcsrc/common/util.qc:1506
 #, c-format
 msgid "RIGHTARROW"
-msgstr ""
+msgstr "СТРЕЛКА НАДЯСНО"
 
 #: qcsrc/common/util.qc:1456
 msgid "ALT"
@@ -4846,7 +4847,7 @@ msgstr ""
 
 #: qcsrc/common/util.qc:1477
 msgid "APOSTROPHE"
-msgstr ""
+msgstr "АПОСТРОФ"
 
 #: qcsrc/common/util.qc:1478
 msgid "BACKSLASH"
@@ -4878,7 +4879,7 @@ msgstr ""
 #: qcsrc/common/util.qc:1510
 #, c-format
 msgid "PERIOD"
-msgstr ""
+msgstr "ТОЧКА"
 
 #: qcsrc/common/util.qc:1512
 #, c-format
@@ -4898,17 +4899,17 @@ msgstr ""
 #: qcsrc/common/util.qc:1515
 #, c-format
 msgid "MINUS"
-msgstr ""
+msgstr "МИНУС"
 
 #: qcsrc/common/util.qc:1516
 #, c-format
 msgid "PLUS"
-msgstr ""
+msgstr "ПЛЮС"
 
 #: qcsrc/common/util.qc:1518
 #, c-format
 msgid "EQUALS"
-msgstr ""
+msgstr "РАВНО"
 
 #: qcsrc/common/util.qc:1523
 msgid "PRINTSCREEN"
@@ -4974,7 +4975,7 @@ msgstr ""
 #: qcsrc/common/util.qc:1546
 #, c-format
 msgid "START"
-msgstr ""
+msgstr "СТАРТ"
 
 #: qcsrc/common/util.qc:1547
 #, c-format
@@ -5060,7 +5061,7 @@ msgstr ""
 #: qcsrc/common/util.qc:1571
 #, c-format
 msgid "UP"
-msgstr ""
+msgstr "НАГОРЕ"
 
 #: qcsrc/common/util.qc:1572
 #, c-format
@@ -5543,7 +5544,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/credits.qc:158
 msgid "Bulgarian"
-msgstr ""
+msgstr "Български"
 
 #: qcsrc/menu/xonotic/credits.qc:165
 msgid "Chinese (China)"
@@ -5559,7 +5560,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/credits.qc:179
 msgid "Czech"
-msgstr ""
+msgstr "Чешки"
 
 #: qcsrc/menu/xonotic/credits.qc:184
 msgid "Dutch"
@@ -5575,19 +5576,19 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/credits.qc:201
 msgid "French"
-msgstr ""
+msgstr "Френски"
 
 #: qcsrc/menu/xonotic/credits.qc:209
 msgid "German"
-msgstr ""
+msgstr "Немски"
 
 #: qcsrc/menu/xonotic/credits.qc:220
 msgid "Greek"
-msgstr ""
+msgstr "Гръцки"
 
 #: qcsrc/menu/xonotic/credits.qc:226
 msgid "Hungarian"
-msgstr ""
+msgstr "Унгарски"
 
 #: qcsrc/menu/xonotic/credits.qc:230
 msgid "Irish"
@@ -5595,7 +5596,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/credits.qc:233
 msgid "Italian"
-msgstr ""
+msgstr "Италиански"
 
 #: qcsrc/menu/xonotic/credits.qc:239
 msgid "Kazakh"
@@ -5603,11 +5604,11 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/credits.qc:242
 msgid "Korean"
-msgstr ""
+msgstr "Корейски"
 
 #: qcsrc/menu/xonotic/credits.qc:246
 msgid "Polish"
-msgstr ""
+msgstr "Полски"
 
 #: qcsrc/menu/xonotic/credits.qc:254
 msgid "Portuguese"
@@ -5615,11 +5616,11 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/credits.qc:260
 msgid "Romanian"
-msgstr ""
+msgstr "Румънски"
 
 #: qcsrc/menu/xonotic/credits.qc:267
 msgid "Russian"
-msgstr ""
+msgstr "Руски"
 
 #: qcsrc/menu/xonotic/credits.qc:278
 msgid "Scottish Gaelic"
@@ -5627,11 +5628,11 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/credits.qc:281
 msgid "Serbian"
-msgstr ""
+msgstr "Сръбски"
 
 #: qcsrc/menu/xonotic/credits.qc:287
 msgid "Spanish"
-msgstr ""
+msgstr "Испански"
 
 #: qcsrc/menu/xonotic/credits.qc:298
 msgid "Swedish"
@@ -5639,7 +5640,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/credits.qc:302
 msgid "Ukrainian"
-msgstr ""
+msgstr "Украински"
 
 #: qcsrc/menu/xonotic/credits.qc:309
 msgid "Past Contributors"
@@ -6501,7 +6502,7 @@ msgstr "По подразбиране"
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:40
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
 msgid "Unlimited"
-msgstr ""
+msgstr "Неограничен"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:74
 msgid "Gametype"
@@ -7227,11 +7228,11 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc:142
 msgid "Previous"
-msgstr ""
+msgstr "Предходен"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc:145
 msgid "Next"
-msgstr ""
+msgstr "Следващ"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc:150
 msgid "Slide show"
@@ -7283,7 +7284,7 @@ msgstr "Държава"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:156
 msgid "Select language..."
-msgstr ""
+msgstr "Избери език..."
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:172
 msgid "Gender:"
@@ -9464,7 +9465,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/keybinder.qc:56
 msgid "reload"
-msgstr ""
+msgstr "презареждане"
 
 #: qcsrc/menu/xonotic/keybinder.qc:57
 msgid "drop weapon / throw nade"
@@ -9524,7 +9525,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/keybinder.qc:102
 msgid "Client"
-msgstr ""
+msgstr "Клиент"
 
 #: qcsrc/menu/xonotic/keybinder.qc:106 qcsrc/menu/xonotic/keybinder.qc:108
 msgid "enter console"
@@ -9782,51 +9783,51 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/statslist.qc:29
 msgid "January"
-msgstr ""
+msgstr "Януари"
 
 #: qcsrc/menu/xonotic/statslist.qc:30
 msgid "February"
-msgstr ""
+msgstr "Февруари"
 
 #: qcsrc/menu/xonotic/statslist.qc:31
 msgid "March"
-msgstr ""
+msgstr "Март"
 
 #: qcsrc/menu/xonotic/statslist.qc:32
 msgid "April"
-msgstr ""
+msgstr "Април"
 
 #: qcsrc/menu/xonotic/statslist.qc:33
 msgid "May"
-msgstr ""
+msgstr "Май"
 
 #: qcsrc/menu/xonotic/statslist.qc:34
 msgid "June"
-msgstr ""
+msgstr "Юни"
 
 #: qcsrc/menu/xonotic/statslist.qc:35
 msgid "July"
-msgstr ""
+msgstr "Юли"
 
 #: qcsrc/menu/xonotic/statslist.qc:36
 msgid "August"
-msgstr ""
+msgstr "Август"
 
 #: qcsrc/menu/xonotic/statslist.qc:37
 msgid "September"
-msgstr ""
+msgstr "Септември"
 
 #: qcsrc/menu/xonotic/statslist.qc:38
 msgid "October"
-msgstr ""
+msgstr "Октомври"
 
 #: qcsrc/menu/xonotic/statslist.qc:39
 msgid "November"
-msgstr ""
+msgstr "Ноември"
 
 #: qcsrc/menu/xonotic/statslist.qc:40
 msgid "December"
-msgstr ""
+msgstr "Декември"
 
 #: qcsrc/menu/xonotic/statslist.qc:46
 #, no-c-format
index 7ae9769891b877aeec3dbbb4026f15854d97143a..d54fca51513842c4622af67339d135a6ac27b436 100644 (file)
@@ -11,7 +11,7 @@ msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2020-06-07 07:23+0200\n"
-"PO-Revision-Date: 2020-07-24 22:50+0000\n"
+"PO-Revision-Date: 2020-07-31 22:16+0000\n"
 "Last-Translator: LegendGuard\n"
 "Language-Team: Catalan (http://www.transifex.com/team-xonotic/xonotic/"
 "language/ca/)\n"
@@ -935,28 +935,39 @@ msgid ""
 "or in all but these game types. You can also specify 'all' as a\n"
 "field to show all fields available for the current game mode."
 msgstr ""
+"Després d'un camp pots posar un signe + o -, i després una llista de \n"
+"tipus de joc separats per comes, després una barra diagonal, per fer \n"
+"que el camp es mostri només en aquests o en tots menys en aquests \n"
+"tipus de jocs. També pots especificar 'all' com a camp per a mostrar \n"
+"tots els camps disponibles per a la manera de joc actual."
 
 #: qcsrc/client/hud/panel/scoreboard.qc:350
 msgid ""
 "The special game type names 'teams' and 'noteams' can be used to\n"
 "include/exclude ALL teams/noteams game modes."
 msgstr ""
+"Els noms especials de tipus de joc 'teams' i 'noteams' poden ser \n"
+"utilitzats per a incloure/excloure TOTS els modes de joc teams/noteams."
 
 #: qcsrc/client/hud/panel/scoreboard.qc:354
 msgid "Example: scoreboard_columns_set name ping pl | +ctf/field3 -dm/field4"
-msgstr ""
+msgstr "Exemple: scoreboard_columns_set name ping pl | +ctf/field3 -dm/field4"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:355
 msgid ""
 "will display name, ping and pl aligned to the left, and the fields\n"
 "right of the vertical bar aligned to the right."
 msgstr ""
+"mostrarà el nom, ping i pl alineats a l'esquerra, i els camps a la \n"
+"dreta de la barra vertical alineada a la dreta."
 
 #: qcsrc/client/hud/panel/scoreboard.qc:357
 msgid ""
 "'field3' will only be shown in CTF, and 'field4' will be shown in all\n"
 "other gamemodes except DM."
 msgstr ""
+"'field3' només serà mostrat en CTF, i 'field4' serà mostrat en tots \n"
+"els altres modes de joc excepte DM."
 
 #: qcsrc/client/hud/panel/scoreboard.qc:621
 #: qcsrc/client/hud/panel/scoreboard.qc:628
@@ -968,81 +979,81 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:164
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:169
 msgid "N/A"
-msgstr ""
+msgstr "N/A"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1206
 #, c-format
 msgid "Accuracy stats (average %d%%)"
-msgstr ""
+msgstr "Estadístiques de precisió (mitjana %d%%)"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1354
 msgid "Map stats:"
-msgstr ""
+msgstr "Estadístiques de mapa:"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1384
 msgid "Monsters killed:"
-msgstr ""
+msgstr "Monstres assassinats:"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1391
 msgid "Secrets found:"
-msgstr ""
+msgstr "Secrets trobats:"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1413
 msgid "Capture time rankings"
-msgstr ""
+msgstr "Classificacions de temps de captura"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1413
 msgid "Rankings"
-msgstr ""
+msgstr "Classificacions"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1631
 #, c-format
 msgid "^3%1.0f minutes"
-msgstr ""
+msgstr "^3%1.0f minuts"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1640
 #: qcsrc/client/hud/panel/scoreboard.qc:1647
 #, c-format
 msgid "^5%s %s"
-msgstr ""
+msgstr "^5%s %s"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1641
 #: qcsrc/client/hud/panel/scoreboard.qc:1648
 #: qcsrc/client/hud/panel/scoreboard.qc:1667
 #: qcsrc/client/hud/panel/scoreboard.qc:1674
 msgid "SCO^points"
-msgstr ""
+msgstr "punts"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1666
 #: qcsrc/client/hud/panel/scoreboard.qc:1673
 #, c-format
 msgid "^2+%s %s"
-msgstr ""
+msgstr "^2+%s %s"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1684
 #, c-format
 msgid "^7Map: ^2%s"
-msgstr ""
+msgstr "^7Mapa: ^2%s"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1823
 #, c-format
 msgid "Speed award: %d%s ^7(%s^7)"
-msgstr ""
+msgstr "Premi de velocitat: %d%s ^7(%s^7)"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1827
 #, c-format
 msgid "All-time fastest: %d%s ^7(%s^7)"
-msgstr ""
+msgstr "El més ràpid de tots els temps: %d%s ^7(%s^7)"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1843
 #, c-format
 msgid "Spectators"
-msgstr ""
+msgstr "Espectadors"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1870
 #, c-format
 msgid "^1Respawning in ^3%s^1..."
-msgstr ""
+msgstr "^1Reapareixent en ^3%s^1..."
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1880
 #, c-format
diff --git a/common.da.po b/common.da.po
new file mode 100644 (file)
index 0000000..9633001
--- /dev/null
@@ -0,0 +1,9835 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: Xonotic\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2020-06-07 07:23+0200\n"
+"PO-Revision-Date: 2013-09-12 16:53+0000\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: Danish (http://www.transifex.com/team-xonotic/xonotic/"
+"language/da/)\n"
+"Language: da\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: qcsrc/client/hud/hud_config.qc:81
+#, c-format
+msgid "^2Successfully exported to %s! (Note: It's saved in data/data/)"
+msgstr ""
+
+#: qcsrc/client/hud/hud_config.qc:85
+#, c-format
+msgid "^1Couldn't write to %s"
+msgstr ""
+
+#: qcsrc/client/hud/panel/centerprint.qc:174
+#, c-format
+msgid "^3Countdown message at time %s, seconds left: ^COUNT"
+msgstr ""
+
+#: qcsrc/client/hud/panel/centerprint.qc:176
+#, c-format
+msgid ""
+"^1Multiline message at time %s that\n"
+"^1lasts longer than normal"
+msgstr ""
+
+#: qcsrc/client/hud/panel/centerprint.qc:178
+#, c-format
+msgid "Message at time %s"
+msgstr ""
+
+#: qcsrc/client/hud/panel/centerprint.qc:183
+msgid "Generic message"
+msgstr ""
+
+#: qcsrc/client/hud/panel/chat.qc:89
+msgid "^3Player^7: This is the chat area."
+msgstr ""
+
+#: qcsrc/client/hud/panel/engineinfo.qc:76
+#, c-format
+msgid "FPS: %.*f"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:95
+msgid "^1Observing"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:97
+#, c-format
+msgid "^1Spectating: ^7%s"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:108
+#, c-format
+msgid "^1Press ^3%s^1 to spectate"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:108
+#: qcsrc/menu/xonotic/keybinder.qc:47
+msgid "primary fire"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:110
+#, c-format
+msgid "^1Press ^3%s^1 or ^3%s^1 for next or previous player"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:110
+#: qcsrc/client/hud/panel/infomessages.qc:114
+msgid "next weapon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:110
+#: qcsrc/client/hud/panel/infomessages.qc:114
+msgid "previous weapon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:114
+#, c-format
+msgid "^1Use ^3%s^1 or ^3%s^1 to change the speed"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:116
+#, c-format
+msgid "^1Press ^3%s^1 to observe, ^3%s^1 to change camera mode"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:116
+#: qcsrc/common/vehicles/cl_vehicles.qc:190
+msgid "drop weapon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:116
+#: qcsrc/menu/xonotic/keybinder.qc:48
+msgid "secondary fire"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:119
+#, c-format
+msgid "^1Press ^3%s^1 for gamemode info"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:119
+#: qcsrc/menu/xonotic/keybinder.qc:103
+msgid "server info"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:132
+msgid "^1Match has already begun"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:134
+msgid "^1You have no more lives left"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:136
+#: qcsrc/client/hud/panel/infomessages.qc:139
+#, c-format
+msgid "^1Press ^3%s^1 to join"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:136
+#: qcsrc/client/hud/panel/infomessages.qc:139
+#: qcsrc/common/notifications/all.qh:430
+msgid "jump"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:147
+#, c-format
+msgid "^1Game starts in ^3%d^1 seconds"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:153
+msgid "^2Currently in ^1warmup^2 stage!"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:168
+#, c-format
+msgid "%sPress ^3%s%s to end warmup"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:168
+#: qcsrc/client/hud/panel/infomessages.qc:170
+#: qcsrc/client/hud/panel/infomessages.qc:183
+#: qcsrc/menu/xonotic/keybinder.qc:99
+msgid "ready"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:170
+#, c-format
+msgid "%sPress ^3%s%s once you are ready"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:175
+msgid "^2Waiting for others to ready up to end warmup..."
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:177
+msgid "^2Waiting for others to ready up..."
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:183
+#, c-format
+msgid "^2Press ^3%s^2 to end warmup"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:204
+msgid "Teamnumbers are unbalanced!"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:207
+#, c-format
+msgid " Press ^3%s%s to adjust"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:207
+#: qcsrc/menu/xonotic/keybinder.qc:115
+msgid "team menu"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:217
+msgid "^1Spectating this player:"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:217
+msgid "^1Spectating you:"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:233
+msgid "^7Press ^3ESC ^7to show HUD options."
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:234
+msgid "^3Doubleclick ^7a panel for panel-specific options."
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:235
+msgid "^3CTRL ^7to disable collision testing, ^3SHIFT ^7and"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:236
+msgid "^3ALT ^7+ ^3ARROW KEYS ^7for fine adjustments."
+msgstr ""
+
+#: qcsrc/client/hud/panel/modicons.qc:183
+msgid "Personal best"
+msgstr ""
+
+#: qcsrc/client/hud/panel/modicons.qc:193
+msgid "Server best"
+msgstr ""
+
+#: qcsrc/client/hud/panel/notify.qc:127 qcsrc/client/hud/panel/notify.qc:128
+#: qcsrc/client/hud/panel/score.qc:69
+#, c-format
+msgid "Player %d"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:597
+#: qcsrc/client/hud/panel/quickmenu.qc:599
+#, c-format
+msgid "Submenu%d"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:604
+#, c-format
+msgid "Command%d"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:630
+msgid "Continue..."
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:787
+#: qcsrc/client/hud/panel/quickmenu.qc:794
+msgid "Chat"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:788
+msgid "QMCMD^Send public message to"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:789
+msgid "QMCMD^:-) / nice one"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:789
+msgid "QMCMD^nice one"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:790
+msgid "QMCMD^good game"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:791
+msgid "QMCMD^hi / good luck"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:791
+msgid "QMCMD^hi / good luck and have fun"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:793
+msgid "QMCMD^Send in English"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:798
+#: qcsrc/client/hud/panel/quickmenu.qc:814
+msgid "QMCMD^Team chat"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:799
+msgid "QMCMD^strength soon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:800
+msgid "QMCMD^free item %x^7 (l:%y^7)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:800
+msgid "QMCMD^free item, icon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:801
+msgid "QMCMD^took item (l:%l^7)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:801
+msgid "QMCMD^took item, icon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:802
+msgid "QMCMD^negative"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:803
+msgid "QMCMD^positive"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:804
+msgid "QMCMD^need help (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:804
+msgid "QMCMD^need help, icon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:805
+msgid "QMCMD^enemy seen (l:%y^7)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:805
+msgid "QMCMD^enemy seen, icon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:806
+msgid "QMCMD^flag seen (l:%y^7)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:806
+msgid "QMCMD^flag seen, icon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:807
+msgid "QMCMD^defending (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:807
+msgid "QMCMD^defending, icon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:808
+msgid "QMCMD^roaming (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:808
+msgid "QMCMD^roaming, icon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:809
+msgid "QMCMD^attacking (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:809
+msgid "QMCMD^attacking, icon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:810
+msgid "QMCMD^killed flagcarrier (l:%y^7)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:810
+msgid "QMCMD^killed flagcarrier, icon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:811
+#, c-format
+msgid "QMCMD^dropped flag (l:%d^7)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:811
+msgid "QMCMD^dropped flag, icon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:812
+msgid "QMCMD^drop weapon, icon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:812
+msgid "QMCMD^dropped weapon %w^7 (l:%l^7)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:813
+msgid "QMCMD^drop flag/key, icon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:813
+msgid "QMCMD^dropped flag/key %w^7 (l:%l^7)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:817
+msgid "QMCMD^Send private message to"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:819
+#: qcsrc/client/hud/panel/quickmenu.qc:849
+msgid "QMCMD^Settings"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:820
+#: qcsrc/client/hud/panel/quickmenu.qc:827
+msgid "QMCMD^View/HUD settings"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:821
+msgid "QMCMD^3rd person view"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:822
+msgid "QMCMD^Player models like mine"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:823
+msgid "QMCMD^Names above players"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:824
+msgid "QMCMD^Crosshair per weapon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:825
+msgid "QMCMD^FPS"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:826
+msgid "QMCMD^Net graph"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:829
+#: qcsrc/client/hud/panel/quickmenu.qc:832
+msgid "QMCMD^Sound settings"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:830
+msgid "QMCMD^Hit sound"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:831
+msgid "QMCMD^Chat sound"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:836
+msgid "QMCMD^Change spectator camera"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:841
+#: qcsrc/client/hud/panel/quickmenu.qc:845
+msgid "QMCMD^Observer camera"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:842
+msgid "QMCMD^Increase speed"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:843
+msgid "QMCMD^Decrease speed"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:844
+msgid "QMCMD^Wall collision"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:848
+msgid "QMCMD^Fullscreen"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:851
+#: qcsrc/client/hud/panel/quickmenu.qc:861
+msgid "QMCMD^Call a vote"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:852
+msgid "QMCMD^Restart the map"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:853
+msgid "QMCMD^End match"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:856
+msgid "QMCMD^Reduce match time"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:857
+msgid "QMCMD^Extend match time"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:860
+msgid "QMCMD^Shuffle teams"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:865
+msgid "QMCMD^Spectate a player"
+msgstr ""
+
+#: qcsrc/client/hud/panel/racetimer.qc:59
+#, c-format
+msgid " (-%dL)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/racetimer.qc:64
+#, c-format
+msgid " (+%dL)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/racetimer.qc:83
+msgid "Start line"
+msgstr ""
+
+#: qcsrc/client/hud/panel/racetimer.qc:85
+#: qcsrc/client/hud/panel/racetimer.qc:89
+msgid "Finish line"
+msgstr ""
+
+#: qcsrc/client/hud/panel/racetimer.qc:87
+#: qcsrc/client/hud/panel/racetimer.qc:156
+#, c-format
+msgid "Intermediate %d"
+msgstr ""
+
+#: qcsrc/client/hud/panel/racetimer.qc:159
+#: qcsrc/client/hud/panel/racetimer.qc:206
+#: qcsrc/client/hud/panel/racetimer.qc:267
+#, c-format
+msgid "PENALTY: %.1f (%s)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/racetimer.qc:159 qcsrc/client/main.qc:1102
+msgid "missing a checkpoint"
+msgstr ""
+
+#: qcsrc/client/hud/panel/radar.qc:386
+msgid "Click to select teleport destination"
+msgstr ""
+
+#: qcsrc/client/hud/panel/radar.qc:390
+msgid "Click to select spawn location"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:105
+msgid "Number of ball carrier kills"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:105
+msgid "SCO^bckills"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:106
+msgid "SCO^bctime"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:106
+msgid "Total amount of time holding the ball in Keepaway"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:107
+msgid "How often a flag (CTF) or a key (KeyHunt) was captured"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:107
+msgid "SCO^caps"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:108
+msgid "SCO^captime"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:108
+msgid "Time of fastest capture (CTF)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:109
+msgid "Number of deaths"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:109
+msgid "SCO^deaths"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:110
+msgid "Number of keys destroyed by pushing them into void"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:110
+msgid "SCO^destroyed"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:111
+msgid "SCO^damage"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:111
+msgid "The total damage done"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:112
+msgid "SCO^dmgtaken"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:112
+msgid "The total damage taken"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:113
+msgid "Number of flag drops"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:113
+msgid "SCO^drops"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:114
+msgid "Player ELO"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:114
+msgid "SCO^elo"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:115
+msgid "SCO^fastest"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:115
+msgid "Time of fastest lap (Race/CTS)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:116
+msgid "Number of faults committed"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:116
+msgid "SCO^faults"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:117
+msgid "Number of flag carrier kills"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:117
+msgid "SCO^fckills"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:118
+msgid "FPS"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:118
+msgid "SCO^fps"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:119
+msgid "Number of kills minus suicides"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:119
+msgid "SCO^frags"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:120
+msgid "Number of goals scored"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:120
+msgid "SCO^goals"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:121
+msgid "Number of keys carrier kills"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:121
+msgid "SCO^kckills"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:122
+msgid "SCO^k/d"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:122
+#: qcsrc/client/hud/panel/scoreboard.qc:123
+#: qcsrc/client/hud/panel/scoreboard.qc:124
+msgid "The kill-death ratio"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:123
+msgid "SCO^kdr"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:124
+msgid "SCO^kdratio"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:125
+msgid "Number of kills"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:125
+msgid "SCO^kills"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:126
+msgid "Number of laps finished (Race/CTS)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:126
+msgid "SCO^laps"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:127
+msgid "Number of lives (LMS)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:127
+msgid "SCO^lives"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:128
+msgid "Number of times a key was lost"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:128
+msgid "SCO^losses"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:129
+#: qcsrc/client/hud/panel/scoreboard.qc:130
+msgid "Player name"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:129
+msgid "SCO^name"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:130
+msgid "SCO^nick"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:131
+msgid "Number of objectives destroyed"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:131
+msgid "SCO^objectives"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:132
+msgid ""
+"How often a flag (CTF) or a key (KeyHunt) or a ball (Keepaway) was picked up"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:132
+msgid "SCO^pickups"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:133
+msgid "Ping time"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:133
+msgid "SCO^ping"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:134
+msgid "Packet loss"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:134
+msgid "SCO^pl"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:135
+msgid "Number of players pushed into void"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:135
+msgid "SCO^pushes"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:136
+msgid "Player rank"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:136
+msgid "SCO^rank"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:137
+msgid "Number of flag returns"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:137
+msgid "SCO^returns"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:138
+msgid "Number of revivals"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:138
+msgid "SCO^revivals"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:139
+msgid "Number of rounds won"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:139
+msgid "SCO^rounds won"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:140
+msgid "SCO^score"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:140
+msgid "Total score"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:141
+msgid "Number of suicides"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:141
+msgid "SCO^suicides"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:142
+msgid "Number of kills minus deaths"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:142
+msgid "SCO^sum"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:143
+msgid "Number of domination points taken (Domination)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:143
+msgid "SCO^takes"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:144
+msgid "Number of teamkills"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:144
+msgid "SCO^teamkills"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:145
+msgid "Number of ticks (Domination)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:145
+msgid "SCO^ticks"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:146
+msgid "SCO^time"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:146
+msgid "Total time raced (Race/CTS)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:330
+msgid ""
+"You can modify the scoreboard using the ^2scoreboard_columns_set command."
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:331
+msgid "Usage:"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:333
+msgid "^2scoreboard_columns_set ^3field1 field2 ..."
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:334
+msgid ""
+"^2scoreboard_columns_set ^7without arguments reads the arguments from the "
+"cvar scoreboard_columns"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:335
+msgid ""
+"  ^5Note: ^7scoreboard_columns_set without arguments is executed on every "
+"map start"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:336
+msgid ""
+"^2scoreboard_columns_set ^3expand_default ^7loads default layout and expands "
+"it into the cvar scoreboard_columns so you can edit it"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:337
+msgid "You can use a ^3|^7 to start the right-aligned fields."
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:338
+msgid "The following field names are recognized (case insensitive):"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:344
+msgid ""
+"Before a field you can put a + or - sign, then a comma separated list\n"
+"of game types, then a slash, to make the field show up only in these\n"
+"or in all but these game types. You can also specify 'all' as a\n"
+"field to show all fields available for the current game mode."
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:350
+msgid ""
+"The special game type names 'teams' and 'noteams' can be used to\n"
+"include/exclude ALL teams/noteams game modes."
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:354
+msgid "Example: scoreboard_columns_set name ping pl | +ctf/field3 -dm/field4"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:355
+msgid ""
+"will display name, ping and pl aligned to the left, and the fields\n"
+"right of the vertical bar aligned to the right."
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:357
+msgid ""
+"'field3' will only be shown in CTF, and 'field4' will be shown in all\n"
+"other gamemodes except DM."
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:621
+#: qcsrc/client/hud/panel/scoreboard.qc:628
+#: qcsrc/client/hud/panel/scoreboard.qc:680
+#: qcsrc/client/hud/panel/scoreboard.qc:691
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:46
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:47
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:164
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:169
+msgid "N/A"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1206
+#, c-format
+msgid "Accuracy stats (average %d%%)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1354
+msgid "Map stats:"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1384
+msgid "Monsters killed:"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1391
+msgid "Secrets found:"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1413
+msgid "Capture time rankings"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1413
+msgid "Rankings"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1631
+#, c-format
+msgid "^3%1.0f minutes"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1640
+#: qcsrc/client/hud/panel/scoreboard.qc:1647
+#, c-format
+msgid "^5%s %s"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1641
+#: qcsrc/client/hud/panel/scoreboard.qc:1648
+#: qcsrc/client/hud/panel/scoreboard.qc:1667
+#: qcsrc/client/hud/panel/scoreboard.qc:1674
+msgid "SCO^points"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1666
+#: qcsrc/client/hud/panel/scoreboard.qc:1673
+#, c-format
+msgid "^2+%s %s"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1684
+#, c-format
+msgid "^7Map: ^2%s"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1823
+#, c-format
+msgid "Speed award: %d%s ^7(%s^7)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1827
+#, c-format
+msgid "All-time fastest: %d%s ^7(%s^7)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1843
+#, c-format
+msgid "Spectators"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1870
+#, c-format
+msgid "^1Respawning in ^3%s^1..."
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1880
+#, c-format
+msgid "You are dead, wait ^3%s^7 before respawning"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1889
+#, c-format
+msgid "You are dead, press ^2%s^7 to respawn"
+msgstr ""
+
+#: qcsrc/client/hud/panel/timer.qc:72
+msgid "WARMUP"
+msgstr ""
+
+#: qcsrc/client/hud/panel/vote.qc:33
+msgid "^1You must answer before entering hud configure mode"
+msgstr ""
+
+#: qcsrc/client/hud/panel/vote.qc:36
+msgid "^2Name ^7instead of \"^1Anonymous player^7\" in stats"
+msgstr ""
+
+#: qcsrc/client/hud/panel/vote.qc:122
+msgid "A vote has been called for:"
+msgstr ""
+
+#: qcsrc/client/hud/panel/vote.qc:124
+msgid "Allow servers to store and display your name?"
+msgstr ""
+
+#: qcsrc/client/hud/panel/vote.qc:128
+msgid "^1Configure the HUD"
+msgstr ""
+
+#: qcsrc/client/hud/panel/vote.qc:132
+#: qcsrc/menu/xonotic/dialog_disconnect.qc:19
+#: qcsrc/menu/xonotic/dialog_firstrun.qc:82
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qc:18
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qc:18
+#: qcsrc/menu/xonotic/dialog_quit.qc:14
+#: qcsrc/menu/xonotic/dialog_settings_bindings_reset.qc:14
+#: qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qc:26
+#: qcsrc/menu/xonotic/dialog_settings_misc_reset.qc:16
+#: qcsrc/menu/xonotic/dialog_uid2name.qc:15
+msgid "Yes"
+msgstr ""
+
+#: qcsrc/client/hud/panel/vote.qc:134
+#: qcsrc/menu/xonotic/dialog_disconnect.qc:22
+#: qcsrc/menu/xonotic/dialog_firstrun.qc:83
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qc:21
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qc:21
+#: qcsrc/menu/xonotic/dialog_quit.qc:16
+#: qcsrc/menu/xonotic/dialog_settings_bindings_reset.qc:17
+#: qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc_reset.qc:17
+#: qcsrc/menu/xonotic/dialog_uid2name.qc:17
+msgid "No"
+msgstr ""
+
+#: qcsrc/client/hud/panel/weapons.qc:584
+msgid "Out of ammo"
+msgstr ""
+
+#: qcsrc/client/hud/panel/weapons.qc:588
+msgid "Don't have"
+msgstr ""
+
+#: qcsrc/client/hud/panel/weapons.qc:592
+msgid "Unavailable"
+msgstr ""
+
+#: qcsrc/client/main.qc:1000
+msgid " qu/s"
+msgstr ""
+
+#: qcsrc/client/main.qc:1002
+msgid " m/s"
+msgstr ""
+
+#: qcsrc/client/main.qc:1004
+msgid " km/h"
+msgstr ""
+
+#: qcsrc/client/main.qc:1006
+msgid " mph"
+msgstr ""
+
+#: qcsrc/client/main.qc:1008
+msgid " knots"
+msgstr ""
+
+#: qcsrc/client/main.qc:1255
+#, c-format
+msgid "%s (not bound)"
+msgstr ""
+
+#: qcsrc/client/mapvoting.qc:59
+msgid " (1 vote)"
+msgstr ""
+
+#: qcsrc/client/mapvoting.qc:61
+#, c-format
+msgid " (%d votes)"
+msgstr ""
+
+#: qcsrc/client/mapvoting.qc:281
+msgid "Don't care"
+msgstr ""
+
+#: qcsrc/client/mapvoting.qc:382
+msgid "Decide the gametype"
+msgstr ""
+
+#: qcsrc/client/mapvoting.qc:382
+msgid "Vote for a map"
+msgstr ""
+
+#: qcsrc/client/mapvoting.qc:399
+#, c-format
+msgid "%d seconds left"
+msgstr ""
+
+#: qcsrc/client/mapvoting.qc:512
+msgid "mv_mapdownload: ^3You're not supposed to use this command on your own!"
+msgstr ""
+
+#: qcsrc/client/mapvoting.qc:522
+msgid "^1Error:^7 Couldn't find pak index."
+msgstr ""
+
+#: qcsrc/client/mapvoting.qc:531
+msgid "Requesting preview..."
+msgstr ""
+
+#: qcsrc/client/miscfunctions.qc:111
+msgid "Trying to remove a team which is not in the teamlist!"
+msgstr ""
+
+#: qcsrc/client/view.qc:939
+msgid "Nade timer"
+msgstr ""
+
+#: qcsrc/client/view.qc:944
+msgid "Capture progress"
+msgstr ""
+
+#: qcsrc/client/view.qc:949
+msgid "Revival progress"
+msgstr ""
+
+#: qcsrc/common/command/generic.qc:156
+msgid "error creating curl handle"
+msgstr ""
+
+#: qcsrc/common/command/generic.qc:412
+msgid "Notification restart command only works with cl_cmd and sv_cmd."
+msgstr ""
+
+#: qcsrc/common/gamemodes/gamemode/nexball/weapon.qh:7
+msgid "Ball Stealer"
+msgstr ""
+
+#: qcsrc/common/items/item/ammo.qh:66
+msgid "bullets"
+msgstr ""
+
+#: qcsrc/common/items/item/ammo.qh:96
+msgid "cells"
+msgstr ""
+
+#: qcsrc/common/items/item/ammo.qh:126
+msgid "plasma"
+msgstr ""
+
+#: qcsrc/common/items/item/ammo.qh:156
+msgid "rockets"
+msgstr ""
+
+#: qcsrc/common/items/item/ammo.qh:190
+msgid "shells"
+msgstr ""
+
+#: qcsrc/common/items/item/armor.qh:42
+msgid "Small armor"
+msgstr ""
+
+#: qcsrc/common/items/item/armor.qh:80
+msgid "Medium armor"
+msgstr ""
+
+#: qcsrc/common/items/item/armor.qh:118 qcsrc/common/items/item/armor.qh:121
+msgid "Big armor"
+msgstr ""
+
+#: qcsrc/common/items/item/armor.qh:158 qcsrc/common/items/item/armor.qh:161
+msgid "Mega armor"
+msgstr ""
+
+#: qcsrc/common/items/item/health.qh:42
+msgid "Small health"
+msgstr ""
+
+#: qcsrc/common/items/item/health.qh:80
+msgid "Medium health"
+msgstr ""
+
+#: qcsrc/common/items/item/health.qh:118 qcsrc/common/items/item/health.qh:121
+msgid "Big health"
+msgstr ""
+
+#: qcsrc/common/items/item/health.qh:158 qcsrc/common/items/item/health.qh:161
+msgid "Mega health"
+msgstr ""
+
+#: qcsrc/common/items/item/jetpack.qh:38 qcsrc/common/items/item/jetpack.qh:41
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:91
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:215
+msgid "Jetpack"
+msgstr ""
+
+#: qcsrc/common/items/item/jetpack.qh:71
+msgid "fuel"
+msgstr ""
+
+#: qcsrc/common/items/item/jetpack.qh:96
+msgid "Fuel regenerator"
+msgstr ""
+
+#: qcsrc/common/items/item/jetpack.qh:99
+msgid "Fuel regen"
+msgstr ""
+
+#: qcsrc/common/items/item/powerup.qh:43 qcsrc/common/items/item/powerup.qh:46
+msgid "Strength"
+msgstr ""
+
+#: qcsrc/common/items/item/powerup.qh:79 qcsrc/common/items/item/powerup.qh:82
+msgid "Shield"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qc:626
+#, no-c-format
+msgid "@!#%'n Tuba Throwing"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:72 qcsrc/common/mapinfo.qh:334
+#: qcsrc/common/mapinfo.qh:529
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+msgid "Frag limit:"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:72 qcsrc/common/mapinfo.qh:334
+#: qcsrc/common/mapinfo.qh:529
+msgid "The amount of frags needed before the match will end"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:115
+msgid "Deathmatch"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:115
+msgid "Score as many frags as you can"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:128
+msgid "Last Man Standing"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:128
+msgid "Survive and kill until the enemies have no lives left"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:137
+msgid "Lives:"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:149
+msgid "Race"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:149
+msgid "Race against other players to the finish line"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:176
+msgid "Laps:"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:189
+msgid "Race CTS"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:189
+msgid "Race for fastest time."
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:206 qcsrc/common/mapinfo.qh:257
+#: qcsrc/common/mapinfo.qh:373 qcsrc/common/mapinfo.qh:416
+#: qcsrc/common/mapinfo.qh:442 qcsrc/common/mapinfo.qh:462
+#: qcsrc/common/mapinfo.qh:582
+msgid "Point limit:"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:219
+msgid "Help your team score the most frags against the enemy team"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:219
+msgid "Team Deathmatch"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:257 qcsrc/common/mapinfo.qh:373
+#: qcsrc/common/mapinfo.qh:416
+msgid "The amount of points needed before the match will end"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:271
+msgid "Capture the Flag"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:271
+msgid ""
+"Find and bring the enemy flag to your base to capture it, defend your base "
+"from the other team"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:289
+msgid "Capture limit:"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:289
+msgid "The amount of captures needed before the match will end"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:306
+msgid "Clan Arena"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:306
+msgid "Kill all enemy teammates to win the round"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:350
+msgid "Capture and defend all the control points to win"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:350
+msgid "Domination"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:388
+msgid "Gather all the keys to win the round"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:388
+msgid "Key Hunt"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:428
+msgid "Assault"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:428
+msgid ""
+"Destroy obstacles to find and destroy the enemy power core before time runs "
+"out"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:452
+msgid "Capture control points to reach and destroy the enemy generator"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:452
+msgid "Onslaught"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:474
+msgid "Nexball"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:474
+msgid "Shoot and kick the ball into the enemies goal, keep your goal clean"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:488
+msgid "Goals:"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:488
+msgid "The amount of goals needed before the match will end"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:501
+msgid "Freeze Tag"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:501
+msgid ""
+"Kill enemies to freeze them, stand next to frozen teammates to revive them; "
+"freeze all enemies to win"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:545
+msgid "Hold the ball to get points for kills"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:545
+msgid "Keepaway"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:560
+msgid "Invasion"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:560
+msgid "Survive against waves of monsters"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:590
+msgid "Duel"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:590
+msgid "Fight in a one versus one arena battle to decide the winner"
+msgstr ""
+
+#: qcsrc/common/minigames/cl_minigames.qc:383
+msgid "It's your turn"
+msgstr ""
+
+#: qcsrc/common/minigames/cl_minigames_hud.qc:366
+#: qcsrc/menu/xonotic/dialog_quit.qh:6
+msgid "Quit"
+msgstr ""
+
+#: qcsrc/common/minigames/cl_minigames_hud.qc:371
+msgid "Invite"
+msgstr ""
+
+#: qcsrc/common/minigames/cl_minigames_hud.qc:410
+msgid "Current Game"
+msgstr ""
+
+#: qcsrc/common/minigames/cl_minigames_hud.qc:435
+msgid "Exit Menu"
+msgstr ""
+
+#: qcsrc/common/minigames/cl_minigames_hud.qc:447
+#: qcsrc/menu/xonotic/dialog_multiplayer.qc:16
+msgid "Create"
+msgstr ""
+
+#: qcsrc/common/minigames/cl_minigames_hud.qc:450
+msgid "Join"
+msgstr ""
+
+#: qcsrc/common/minigames/cl_minigames_hud.qc:526
+msgid "Minigames"
+msgstr ""
+
+#: qcsrc/common/minigames/cl_minigames_hud.qc:587
+msgid "Minigame message"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/bd.qc:2
+msgid "Bulldozer"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/bd.qc:1092
+#: qcsrc/common/minigames/minigame/ps.qc:421
+#: qcsrc/common/minigames/minigame/ps.qc:427
+msgid "Game over!"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/bd.qc:1095
+msgid "Well done! Click 'Next Level' to continue"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/bd.qc:1162
+msgid "Better luck next time!"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/bd.qc:1167
+msgid "Tubular! Press \"Next Level\" to continue!"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/bd.qc:1169
+msgid "Wicked! Press \"Next Level\" to continue!"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/bd.qc:1173
+msgid "Press the space bar to change your currently selected tile"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/bd.qc:1176
+msgid "Push the boulders onto the targets"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/bd.qc:1403
+msgid "Next Level"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/bd.qc:1404
+msgid "Restart"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/bd.qc:1405
+msgid "Editor"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/bd.qc:1406
+#: qcsrc/menu/xonotic/dialog_settings_input_userbind.qc:37
+msgid "Save"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/c4.qc:2
+msgid "Connect Four"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/c4.qc:311
+#: qcsrc/common/minigames/minigame/c4.qc:317
+#: qcsrc/common/minigames/minigame/nmm.qc:491
+#: qcsrc/common/minigames/minigame/nmm.qc:497
+#: qcsrc/common/minigames/minigame/pp.qc:362
+#: qcsrc/common/minigames/minigame/pp.qc:368
+#, c-format
+msgid "%s^7 won the game!"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/c4.qc:373
+#: qcsrc/common/minigames/minigame/pp.qc:438
+#: qcsrc/common/minigames/minigame/ttt.qc:319
+msgid "Draw"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/c4.qc:378
+#: qcsrc/common/minigames/minigame/nmm.qc:606
+#: qcsrc/common/minigames/minigame/pp.qc:444
+#: qcsrc/common/minigames/minigame/ttt.qc:326
+msgid "You lost the game!"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/c4.qc:379
+#: qcsrc/common/minigames/minigame/nmm.qc:607
+#: qcsrc/common/minigames/minigame/pp.qc:445
+#: qcsrc/common/minigames/minigame/ttt.qc:327
+msgid "You win!"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/c4.qc:383
+#: qcsrc/common/minigames/minigame/nmm.qc:611
+#: qcsrc/common/minigames/minigame/pp.qc:456
+#: qcsrc/common/minigames/minigame/ttt.qc:338
+msgid "Wait for your opponent to make their move"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/c4.qc:386
+#: qcsrc/common/minigames/minigame/nmm.qc:613
+#: qcsrc/common/minigames/minigame/pp.qc:459
+#: qcsrc/common/minigames/minigame/ttt.qc:341
+msgid "Click on the game board to place your piece"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/nmm.qc:7
+msgid "Nine Men's Morris"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/nmm.qc:615
+msgid ""
+"You can select one of your pieces to move it in one of the surrounding places"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/nmm.qc:617
+msgid "You can select one of your pieces to move it anywhere on the board"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/nmm.qc:619
+msgid "You can take one of the opponent's pieces"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/pong.qc:2
+msgid "Pong"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/pong.qc:589
+#: qcsrc/common/minigames/minigame/ttt.qc:299
+msgid "AI"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/pong.qc:606
+msgid "Press ^1Start Match^7 to start the match with the current players"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/pong.qc:679
+msgid "Start Match"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/pong.qc:680
+msgid "Add AI player"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/pong.qc:681
+msgid "Remove AI player"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/pp.qc:2
+msgid "Push-Pull"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/pp.qc:444
+#: qcsrc/common/minigames/minigame/ttt.qc:326
+msgid "Select \"^1Next Match^7\" on the menu for a rematch!"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/pp.qc:445
+#: qcsrc/common/minigames/minigame/pp.qc:451
+#: qcsrc/common/minigames/minigame/ttt.qc:327
+#: qcsrc/common/minigames/minigame/ttt.qc:333
+msgid "Select \"^1Next Match^7\" on the menu to start a new match!"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/pp.qc:452
+#: qcsrc/common/minigames/minigame/ttt.qc:334
+msgid "Wait for your opponent to confirm the rematch"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/pp.qc:587
+#: qcsrc/common/minigames/minigame/ttt.qc:671
+msgid "Next Match"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/ps.qc:2
+msgid "Peg Solitaire"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/ps.qc:414
+msgid "All pieces cleared!"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/ps.qc:416
+msgid "Remaining pieces:"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/ps.qc:481
+#, c-format
+msgid "Pieces left: %s"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/ps.qc:491
+msgid "No more valid moves"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/ps.qc:494
+msgid "Well done, you win!"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/ps.qc:497
+msgid "Jump a piece over another to capture it"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/ttt.qc:2
+msgid "Tic Tac Toe"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/ttt.qc:672
+msgid "Single Player"
+msgstr ""
+
+#: qcsrc/common/monsters/monster/mage.qh:17
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:18
+msgid "Mage"
+msgstr ""
+
+#: qcsrc/common/monsters/monster/mage.qh:29
+msgid "Mage spike"
+msgstr ""
+
+#: qcsrc/common/monsters/monster/shambler.qh:17
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:17
+msgid "Shambler"
+msgstr ""
+
+#: qcsrc/common/monsters/monster/spider.qh:17
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:16
+msgid "Spider"
+msgstr ""
+
+#: qcsrc/common/monsters/monster/spider.qh:28
+msgid "Spider attack"
+msgstr ""
+
+#: qcsrc/common/monsters/monster/wyvern.qh:17
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:19
+msgid "Wyvern"
+msgstr ""
+
+#: qcsrc/common/monsters/monster/wyvern.qh:28
+msgid "Wyvern attack"
+msgstr ""
+
+#: qcsrc/common/monsters/monster/zombie.qh:17
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:15
+msgid "Zombie"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:16
+msgid "Ammo"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:25
+msgid "Resistance"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:34
+#: qcsrc/common/mutators/mutator/instagib/items.qh:126
+#: qcsrc/common/mutators/mutator/instagib/items.qh:129
+msgid "Speed"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:44
+msgid "Medic"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:54
+msgid "Bash"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:63
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:83
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:184
+msgid "Vampire"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:71
+msgid "Disability"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:79
+msgid "Vengeance"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:87
+msgid "Jump"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:96
+msgid "Invisible"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:105
+msgid "Inferno"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:113
+msgid "Swapper"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:121
+msgid "Magnet"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:129
+msgid "Luck"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:137
+msgid "Flight"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/buffs.qh:11
+msgid "Buff"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/damagetext/ui_damagetext.qc:8
+msgid "Damage text"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/damagetext/ui_damagetext.qc:18
+msgid "Draw damage numbers"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/damagetext/ui_damagetext.qc:20
+msgid "Font size minimum:"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/damagetext/ui_damagetext.qc:25
+msgid "Font size maximum:"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/damagetext/ui_damagetext.qc:30
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:55
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:102
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:60
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:109
+#: qcsrc/menu/xonotic/util.qc:775
+msgid "Color:"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/damagetext/ui_damagetext.qc:36
+msgid "Draw damage numbers for friendly fire"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/instagib/items.qh:33
+msgid "Vaporizer ammo"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/instagib/items.qh:59
+#: qcsrc/common/mutators/mutator/instagib/items.qh:62
+msgid "Extra life"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/instagib/items.qh:91
+#: qcsrc/common/mutators/mutator/instagib/items.qh:94
+msgid "Invisibility"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/nades/nades.inc:18
+msgid "Napalm grenade"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/nades/nades.inc:26
+msgid "Ice grenade"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/nades/nades.inc:34
+msgid "Translocate grenade"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/nades/nades.inc:42
+msgid "Spawn grenade"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/nades/nades.inc:50
+msgid "Heal grenade"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/nades/nades.inc:58
+msgid "Monster grenade"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/nades/nades.inc:66
+msgid "Entrap grenade"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/nades/nades.inc:74
+msgid "Veil grenade"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/nades/nades.qh:33
+msgid "Grenade"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/overkill/okhmg.qh:20
+msgid "Overkill Heavy Machine Gun"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/overkill/okmachinegun.qh:18
+msgid "Overkill MachineGun"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/overkill/oknex.qh:19
+msgid "Overkill Nex"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/overkill/okrpc.qh:20
+msgid "Overkill Rocket Propelled Chainsaw"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/overkill/okshotgun.qh:18
+msgid "Overkill Shotgun"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:3
+msgid "Waypoint"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:4
+msgid "Help me!"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:5
+msgid "Here"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:6
+msgid "DANGER"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:8
+msgid "Frozen!"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:10
+msgid "Item"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:12
+msgid "Checkpoint"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:13
+#: qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc:240
+msgid "Finish"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:14
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:15
+#: qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc:240
+msgid "Start"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:17
+msgid "Defend"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:18
+msgid "Destroy"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:19
+msgid "Push"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:21
+msgid "Flag carrier"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:22
+msgid "Enemy carrier"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:23
+msgid "Dropped flag"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:24
+msgid "White base"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:25
+msgid "Red base"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:26
+msgid "Blue base"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:27
+msgid "Yellow base"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:28
+msgid "Pink base"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:29
+msgid "Return flag here"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:31
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:32
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:33
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:34
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:35
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:51
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:52
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:53
+msgid "Control point"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:37
+msgid "Dropped key"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:38
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:40
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:41
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:42
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:43
+msgid "Key carrier"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:39
+msgid "Run here"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:45
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:48
+msgid "Ball"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:46
+msgid "Ball carrier"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:49
+msgid "Goal"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:54
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:55
+msgid "Generator"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:57
+msgid "Weapon"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:59
+msgid "Monster"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:61
+msgid "Vehicle"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:62
+msgid "Intruder!"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:64
+msgid "Tagged"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc:697
+#, c-format
+msgid "%s needing help!"
+msgstr ""
+
+#: qcsrc/common/net_notice.qc:90
+msgid "^1Server notices:"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:230
+msgid "^F4NOTE: ^BGSpectator chat is not sent to players during the match"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:232
+#, c-format
+msgid "^BG%s^BG captured the ^TC^TT^BG flag"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:233
+#, c-format
+msgid ""
+"^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds, breaking ^BG"
+"%s^BG's previous record of ^F2%s^BG seconds"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:234
+#, c-format
+msgid "^BG%s^BG captured the flag"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:235
+#, c-format
+msgid "^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:236
+#, c-format
+msgid ""
+"^BG%s^BG captured the ^TC^TT^BG flag in ^F2%s^BG seconds, failing to break "
+"^BG%s^BG's previous record of ^F1%s^BG seconds"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:237
+msgid "^BGThe ^TC^TT^BG flag was returned to base by its owner"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:238
+msgid "^BGThe flag was returned by its owner"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:239
+msgid "^BGThe ^TC^TT^BG flag was destroyed and returned to base"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:240
+msgid "^BGThe flag was destroyed and returned to base"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:241
+msgid "^BGThe ^TC^TT^BG flag was dropped in the base and returned itself"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:242
+msgid "^BGThe flag was dropped in the base and returned itself"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:243
+msgid ""
+"^BGThe ^TC^TT^BG flag fell somewhere it couldn't be reached and returned to "
+"base"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:244
+msgid "^BGThe flag fell somewhere it couldn't be reached and returned to base"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:245
+#, c-format
+msgid ""
+"^BGThe ^TC^TT^BG flag became impatient after ^F1%.2f^BG seconds and returned "
+"itself"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:246
+#, c-format
+msgid ""
+"^BGThe flag became impatient after ^F1%.2f^BG seconds and returned itself"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:247
+msgid "^BGThe ^TC^TT^BG flag has returned to the base"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:248
+msgid "^BGThe flag has returned to the base"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:249
+#, c-format
+msgid "^BG%s^BG lost the ^TC^TT^BG flag"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:250
+#, c-format
+msgid "^BG%s^BG lost the flag"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:251
+#, c-format
+msgid "^BG%s^BG got the ^TC^TT^BG flag"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:252
+#, c-format
+msgid "^BG%s^BG got the flag"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:253
+#: qcsrc/common/notifications/all.inc:254
+#, c-format
+msgid "^BG%s^BG returned the ^TC^TT^BG flag"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:256
+#: qcsrc/common/notifications/all.inc:544
+#, c-format
+msgid "^F2Throwing coin... Result: %s^F2!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:258
+msgid "^BGYou don't have any fuel for the ^F1Jetpack"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:260
+msgid "^F2You lack a UID, superspec options will not be saved/restored"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:262
+msgid "^F1Round already started, you will join the game in the next round"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:263
+msgid "^F2You will spectate in the next round"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:265
+#, c-format
+msgid "^BG%s%s^K1 was killed by ^BG%s^K1's ^BG%s^K1 buff ^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:265
+#, c-format
+msgid "^BG%s%s^K1 was scored against by ^BG%s^K1's ^BG%s^K1 buff ^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:266
+#, c-format
+msgid "^BG%s%s^K1 was unfairly eliminated by ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:267
+#, c-format
+msgid "^BG%s%s^K1 was drowned by ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:268
+#, c-format
+msgid "^BG%s%s^K1 was grounded by ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:269
+#, c-format
+msgid "^BG%s%s^K1 felt a little hot from ^BG%s^K1's fire^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:269
+#, c-format
+msgid "^BG%s%s^K1 was burnt up into a crisp by ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:270
+#, c-format
+msgid "^BG%s%s^K1 was cooked by ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:271
+#, c-format
+msgid "^BG%s%s^K1 was pushed in front of a monster by ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:272
+#, c-format
+msgid "^BG%s%s^K1 was blown up by ^BG%s^K1's Nade%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:273
+#, c-format
+msgid "^BG%s%s^K1 got too close to a napalm explosion%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:273
+#, c-format
+msgid "^BG%s%s^K1 was burned to death by ^BG%s^K1's Napalm Nade%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:274
+#, c-format
+msgid "^BG%s%s^K1 was blown up by ^BG%s^K1's Ice Nade%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:275
+#, c-format
+msgid "^BG%s%s^K1 was frozen to death by ^BG%s^K1's Ice Nade%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:276
+#, c-format
+msgid "^BG%s%s^K1 has not been healed by ^BG%s^K1's Healing Nade%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:277
+#, c-format
+msgid "^BG%s%s^K1 was shot into space by ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:278
+#, c-format
+msgid "^BG%s%s^K1 was slimed by ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:279
+#, c-format
+msgid "^BG%s%s^K1 was preserved by ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:280
+#, c-format
+msgid "^BG%s%s^K1 tried to occupy ^BG%s^K1's teleport destination space%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:280
+#, c-format
+msgid "^BG%s%s^K1 was telefragged by ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:281
+#, c-format
+msgid "^BG%s%s^K1 died in an accident with ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:282
+#, c-format
+msgid ""
+"^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Bumblebee exploded%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:283
+#, c-format
+msgid "^BG%s%s^K1 saw the pretty lights of ^BG%s^K1's Bumblebee gun%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:284
+#, c-format
+msgid "^BG%s%s^K1 was crushed by ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:285
+#, c-format
+msgid "^BG%s%s^K1 was cluster bombed by ^BG%s^K1's Raptor%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:286
+#, c-format
+msgid "^BG%s%s^K1 couldn't resist ^BG%s^K1's purple blobs%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:287
+#, c-format
+msgid "^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Raptor exploded%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:288
+#, c-format
+msgid ""
+"^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Spiderbot exploded%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:289
+#, c-format
+msgid "^BG%s%s^K1 got shredded by ^BG%s^K1's Spiderbot%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:290
+#, c-format
+msgid "^BG%s%s^K1 was blasted to bits by ^BG%s^K1's Spiderbot%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:291
+#, c-format
+msgid "^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Racer exploded%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:292
+#, c-format
+msgid "^BG%s%s^K1 was bolted down by ^BG%s^K1's Racer%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:293
+#, c-format
+msgid "^BG%s%s^K1 couldn't find shelter from ^BG%s^K1's Racer%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:294
+#, c-format
+msgid "^BG%s%s^K1 was thrown into a world of hurt by ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:296
+#, c-format
+msgid "^BG%s^K1 was moved into the %s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:297
+#, c-format
+msgid "^BG%s^K1 became enemies with the Lord of Teamplay%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:298
+#, c-format
+msgid "^BG%s^K1 thought they found a nice camping ground%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:299
+#, c-format
+msgid "^BG%s^K1 unfairly eliminated themself%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:301
+#, c-format
+msgid "^BG%s^K1 couldn't catch their breath%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:301
+#, c-format
+msgid "^BG%s^K1 was in the water for too long%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:302
+#, c-format
+msgid "^BG%s^K1 hit the ground with a bit too much force%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:302
+#, c-format
+msgid "^BG%s^K1 hit the ground with a crunch%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:303
+#, c-format
+msgid "^BG%s^K1 became a bit too crispy%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:303
+#, c-format
+msgid "^BG%s^K1 felt a little hot%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:304
+#, c-format
+msgid "^BG%s^K1 died%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:305
+#, c-format
+msgid "^BG%s^K1 found a hot place%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:305
+#, c-format
+msgid "^BG%s^K1 turned into hot slag%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:306
+#, c-format
+msgid "^BG%s^K1 was exploded by a Mage%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:307
+#, c-format
+msgid "^BG%s^K1's innards became outwards by a Shambler%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:308
+#, c-format
+msgid "^BG%s^K1 was smashed by a Shambler%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:309
+#, c-format
+msgid "^BG%s^K1 was zapped to death by a Shambler%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:310
+#, c-format
+msgid "^BG%s^K1 was bitten by a Spider%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:311
+#, c-format
+msgid "^BG%s^K1 was fireballed by a Wyvern%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:312
+#, c-format
+msgid "^BG%s^K1 joins the Zombies%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:313
+#, c-format
+msgid "^BG%s^K1 was given kung fu lessons by a Zombie%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:314
+#: qcsrc/common/notifications/all.inc:316
+#, c-format
+msgid "^BG%s^K1 mastered the art of self-nading%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:315
+#, c-format
+msgid ""
+"^BG%s^K1 decided to take a look at the results of their napalm explosion%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:315
+#, c-format
+msgid "^BG%s^K1 was burned to death by their own Napalm Nade%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:317
+#, c-format
+msgid "^BG%s^K1 felt a little chilly%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:317
+#, c-format
+msgid "^BG%s^K1 was frozen to death by their own Ice Nade%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:318
+#, c-format
+msgid "^BG%s^K1's Healing Nade didn't quite heal them%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:319
+#, c-format
+msgid "^BG%s^K1 died%s%s. What's the point of living without ammo?"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:319
+#, c-format
+msgid "^BG%s^K1 ran out of ammo%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:320
+#, c-format
+msgid "^BG%s^K1 rotted away%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:321
+#, c-format
+msgid "^BG%s^K1 became a shooting star%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:322
+#, c-format
+msgid "^BG%s^K1 was slimed%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:323
+#, c-format
+msgid "^BG%s^K1 couldn't take it anymore%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:324
+#, c-format
+msgid "^BG%s^K1 is now preserved for centuries to come%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:325
+#, c-format
+msgid "^BG%s^K1 switched to the %s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:326
+#, c-format
+msgid "^BG%s^K1 died in an accident%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:327
+#, c-format
+msgid "^BG%s^K1 ran into a turret%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:328
+#, c-format
+msgid "^BG%s^K1 was blasted away by an eWheel turret%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:329
+#, c-format
+msgid "^BG%s^K1 got caught up in the FLAC turret fire%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:330
+#, c-format
+msgid "^BG%s^K1 was blasted away by a Hellion turret%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:331
+#, c-format
+msgid "^BG%s^K1 could not hide from the Hunter turret%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:332
+#, c-format
+msgid "^BG%s^K1 was riddled full of holes by a Machinegun turret%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:333
+#, c-format
+msgid "^BG%s^K1 got turned into smoldering gibs by an MLRS turret%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:334
+#, c-format
+msgid "^BG%s^K1 was phased out by a turret%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:335
+#, c-format
+msgid "^BG%s^K1 got served some superheated plasma from a turret%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:336
+#, c-format
+msgid "^BG%s^K1 was electrocuted by a Tesla turret%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:337
+#, c-format
+msgid "^BG%s^K1 got served a lead enrichment by a Walker turret%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:338
+#, c-format
+msgid "^BG%s^K1 was impaled by a Walker turret%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:339
+#, c-format
+msgid "^BG%s^K1 was blasted away by a Walker turret%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:340
+#, c-format
+msgid "^BG%s^K1 got caught in the blast of a Bumblebee explosion%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:341
+#, c-format
+msgid "^BG%s^K1 was crushed by a vehicle%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:342
+#, c-format
+msgid "^BG%s^K1 was caught in a Raptor cluster bomb%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:343
+#, c-format
+msgid "^BG%s^K1 got caught in the blast of a Raptor explosion%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:344
+#, c-format
+msgid "^BG%s^K1 got caught in the blast of a Spiderbot explosion%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:345
+#, c-format
+msgid "^BG%s^K1 was blasted to bits by a Spiderbot rocket%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:346
+#, c-format
+msgid "^BG%s^K1 got caught in the blast of a Racer explosion%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:347
+#, c-format
+msgid "^BG%s^K1 couldn't find shelter from a Racer rocket%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:350
+#, c-format
+msgid "^BG%s^K1 was betrayed by ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:352
+#, c-format
+msgid "^BG%s^BG%s^BG (%s %s every %s seconds)"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:354
+#, c-format
+msgid "^BG%s^K1 was frozen by ^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:355
+#, c-format
+msgid "^BG%s^K3 was revived by ^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:356
+#, c-format
+msgid "^BG%s^K3 was revived by falling"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:357
+#, c-format
+msgid "^BG%s^K3 was revived by their Nade explosion"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:358
+#, c-format
+msgid "^BG%s^K3 was automatically revived after %s seconds"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:359
+#, c-format
+msgid "^BG%s^K1 froze themself"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:361
+#: qcsrc/common/notifications/all.inc:675
+msgid "^TC^TT^BG team wins the round"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:362
+#: qcsrc/common/notifications/all.inc:676
+#, c-format
+msgid "^BG%s^BG wins the round"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:363
+#: qcsrc/common/notifications/all.inc:539
+msgid "^BGRound tied"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:364
+#: qcsrc/common/notifications/all.inc:540
+msgid "^BGRound over, there's no winner"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:366
+#, c-format
+msgid "^BGGodmode saved you %s units of damage, cheater!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:368
+#, c-format
+msgid "^BG%s^BG got the %s^BG buff!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:369
+#, c-format
+msgid "^BG%s^BG lost the %s^BG buff!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:370
+#: qcsrc/common/notifications/all.inc:683
+#, c-format
+msgid "^BGYou dropped the %s^BG buff!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:371
+#: qcsrc/common/notifications/all.inc:684
+#, c-format
+msgid "^BGYou got the %s^BG buff!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:373
+#: qcsrc/common/notifications/all.inc:687
+#, c-format
+msgid "^BGYou do not have the ^F1%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:374
+#: qcsrc/common/notifications/all.inc:688
+#, c-format
+msgid "^BGYou dropped the ^F1%s^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:375
+#: qcsrc/common/notifications/all.inc:689
+#, c-format
+msgid "^BGYou got the ^F1%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:376
+#: qcsrc/common/notifications/all.inc:690
+#, c-format
+msgid "^BGYou don't have enough ammo for the ^F1%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:377
+#: qcsrc/common/notifications/all.inc:691
+#, c-format
+msgid "^F1%s %s^BG is unable to fire, but its ^F1%s^BG can"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:378
+#: qcsrc/common/notifications/all.inc:692
+#, c-format
+msgid "^F1%s^BG is ^F4not available^BG on this map"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:380
+#, c-format
+msgid "^BG%s^BG is connecting..."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:381
+#, c-format
+msgid "^BG%s^F3 connected"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:382
+#, c-format
+msgid "^BG%s^F3 is now playing"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:383
+#, c-format
+msgid "^BG%s^F3 is now playing on the ^TC^TT team"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:385
+#: qcsrc/common/notifications/all.inc:697
+#, c-format
+msgid "^BG%s^BG has dropped the ball!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:386
+#: qcsrc/common/notifications/all.inc:698
+#, c-format
+msgid "^BG%s^BG has picked up the ball!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:388
+#, c-format
+msgid "^BG%s^BG captured the keys for the ^TC^TT team"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:389
+#, c-format
+msgid "^BG%s^BG dropped the ^TC^TT Key"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:390
+#, c-format
+msgid "^BG%s^BG lost the ^TC^TT Key"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:391
+#, c-format
+msgid "^BG%s^BG pushed %s^BG causing the ^TC^TT Key ^BGdestruction"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:392
+#, c-format
+msgid "^BG%s^BG destroyed the ^TC^TT Key"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:393
+#, c-format
+msgid "^BG%s^BG picked up the ^TC^TT Key"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:395
+#, c-format
+msgid "^BG%s^F3 forfeited"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:396
+#, c-format
+msgid "^BG%s^F3 has no more lives left"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:398
+msgid "^BGMonsters are currently disabled"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:400
+msgid "^BGThe ^TC^TT^BG team held the ball for too long"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:402
+#, c-format
+msgid "^BG%s^BG captured %s^BG control point"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:403
+#, c-format
+msgid "^BG%s^BG captured a control point"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:404
+#, c-format
+msgid "^TC^TT^BG team %s^BG control point has been destroyed by %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:405
+#, c-format
+msgid "^TC^TT^BG team control point has been destroyed by %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:406
+msgid "^TC^TT^BG generator has been destroyed"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:407
+msgid "^TC^TT^BG generator spontaneously combusted due to overtime!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:409
+#, c-format
+msgid "^BG%s^K1 picked up Invisibility"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:410
+#, c-format
+msgid "^BG%s^K1 picked up Shield"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:411
+#, c-format
+msgid "^BG%s^K1 picked up Speed"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:412
+#, c-format
+msgid "^BG%s^K1 picked up Strength"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:414
+#, c-format
+msgid "^BG%s^F3 disconnected"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:415
+#, c-format
+msgid "^BG%s^F3 was kicked for idling"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:416
+msgid ""
+"^F2You were kicked from the server because you are a spectator and "
+"spectators aren't allowed at the moment."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:417
+#, c-format
+msgid "^BG%s^F3 was kicked for excessive teamkilling"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:418
+#, c-format
+msgid "^BG%s^F3 is now spectating"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:420
+#, c-format
+msgid "^BG%s^BG has abandoned the race"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:421
+#, c-format
+msgid "^BG%s^BG couldn't break their %s%s^BG place record of %s%s %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:422
+#, c-format
+msgid "^BG%s^BG couldn't break the %s%s^BG place record of %s%s %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:423
+#, c-format
+msgid "^BG%s^BG has finished the race"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:424
+#, c-format
+msgid "^BG%s^BG broke %s^BG's %s%s^BG place record with %s%s %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:425
+#, c-format
+msgid "^BG%s^BG improved their %s%s^BG place record with %s%s %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:426
+#, c-format
+msgid ""
+"^BG%s^BG scored a new record with ^F2%s^BG, but unfortunately lacks a UID "
+"and will be lost."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:427
+#, c-format
+msgid ""
+"^BG%s^BG scored a new record with ^F2%s^BG, but is anonymous and will be "
+"lost."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:428
+#, c-format
+msgid "^BG%s^BG set the %s%s^BG place record with %s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:430
+#, c-format
+msgid ""
+"^F4You have been invited by ^BG%s^F4 to join their game of ^F2%s^F4 "
+"(^F1%s^F4)"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:432
+msgid "^TC^TT ^BGteam scores!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:434
+#, c-format
+msgid ""
+"^F2You have to become a player within the next %s, otherwise you will be "
+"kicked, because spectating isn't allowed at this time!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:436
+#, c-format
+msgid "^BG%s^K1 picked up a Superweapon"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:438
+msgid "^BGYou cannot change to a larger team"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:439
+msgid "^BGYou are not allowed to change teams"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:441
+#, c-format
+msgid ""
+"^F4NOTE: ^BGThe server is running ^F1Xonotic %s (beta)^BG, you have "
+"^F2Xonotic %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:442
+#, c-format
+msgid ""
+"^F4NOTE: ^BGThe server is running ^F1Xonotic %s^BG, you have ^F2Xonotic %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:443
+#, c-format
+msgid ""
+"^F4NOTE: ^F1Xonotic %s^BG is out, and you still have ^F2Xonotic %s^BG - get "
+"the update from ^F3http://www.xonotic.org/^BG!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:445
+#, c-format
+msgid "^F3SVQC Build information: ^F4%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:447
+#, c-format
+msgid ""
+"^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Accordeon%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:448
+#, c-format
+msgid "^BG%s^K1 hurt their own ears with the @!#%%'n Accordeon%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:449
+#, c-format
+msgid "^BG%s%s^K1 was electrocuted by ^BG%s^K1's Arc%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:450
+#, c-format
+msgid "^BG%s%s^K1 was blasted by ^BG%s^K1's Arc bolts%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:451
+#, c-format
+msgid "^BG%s%s^K1 was shot to death by ^BG%s^K1's Blaster%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:452
+#, c-format
+msgid "^BG%s^K1 shot themself to hell with their Blaster%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:453
+#, c-format
+msgid "^BG%s%s^K1 felt the strong pull of ^BG%s^K1's Crylink%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:454
+#, c-format
+msgid "^BG%s^K1 felt the strong pull of their Crylink%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:455
+#, c-format
+msgid "^BG%s%s^K1 ate ^BG%s^K1's rocket%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:456
+#, c-format
+msgid "^BG%s%s^K1 got too close to ^BG%s^K1's rocket%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:457
+#, c-format
+msgid "^BG%s^K1 blew themself up with their Devastator%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:458
+#, c-format
+msgid "^BG%s%s^K1 was blasted by ^BG%s^K1's Electro bolt%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:459
+#, c-format
+msgid "^BG%s%s^K1 felt the electrifying air of ^BG%s^K1's Electro combo%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:460
+#, c-format
+msgid "^BG%s%s^K1 got too close to ^BG%s^K1's Electro orb%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:461
+#, c-format
+msgid "^BG%s^K1 played with Electro bolts%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:462
+#, c-format
+msgid "^BG%s^K1 could not remember where they put their Electro orb%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:463
+#, c-format
+msgid "^BG%s%s^K1 got too close to ^BG%s^K1's fireball%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:464
+#, c-format
+msgid "^BG%s%s^K1 got burnt by ^BG%s^K1's firemine%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:465
+#, c-format
+msgid "^BG%s^K1 should have used a smaller gun%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:466
+#, c-format
+msgid "^BG%s^K1 forgot about their firemine%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:467
+#, c-format
+msgid "^BG%s%s^K1 was pummeled by a burst of ^BG%s^K1's Hagar rockets%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:468
+#, c-format
+msgid "^BG%s%s^K1 was pummeled by ^BG%s^K1's Hagar rockets%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:469
+#, c-format
+msgid "^BG%s^K1 played with tiny Hagar rockets%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:470
+#, c-format
+msgid "^BG%s%s^K1 was cut down with ^BG%s^K1's HLAC%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:471
+#, c-format
+msgid "^BG%s^K1 got a little jumpy with their HLAC%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:472
+#, c-format
+msgid "^BG%s%s^K1 was caught in ^BG%s^K1's Hook gravity bomb%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:473
+#, c-format
+msgid ""
+"^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Klein Bottle%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:474
+#, c-format
+msgid "^BG%s^K1 hurt their own ears with the @!#%%'n Klein Bottle%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:475
+#, c-format
+msgid "^BG%s%s^K1 was sniped by ^BG%s^K1's Machine Gun%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:476
+#, c-format
+msgid "^BG%s%s^K1 was riddled full of holes by ^BG%s^K1's Machine Gun%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:477
+#: qcsrc/common/notifications/all.inc:782
+#, c-format
+msgid "^BGYou cannot place more than ^F2%s^BG mines at a time"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:478
+#, c-format
+msgid "^BG%s%s^K1 got too close to ^BG%s^K1's mine%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:479
+#, c-format
+msgid "^BG%s^K1 forgot about their mine%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:480
+#, c-format
+msgid "^BG%s%s^K1 got too close to ^BG%s^K1's Mortar grenade%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:481
+#, c-format
+msgid "^BG%s%s^K1 ate ^BG%s^K1's Mortar grenade%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:482
+#, c-format
+msgid "^BG%s^K1 didn't see their own Mortar grenade%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:483
+#, c-format
+msgid "^BG%s^K1 blew themself up with their own Mortar%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:484
+#, c-format
+msgid "^BG%s%s^K1 was sniped by ^BG%s^K1's Overkill Heavy Machine Gun%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:485
+#, c-format
+msgid ""
+"^BG%s%s^K1 was torn to bits by ^BG%s^K1's Overkill Heavy Machine Gun%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:486
+#, c-format
+msgid ""
+"^BG%s%s^K1 was riddled full of holes by ^BG%s^K1's Overkill Machine Gun%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:487
+#, c-format
+msgid "^BG%s%s^K1 has been vaporized by ^BG%s^K1's Overkill Nex%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:488
+#, c-format
+msgid ""
+"^BG%s%s^K1 was sawn in half by ^BG%s^K1's Overkill Rocket Propelled Chainsaw"
+"%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:489
+#, c-format
+msgid ""
+"^BG%s%s^K1 almost dodged ^BG%s^K1's Overkill Rocket Propelled Chainsaw%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:490
+#, c-format
+msgid ""
+"^BG%s^K1 was sawn in half by their own Overkill Rocket Propelled Chainsaw%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:491
+#, c-format
+msgid ""
+"^BG%s^K1 blew themself up with their Overkill Rocket Propelled Chainsaw%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:493
+#, c-format
+msgid "^BG%s%s^K1 was gunned down by ^BG%s^K1's Overkill Shotgun%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:494
+#, c-format
+msgid "^BG%s%s^K1 was sniped with a Rifle by ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:495
+#, c-format
+msgid "^BG%s%s^K1 died in ^BG%s^K1's Rifle bullet hail%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:496
+#, c-format
+msgid "^BG%s%s^K1 failed to hide from ^BG%s^K1's Rifle bullet hail%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:497
+#, c-format
+msgid "^BG%s%s^K1 failed to hide from ^BG%s^K1's Rifle%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:498
+#, c-format
+msgid "^BG%s%s^K1 was pummeled by ^BG%s^K1's Seeker rockets%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:499
+#, c-format
+msgid "^BG%s%s^K1 was tagged by ^BG%s^K1's Seeker%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:500
+#, c-format
+msgid "^BG%s^K1 played with tiny Seeker rockets%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:501
+#, c-format
+msgid "^BG%s%s^K1 was gunned down by ^BG%s^K1's Shockwave%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:502
+#, c-format
+msgid "^BG%s%s^K1 slapped ^BG%s^K1 around a bit with a large Shockwave%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:503
+#, c-format
+msgid "^BG%s%s^K1 was gunned down by ^BG%s^K1's Shotgun%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:504
+#, c-format
+msgid "^BG%s%s^K1 slapped ^BG%s^K1 around a bit with a large Shotgun%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:505
+#, c-format
+msgid "^BG%s^K1 is now thinking with portals%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:506
+#, c-format
+msgid "^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Tuba%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:507
+#, c-format
+msgid "^BG%s^K1 hurt their own ears with the @!#%%'n Tuba%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:508
+#, c-format
+msgid "^BG%s%s^K1 has been sublimated by ^BG%s^K1's Vaporizer%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:509
+#, c-format
+msgid "^BG%s%s^K1 has been vaporized by ^BG%s^K1's Vortex%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:528
+msgid "^F4You are now alone!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:530
+msgid "^BGYou are attacking!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:531
+msgid "^BGYou are defending!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:532
+#, c-format
+msgid "^BGObjective destroyed in ^F4%s^BG!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:534
+msgid "^F4Begin!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:535
+msgid "^F4Game starts in ^COUNT"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:536
+msgid "^F4Round starts in ^COUNT"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:537
+msgid "^F4Round cannot start"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:542
+msgid "^F2Don't camp!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:546
+msgid ""
+"^BGYou are now free.\n"
+"^BGFeel free to ^F2try to capture^BG the flag again\n"
+"^BGif you think you will succeed."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:547
+msgid "^BGThis flag is currently inactive"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:548
+msgid ""
+"^BGYou are now ^F1shielded^BG from the flag(s)\n"
+"^BGfor ^F2too many unsuccessful attempts^BG to capture.\n"
+"^BGMake some defensive scores before trying again."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:549
+msgid "^BGYou captured the ^TC^TT^BG flag!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:550
+msgid "^BGYou captured the flag!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:551
+#, c-format
+msgid "^BGToo many flag throws! Throwing disabled for %s."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:552
+#, c-format
+msgid "^BG%s^BG passed the ^TC^TT^BG flag to %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:553
+#, c-format
+msgid "^BG%s^BG passed the flag to %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:554
+#, c-format
+msgid "^BGYou received the ^TC^TT^BG flag from %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:555
+#, c-format
+msgid "^BGYou received the flag from %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:556
+#, c-format
+msgid "^BGPress ^F2%s^BG to receive the flag from %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:557
+#, c-format
+msgid "^BGRequesting %s^BG to pass you the flag"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:558
+#, c-format
+msgid "^BGYou passed the ^TC^TT^BG flag to %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:559
+#, c-format
+msgid "^BGYou passed the flag to %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:560
+msgid "^BGYou got the ^TC^TT^BG flag!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:561
+msgid "^BGYou got the flag!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:562
+#, c-format
+msgid "^BGYou got your %steam^BG's flag, return it!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:563
+#, c-format
+msgid "^BGYou got the %senemy^BG's flag, return it!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:564
+#, c-format
+msgid "^BGThe %senemy^BG got your flag! Retrieve it!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:565
+#, c-format
+msgid "^BGThe %senemy (^BG%s%s)^BG got your flag! Retrieve it!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:566
+#, c-format
+msgid "^BGThe %senemy^BG got the flag! Retrieve it!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:567
+#, c-format
+msgid "^BGThe %senemy (^BG%s%s)^BG got the flag! Retrieve it!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:568
+#, c-format
+msgid "^BGThe %senemy^BG got their flag! Retrieve it!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:569
+#, c-format
+msgid "^BGThe %senemy (^BG%s%s)^BG got their flag! Retrieve it!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:570
+#, c-format
+msgid "^BGYour %steam mate^BG got the ^TC^TT^BG flag! Protect them!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:571
+#, c-format
+msgid "^BGYour %steam mate (^BG%s%s)^BG got the ^TC^TT^BG flag! Protect them!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:572
+#, c-format
+msgid "^BGYour %steam mate^BG got the flag! Protect them!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:573
+#, c-format
+msgid "^BGYour %steam mate (^BG%s%s)^BG got the flag! Protect them!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:574
+msgid "^BGEnemies can now see you on radar!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:575
+msgid "^BGYou returned the ^TC^TT^BG flag!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:576
+msgid "^BGStalemate! Enemies can now see you on radar!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:577
+msgid "^BGStalemate! Flag carriers can now be seen by enemies on radar!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:581
+#, c-format
+msgid "^K3%sYou fragged ^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:582
+#: qcsrc/common/notifications/all.inc:591
+#: qcsrc/common/notifications/all.inc:600
+#, c-format
+msgid "^K3%sYou scored against ^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:583
+#, c-format
+msgid "^K1%sYou were fragged by ^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:584
+#: qcsrc/common/notifications/all.inc:593
+#: qcsrc/common/notifications/all.inc:602
+#, c-format
+msgid "^K1%sYou were scored against by ^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:590
+#, c-format
+msgid "^K3%sYou burned ^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:592
+#, c-format
+msgid "^K1%sYou were burned by ^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:599
+#, c-format
+msgid "^K3%sYou froze ^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:601
+#, c-format
+msgid "^K1%sYou were frozen by ^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:608
+#, c-format
+msgid "^K1%sYou typefragged ^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:609
+#, c-format
+msgid "^K1%sYou scored against ^BG%s^K1 while they were typing"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:610
+#, c-format
+msgid "^K1%sYou were typefragged by ^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:611
+#, c-format
+msgid "^K1%sYou were scored against by ^BG%s^K1 while typing"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:617
+#, c-format
+msgid "^BGPress ^F2%s^BG again to toss the nade!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:618
+msgid "^F2You got a ^K1BONUS GRENADE^F2!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:620
+#, c-format
+msgid ""
+"^BGYou have been moved into a different team\n"
+"You are now on: %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:621
+msgid "^K1Don't go against your team mates!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:621
+msgid "^K1Don't shoot your team mates!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:622
+msgid "^K1Die camper!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:622
+msgid "^K1Reconsider your tactics, camper!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:623
+msgid "^K1You unfairly eliminated yourself!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:624
+#, c-format
+msgid "^K1You were %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:625
+msgid "^K1You couldn't catch your breath!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:626
+msgid "^K1You hit the ground with a crunch!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:627
+msgid "^K1You felt a little too hot!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:627
+msgid "^K1You got a little bit too crispy!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:628
+msgid "^K1You killed your own dumb self!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:628
+msgid "^K1You need to be more careful!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:629
+msgid "^K1You couldn't stand the heat!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:630
+msgid "^K1You need to watch out for monsters!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:630
+msgid "^K1You were killed by a monster!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:631
+msgid "^K1Tastes like chicken!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:631
+msgid "^K1You forgot to put the pin back in!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:632
+msgid "^K1Hanging around a napalm explosion is bad!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:633
+msgid "^K1You felt a little chilly!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:633
+msgid "^K1You got a little bit too cold!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:634
+msgid "^K1Your Healing Nade is a bit defective"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:635
+msgid "^K1You are respawning for running out of ammo..."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:635
+msgid "^K1You were killed for running out of ammo..."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:636
+msgid "^K1You grew too old without taking your medicine"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:636
+msgid "^K1You need to preserve your health"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:637
+msgid "^K1You became a shooting star!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:638
+msgid "^K1You melted away in slime!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:639
+msgid "^K1You committed suicide!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:639
+msgid "^K1You ended it all!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:640
+msgid "^K1You got stuck in a swamp!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:641
+#, c-format
+msgid "^BGYou are now on: %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:642
+msgid "^K1You died in an accident!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:643
+msgid "^K1You had an unfortunate run in with a turret!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:643
+msgid "^K1You were fragged by a turret!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:644
+msgid "^K1You had an unfortunate run in with an eWheel turret!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:644
+msgid "^K1You were fragged by an eWheel turret!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:645
+msgid "^K1You had an unfortunate run in with a Walker turret!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:645
+msgid "^K1You were fragged by a Walker turret!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:646
+msgid "^K1You got caught in the blast of a Bumblebee explosion!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:647
+msgid "^K1You were crushed by a vehicle!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:648
+msgid "^K1You were caught in a Raptor cluster bomb!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:649
+msgid "^K1You got caught in the blast of a Raptor explosion!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:650
+msgid "^K1You got caught in the blast of a Spiderbot explosion!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:651
+msgid "^K1You were blasted to bits by a Spiderbot rocket!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:652
+msgid "^K1You got caught in the blast of a Racer explosion!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:653
+msgid "^K1You couldn't find shelter from a Racer rocket!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:654
+msgid "^K1Watch your step!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:656
+#, c-format
+msgid "^K1Moron! You fragged ^BG%s^K1, a team mate!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:656
+#, c-format
+msgid "^K1Moron! You went against ^BG%s^K1, a team mate!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:657
+#, c-format
+msgid "^K1You were fragged by ^BG%s^K1, a team mate"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:657
+#, c-format
+msgid "^K1You were scored against by ^BG%s^K1, a team mate"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:659
+msgid ""
+"^K1Stop idling!\n"
+"^BGDisconnecting in ^COUNT..."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:661
+#, c-format
+msgid "^BGYou need %s^BG!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:662
+#, c-format
+msgid "^BGYou also need %s^BG!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:663
+msgid "^BGDoor unlocked!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:665
+#, c-format
+msgid "^F2Extra lives taken: ^K1%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:667
+#, c-format
+msgid "^K3You revived ^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:668
+msgid "^K3You revived yourself"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:669
+#, c-format
+msgid "^K3You were revived by ^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:670
+#, c-format
+msgid "^K3You were automatically revived after %s seconds"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:672
+msgid "^BGThe generator is under attack!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:674
+msgid "^TC^TT^BG team loses the round"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:678
+msgid "^K1You froze yourself"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:679
+msgid "^K1Round already started, you spawn as frozen"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:681
+#, c-format
+msgid "^K1A %s has arrived!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:685
+msgid "^BGYou got the ^F1Fuel regenerator"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:686
+msgid "^BGYou got the ^F1Jetpack"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:694
+msgid ""
+"^K1No spawnpoints available!\n"
+"Hope your team can fix it..."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:695
+msgid ""
+"^K1You may not join the game at this time.\n"
+"The player limit reached maximum capacity."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:699
+msgid "^BGYou picked up the ball"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:700
+msgid "^BGKilling people while you don't have the ball gives no points!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:702
+msgid ""
+"^BGAll keys are in your team's hands!\n"
+"Help the key carriers to meet!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:703
+msgid ""
+"^BGAll keys are in ^TC^TT team^BG's hands!\n"
+"Interfere ^F4NOW^BG!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:704
+msgid ""
+"^BGAll keys are in your team's hands!\n"
+"Meet the other key carriers ^F4NOW^BG!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:705
+msgid "^F4Round will start in ^COUNT"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:706
+msgid "^BGScanning frequency range..."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:707
+msgid "^BGYou are starting with the ^TC^TT Key"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:709
+msgid "^BGYou have no lives left, you must wait until the next match"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:711
+#, c-format
+msgid ""
+"^BGWaiting for players to join...\n"
+"Need active players for: %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:712
+#, c-format
+msgid "^BGWaiting for %s player(s) to join..."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:714
+msgid "^BGYour weapon has been downgraded until you find some ammo!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:715
+msgid "^F4^COUNT^BG left to find some ammo!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:716
+msgid "^BGGet some ammo or you'll be dead in ^F4^COUNT^BG!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:716
+msgid "^BGGet some ammo! ^F4^COUNT^BG left!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:717
+#, c-format
+msgid "^F2Extra lives remaining: ^K1%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:719 qcsrc/menu/xonotic/campaign.qc:244
+#, c-format
+msgid "Level %s: "
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:719
+#, c-format
+msgid "^BGPress ^F2%s^BG to enter the game"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:722
+#, c-format
+msgid ""
+"^F2^COUNT^BG until weapon change...\n"
+"Next weapon: ^F1%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:723
+#, c-format
+msgid "^F2Active weapon: ^F1%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:725
+#, c-format
+msgid "^BGYou captured %s^BG control point"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:726
+msgid "^BGYou captured a control point"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:727
+#, c-format
+msgid "^TC^TT^BG team captured %s^BG control point"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:728
+msgid "^TC^TT^BG team captured a control point"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:729
+msgid "^BGThis control point currently cannot be captured"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:730
+msgid ""
+"^BGThe enemy generator cannot be destroyed yet\n"
+"^F2Capture some control points to unshield it"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:731
+msgid "^BGThe ^TCenemy^BG generator is no longer shielded!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:732
+msgid ""
+"^K1Your generator is NOT shielded!\n"
+"^BGRe-capture control points to shield it!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:733
+#, c-format
+msgid "^BGPress ^F2%s^BG to teleport"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:734
+#, c-format
+msgid "^BGTeleporting disabled for %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:736
+msgid ""
+"^F2Now playing ^F4OVERTIME^F2!\n"
+"Keep fragging until we have a winner!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:736
+msgid ""
+"^F2Now playing ^F4OVERTIME^F2!\n"
+"Keep scoring until we have a winner!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:737
+msgid ""
+"^F2Now playing ^F4OVERTIME^F2!\n"
+"\n"
+"Generators are now decaying.\n"
+"The more control points your team holds,\n"
+"the faster the enemy generator decays"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:738
+#, c-format
+msgid ""
+"^F2Now playing ^F4OVERTIME^F2!\n"
+"^BGAdded ^F4%s^BG to the game!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:740
+msgid "^K1In^BG-portal created"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:741
+msgid "^F3Out^BG-portal created"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:742
+msgid "^F1Portal creation failed"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:744
+msgid "^F2Strength infuses your weapons with devastating power"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:745
+msgid "^F2Strength has worn off"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:747
+msgid "^F2Shield surrounds you"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:748
+msgid "^F2Shield has worn off"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:750
+msgid "^F2You are on speed"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:751
+msgid "^F2Speed has worn off"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:753
+msgid "^F2You are invisible"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:754
+msgid "^F2Invisibility has worn off"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:756
+msgid "^F2The race is over, finish your lap!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:758
+msgid "^BGSequence completed!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:759
+msgid "^BGThere are more to go..."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:760
+#, c-format
+msgid "^BGOnly %s^BG more to go..."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:762
+msgid "^F2Superweapons have broken down"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:763
+msgid "^F2Superweapons have been lost"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:764
+msgid "^F2You now have a superweapon"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:766
+msgid "^K1Changing to ^TC^TT^K1 in ^COUNT"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:767
+msgid "^K1Changing team in ^COUNT"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:768
+msgid "^K1Spectating in ^COUNT"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:769
+msgid "^K1Suicide in ^COUNT"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:771
+msgid "^F4Timeout begins in ^COUNT"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:772
+msgid "^F4Timeout ends in ^COUNT"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:774
+msgid "^K1Cannot join given minigame session!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:776
+#, c-format
+msgid "^BGPress ^F2%s^BG to enter/exit the vehicle"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:777
+#, c-format
+msgid "^BGPress ^F2%s^BG to enter the vehicle gunner"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:778
+#, c-format
+msgid "^BGPress ^F2%s^BG to steal this vehicle"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:779
+msgid ""
+"^F2The enemy is stealing one of your vehicles!\n"
+"^F4Stop them!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:780
+msgid "^F2Intruder detected, disabling shields!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:198
+msgid "Notification dump command only works with cl_cmd and sv_cmd."
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:408 qcsrc/common/notifications/all.qh:409
+#, c-format
+msgid " (near %s)"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:416 qcsrc/common/notifications/all.qh:417
+msgid "primary"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:416 qcsrc/common/notifications/all.qh:417
+msgid "secondary"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:419
+msgid "point"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:419
+msgid "points"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:428
+msgid "drop flag"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:429
+msgid "throw nade"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:455
+#, c-format
+msgid "%s^K1 made a TRIPLE FRAG! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:455
+#, c-format
+msgid "%s^K1 made a TRIPLE SCORE! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:455
+msgid "TRIPLE FRAG! "
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:456
+#, c-format
+msgid "%s^K1 made FIVE SCORES IN A ROW! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:456
+#, c-format
+msgid "%s^K1 unlocked RAGE! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:456
+msgid "RAGE! "
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:457
+#, c-format
+msgid "%s^K1 made TEN SCORES IN A ROW! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:457
+#, c-format
+msgid "%s^K1 started a MASSACRE! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:457
+msgid "MASSACRE! "
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:458
+#, c-format
+msgid "%s^K1 executed MAYHEM! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:458
+#, c-format
+msgid "%s^K1 made FIFTEEN SCORES IN A ROW! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:458
+msgid "MAYHEM! "
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:459
+#, c-format
+msgid "%s^K1 is a BERSERKER! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:459
+#, c-format
+msgid "%s^K1 made TWENTY SCORES IN A ROW! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:459
+msgid "BERSERKER! "
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:460
+#, c-format
+msgid "%s^K1 inflicts CARNAGE! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:460
+#, c-format
+msgid "%s^K1 made TWENTY FIVE SCORES IN A ROW! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:460
+msgid "CARNAGE! "
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:461
+#, c-format
+msgid "%s^K1 made THIRTY SCORES IN A ROW! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:461
+#, c-format
+msgid "%s^K1 unleashes ARMAGEDDON! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:461
+msgid "ARMAGEDDON! "
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:468
+#, c-format
+msgid "%s(^F1Bot^BG)"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:470
+#, c-format
+msgid "%s(Ping ^F1%d^BG)"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:477
+#, c-format
+msgid ""
+"\n"
+"(Health ^1%d^BG / Armor ^2%d^BG)%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:479
+#, c-format
+msgid ""
+"\n"
+"(^F4Dead^BG)%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:500 qcsrc/common/notifications/all.qh:513
+#, c-format
+msgid "%d score spree! "
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:512
+#, c-format
+msgid "%d frag spree! "
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:525
+msgid "First blood! "
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:525
+msgid "First score! "
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:529
+msgid "First casualty! "
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:529
+msgid "First victim! "
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:570
+#, c-format
+msgid "%s^K1 has %d frags in a row! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:571
+#, c-format
+msgid "%s^K1 made %d scores in a row! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:589
+#, c-format
+msgid "%s^K1 drew first blood! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:590
+#, c-format
+msgid "%s^K1 got the first score! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:606
+#, c-format
+msgid ", ending their %d frag spree"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:607
+#, c-format
+msgid ", ending their %d score spree"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:621
+#, c-format
+msgid ", losing their %d frag spree"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:622
+#, c-format
+msgid ", losing their %d score spree"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:647
+#, c-format
+msgid " with %d %s"
+msgstr ""
+
+#: qcsrc/common/teams.qh:31
+msgid "TEAM^Red"
+msgstr ""
+
+#: qcsrc/common/teams.qh:32
+msgid "TEAM^Blue"
+msgstr ""
+
+#: qcsrc/common/teams.qh:33
+msgid "TEAM^Yellow"
+msgstr ""
+
+#: qcsrc/common/teams.qh:34
+msgid "TEAM^Pink"
+msgstr ""
+
+#: qcsrc/common/teams.qh:35
+msgid "Team"
+msgstr ""
+
+#: qcsrc/common/teams.qh:36
+msgid "Neutral"
+msgstr ""
+
+#: qcsrc/common/teams.qh:39
+msgid "KEY^Red"
+msgstr ""
+
+#: qcsrc/common/teams.qh:40
+msgid "KEY^Blue"
+msgstr ""
+
+#: qcsrc/common/teams.qh:41
+msgid "KEY^Yellow"
+msgstr ""
+
+#: qcsrc/common/teams.qh:42
+msgid "KEY^Pink"
+msgstr ""
+
+#: qcsrc/common/teams.qh:43
+msgid "FLAG^Red"
+msgstr ""
+
+#: qcsrc/common/teams.qh:44
+msgid "FLAG^Blue"
+msgstr ""
+
+#: qcsrc/common/teams.qh:45
+msgid "FLAG^Yellow"
+msgstr ""
+
+#: qcsrc/common/teams.qh:46
+msgid "FLAG^Pink"
+msgstr ""
+
+#: qcsrc/common/teams.qh:47
+msgid "GENERATOR^Red"
+msgstr ""
+
+#: qcsrc/common/teams.qh:48
+msgid "GENERATOR^Blue"
+msgstr ""
+
+#: qcsrc/common/teams.qh:49
+msgid "GENERATOR^Yellow"
+msgstr ""
+
+#: qcsrc/common/teams.qh:50
+msgid "GENERATOR^Pink"
+msgstr ""
+
+#: qcsrc/common/turrets/all.qh:95
+msgid "Turrets dump command only works with sv_cmd."
+msgstr ""
+
+#: qcsrc/common/turrets/cl_turrets.qc:125
+#, c-format
+msgid "%s under attack!"
+msgstr ""
+
+#: qcsrc/common/turrets/turret.qh:11
+msgid "Turret"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/ewheel.qh:15
+msgid "eWheel Turret"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/ewheel_weapon.qh:7
+msgid "eWheel"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/flac.qh:13
+msgid "FLAC Cannon"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/flac_weapon.qh:7
+msgid "FLAC"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/fusionreactor.qh:11
+msgid "Fusion Reactor"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/hellion.qh:13
+msgid "Hellion Missile Turret"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/hellion_weapon.qh:7
+msgid "Hellion"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/hk.qh:15
+msgid "Hunter-Killer Turret"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/hk_weapon.qh:7
+msgid "Hunter-Killer"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/machinegun.qh:13
+msgid "Machinegun Turret"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/machinegun_weapon.qh:7
+msgid "Machinegun"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/mlrs.qh:13
+msgid "MLRS Turret"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/mlrs_weapon.qh:7
+msgid "MLRS"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/phaser.qh:13
+msgid "Phaser Cannon"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/phaser_weapon.qh:7
+msgid "Phaser"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/plasma.qh:13
+msgid "Plasma Cannon"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/plasma_dual.qh:8
+msgid "Dual plasma"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/plasma_dual.qh:20
+msgid "Dual Plasma Cannon"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/plasma_weapon.qh:7
+msgid "Plasma"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/tesla.qh:13
+#: qcsrc/common/turrets/turret/tesla_weapon.qh:7
+msgid "Tesla Coil"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/walker.qh:15
+msgid "Walker Turret"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/walker_weapon.qh:7
+msgid "Walker"
+msgstr ""
+
+#: qcsrc/common/util.qc:1390
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:176
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:186
+msgid "Male"
+msgstr ""
+
+#: qcsrc/common/util.qc:1391
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:175
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:185
+msgid "Female"
+msgstr ""
+
+#: qcsrc/common/util.qc:1392
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:174
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:187
+msgid "Undisclosed"
+msgstr ""
+
+#: qcsrc/common/util.qc:1439
+msgid "<KEY NOT FOUND>"
+msgstr ""
+
+#: qcsrc/common/util.qc:1440
+msgid "<UNKNOWN KEYNUM>"
+msgstr ""
+
+#: qcsrc/common/util.qc:1445
+msgid "TAB"
+msgstr ""
+
+#: qcsrc/common/util.qc:1446 qcsrc/common/util.qc:1517
+#, c-format
+msgid "ENTER"
+msgstr ""
+
+#: qcsrc/common/util.qc:1447
+msgid "ESCAPE"
+msgstr ""
+
+#: qcsrc/common/util.qc:1448
+msgid "SPACE"
+msgstr ""
+
+#: qcsrc/common/util.qc:1450
+msgid "BACKSPACE"
+msgstr ""
+
+#: qcsrc/common/util.qc:1451 qcsrc/common/util.qc:1508
+#, c-format
+msgid "UPARROW"
+msgstr ""
+
+#: qcsrc/common/util.qc:1452 qcsrc/common/util.qc:1503
+#, c-format
+msgid "DOWNARROW"
+msgstr ""
+
+#: qcsrc/common/util.qc:1453 qcsrc/common/util.qc:1505
+#, c-format
+msgid "LEFTARROW"
+msgstr ""
+
+#: qcsrc/common/util.qc:1454 qcsrc/common/util.qc:1506
+#, c-format
+msgid "RIGHTARROW"
+msgstr ""
+
+#: qcsrc/common/util.qc:1456
+msgid "ALT"
+msgstr ""
+
+#: qcsrc/common/util.qc:1457
+msgid "CTRL"
+msgstr ""
+
+#: qcsrc/common/util.qc:1458
+msgid "SHIFT"
+msgstr ""
+
+#: qcsrc/common/util.qc:1460 qcsrc/common/util.qc:1501
+#, c-format
+msgid "INS"
+msgstr ""
+
+#: qcsrc/common/util.qc:1461 qcsrc/common/util.qc:1511
+#, c-format
+msgid "DEL"
+msgstr ""
+
+#: qcsrc/common/util.qc:1462 qcsrc/common/util.qc:1504
+#, c-format
+msgid "PGDN"
+msgstr ""
+
+#: qcsrc/common/util.qc:1463 qcsrc/common/util.qc:1509
+#, c-format
+msgid "PGUP"
+msgstr ""
+
+#: qcsrc/common/util.qc:1464 qcsrc/common/util.qc:1507
+#, c-format
+msgid "HOME"
+msgstr ""
+
+#: qcsrc/common/util.qc:1465 qcsrc/common/util.qc:1502
+#, c-format
+msgid "END"
+msgstr ""
+
+#: qcsrc/common/util.qc:1467
+msgid "PAUSE"
+msgstr ""
+
+#: qcsrc/common/util.qc:1469
+msgid "NUMLOCK"
+msgstr ""
+
+#: qcsrc/common/util.qc:1470
+msgid "CAPSLOCK"
+msgstr ""
+
+#: qcsrc/common/util.qc:1471
+msgid "SCROLLOCK"
+msgstr ""
+
+#: qcsrc/common/util.qc:1473
+msgid "SEMICOLON"
+msgstr ""
+
+#: qcsrc/common/util.qc:1474
+msgid "TILDE"
+msgstr ""
+
+#: qcsrc/common/util.qc:1475
+msgid "BACKQUOTE"
+msgstr ""
+
+#: qcsrc/common/util.qc:1476
+msgid "QUOTE"
+msgstr ""
+
+#: qcsrc/common/util.qc:1477
+msgid "APOSTROPHE"
+msgstr ""
+
+#: qcsrc/common/util.qc:1478
+msgid "BACKSLASH"
+msgstr ""
+
+#: qcsrc/common/util.qc:1486
+#, c-format
+msgid "F%d"
+msgstr ""
+
+#: qcsrc/common/util.qc:1496
+#, c-format
+msgid "KP_%d"
+msgstr ""
+
+#: qcsrc/common/util.qc:1501 qcsrc/common/util.qc:1502
+#: qcsrc/common/util.qc:1503 qcsrc/common/util.qc:1504
+#: qcsrc/common/util.qc:1505 qcsrc/common/util.qc:1506
+#: qcsrc/common/util.qc:1507 qcsrc/common/util.qc:1508
+#: qcsrc/common/util.qc:1509 qcsrc/common/util.qc:1510
+#: qcsrc/common/util.qc:1511 qcsrc/common/util.qc:1512
+#: qcsrc/common/util.qc:1513 qcsrc/common/util.qc:1514
+#: qcsrc/common/util.qc:1515 qcsrc/common/util.qc:1516
+#: qcsrc/common/util.qc:1517 qcsrc/common/util.qc:1518
+#, c-format
+msgid "KP_%s"
+msgstr ""
+
+#: qcsrc/common/util.qc:1510
+#, c-format
+msgid "PERIOD"
+msgstr ""
+
+#: qcsrc/common/util.qc:1512
+#, c-format
+msgid "DIVIDE"
+msgstr ""
+
+#: qcsrc/common/util.qc:1513
+#, c-format
+msgid "SLASH"
+msgstr ""
+
+#: qcsrc/common/util.qc:1514
+#, c-format
+msgid "MULTIPLY"
+msgstr ""
+
+#: qcsrc/common/util.qc:1515
+#, c-format
+msgid "MINUS"
+msgstr ""
+
+#: qcsrc/common/util.qc:1516
+#, c-format
+msgid "PLUS"
+msgstr ""
+
+#: qcsrc/common/util.qc:1518
+#, c-format
+msgid "EQUALS"
+msgstr ""
+
+#: qcsrc/common/util.qc:1523
+msgid "PRINTSCREEN"
+msgstr ""
+
+#: qcsrc/common/util.qc:1526
+#, c-format
+msgid "MOUSE%d"
+msgstr ""
+
+#: qcsrc/common/util.qc:1528
+msgid "MWHEELUP"
+msgstr ""
+
+#: qcsrc/common/util.qc:1529
+msgid "MWHEELDOWN"
+msgstr ""
+
+#: qcsrc/common/util.qc:1532
+#, c-format
+msgid "JOY%d"
+msgstr ""
+
+#: qcsrc/common/util.qc:1535
+#, c-format
+msgid "AUX%d"
+msgstr ""
+
+#: qcsrc/common/util.qc:1542
+#, c-format
+msgid "DPAD_UP"
+msgstr ""
+
+#: qcsrc/common/util.qc:1542 qcsrc/common/util.qc:1543
+#: qcsrc/common/util.qc:1544 qcsrc/common/util.qc:1545
+#: qcsrc/common/util.qc:1546 qcsrc/common/util.qc:1547
+#: qcsrc/common/util.qc:1548 qcsrc/common/util.qc:1549
+#: qcsrc/common/util.qc:1550 qcsrc/common/util.qc:1551
+#: qcsrc/common/util.qc:1552 qcsrc/common/util.qc:1553
+#: qcsrc/common/util.qc:1554 qcsrc/common/util.qc:1555
+#: qcsrc/common/util.qc:1556 qcsrc/common/util.qc:1557
+#: qcsrc/common/util.qc:1558 qcsrc/common/util.qc:1559
+#: qcsrc/common/util.qc:1560 qcsrc/common/util.qc:1561
+#, c-format
+msgid "X360_%s"
+msgstr ""
+
+#: qcsrc/common/util.qc:1543
+#, c-format
+msgid "DPAD_DOWN"
+msgstr ""
+
+#: qcsrc/common/util.qc:1544
+#, c-format
+msgid "DPAD_LEFT"
+msgstr ""
+
+#: qcsrc/common/util.qc:1545
+#, c-format
+msgid "DPAD_RIGHT"
+msgstr ""
+
+#: qcsrc/common/util.qc:1546
+#, c-format
+msgid "START"
+msgstr ""
+
+#: qcsrc/common/util.qc:1547
+#, c-format
+msgid "BACK"
+msgstr ""
+
+#: qcsrc/common/util.qc:1548
+#, c-format
+msgid "LEFT_THUMB"
+msgstr ""
+
+#: qcsrc/common/util.qc:1549
+#, c-format
+msgid "RIGHT_THUMB"
+msgstr ""
+
+#: qcsrc/common/util.qc:1550
+#, c-format
+msgid "LEFT_SHOULDER"
+msgstr ""
+
+#: qcsrc/common/util.qc:1551
+#, c-format
+msgid "RIGHT_SHOULDER"
+msgstr ""
+
+#: qcsrc/common/util.qc:1552
+#, c-format
+msgid "LEFT_TRIGGER"
+msgstr ""
+
+#: qcsrc/common/util.qc:1553
+#, c-format
+msgid "RIGHT_TRIGGER"
+msgstr ""
+
+#: qcsrc/common/util.qc:1554
+#, c-format
+msgid "LEFT_THUMB_UP"
+msgstr ""
+
+#: qcsrc/common/util.qc:1555
+#, c-format
+msgid "LEFT_THUMB_DOWN"
+msgstr ""
+
+#: qcsrc/common/util.qc:1556
+#, c-format
+msgid "LEFT_THUMB_LEFT"
+msgstr ""
+
+#: qcsrc/common/util.qc:1557
+#, c-format
+msgid "LEFT_THUMB_RIGHT"
+msgstr ""
+
+#: qcsrc/common/util.qc:1558
+#, c-format
+msgid "RIGHT_THUMB_UP"
+msgstr ""
+
+#: qcsrc/common/util.qc:1559
+#, c-format
+msgid "RIGHT_THUMB_DOWN"
+msgstr ""
+
+#: qcsrc/common/util.qc:1560
+#, c-format
+msgid "RIGHT_THUMB_LEFT"
+msgstr ""
+
+#: qcsrc/common/util.qc:1561
+#, c-format
+msgid "RIGHT_THUMB_RIGHT"
+msgstr ""
+
+#: qcsrc/common/util.qc:1571 qcsrc/common/util.qc:1572
+#: qcsrc/common/util.qc:1573 qcsrc/common/util.qc:1574
+#, c-format
+msgid "JOY_%s"
+msgstr ""
+
+#: qcsrc/common/util.qc:1571
+#, c-format
+msgid "UP"
+msgstr ""
+
+#: qcsrc/common/util.qc:1572
+#, c-format
+msgid "DOWN"
+msgstr ""
+
+#: qcsrc/common/util.qc:1573
+#, c-format
+msgid "LEFT"
+msgstr ""
+
+#: qcsrc/common/util.qc:1574
+#, c-format
+msgid "RIGHT"
+msgstr ""
+
+#: qcsrc/common/util.qc:1580
+#, c-format
+msgid "MIDINOTE%d"
+msgstr ""
+
+#: qcsrc/common/vehicles/cl_vehicles.qc:190
+#, c-format
+msgid "Press %s"
+msgstr ""
+
+#: qcsrc/common/vehicles/vehicle/bumblebee.qc:954
+msgid "No right gunner!"
+msgstr ""
+
+#: qcsrc/common/vehicles/vehicle/bumblebee.qc:960
+msgid "No left gunner!"
+msgstr ""
+
+#: qcsrc/common/vehicles/vehicle/bumblebee.qh:19
+msgid "Bumblebee"
+msgstr ""
+
+#: qcsrc/common/vehicles/vehicle/racer.qh:19
+msgid "Racer"
+msgstr ""
+
+#: qcsrc/common/vehicles/vehicle/racer_weapon.qh:9
+msgid "Racer cannon"
+msgstr ""
+
+#: qcsrc/common/vehicles/vehicle/raptor.qh:19
+msgid "Raptor"
+msgstr ""
+
+#: qcsrc/common/vehicles/vehicle/raptor_weapons.qh:9
+msgid "Raptor cannon"
+msgstr ""
+
+#: qcsrc/common/vehicles/vehicle/raptor_weapons.qh:17
+msgid "Raptor bomb"
+msgstr ""
+
+#: qcsrc/common/vehicles/vehicle/raptor_weapons.qh:25
+msgid "Raptor flare"
+msgstr ""
+
+#: qcsrc/common/vehicles/vehicle/spiderbot.qh:19
+msgid "Spiderbot"
+msgstr ""
+
+#: qcsrc/common/weapons/all.qh:76
+msgid "Weapons dump command only works with sv_cmd."
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/arc.qh:18
+msgid "Arc"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/blaster.qh:18
+msgid "Blaster"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/crylink.qh:18
+msgid "Crylink"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/devastator.qh:18
+msgid "Devastator"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/electro.qh:18
+msgid "Electro"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/fireball.qh:18
+msgid "Fireball"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/hagar.qh:18
+msgid "Hagar"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/hlac.qh:18
+msgid "Heavy Laser Assault Cannon"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/hook.qh:18
+msgid "Grappling Hook"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/machinegun.qh:18
+msgid "MachineGun"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/minelayer.qh:18
+msgid "Mine Layer"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/mortar.qh:18
+msgid "Mortar"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/porto.qh:18
+msgid "Port-O-Launch"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/rifle.qh:19
+msgid "Rifle"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/seeker.qh:18
+msgid "T.A.G. Seeker"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/shockwave.qh:18
+msgid "Shockwave"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/shotgun.qh:18
+msgid "Shotgun"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/tuba.qh:18
+#, no-c-format
+msgid "@!#%'n Tuba"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/vaporizer.qh:19
+msgid "Vaporizer"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/vortex.qh:19
+msgid "Vortex"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:9
+#, c-format
+msgid "CI_DEC^%s years"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:12
+#, c-format
+msgid "CI_ZER^%d years"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:13
+#, c-format
+msgid "CI_FIR^%d year"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:14
+#, c-format
+msgid "CI_SEC^%d years"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:15
+#, c-format
+msgid "CI_THI^%d years"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:16
+#, c-format
+msgid "CI_MUL^%d years"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:18
+#, c-format
+msgid "CI_DEC^%s weeks"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:21
+#, c-format
+msgid "CI_ZER^%d weeks"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:22
+#, c-format
+msgid "CI_FIR^%d week"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:23
+#, c-format
+msgid "CI_SEC^%d weeks"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:24
+#, c-format
+msgid "CI_THI^%d weeks"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:25
+#, c-format
+msgid "CI_MUL^%d weeks"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:27
+#, c-format
+msgid "CI_DEC^%s days"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:30
+#, c-format
+msgid "CI_ZER^%d days"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:31
+#, c-format
+msgid "CI_FIR^%d day"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:32
+#, c-format
+msgid "CI_SEC^%d days"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:33
+#, c-format
+msgid "CI_THI^%d days"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:34
+#, c-format
+msgid "CI_MUL^%d days"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:36
+#, c-format
+msgid "CI_DEC^%s hours"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:39
+#, c-format
+msgid "CI_ZER^%d hours"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:40
+#, c-format
+msgid "CI_FIR^%d hour"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:41
+#, c-format
+msgid "CI_SEC^%d hours"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:42
+#, c-format
+msgid "CI_THI^%d hours"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:43
+#, c-format
+msgid "CI_MUL^%d hours"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:46
+#, c-format
+msgid "CI_DEC^%s minutes"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:49
+#, c-format
+msgid "CI_ZER^%d minutes"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:50
+#, c-format
+msgid "CI_FIR^%d minute"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:51
+#, c-format
+msgid "CI_SEC^%d minutes"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:52
+#, c-format
+msgid "CI_THI^%d minutes"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:53
+#, c-format
+msgid "CI_MUL^%d minutes"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:55
+#, c-format
+msgid "CI_DEC^%s seconds"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:58
+#, c-format
+msgid "CI_ZER^%d seconds"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:59
+#, c-format
+msgid "CI_FIR^%d second"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:60
+#, c-format
+msgid "CI_SEC^%d seconds"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:61
+#, c-format
+msgid "CI_THI^%d seconds"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:62
+#, c-format
+msgid "CI_MUL^%d seconds"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:79
+#, c-format
+msgid "%dst"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:80
+#, c-format
+msgid "%dnd"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:81
+#, c-format
+msgid "%drd"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:85
+#, c-format
+msgid "%dth"
+msgstr ""
+
+#: qcsrc/lib/oo.qh:324
+msgid "No description"
+msgstr ""
+
+#: qcsrc/lib/spawnfunc.qh:248
+#, c-format
+msgid ""
+"Entity field %s.%s (%s) is not whitelisted. If you believe this is an error, "
+"please file an issue."
+msgstr ""
+
+#: qcsrc/lib/string.qh:81
+#, c-format
+msgid "%d days, %02d:%02d:%02d"
+msgstr ""
+
+#: qcsrc/lib/string.qh:82
+#, c-format
+msgid "%02d:%02d:%02d"
+msgstr ""
+
+#: qcsrc/menu/command/menu_cmd.qc:48
+msgid "Usage: menu_cmd command..., where possible commands are:"
+msgstr ""
+
+#: qcsrc/menu/command/menu_cmd.qc:49
+msgid "  sync - reloads all cvars on the current menu page"
+msgstr ""
+
+#: qcsrc/menu/command/menu_cmd.qc:50
+msgid "  directmenu ITEM - select a menu item as main item"
+msgstr ""
+
+#: qcsrc/menu/command/menu_cmd.qc:51
+msgid "  dumptree - dump the state of the menu as a tree to the console"
+msgstr ""
+
+#: qcsrc/menu/command/menu_cmd.qc:81
+msgid "Available options:"
+msgstr ""
+
+#: qcsrc/menu/command/menu_cmd.qc:130
+msgid "Invalid command. For a list of supported commands, try menu_cmd help."
+msgstr ""
+
+#: qcsrc/menu/item/listbox.qc:413
+#, c-format
+msgid "Item %d"
+msgstr ""
+
+#: qcsrc/menu/item/textslider.qc:11 qcsrc/menu/item/textslider.qc:12
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:115
+msgid "Custom"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:4
+msgid "Core Team"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:15
+msgid "Extended Team"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:46
+msgid "Website"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:51
+msgid "Stats"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:55
+msgid "Art"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:63
+msgid "Animation"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:67
+msgid "Level Design"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:90
+msgid "Music / Sound FX"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:106
+msgid "Game Code"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:114
+msgid "Marketing / PR"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:120
+msgid "Legal"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:125
+msgid "Game Engine"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:129
+msgid "Engine Additions"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:135
+msgid "Compiler"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:141
+msgid "Other Active Contributors"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:148
+msgid "Translators"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:150
+msgid "Asturian"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:155
+msgid "Belarusian"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:158
+msgid "Bulgarian"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:165
+msgid "Chinese (China)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:171
+msgid "Chinese (Taiwan)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:176
+msgid "Cornish"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:179
+msgid "Czech"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:184
+msgid "Dutch"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:191
+msgid "English (Australia)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:196
+msgid "Finnish"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:201
+msgid "French"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:209
+msgid "German"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:220
+msgid "Greek"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:226
+msgid "Hungarian"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:230
+msgid "Irish"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:233
+msgid "Italian"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:239
+msgid "Kazakh"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:242
+msgid "Korean"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:246
+msgid "Polish"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:254
+msgid "Portuguese"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:260
+msgid "Romanian"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:267
+msgid "Russian"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:278
+msgid "Scottish Gaelic"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:281
+msgid "Serbian"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:287
+msgid "Spanish"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:298
+msgid "Swedish"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:302
+msgid "Ukrainian"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:309
+msgid "Past Contributors"
+msgstr ""
+
+#: qcsrc/menu/xonotic/cvarlist.qc:73
+msgid "forced to be saved to config.cfg"
+msgstr ""
+
+#: qcsrc/menu/xonotic/cvarlist.qc:79 qcsrc/menu/xonotic/cvarlist.qc:89
+msgid "will not be saved"
+msgstr ""
+
+#: qcsrc/menu/xonotic/cvarlist.qc:84
+msgid "will be saved to config.cfg"
+msgstr ""
+
+#: qcsrc/menu/xonotic/cvarlist.qc:93
+msgid "private"
+msgstr ""
+
+#: qcsrc/menu/xonotic/cvarlist.qc:95
+msgid "engine setting"
+msgstr ""
+
+#: qcsrc/menu/xonotic/cvarlist.qc:97
+msgid "read only"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_credits.qc:13
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:38
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:303
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:85
+#: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc:75
+#: qcsrc/menu/xonotic/dialog_singleplayer_winner.qc:14
+msgid "OK"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_credits.qh:7
+msgid "Credits"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_credits.qh:8
+msgid "The Xonotic credits"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_disconnect.qc:16
+msgid "Are you sure to disconnect from server?"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_disconnect.qc:19
+msgid "I would disconnect from server..."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_disconnect.qc:22
+msgid "I would play more!"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_disconnect.qh:6
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qh:6
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qh:6
+msgid "Disconnect"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_disconnect.qh:7
+msgid "Disconnect from the server you are connected to"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_firstrun.qc:39
+msgid ""
+"Welcome to Xonotic, please select your language preference and enter your "
+"player name to get started.  You can change these options later through the "
+"menu system."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_firstrun.qc:45
+#: qcsrc/menu/xonotic/dialog_settings_input_userbind.qc:28
+msgid "Name:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_firstrun.qc:53
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:62
+msgid "Name under which you will appear in the game"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_firstrun.qc:69
+msgid "Text language:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_firstrun.qc:78
+msgid "Allow player statistics to use your nickname at stats.xonotic.org?"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_firstrun.qc:84
+msgid "Undecided"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_firstrun.qc:88
+msgid "Save settings"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_firstrun.qh:6
+msgid "Welcome"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc:18
+msgid "Ammunition display:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc:21
+msgid "Show only current ammo type"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc:24
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:46
+msgid "Noncurrent alpha:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc:28
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:50
+msgid "Noncurrent scale:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc:32
+#: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:24
+msgid "Align icon:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc:33
+#: qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc:32
+#: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:25
+#: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:37
+#: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:25
+#: qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc:23
+#: qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc:35
+#: qcsrc/menu/xonotic/dialog_hudpanel_quickmenu.qc:21
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:57
+msgid "Left"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc:34
+#: qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc:34
+#: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:27
+#: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:38
+#: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:26
+#: qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc:25
+#: qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc:36
+#: qcsrc/menu/xonotic/dialog_hudpanel_quickmenu.qc:23
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:59
+msgid "Right"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_ammo.qh:6
+msgid "Ammo Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc:19
+msgid "Message duration:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc:23
+msgid "Fade time:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc:27
+msgid "Flip messages order"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc:29
+#: qcsrc/menu/xonotic/dialog_hudpanel_quickmenu.qc:18
+msgid "Text alignment:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc:33
+#: qcsrc/menu/xonotic/dialog_hudpanel_quickmenu.qc:22
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:70
+msgid "Center"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc:37
+msgid "Font scale:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qh:6
+msgid "Centerprint Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_chat.qc:17
+msgid "Chat entries:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_chat.qc:20
+msgid "Chat size:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_chat.qc:24
+msgid "Chat lifetime:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_chat.qc:28
+msgid "Chat beep sound"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_chat.qh:6
+msgid "Chat Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_engineinfo.qc:16
+msgid "Engine info:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_engineinfo.qc:19
+msgid "Use an averaging algorithm for fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_engineinfo.qh:6
+msgid "Engine Info Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:17
+msgid "Combine health and armor"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:19
+#: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:28
+#: qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc:17
+msgid "Enable status bar"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:21
+#: qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc:19
+msgid "Status bar alignment:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:29
+#: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:39
+#: qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc:27
+#: qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc:37
+msgid "Inward"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:31
+#: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:40
+#: qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc:29
+#: qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc:38
+msgid "Outward"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:34
+#: qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc:32
+msgid "Icon alignment:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:42
+msgid "Flip health and armor positions"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qh:6
+msgid "Health/Armor Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_infomessages.qc:16
+msgid "Info messages:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_infomessages.qc:19
+msgid "Flip align"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_infomessages.qh:6
+msgid "Info Messages Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:16
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:15
+#: qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qc:14
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:15
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:50
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:62
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:77
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:116
+#: qcsrc/menu/xonotic/util.qc:770 qcsrc/menu/xonotic/util.qc:786
+#: qcsrc/menu/xonotic/util.qc:803
+msgid "Disable"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:17
+#: qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qc:15
+msgid "Enable spectating"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:18
+msgid "Enable even playing in warmup"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:29
+msgid "Reduced"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:32
+msgid "Text/icon ratio:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:35
+msgid "Hide spawned items"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:37
+msgid "Hide big armor and health"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:39
+msgid "Dynamic size"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qh:6
+msgid "Items Time Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_modicons.qh:6
+msgid "Mod Icons Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_notification.qc:17
+msgid "Notifications:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_notification.qc:20
+msgid "Also print notifications to the console"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_notification.qc:23
+msgid "Flip notify order"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_notification.qc:26
+msgid "Entry lifetime:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_notification.qc:30
+msgid "Entry fadetime:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_notification.qh:6
+msgid "Notification Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:16
+#: qcsrc/menu/xonotic/util.qc:758
+msgid "Enable"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:17
+msgid "Enable even observing"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:18
+msgid "Enable only in Race/CTS"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:24
+msgid "Status bar"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:26
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:67
+msgid "Left align"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:73
+msgid "Right align"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:28
+msgid "Inward align"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:29
+msgid "Outward align"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:33
+msgid "Flip speed/acceleration positions"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:37
+msgid "Speed:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:38
+msgid "Include vertical speed"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:49
+msgid "Speed unit:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:51
+msgid "qu/s"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:52
+msgid "m/s"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:53
+msgid "km/h"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:54
+msgid "mph"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:55
+msgid "knots"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:57
+msgid "Show"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:60
+msgid "Top speed"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:66
+msgid "Acceleration:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:67
+msgid "Include vertical acceleration"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qh:6
+msgid "Physics Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_powerups.qh:6
+msgid "Powerups Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qc:16
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:17
+msgid "Always enable"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qc:23
+msgid "Forced aspect:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qh:6
+msgid "Pressed Keys Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_quickmenu.qh:6
+msgid "Quick Menu Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_racetimer.qh:6
+msgid "Race Timer Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:16
+msgid "Enable in team games"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:23
+msgid "Radar:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:26
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:68
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:107
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:103
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:45
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:70
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:124
+#: qcsrc/menu/xonotic/util.qc:792
+msgid "Alpha:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:30
+msgid "Rotation:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:32
+msgid "Forward"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:33
+msgid "West"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:34
+msgid "South"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:35
+msgid "East"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:36
+msgid "North"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:40
+msgid "Scale:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:44
+msgid "Zoom mode:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:46
+msgid "Zoomed in"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:47
+msgid "Zoomed out"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:48
+msgid "Always zoomed"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:49
+msgid "Never zoomed"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qh:6
+msgid "Radar Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_score.qc:17
+msgid "Score:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_score.qc:20
+msgid "Rankings:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_score.qc:21
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:58
+msgid "Off"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_score.qc:22
+msgid "And me"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_score.qc:23
+msgid "Pure"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_score.qh:6
+msgid "Score Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_timer.qc:16
+msgid "Timer:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_timer.qc:19
+msgid "Show elapsed time"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_timer.qh:6
+msgid "Timer Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_vote.qc:17
+msgid "Alpha after voting:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_vote.qh:6
+msgid "Vote Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:22
+msgid "Fade out after:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:24
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:167
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:145
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:55
+msgid "Never"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:26
+#, c-format
+msgid "%ds"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:30
+msgid "Fade effect:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:33
+msgid "EF^None"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:34
+msgid "Alpha"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:35
+msgid "Slide"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:36
+msgid "EF^Both"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:40
+msgid "Weapon icons:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:43
+msgid "Show only owned weapons"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:54
+msgid "Show weapon ID as:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:55
+msgid "SHOWAS^None"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:56
+msgid "Number"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:57
+msgid "Bind"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:60
+msgid "Weapon ID scale:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:66
+msgid "Show Accuracy"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:67
+msgid "Show Ammo"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:70
+msgid "Ammo bar alpha:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:76
+msgid "Ammo bar color:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qh:6
+msgid "Weapons Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:19
+msgid "HUD skins"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:22
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
+#: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:32
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:42
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:25
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc:33
+msgid "Filter:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:30
+#: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:54
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc:43
+msgid "Refresh"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:33
+#: qcsrc/menu/xonotic/dialog_settings_user.qc:28
+msgid "Set skin"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:37
+msgid "Save current skin"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:46
+msgid "Panel background defaults:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:48
+#: qcsrc/menu/xonotic/util.qc:767
+msgid "Background:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:60
+#: qcsrc/menu/xonotic/util.qc:783
+msgid "Border size:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:75
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:114
+msgid "Team color:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:83
+#: qcsrc/menu/xonotic/util.qc:809
+msgid "Test team color in configure mode"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:86
+#: qcsrc/menu/xonotic/util.qc:812
+msgid "Padding:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:93
+msgid "HUD Dock:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:95
+msgid "DOCK^Disabled"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:96
+msgid "DOCK^Small"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:97
+msgid "DOCK^Medium"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:98
+msgid "DOCK^Large"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:121
+msgid "Grid settings:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:124
+msgid "Snap panels to grid"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:127
+msgid "Grid size:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:129
+msgid "X:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:136
+msgid "Y:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:145
+msgid "Exit setup"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qh:6
+msgid "Panel HUD Setup"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:13
+msgid "Monster:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:22
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:20
+msgid "Spawn"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:23
+msgid "Remove"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:25
+msgid "Move target:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:26
+msgid "Follow"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:27
+msgid "Wander"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:28
+msgid "Spawnpoint"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:29
+msgid "No moving"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:31
+msgid "Colors:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:33
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:39
+msgid "Set skin:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_monstertools.qh:6
+msgid "Monster Tools"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer.qc:14
+msgid "Servers"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer.qc:15
+msgid "Find servers to play on"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer.qc:17
+msgid "Host your own game"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer.qc:18
+msgid "Media"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer.qc:19
+msgid "Profile"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer.qh:6
+msgid "Multiplayer"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer.qh:7
+msgid ""
+"Play online, against your friends in LAN, view demos or change player "
+"settings"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:38
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
+#: qcsrc/menu/xonotic/skinlist.qc:88 qcsrc/menu/xonotic/util.qc:769
+#: qcsrc/menu/xonotic/util.qc:785 qcsrc/menu/xonotic/util.qc:794
+#: qcsrc/menu/xonotic/util.qc:802 qcsrc/menu/xonotic/util.qc:814
+msgid "Default"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
+msgid "Unlimited"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:74
+msgid "Gametype"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:79
+msgid "Time limit:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
+msgid "Timelimit in minutes that when hit, will end the match"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
+#, c-format
+msgid "%d minutes"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
+msgid "TIMLIM^Default"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
+msgid "1 minute"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
+msgid "TIMLIM^Infinite"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+msgid "Teams:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
+msgid "2 teams"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+msgid "3 teams"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:114
+msgid "4 teams"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+msgid "Player slots:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+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:121
+msgid "Number of bots:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
+msgid "Amount of bots on your server"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+msgid "Bot skill:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+msgid "Specify how experienced the bots will be"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+msgid "Botlike"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+msgid "Beginner"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+msgid "You will win"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+msgid "You can win"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+msgid "You might win"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+msgid "Advanced"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+msgid "Expert"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
+msgid "Pro"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
+msgid "Assassin"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:138
+msgid "Unhuman"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:139
+msgid "Godlike"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:155
+msgid "Mutators..."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:156
+msgid "Mutators and weapon arenas"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:165
+msgid "Maplist"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:175
+msgid ""
+"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:184
+msgid "Add shown"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+msgid "Add the maps shown in the list to your selection"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove shown"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:189
+msgid "Remove the maps shown in the list from your selection"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
+msgid "Add all"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+msgid "Add every available map to your selection"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
+msgid "Remove all"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:199
+msgid "Remove all the maps from your selection"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:206
+msgid "Start Multiplayer!"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc:50
+msgid "Title:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc:56
+msgid "Author:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc:62
+msgid "Game types:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc:85
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:257
+msgid "Close"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc:88
+msgid "MAP^Play"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qh:7
+msgid "Map Information"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:28
+msgid "All Weapons Arena"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:30
+msgid "Most Weapons Arena"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:46
+#, c-format
+msgid "%s Arena"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:57
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:163
+msgid "Dodging"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:59
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:283
+msgid "InstaGib"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:61
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:224
+msgid "New Toys"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:63
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:288
+msgid "NIX"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:65
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:229
+msgid "Rocket Flying"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:67
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:219
+msgid "Invincible Projectiles"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:71
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:298
+msgid "No start weapons"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:73
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:202
+msgid "Low gravity"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:75
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:171
+msgid "Cloaked"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:77
+msgid "Hook"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:79
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:180
+msgid "Midair"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:81
+msgid "Melee only"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:85
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:234
+msgid "Piñata"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:87
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:239
+msgid "Weapons stay"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:89
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:191
+msgid "Blood loss"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:93
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:175
+msgid "Buffs"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:95
+msgid "Overkill"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:97
+msgid "No powerups"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:99
+msgid "Powerups"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:101
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:167
+msgid "Touch explode"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:103
+msgid "Wall jumping"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:105
+msgid "MUT^None"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:160
+msgid "Gameplay mutators:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:164
+msgid ""
+"Enable dodging (quick acceleration in a given direction). Double-tap a "
+"directional key to dodge"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:168
+msgid "An explosion occurs when two players collide"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:172
+msgid "All players are almost invisible"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:176
+msgid ""
+"Enable buff pickups (random bonuses like Medic, Invisible, etc.) on the maps "
+"that support it"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:181
+msgid "Only possible to inflict damage on your enemy while they're airborne"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:185
+msgid "Damage done to your enemy gets added to your own health"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:190
+msgid ""
+"Amount of health below which players start bleeding out (health rots and "
+"they can't jump)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:199
+msgid "Make things fall to the ground slower (percentage of normal gravity)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:208
+msgid "Weapon & item mutators:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:211
+msgid "Grappling hook"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:212
+msgid "Players spawn with the grappling hook. Press the 'hook' key to use it"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:216
+msgid ""
+"Players spawn with the jetpack. Double-tap 'jump' or press the 'jetpack' key "
+"to use it"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:220
+msgid ""
+"Projectiles can't be destroyed. However, you can still explode Electro orbs "
+"with the Electro primary fire"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:225
+msgid ""
+"Some weapon spawns will be randomly replaced with new weapons: Heavy Laser "
+"Assault Cannon, Mine Layer, Rifle, T.A.G. Seeker"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:230
+msgid ""
+"Devastator rockets can be detonated instantly (otherwise, there's a short "
+"delay). This allows players to fire and detonate a Devastator rocket while "
+"in the air for a strong mid-air boost even while moving fast"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:235
+msgid "Players will drop all weapons they possessed when they are killed"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:240
+msgid "Weapons stay after they are picked up"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:245
+msgid "Regular (no arena)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:246
+msgid ""
+"Players will be given a set of weapons at spawn as well as unlimited ammo, "
+"without weapon pickups"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:248
+msgid "Weapon arenas:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:251
+msgid "Custom weapons"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:273
+msgid "Most weapons"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:277
+msgid "All weapons"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:280
+msgid "Special arenas:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:284
+msgid ""
+"Players will be given only one weapon, which can instantly kill the opponent "
+"with a single shot. If the player runs out of ammo, he will have 10 seconds "
+"to find some or if he fails to do so, face death. The secondary fire mode "
+"does not inflict any damage but is good for doing trickjumps."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:289
+msgid ""
+"No items Xonotic - instead of pickup items, everyone plays with the same "
+"weapon. After some time, a countdown will start, after which everyone will "
+"switch to another weapon."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:293
+msgid "with blaster"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:294
+msgid "Always carry the blaster as an additional weapon in Nix"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qh:9
+msgid "Mutators"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:39
+msgid "SRVS^Categories"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:42
+msgid "SRVS^Empty"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:43
+msgid "Show empty servers"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:47
+msgid "SRVS^Full"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:48
+msgid "Show full servers that have no slots available"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:52
+msgid "Pause"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:53
+msgid ""
+"Pause updating the server list to prevent servers from \"jumping around\""
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:54
+msgid "Reload the server list"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:68
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:184
+msgid "Address:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:79
+msgid "Info..."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:80
+msgid "Show more information about the currently highlighted server"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:92
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:264
+msgid "Join!"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:114
+#: qcsrc/menu/xonotic/serverlist.qc:1020
+msgid "MOD^Default"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:121
+#, c-format
+msgid "%d modified"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:121
+msgid "Official"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:129
+msgid "N/A (auth library missing, can't connect)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:131
+msgid "N/A (auth library missing)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:137
+msgid "Not supported (can't connect)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:139
+msgid "Not supported (won't encrypt)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:143
+msgid "Supported (will encrypt)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:145
+msgid "Supported (won't encrypt)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:149
+msgid "Requested (will encrypt)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:151
+msgid "Requested (won't encrypt)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:155
+msgid "Required (can't connect)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:157
+msgid "Required (will encrypt)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:161
+msgid "Use the `crypto_aeslevel` cvar to change your preferences"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:178
+msgid "Hostname:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:192
+msgid "Gametype:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:197
+msgid "Map:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:202
+msgid "Mod:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:207
+msgid "Version:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:212
+msgid "Settings:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:219
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:251
+msgid "Players:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:224
+msgid "Bots:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:229
+msgid "Free slots:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:235
+msgid "Encryption:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:240
+msgid "ID:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:245
+msgid "Key:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qh:7
+msgid "Server Information"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:25
+msgid "Demos"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:26
+msgid "Screenshots"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:27
+msgid "Music Player"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:48
+msgid "Auto record demos"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:57
+msgid "Timedemo"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:58
+msgid "Benchmark how fast your computer can run the highlighted demo"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:62
+msgid "DEMO^Play"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qc:13
+msgid "Playing a demo will disconnect you from the current match."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qc:15
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qc:15
+msgid "Do you really wish to disconnect now?"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qc:13
+msgid "Timing a demo will disconnect you from the current match."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:37
+msgid "MUSICPL^Add"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:40
+msgid "MUSICPL^Add all"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:44
+msgid "Set as menu track"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:48
+msgid "Reset default menu track"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:54
+msgid "Playlist:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:55
+msgid "Random order"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:60
+msgid "MUSICPL^Stop"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:63
+msgid "MUSICPL^Play"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:66
+msgid "MUSICPL^Pause"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:69
+msgid "MUSICPL^Prev"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:72
+msgid "MUSICPL^Next"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:76
+msgid "MUSICPL^Remove"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:79
+msgid "MUSICPL^Remove all"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc:41
+msgid "Auto screenshot scoreboard"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc:62
+msgid "Open in the viewer"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc:137
+msgid "Reset"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc:142
+msgid "Previous"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc:145
+msgid "Next"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc:150
+msgid "Slide show"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:21
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:26
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:21
+msgid "Apply immediately"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:50
+msgid "Name"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:79
+msgid "Model"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:98
+msgid "Glowing color"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:108
+msgid "Detail color"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:123
+msgid "Statistics"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:127
+msgid "Allow player statistics to track your client"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:131
+msgid "Allow player statistics to use your nickname"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:136
+msgid "Allow player statistics to rank you in leaderboards"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:152
+msgid "Country"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:156
+msgid "Select language..."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:172
+msgid "Gender:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:179
+msgid "Gender"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_quit.qc:11
+msgid "Are you sure you want to quit?"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_quit.qc:15
+msgid "Back to work..."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_quit.qc:17
+msgid "I got some more fragging to do!"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_quit.qh:7
+msgid "Quit the game"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:15
+msgid "Model:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:21
+msgid "Remove *"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:23
+msgid "Copy *"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:24
+msgid "Paste"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:26
+msgid "Bone:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:31
+msgid "Set * as child"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:32
+msgid "Attach to *"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:34
+msgid "Detach from *"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:37
+msgid "Visual object properties for *:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:41
+msgid "Set alpha:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:44
+msgid "Set color main:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:46
+msgid "Set color glow:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:50
+msgid "Set frame:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:54
+msgid "Physical object properties for *:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:56
+msgid "Set material:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:62
+msgid "Set solidity:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:63
+msgid "Non-solid"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:64
+msgid "Solid"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:65
+msgid "Set physics:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:66
+msgid "Static"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:67
+msgid "Movable"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:68
+msgid "Physical"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:70
+msgid "Set scale:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:72
+msgid "Set force:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:76
+msgid "Claim *"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:78
+msgid "* object info"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:79
+msgid "* mesh info"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:80
+msgid "* attachment info"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:81
+msgid "Show help"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:82
+msgid "* is the object you are facing"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qh:6
+msgid "Sandbox Tools"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings.qc:18
+msgid "Video"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings.qc:19
+msgid "Effects"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings.qc:20
+msgid "Audio"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings.qc:22
+msgid "Game"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings.qc:23
+msgid "Input"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings.qc:24
+msgid "User"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings.qc:25
+#: qcsrc/menu/xonotic/keybinder.qc:119
+msgid "Misc"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings.qh:6
+msgid "Settings"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings.qh:7
+msgid "Change the game settings"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
+msgid "Master:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:35
+msgid "Music:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:43
+msgid "VOL^Ambient:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:50
+msgid "Info:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:57
+msgid "Items:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:64
+msgid "Pain:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:71
+msgid "Player:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:78
+msgid "Shots:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:85
+msgid "Voice:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:93
+msgid "Weapons:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:99
+msgid "New style sound attenuation"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:102
+msgid "Mute sounds when not active"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:105
+msgid "Frequency:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:107
+msgid "Sound output frequency"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:108
+msgid "8 kHz"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:109
+msgid "11.025 kHz"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:110
+msgid "16 kHz"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:111
+msgid "22.05 kHz"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:112
+msgid "24 kHz"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:113
+msgid "32 kHz"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:114
+msgid "44.1 kHz"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:115
+msgid "48 kHz"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:119
+msgid "Channels:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:121
+msgid "Number of channels for the sound output"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:122
+msgid "Mono"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:123
+msgid "Stereo"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:124
+msgid "2.1"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:125
+msgid "4"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:126
+msgid "5"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:127
+msgid "5.1"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:128
+msgid "6.1"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:129
+msgid "7.1"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:134
+msgid "Swap stereo output channels"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:135
+msgid "Swap left/right channels"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:138
+msgid "Headphone friendly mode"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:139
+msgid ""
+"Enable spatialization (blend the right and left channel slightly to decrease "
+"stereo separation a bit for headphones)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:143
+msgid "Hit indication sound"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:144
+msgid "Play a hit indicator sound when your shot hits an enemy"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:147
+msgid "Chat message sound"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:149
+msgid "Menu sounds"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:150
+msgid "Play sounds when clicking menu items"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:151
+msgid "Focus sounds"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:152
+msgid "Play sounds when hovering over menu items too"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:156
+msgid "Time announcer:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "WRN^Disabled"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:160
+msgid "5 minutes"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:161
+msgid "WRN^Both"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:164
+msgid "Automatic taunts:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:166
+msgid "Automatically taunt enemies after fragging them"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:168
+msgid "Sometimes"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:169
+msgid "Often"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:170
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:57
+msgid "Always"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:176
+msgid "Debug info about sounds"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_bindings_reset.qc:11
+msgid "Are you sure you want to reset all key bindings?"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_bindings_reset.qh:6
+msgid "Reset key bindings"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:41
+msgid "Quality preset:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:45
+msgid "PRE^OMG!"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:48
+msgid "PRE^Low"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:50
+msgid "PRE^Medium"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:52
+msgid "PRE^Normal"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:54
+msgid "PRE^High"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:56
+msgid "PRE^Ultra"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:60
+msgid "PRE^Ultimate"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:65
+msgid "Geometry detail:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:67
+msgid "Change the smoothness of the curves on the map"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:68
+msgid "DET^Lowest"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:69
+msgid "DET^Low"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:70
+msgid "DET^Normal"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:71
+msgid "DET^Good"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:72
+msgid "DET^Best"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:73
+msgid "DET^Insane"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:77
+msgid "Player detail:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:79
+msgid "PDET^Low"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:80
+msgid "PDET^Medium"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:81
+msgid "PDET^Normal"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:82
+msgid "PDET^Good"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:83
+msgid "PDET^Best"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:87
+msgid "Texture resolution:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:91
+msgid "RES^Leet"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:92
+msgid "RES^Lowest"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:93
+msgid "RES^Very low"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:94
+msgid "RES^Low"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:95
+msgid "RES^Normal"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:96
+msgid "RES^Good"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:97
+msgid "RES^Best"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:115
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:120
+msgid "Avoid lossy texture compression"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:129
+msgid "Disable sky for performance and visibility"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:129
+msgid "Show sky"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:132
+msgid "Show surfaces"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:133
+msgid ""
+"Disable textures completely for very slow hardware. This gives a huge "
+"performance boost, but looks very ugly."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:136
+msgid "Use lightmaps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:137
+msgid ""
+"Use high resolution lightmaps, which will look pretty but use up some extra "
+"video memory"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:139
+msgid "Deluxe mapping"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:140
+msgid "Use per-pixel lighting effects"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:142
+msgid "Gloss"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:143
+msgid "Enable the use of glossmaps on textures supporting it"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:146
+msgid "Offset mapping"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:147
+msgid ""
+"Offset mapping effect that will make textures with bumpmaps appear like they "
+"\"pop out\" of the flat 2D surface"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:149
+msgid "Relief mapping"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:150
+msgid ""
+"Higher quality offset mapping, which also has a huge impact on performance"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:153
+msgid "Reflections:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:154
+msgid ""
+"Reflection and refraction quality, has a huge impact on performance on maps "
+"with reflecting surfaces"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:157
+msgid "Resolution of reflections/refractions"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:158
+msgid "Blurred"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:159
+msgid "REFL^Good"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:160
+msgid "Sharp"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:164
+msgid "Decals"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:165
+msgid "Enable decals (bullet holes and blood)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:166
+msgid "Decals on models"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:170
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:254
+msgid "Distance:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:173
+msgid "Decals further away than this will not be drawn"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:177
+msgid "Time:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:180
+msgid "Time in seconds before decals fade away"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:184
+msgid "Damage effects:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:186
+msgid "DMGFX^Disabled"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:187
+msgid "Skeletal"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:188
+msgid "DMGFX^All"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:192
+msgid "No dynamic lighting"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:193
+msgid "Enable corona flares around certain lights"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:195
+msgid "Fake corona lighting"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:196
+msgid ""
+"Enable faster but uglier dynamic lights by rendering bright coronas instead "
+"of real dynamic lights"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:199
+msgid "Realtime dynamic lighting"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:200
+msgid "Enable rendering of dynamic lights such as explosions and rocket lights"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:202
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:208
+msgid "Shadows"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:203
+msgid "Enable rendering of shadows from dynamic lights"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:206
+msgid "Realtime world lighting"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:207
+msgid ""
+"Enable rendering of full realtime world lighting on maps that support it. "
+"Note that this might have a big impact on performance."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:209
+msgid "Enable rendering of shadows from realtime world lights"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:213
+msgid "Use normal maps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:214
+msgid "Enable use of directional shading on textures"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:216
+msgid "Soft shadows"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Fade corona according to visibility"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:221
+msgid "Fade coronas according to visibility"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
+msgid "Bloom"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:226
+msgid ""
+"Enable bloom effect, which brightens the neighboring pixels of very bright "
+"pixels. Has a big impact on performance."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:227
+msgid "Extra postprocessing effects"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:228
+msgid ""
+"Enables special postprocessing effects for when damaged or under water or "
+"using a powerup"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+msgid "Motion blur strength - 0.4 recommended"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
+msgid "Motion blur:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:240
+msgid "Particles"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:241
+msgid "Spawnpoint effects"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:242
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:247
+msgid "Quality:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:250
+#: qcsrc/menu/xonotic/slider_particles.qc:13
+msgid ""
+"Multiplier for amount of particles. Less means less particles, which in turn "
+"gives for better performance"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:257
+msgid "Particles further away than this will not be drawn"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:31
+msgid "No crosshair"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:33
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:62
+msgid "Per weapon"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:34
+msgid ""
+"Set a different crosshair for each weapon, good if you play without weapon "
+"models"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:81
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:97
+msgid "Size:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:64
+msgid "By health"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:76
+msgid "Use rings to indicate weapon status"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:93
+msgid "Enable center crosshair dot"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:111
+msgid "Use normal crosshair color"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:122
+msgid "Smooth effects of crosshairs"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:125
+msgid "Hit testing:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:128
+msgid ""
+"None: do not do hit tests for the crosshair; TrueAim: blur the crosshair "
+"when there's an obstacle between your gun and the target; Enemies: also "
+"enlarge the crosshair when you would hit an enemy"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:129
+msgid "HTTST^Disabled"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:130
+msgid "HTTST^TrueAim"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:131
+msgid "HTTST^Enemies"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:136
+msgid "Blur crosshair if the shot is obstructed"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:140
+msgid "Enlarge crosshair if targeting an enemy"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:143
+msgid "Animate crosshair when hitting an enemy"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:146
+msgid "Animate crosshair when picking up an item"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qh:7
+msgid "Crosshair"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:43
+msgid "Scoreboard"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:48
+msgid "Fading speed:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:51
+msgid "Enable rows / columns highlighting"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:53
+msgid "Show accuracy underneath scoreboard"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:55
+msgid "Show team sizes:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:56
+msgid ""
+"Team size position: Off=do not show; Left=on the left side of the scoreboard "
+"and move team scores to the right; Right=on the right of the scoreboard"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:64
+msgid "Waypoints"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:66
+msgid "Display waypoint markers for objectives on the map"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:67
+msgid "Show various gametype specific waypoints"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:73
+msgid "Control transparency of the waypoints"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:130
+msgid "Fontsize:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:83
+msgid "Edge offset:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:91
+msgid "Fade when near the crosshair"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:95
+msgid "Display names instead of icons"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:100
+msgid "Damage"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:102
+msgid "Overlay:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:105
+msgid "Factor:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:110
+msgid "Fade rate:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:118
+msgid "Player Names"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:120
+msgid "Show names above players"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:136
+msgid "Max distance:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:142
+msgid "Decolorize:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:146
+#: qcsrc/menu/xonotic/keybinder.qc:113
+msgid "Teamplay"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:154
+msgid "Only when near crosshair"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:158
+msgid "Display health and armor"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:163
+msgid "Damage overlay:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:166
+msgid "Dynamic HUD"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:167
+msgid "HUD moves around following player's movement"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:169
+msgid "Shake the HUD when hurt"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:173
+#: qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qh:6
+msgid "Enter HUD editor"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qh:7
+msgid "HUD"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qc:21
+msgid "In order for the HUD editor to show, you must first be in game."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qc:23
+msgid "Do you wish to start a local game to set up the HUD?"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:24
+msgid "Frag Information"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:26
+msgid "Display information about killing sprees"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:29
+msgid "Only display sprees if they are achievements"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:34
+msgid "Show spree information in centerprints"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:38
+msgid "Show spree information in death messages"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:43
+msgid "Sprees in info messages:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:46
+msgid "SPREES^Disabled"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:47
+msgid "Target"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:48
+msgid "Attacker"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:49
+msgid "SPREES^Both"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:55
+msgid "Print on a seperate line"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:58
+msgid "Add extra frag information to centerprint when available"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:62
+msgid "Add frag location to death messages when available"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:65
+msgid "Gamemode Settings"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:67
+msgid "Display capture times in Capture The Flag"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:71
+msgid "Display name of flag stealer in Capture The Flag"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:126
+msgid "Other"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:78
+msgid "Display console messages in the top left corner"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:80
+msgid "Display all info messages in the chatbox"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:82
+msgid "Display player statuses in the chatbox"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:86
+msgid "Powerup notifications"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:89
+msgid "Weapon centerprint notifications"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:92
+msgid "Weapon info message notifications"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:96
+msgid "Announcers"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:98
+msgid "Respawn countdown sounds"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:101
+msgid "Killstreak sounds"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:104
+msgid "Achievement sounds"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qh:7
+msgid "Messages"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:30
+msgid "Items"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:32
+msgid "Use simple 2D images instead of item models"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:34
+msgid "Unavailable alpha:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:37
+msgid "Unavailable color:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:39
+msgid "GHOITEMS^Black"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:40
+msgid "GHOITEMS^Dark"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:41
+msgid "GHOITEMS^Tinted"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:42
+msgid "GHOITEMS^Normal"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:43
+msgid "GHOITEMS^Blue"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:49
+#: qcsrc/menu/xonotic/serverlist.qc:737
+msgid "Players"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:51
+msgid "Force player models to mine"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:53
+msgid "Force player colors to mine"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:56
+msgid "In non teamplay modes only"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:60
+msgid "Body fading:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:63
+msgid "Gibs:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:65
+msgid "GIBS^None"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:66
+msgid "GIBS^Few"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:67
+msgid "GIBS^Many"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:68
+msgid "GIBS^Lots"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qh:7
+msgid "Models"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qh:8
+msgid "Customize how players and items are displayed in game"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:26
+msgid "1st person perspective"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:29
+msgid "Slide to third person upon death"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:33
+msgid "Smooth the view when landing from a jump"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:37
+msgid "Smooth the view while crouching"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:41
+msgid "View waving while idle"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:45
+msgid "View bobbing while walking around"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:50
+msgid "3rd person perspective"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:53
+msgid "Back distance"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:59
+msgid "Up distance"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:65
+msgid "Allow passing through walls while spectating"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:69
+msgid "Field of view:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:71
+msgid "Field of vision in degrees"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:75
+msgid "ZOOM^Zoom factor:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:77
+msgid "How big the zoom factor is when the zoom button is pressed"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:80
+msgid "ZOOM^Zoom speed:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:82
+msgid "How fast the view will be zoomed, disable to zoom instantly"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:91
+msgid "ZOOM^Instant"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:95
+msgid "ZOOM^Zoom sensitivity:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:97
+msgid ""
+"How zoom changes sensitivity, from 0 (lower sensitivity) to 1 (no "
+"sensitivity change)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:100
+msgid "Velocity zoom"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:101
+msgid "Forward movement only"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:105
+msgid "VZOOM^Factor"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:112
+msgid "Display reticle 2D overlay while zooming"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:115
+msgid "Release zoom when you die or respawn"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:119
+msgid "Release zoom when you switch weapons"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qh:7
+#: qcsrc/menu/xonotic/keybinder.qc:83
+msgid "View"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:33
+msgid "Weapon Priority List (* = mutator weapon)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:39
+msgid "Up"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:43
+msgid "Down"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:49
+msgid "Use priority list for weapon cycling"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:50
+msgid ""
+"Make use of the list above when cycling through weapons with the mouse wheel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:52
+msgid "Cycle through only usable weapon selections"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:56
+msgid "Auto switch weapons on pickup"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:57
+msgid ""
+"Automatically switch to newly picked up weapons if they are better than what "
+"you are carrying"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:60
+msgid "Release attack buttons when you switch weapons"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:63
+msgid "Draw 1st person weapon model"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:64
+msgid "Draw the weapon model"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:71
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:74
+msgid "Position of the weapon model; requires reconnect"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:77
+msgid "Weapon model opacity:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:91
+msgid "Gun model swaying"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:96
+msgid "Gun model bobbing"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qh:7
+#: qcsrc/menu/xonotic/keybinder.qc:51
+msgid "Weapons"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:34
+msgid "Key Bindings"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:38
+msgid "Change key..."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:42
+msgid "Edit..."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:48
+msgid "Clear"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:53
+msgid "Reset all"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:58
+msgid "Mouse"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:60
+msgid "Sensitivity:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:62
+msgid "Mouse speed multiplier"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:64
+msgid "Smooth aiming"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:65
+msgid "Smoothes the mouse movement, but makes aiming slightly less responsive"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:67
+msgid "Invert aiming"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:68
+msgid "Invert mouse movement on the Y-axis"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:70
+msgid "Use system mouse positioning"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:75
+msgid "Enable built in mouse acceleration"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:79
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:83
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:86
+msgid "Disable system mouse acceleration"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:80
+msgid "Make use of DGA mouse input"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:94
+msgid "Pressing \"enter console\" key also closes it"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:95
+msgid "Allow the console toggling bind to also close the console"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:97
+msgid "Automatically repeat jumping if holding jump"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:100
+msgid "Jetpack on jump:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:102
+msgid "JPJUMP^Disabled"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:103
+msgid "Air only"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:104
+msgid "JPJUMP^All"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:115
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:120
+msgid "Use joystick input"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input_userbind.qc:31
+msgid "Command when pressed:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input_userbind.qc:34
+msgid "Command when released:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input_userbind.qc:40
+msgid "Cancel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input_userbind.qh:7
+msgid "User defined key bind"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:11
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:12
+#, c-format
+msgid "%d KB/s"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:13
+#, c-format
+msgid "%d MB/s"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+msgid "Network"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+msgid "Client UDP port:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+msgid "Force client to use chosen port unless it is set to 0"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+msgid "Bandwidth:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
+msgid "Specify your network speed"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "56k"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+msgid "ISDN"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+msgid "Slow ADSL"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+msgid "Fast ADSL"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+msgid "Broadband"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+msgid "Server queries/s:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+msgid "Downloads:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:50
+msgid "Maximum number of concurrent HTTP/FTP downloads"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+msgid "Download speed:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:65
+msgid "Local latency:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
+msgid "Show netgraph"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
+msgid "Show a graph of packet sizes and other information"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:72
+msgid "Client-side movement prediction"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:74
+msgid "Movement error compensation"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:78
+msgid "Use encryption (AES) when available"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:81
+msgid "Framerate"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:83
+msgid "Maximum:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
+msgid "MAXFPS^Unlimited"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:96
+msgid "Target:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:98
+msgid "TRGT^Disabled"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:109
+msgid "Idle limit:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
+msgid "IDLFPS^Unlimited"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:119
+msgid "Save processing time for other apps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:122
+msgid "Show frames per second"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:123
+msgid "Show your rendered frames per second"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:128
+msgid "Menu tooltips:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:130
+msgid ""
+"Menu tooltips: disabled, standard or advanced (also shows cvar or console "
+"command bound to the menu item)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:131
+msgid "TLTIP^Disabled"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:132
+msgid "TLTIP^Standard"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:133
+msgid "TLTIP^Advanced"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:136
+msgid "Show current date and time"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:137
+msgid "Show current date and time of day, useful on screenshots"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:140
+msgid "Enable developer mode"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:144
+msgid "Advanced settings..."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:145
+msgid "Advanced settings where you can tweak every single variable of the game"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:150
+#: qcsrc/menu/xonotic/dialog_settings_misc_reset.qh:6
+msgid "Factory reset"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc:31
+msgid "Cvar filter:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc:38
+msgid "Modified cvars only"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc:45
+msgid "Setting:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc:49
+msgid "Type:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc:53
+msgid "Value:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc:70
+msgid "Description:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qh:7
+msgid "Advanced settings"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc_reset.qc:11
+msgid "Are you sure you want to reset all settings?"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc_reset.qc:13
+msgid "This will create a backup config in your data directory"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_user.qc:23
+msgid "Menu Skins"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_user.qc:62
+msgid "Text Language"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_user.qc:67
+msgid "Set language"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_user.qc:72
+msgid "Disable gore effects and harsh language"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_user.qc:73
+msgid "Replace blood and gibs with content that does not have any gore effects"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc:10
+msgid "While connected language changes will be applied only to the menu,"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc:12
+msgid "full language changes will take effect starting from the next game"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc:16
+msgid "Disconnect now"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc:17
+msgid "Switch language"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qh:6
+msgid "Warning"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:33
+msgid "Resolution:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:37
+msgid "Font/UI size:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:39
+msgid "SZ^Unreadable"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:40
+msgid "SZ^Tiny"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:41
+msgid "SZ^Little"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:42
+msgid "SZ^Small"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:43
+msgid "SZ^Medium"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:44
+msgid "SZ^Large"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:45
+msgid "SZ^Huge"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:46
+msgid "SZ^Gigantic"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:47
+msgid "SZ^Colossal"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:51
+msgid "Color depth:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+msgid "How many bits per pixel (BPP) to render at, 32 is recommended"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:54
+msgid "16bit"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:55
+msgid "32bit"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+msgid "Full screen"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
+msgid "Vertical Synchronization"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+msgid ""
+"Enable vertical synchronization to prevent tearing, will cap your fps to the "
+"screen refresh rate"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
+msgid "Flip view horizontally"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+msgid "Poor man's left handed mode"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
+msgid "Anisotropy:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:73
+msgid "Anisotropic filtering quality"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
+msgid "ANISO^Disabled"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
+msgid "2x"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+msgid "4x"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+msgid "8x"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+msgid "16x"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
+msgid "Antialiasing:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:84
+msgid ""
+"Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
+"might decrease performance by quite a lot"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:85
+msgid "AA^Disabled"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+msgid "High-quality frame buffer"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
+msgid "Depth first:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:99
+msgid ""
+"Eliminate overdraw by rendering a depth-only version of the scene before the "
+"normal rendering starts"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
+msgid "DF^Disabled"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+msgid "DF^World"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
+msgid "DF^All"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:105
+msgid "Vertex Buffer Objects (VBOs)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
+msgid "VBO^Off"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:109
+msgid "Vertices, some Tris (compatible)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+msgid ""
+"Make use of Vertex Buffer Objects to store static geometry in video memory "
+"for faster rendering"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:113
+msgid "Vertices"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:115
+msgid "Vertices and Triangles"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
+msgid "Brightness:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+msgid "Brightness of black"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:123
+msgid "Contrast:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
+msgid "Brightness of white"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+msgid "Gamma:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+msgid ""
+"Inverse gamma correction value, a brightness effect that does not affect "
+"white or black"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+msgid "Contrast boost:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:136
+msgid "By how much to multiply the contrast in dark areas"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+msgid "Saturation:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:142
+msgid ""
+"Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
+"requires GLSL color control"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+msgid "LIT^Ambient:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:148
+msgid ""
+"Ambient lighting, if set too high it tends to make light on maps look dull "
+"and flat"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
+msgid "Intensity:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+msgid "Global rendering brightness"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:155
+msgid "Wait for GPU to finish each frame"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
+msgid ""
+"Make the CPU wait for the GPU to finish each frame, can help with some "
+"strange input or video lag on some machines"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+msgid "Use OpenGL 2.0 shaders (GLSL)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:163
+msgid "Psycho coloring (easter egg)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+msgid "Trippy vertices (easter egg)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_singleplayer.qc:109
+msgid "Instant action! (random map with bots)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_singleplayer.qc:116
+msgid "???"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_singleplayer.qc:129
+msgid "Campaign Difficulty:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_singleplayer.qc:130
+msgid "CSKL^Easy"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_singleplayer.qc:131
+msgid "CSKL^Medium"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_singleplayer.qc:132
+msgid "CSKL^Hard"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_singleplayer.qc:134
+msgid "Start Singleplayer!"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_singleplayer.qh:6
+msgid "Singleplayer"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_singleplayer.qh:7
+msgid "Play the singleplayer campaign or instant action matches against bots"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_singleplayer_winner.qh:7
+msgid "Winner"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_teamselect.qc:32
+msgid "join 'best' team (auto-select)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_teamselect.qc:33
+msgid "Autoselect team (recommended)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_teamselect.qc:37
+msgid "red"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_teamselect.qc:38
+msgid "blue"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_teamselect.qc:39
+msgid "yellow"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_teamselect.qc:40
+msgid "pink"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_teamselect.qc:43
+#: qcsrc/menu/xonotic/keybinder.qc:116
+msgid "spectate"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_teamselect.qh:7
+msgid "Team Selection"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_uid2name.qc:10
+msgid "Allow player statistics to use your nickname?"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_uid2name.qc:12
+msgid "Answering \"No\" you will appear as \"Anonymous player\""
+msgstr ""
+
+#: qcsrc/menu/xonotic/gametypelist.qc:87
+msgid "teamplay"
+msgstr ""
+
+#: qcsrc/menu/xonotic/gametypelist.qc:89
+msgid "free for all"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:35
+msgid "Moving"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:36
+msgid "forward"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:37
+msgid "backpedal"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:38
+msgid "strafe left"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:39
+msgid "strafe right"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:40
+msgid "jump / swim"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:41
+msgid "crouch / sink"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:42
+msgid "off-hand hook"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:43
+msgid "jetpack"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:46
+msgid "Attacking"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:52
+msgid "WEAPON^previous"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:53
+msgid "WEAPON^next"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:54
+msgid "WEAPON^previously used"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:55
+msgid "WEAPON^best"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:56
+msgid "reload"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:57
+msgid "drop weapon / throw nade"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:84
+msgid "hold zoom"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:85
+msgid "toggle zoom"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:86
+msgid "show scores"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:87
+msgid "screen shot"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:88
+msgid "maximize radar"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:89
+msgid "3rd person view"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:90
+msgid "enter spectator mode"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:93
+msgid "Communication"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:94
+msgid "public chat"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:95
+msgid "team chat"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:96
+msgid "show chat history"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:97
+msgid "vote YES"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:98
+msgid "vote NO"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:102
+msgid "Client"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:106 qcsrc/menu/xonotic/keybinder.qc:108
+msgid "enter console"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:109
+msgid "disconnect"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:110
+msgid "quit"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:114
+msgid "auto-join team"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:120
+msgid "drop key/flag, exit vehicle"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:121
+msgid "suicide / respawn"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:122
+msgid "quick menu"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:125
+msgid "User defined"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:132
+msgid "Development"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:133
+msgid "sandbox menu"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:134
+msgid "drag object (sandbox)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:135
+msgid "waypoint editor menu"
+msgstr ""
+
+#: qcsrc/menu/xonotic/mainwindow.qc:96 qcsrc/menu/xonotic/mainwindow.qc:99
+msgid "Do not press this button again!"
+msgstr ""
+
+#: qcsrc/menu/xonotic/maplist.qc:288
+msgid ""
+"Huh? Can't play this (m is NULL). Refiltering so this won't happen again."
+msgstr ""
+
+#: qcsrc/menu/xonotic/maplist.qc:296
+#, c-format
+msgid "%s's Xonotic Server"
+msgstr ""
+
+#: qcsrc/menu/xonotic/maplist.qc:301
+msgid ""
+"Huh? Can't play this (invalid game type). Refiltering so this won't happen "
+"again."
+msgstr ""
+
+#: qcsrc/menu/xonotic/playerlist.qc:102 qcsrc/menu/xonotic/playerlist.qc:112
+msgid "spectator"
+msgstr ""
+
+#: qcsrc/menu/xonotic/playermodel.qc:161
+msgid "<no model found>"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:256
+msgid "SERVER^Remove favorite"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:257
+msgid "Remove the currently highlighted server from bookmarks"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:261
+msgid "SERVER^Favorite"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:262
+msgid ""
+"Bookmark the currently highlighted server so that it's faster to find in the "
+"future"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:733
+msgid "Ping"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:734
+msgid "Hostname"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:735
+msgid "Map"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:736
+msgid "Type"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:1019
+#, c-format
+msgid "AES level %d"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:1019
+msgid "ENC^none"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:1019
+msgid "encryption:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:1020
+#, c-format
+msgid "mod: %s"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:1022
+#, c-format
+msgid "modified settings"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:1022
+#, c-format
+msgid "official settings"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:1024
+msgid "stats disabled"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:1024
+msgid "stats enabled"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qh:152
+msgid "SLCAT^Favorites"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qh:153
+msgid "SLCAT^Recommended"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qh:154
+msgid "SLCAT^Normal Servers"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qh:155
+msgid "SLCAT^Servers"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qh:156
+msgid "SLCAT^Competitive Mode"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qh:157
+msgid "SLCAT^Modified Servers"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qh:158
+msgid "SLCAT^Overkill"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qh:159
+msgid "SLCAT^InstaGib"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qh:160
+msgid "SLCAT^Defrag Mode"
+msgstr ""
+
+#: qcsrc/menu/xonotic/skinlist.qc:70
+msgid "<TITLE>"
+msgstr ""
+
+#: qcsrc/menu/xonotic/skinlist.qc:71
+msgid "<AUTHOR>"
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_decibels.qc:72
+msgid "VOL^MAX"
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_decibels.qc:74
+msgid "VOL^OFF"
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_decibels.qc:82
+#, c-format
+msgid "%s dB"
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_particles.qc:14
+msgid "PART^OMG"
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_particles.qc:15
+msgid "PART^Low"
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_particles.qc:16
+msgid "PART^Medium"
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_particles.qc:17
+#: qcsrc/menu/xonotic/slider_sbfadetime.qc:14
+msgid "PART^Normal"
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_particles.qc:18
+msgid "PART^High"
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_particles.qc:19
+msgid "PART^Ultra"
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_particles.qc:20
+msgid "PART^Ultimate"
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_picmip.qc:13
+msgid ""
+"Change the sharpness of the textures. Lowering it will effectively reduce "
+"texture memory usage, but make the textures appear very blurry."
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_resolution.qc:115
+msgid "Screen resolution"
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_sbfadetime.qc:13
+msgid "PART^Slow"
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_sbfadetime.qc:15
+msgid "PART^Fast"
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_sbfadetime.qc:16
+msgid "PART^Instant"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:29
+msgid "January"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:30
+msgid "February"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:31
+msgid "March"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:32
+msgid "April"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:33
+msgid "May"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:34
+msgid "June"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:35
+msgid "July"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:36
+msgid "August"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:37
+msgid "September"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:38
+msgid "October"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:39
+msgid "November"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:40
+msgid "December"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:46
+#, no-c-format
+msgid "DATE^%m %d, %Y"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:97
+msgid "Joined:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:104
+msgid "Last match:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:111
+msgid "Time played:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:118 qcsrc/menu/xonotic/statslist.qc:231
+msgid "Favorite map:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:150 qcsrc/menu/xonotic/statslist.qc:202
+#: qcsrc/menu/xonotic/statslist.qc:245
+#, c-format
+msgid "Matches:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:155
+#, c-format
+msgid "Wins/Losses:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:156
+#, c-format
+msgid "Win percentage:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:167
+#, c-format
+msgid "Kills/Deaths:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:173
+#, c-format
+msgid "Kill ratio:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:208
+msgid "ELO:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:215
+msgid "Rank:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:222
+msgid "Percentile:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:247
+#, c-format
+msgid "%d (unranked)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/util.qc:420
+msgid "Update can be downloaded at:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/util.qc:528
+msgid "Autogenerating mapinfo for newly added maps..."
+msgstr ""
+
+#: qcsrc/menu/xonotic/util.qc:566
+#, c-format
+msgid "Update to %s now!"
+msgstr ""
+
+#: qcsrc/menu/xonotic/util.qc:650
+msgid ""
+"^1ERROR: Texture compression is required but not supported.\n"
+"^1Expect visual problems."
+msgstr ""
+
+#: qcsrc/menu/xonotic/util.qc:780
+msgid "Use default"
+msgstr ""
+
+#: qcsrc/menu/xonotic/util.qc:800
+msgid "Team Color:"
+msgstr ""
diff --git a/common.gl.po b/common.gl.po
new file mode 100644 (file)
index 0000000..53ac15c
--- /dev/null
@@ -0,0 +1,9837 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+# LegendGuard, 2020
+# LegendGuard, 2020
+msgid ""
+msgstr ""
+"Project-Id-Version: Xonotic\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2020-06-07 07:23+0200\n"
+"PO-Revision-Date: 2020-07-30 22:37+0000\n"
+"Last-Translator: LegendGuard\n"
+"Language-Team: Galician (http://www.transifex.com/team-xonotic/xonotic/"
+"language/gl/)\n"
+"Language: gl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: qcsrc/client/hud/hud_config.qc:81
+#, c-format
+msgid "^2Successfully exported to %s! (Note: It's saved in data/data/)"
+msgstr ""
+
+#: qcsrc/client/hud/hud_config.qc:85
+#, c-format
+msgid "^1Couldn't write to %s"
+msgstr ""
+
+#: qcsrc/client/hud/panel/centerprint.qc:174
+#, c-format
+msgid "^3Countdown message at time %s, seconds left: ^COUNT"
+msgstr ""
+
+#: qcsrc/client/hud/panel/centerprint.qc:176
+#, c-format
+msgid ""
+"^1Multiline message at time %s that\n"
+"^1lasts longer than normal"
+msgstr ""
+
+#: qcsrc/client/hud/panel/centerprint.qc:178
+#, c-format
+msgid "Message at time %s"
+msgstr ""
+
+#: qcsrc/client/hud/panel/centerprint.qc:183
+msgid "Generic message"
+msgstr "Mensaxe xenérica"
+
+#: qcsrc/client/hud/panel/chat.qc:89
+msgid "^3Player^7: This is the chat area."
+msgstr "^3Xogador^7: Esta é a área de chat."
+
+#: qcsrc/client/hud/panel/engineinfo.qc:76
+#, c-format
+msgid "FPS: %.*f"
+msgstr "FPS: %.*f"
+
+#: qcsrc/client/hud/panel/infomessages.qc:95
+msgid "^1Observing"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:97
+#, c-format
+msgid "^1Spectating: ^7%s"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:108
+#, c-format
+msgid "^1Press ^3%s^1 to spectate"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:108
+#: qcsrc/menu/xonotic/keybinder.qc:47
+msgid "primary fire"
+msgstr "tiro principal"
+
+#: qcsrc/client/hud/panel/infomessages.qc:110
+#, c-format
+msgid "^1Press ^3%s^1 or ^3%s^1 for next or previous player"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:110
+#: qcsrc/client/hud/panel/infomessages.qc:114
+msgid "next weapon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:110
+#: qcsrc/client/hud/panel/infomessages.qc:114
+msgid "previous weapon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:114
+#, c-format
+msgid "^1Use ^3%s^1 or ^3%s^1 to change the speed"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:116
+#, c-format
+msgid "^1Press ^3%s^1 to observe, ^3%s^1 to change camera mode"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:116
+#: qcsrc/common/vehicles/cl_vehicles.qc:190
+msgid "drop weapon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:116
+#: qcsrc/menu/xonotic/keybinder.qc:48
+msgid "secondary fire"
+msgstr "tiro secundario"
+
+#: qcsrc/client/hud/panel/infomessages.qc:119
+#, c-format
+msgid "^1Press ^3%s^1 for gamemode info"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:119
+#: qcsrc/menu/xonotic/keybinder.qc:103
+msgid "server info"
+msgstr "información do servidor"
+
+#: qcsrc/client/hud/panel/infomessages.qc:132
+msgid "^1Match has already begun"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:134
+msgid "^1You have no more lives left"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:136
+#: qcsrc/client/hud/panel/infomessages.qc:139
+#, c-format
+msgid "^1Press ^3%s^1 to join"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:136
+#: qcsrc/client/hud/panel/infomessages.qc:139
+#: qcsrc/common/notifications/all.qh:430
+msgid "jump"
+msgstr "saltar"
+
+#: qcsrc/client/hud/panel/infomessages.qc:147
+#, c-format
+msgid "^1Game starts in ^3%d^1 seconds"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:153
+msgid "^2Currently in ^1warmup^2 stage!"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:168
+#, c-format
+msgid "%sPress ^3%s%s to end warmup"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:168
+#: qcsrc/client/hud/panel/infomessages.qc:170
+#: qcsrc/client/hud/panel/infomessages.qc:183
+#: qcsrc/menu/xonotic/keybinder.qc:99
+msgid "ready"
+msgstr "listo"
+
+#: qcsrc/client/hud/panel/infomessages.qc:170
+#, c-format
+msgid "%sPress ^3%s%s once you are ready"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:175
+msgid "^2Waiting for others to ready up to end warmup..."
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:177
+msgid "^2Waiting for others to ready up..."
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:183
+#, c-format
+msgid "^2Press ^3%s^2 to end warmup"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:204
+msgid "Teamnumbers are unbalanced!"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:207
+#, c-format
+msgid " Press ^3%s%s to adjust"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:207
+#: qcsrc/menu/xonotic/keybinder.qc:115
+msgid "team menu"
+msgstr "menú do equipo"
+
+#: qcsrc/client/hud/panel/infomessages.qc:217
+msgid "^1Spectating this player:"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:217
+msgid "^1Spectating you:"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:233
+msgid "^7Press ^3ESC ^7to show HUD options."
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:234
+msgid "^3Doubleclick ^7a panel for panel-specific options."
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:235
+msgid "^3CTRL ^7to disable collision testing, ^3SHIFT ^7and"
+msgstr ""
+
+#: qcsrc/client/hud/panel/infomessages.qc:236
+msgid "^3ALT ^7+ ^3ARROW KEYS ^7for fine adjustments."
+msgstr ""
+
+#: qcsrc/client/hud/panel/modicons.qc:183
+msgid "Personal best"
+msgstr ""
+
+#: qcsrc/client/hud/panel/modicons.qc:193
+msgid "Server best"
+msgstr ""
+
+#: qcsrc/client/hud/panel/notify.qc:127 qcsrc/client/hud/panel/notify.qc:128
+#: qcsrc/client/hud/panel/score.qc:69
+#, c-format
+msgid "Player %d"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:597
+#: qcsrc/client/hud/panel/quickmenu.qc:599
+#, c-format
+msgid "Submenu%d"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:604
+#, c-format
+msgid "Command%d"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:630
+msgid "Continue..."
+msgstr "Continúa..."
+
+#: qcsrc/client/hud/panel/quickmenu.qc:787
+#: qcsrc/client/hud/panel/quickmenu.qc:794
+msgid "Chat"
+msgstr "Chat"
+
+#: qcsrc/client/hud/panel/quickmenu.qc:788
+msgid "QMCMD^Send public message to"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:789
+msgid "QMCMD^:-) / nice one"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:789
+msgid "QMCMD^nice one"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:790
+msgid "QMCMD^good game"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:791
+msgid "QMCMD^hi / good luck"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:791
+msgid "QMCMD^hi / good luck and have fun"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:793
+msgid "QMCMD^Send in English"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:798
+#: qcsrc/client/hud/panel/quickmenu.qc:814
+msgid "QMCMD^Team chat"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:799
+msgid "QMCMD^strength soon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:800
+msgid "QMCMD^free item %x^7 (l:%y^7)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:800
+msgid "QMCMD^free item, icon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:801
+msgid "QMCMD^took item (l:%l^7)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:801
+msgid "QMCMD^took item, icon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:802
+msgid "QMCMD^negative"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:803
+msgid "QMCMD^positive"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:804
+msgid "QMCMD^need help (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:804
+msgid "QMCMD^need help, icon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:805
+msgid "QMCMD^enemy seen (l:%y^7)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:805
+msgid "QMCMD^enemy seen, icon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:806
+msgid "QMCMD^flag seen (l:%y^7)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:806
+msgid "QMCMD^flag seen, icon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:807
+msgid "QMCMD^defending (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:807
+msgid "QMCMD^defending, icon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:808
+msgid "QMCMD^roaming (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:808
+msgid "QMCMD^roaming, icon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:809
+msgid "QMCMD^attacking (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:809
+msgid "QMCMD^attacking, icon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:810
+msgid "QMCMD^killed flagcarrier (l:%y^7)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:810
+msgid "QMCMD^killed flagcarrier, icon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:811
+#, c-format
+msgid "QMCMD^dropped flag (l:%d^7)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:811
+msgid "QMCMD^dropped flag, icon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:812
+msgid "QMCMD^drop weapon, icon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:812
+msgid "QMCMD^dropped weapon %w^7 (l:%l^7)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:813
+msgid "QMCMD^drop flag/key, icon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:813
+msgid "QMCMD^dropped flag/key %w^7 (l:%l^7)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:817
+msgid "QMCMD^Send private message to"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:819
+#: qcsrc/client/hud/panel/quickmenu.qc:849
+msgid "QMCMD^Settings"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:820
+#: qcsrc/client/hud/panel/quickmenu.qc:827
+msgid "QMCMD^View/HUD settings"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:821
+msgid "QMCMD^3rd person view"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:822
+msgid "QMCMD^Player models like mine"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:823
+msgid "QMCMD^Names above players"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:824
+msgid "QMCMD^Crosshair per weapon"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:825
+msgid "QMCMD^FPS"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:826
+msgid "QMCMD^Net graph"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:829
+#: qcsrc/client/hud/panel/quickmenu.qc:832
+msgid "QMCMD^Sound settings"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:830
+msgid "QMCMD^Hit sound"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:831
+msgid "QMCMD^Chat sound"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:836
+msgid "QMCMD^Change spectator camera"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:841
+#: qcsrc/client/hud/panel/quickmenu.qc:845
+msgid "QMCMD^Observer camera"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:842
+msgid "QMCMD^Increase speed"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:843
+msgid "QMCMD^Decrease speed"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:844
+msgid "QMCMD^Wall collision"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:848
+msgid "QMCMD^Fullscreen"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:851
+#: qcsrc/client/hud/panel/quickmenu.qc:861
+msgid "QMCMD^Call a vote"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:852
+msgid "QMCMD^Restart the map"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:853
+msgid "QMCMD^End match"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:856
+msgid "QMCMD^Reduce match time"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:857
+msgid "QMCMD^Extend match time"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:860
+msgid "QMCMD^Shuffle teams"
+msgstr ""
+
+#: qcsrc/client/hud/panel/quickmenu.qc:865
+msgid "QMCMD^Spectate a player"
+msgstr ""
+
+#: qcsrc/client/hud/panel/racetimer.qc:59
+#, c-format
+msgid " (-%dL)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/racetimer.qc:64
+#, c-format
+msgid " (+%dL)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/racetimer.qc:83
+msgid "Start line"
+msgstr ""
+
+#: qcsrc/client/hud/panel/racetimer.qc:85
+#: qcsrc/client/hud/panel/racetimer.qc:89
+msgid "Finish line"
+msgstr ""
+
+#: qcsrc/client/hud/panel/racetimer.qc:87
+#: qcsrc/client/hud/panel/racetimer.qc:156
+#, c-format
+msgid "Intermediate %d"
+msgstr ""
+
+#: qcsrc/client/hud/panel/racetimer.qc:159
+#: qcsrc/client/hud/panel/racetimer.qc:206
+#: qcsrc/client/hud/panel/racetimer.qc:267
+#, c-format
+msgid "PENALTY: %.1f (%s)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/racetimer.qc:159 qcsrc/client/main.qc:1102
+msgid "missing a checkpoint"
+msgstr ""
+
+#: qcsrc/client/hud/panel/radar.qc:386
+msgid "Click to select teleport destination"
+msgstr ""
+
+#: qcsrc/client/hud/panel/radar.qc:390
+msgid "Click to select spawn location"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:105
+msgid "Number of ball carrier kills"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:105
+msgid "SCO^bckills"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:106
+msgid "SCO^bctime"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:106
+msgid "Total amount of time holding the ball in Keepaway"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:107
+msgid "How often a flag (CTF) or a key (KeyHunt) was captured"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:107
+msgid "SCO^caps"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:108
+msgid "SCO^captime"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:108
+msgid "Time of fastest capture (CTF)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:109
+msgid "Number of deaths"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:109
+msgid "SCO^deaths"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:110
+msgid "Number of keys destroyed by pushing them into void"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:110
+msgid "SCO^destroyed"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:111
+msgid "SCO^damage"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:111
+msgid "The total damage done"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:112
+msgid "SCO^dmgtaken"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:112
+msgid "The total damage taken"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:113
+msgid "Number of flag drops"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:113
+msgid "SCO^drops"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:114
+msgid "Player ELO"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:114
+msgid "SCO^elo"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:115
+msgid "SCO^fastest"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:115
+msgid "Time of fastest lap (Race/CTS)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:116
+msgid "Number of faults committed"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:116
+msgid "SCO^faults"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:117
+msgid "Number of flag carrier kills"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:117
+msgid "SCO^fckills"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:118
+msgid "FPS"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:118
+msgid "SCO^fps"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:119
+msgid "Number of kills minus suicides"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:119
+msgid "SCO^frags"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:120
+msgid "Number of goals scored"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:120
+msgid "SCO^goals"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:121
+msgid "Number of keys carrier kills"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:121
+msgid "SCO^kckills"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:122
+msgid "SCO^k/d"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:122
+#: qcsrc/client/hud/panel/scoreboard.qc:123
+#: qcsrc/client/hud/panel/scoreboard.qc:124
+msgid "The kill-death ratio"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:123
+msgid "SCO^kdr"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:124
+msgid "SCO^kdratio"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:125
+msgid "Number of kills"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:125
+msgid "SCO^kills"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:126
+msgid "Number of laps finished (Race/CTS)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:126
+msgid "SCO^laps"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:127
+msgid "Number of lives (LMS)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:127
+msgid "SCO^lives"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:128
+msgid "Number of times a key was lost"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:128
+msgid "SCO^losses"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:129
+#: qcsrc/client/hud/panel/scoreboard.qc:130
+msgid "Player name"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:129
+msgid "SCO^name"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:130
+msgid "SCO^nick"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:131
+msgid "Number of objectives destroyed"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:131
+msgid "SCO^objectives"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:132
+msgid ""
+"How often a flag (CTF) or a key (KeyHunt) or a ball (Keepaway) was picked up"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:132
+msgid "SCO^pickups"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:133
+msgid "Ping time"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:133
+msgid "SCO^ping"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:134
+msgid "Packet loss"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:134
+msgid "SCO^pl"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:135
+msgid "Number of players pushed into void"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:135
+msgid "SCO^pushes"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:136
+msgid "Player rank"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:136
+msgid "SCO^rank"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:137
+msgid "Number of flag returns"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:137
+msgid "SCO^returns"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:138
+msgid "Number of revivals"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:138
+msgid "SCO^revivals"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:139
+msgid "Number of rounds won"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:139
+msgid "SCO^rounds won"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:140
+msgid "SCO^score"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:140
+msgid "Total score"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:141
+msgid "Number of suicides"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:141
+msgid "SCO^suicides"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:142
+msgid "Number of kills minus deaths"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:142
+msgid "SCO^sum"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:143
+msgid "Number of domination points taken (Domination)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:143
+msgid "SCO^takes"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:144
+msgid "Number of teamkills"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:144
+msgid "SCO^teamkills"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:145
+msgid "Number of ticks (Domination)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:145
+msgid "SCO^ticks"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:146
+msgid "SCO^time"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:146
+msgid "Total time raced (Race/CTS)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:330
+msgid ""
+"You can modify the scoreboard using the ^2scoreboard_columns_set command."
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:331
+msgid "Usage:"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:333
+msgid "^2scoreboard_columns_set ^3field1 field2 ..."
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:334
+msgid ""
+"^2scoreboard_columns_set ^7without arguments reads the arguments from the "
+"cvar scoreboard_columns"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:335
+msgid ""
+"  ^5Note: ^7scoreboard_columns_set without arguments is executed on every "
+"map start"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:336
+msgid ""
+"^2scoreboard_columns_set ^3expand_default ^7loads default layout and expands "
+"it into the cvar scoreboard_columns so you can edit it"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:337
+msgid "You can use a ^3|^7 to start the right-aligned fields."
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:338
+msgid "The following field names are recognized (case insensitive):"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:344
+msgid ""
+"Before a field you can put a + or - sign, then a comma separated list\n"
+"of game types, then a slash, to make the field show up only in these\n"
+"or in all but these game types. You can also specify 'all' as a\n"
+"field to show all fields available for the current game mode."
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:350
+msgid ""
+"The special game type names 'teams' and 'noteams' can be used to\n"
+"include/exclude ALL teams/noteams game modes."
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:354
+msgid "Example: scoreboard_columns_set name ping pl | +ctf/field3 -dm/field4"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:355
+msgid ""
+"will display name, ping and pl aligned to the left, and the fields\n"
+"right of the vertical bar aligned to the right."
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:357
+msgid ""
+"'field3' will only be shown in CTF, and 'field4' will be shown in all\n"
+"other gamemodes except DM."
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:621
+#: qcsrc/client/hud/panel/scoreboard.qc:628
+#: qcsrc/client/hud/panel/scoreboard.qc:680
+#: qcsrc/client/hud/panel/scoreboard.qc:691
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:46
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:47
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:121
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:164
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:169
+msgid "N/A"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1206
+#, c-format
+msgid "Accuracy stats (average %d%%)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1354
+msgid "Map stats:"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1384
+msgid "Monsters killed:"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1391
+msgid "Secrets found:"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1413
+msgid "Capture time rankings"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1413
+msgid "Rankings"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1631
+#, c-format
+msgid "^3%1.0f minutes"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1640
+#: qcsrc/client/hud/panel/scoreboard.qc:1647
+#, c-format
+msgid "^5%s %s"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1641
+#: qcsrc/client/hud/panel/scoreboard.qc:1648
+#: qcsrc/client/hud/panel/scoreboard.qc:1667
+#: qcsrc/client/hud/panel/scoreboard.qc:1674
+msgid "SCO^points"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1666
+#: qcsrc/client/hud/panel/scoreboard.qc:1673
+#, c-format
+msgid "^2+%s %s"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1684
+#, c-format
+msgid "^7Map: ^2%s"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1823
+#, c-format
+msgid "Speed award: %d%s ^7(%s^7)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1827
+#, c-format
+msgid "All-time fastest: %d%s ^7(%s^7)"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1843
+#, c-format
+msgid "Spectators"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1870
+#, c-format
+msgid "^1Respawning in ^3%s^1..."
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1880
+#, c-format
+msgid "You are dead, wait ^3%s^7 before respawning"
+msgstr ""
+
+#: qcsrc/client/hud/panel/scoreboard.qc:1889
+#, c-format
+msgid "You are dead, press ^2%s^7 to respawn"
+msgstr ""
+
+#: qcsrc/client/hud/panel/timer.qc:72
+msgid "WARMUP"
+msgstr ""
+
+#: qcsrc/client/hud/panel/vote.qc:33
+msgid "^1You must answer before entering hud configure mode"
+msgstr ""
+
+#: qcsrc/client/hud/panel/vote.qc:36
+msgid "^2Name ^7instead of \"^1Anonymous player^7\" in stats"
+msgstr ""
+
+#: qcsrc/client/hud/panel/vote.qc:122
+msgid "A vote has been called for:"
+msgstr ""
+
+#: qcsrc/client/hud/panel/vote.qc:124
+msgid "Allow servers to store and display your name?"
+msgstr ""
+
+#: qcsrc/client/hud/panel/vote.qc:128
+msgid "^1Configure the HUD"
+msgstr ""
+
+#: qcsrc/client/hud/panel/vote.qc:132
+#: qcsrc/menu/xonotic/dialog_disconnect.qc:19
+#: qcsrc/menu/xonotic/dialog_firstrun.qc:82
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qc:18
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qc:18
+#: qcsrc/menu/xonotic/dialog_quit.qc:14
+#: qcsrc/menu/xonotic/dialog_settings_bindings_reset.qc:14
+#: qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qc:26
+#: qcsrc/menu/xonotic/dialog_settings_misc_reset.qc:16
+#: qcsrc/menu/xonotic/dialog_uid2name.qc:15
+msgid "Yes"
+msgstr ""
+
+#: qcsrc/client/hud/panel/vote.qc:134
+#: qcsrc/menu/xonotic/dialog_disconnect.qc:22
+#: qcsrc/menu/xonotic/dialog_firstrun.qc:83
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qc:21
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qc:21
+#: qcsrc/menu/xonotic/dialog_quit.qc:16
+#: qcsrc/menu/xonotic/dialog_settings_bindings_reset.qc:17
+#: qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qc:29
+#: qcsrc/menu/xonotic/dialog_settings_misc_reset.qc:17
+#: qcsrc/menu/xonotic/dialog_uid2name.qc:17
+msgid "No"
+msgstr ""
+
+#: qcsrc/client/hud/panel/weapons.qc:584
+msgid "Out of ammo"
+msgstr ""
+
+#: qcsrc/client/hud/panel/weapons.qc:588
+msgid "Don't have"
+msgstr ""
+
+#: qcsrc/client/hud/panel/weapons.qc:592
+msgid "Unavailable"
+msgstr ""
+
+#: qcsrc/client/main.qc:1000
+msgid " qu/s"
+msgstr ""
+
+#: qcsrc/client/main.qc:1002
+msgid " m/s"
+msgstr ""
+
+#: qcsrc/client/main.qc:1004
+msgid " km/h"
+msgstr ""
+
+#: qcsrc/client/main.qc:1006
+msgid " mph"
+msgstr ""
+
+#: qcsrc/client/main.qc:1008
+msgid " knots"
+msgstr ""
+
+#: qcsrc/client/main.qc:1255
+#, c-format
+msgid "%s (not bound)"
+msgstr ""
+
+#: qcsrc/client/mapvoting.qc:59
+msgid " (1 vote)"
+msgstr ""
+
+#: qcsrc/client/mapvoting.qc:61
+#, c-format
+msgid " (%d votes)"
+msgstr ""
+
+#: qcsrc/client/mapvoting.qc:281
+msgid "Don't care"
+msgstr ""
+
+#: qcsrc/client/mapvoting.qc:382
+msgid "Decide the gametype"
+msgstr ""
+
+#: qcsrc/client/mapvoting.qc:382
+msgid "Vote for a map"
+msgstr ""
+
+#: qcsrc/client/mapvoting.qc:399
+#, c-format
+msgid "%d seconds left"
+msgstr ""
+
+#: qcsrc/client/mapvoting.qc:512
+msgid "mv_mapdownload: ^3You're not supposed to use this command on your own!"
+msgstr ""
+
+#: qcsrc/client/mapvoting.qc:522
+msgid "^1Error:^7 Couldn't find pak index."
+msgstr ""
+
+#: qcsrc/client/mapvoting.qc:531
+msgid "Requesting preview..."
+msgstr ""
+
+#: qcsrc/client/miscfunctions.qc:111
+msgid "Trying to remove a team which is not in the teamlist!"
+msgstr ""
+
+#: qcsrc/client/view.qc:939
+msgid "Nade timer"
+msgstr ""
+
+#: qcsrc/client/view.qc:944
+msgid "Capture progress"
+msgstr ""
+
+#: qcsrc/client/view.qc:949
+msgid "Revival progress"
+msgstr ""
+
+#: qcsrc/common/command/generic.qc:156
+msgid "error creating curl handle"
+msgstr ""
+
+#: qcsrc/common/command/generic.qc:412
+msgid "Notification restart command only works with cl_cmd and sv_cmd."
+msgstr ""
+
+#: qcsrc/common/gamemodes/gamemode/nexball/weapon.qh:7
+msgid "Ball Stealer"
+msgstr ""
+
+#: qcsrc/common/items/item/ammo.qh:66
+msgid "bullets"
+msgstr ""
+
+#: qcsrc/common/items/item/ammo.qh:96
+msgid "cells"
+msgstr ""
+
+#: qcsrc/common/items/item/ammo.qh:126
+msgid "plasma"
+msgstr ""
+
+#: qcsrc/common/items/item/ammo.qh:156
+msgid "rockets"
+msgstr ""
+
+#: qcsrc/common/items/item/ammo.qh:190
+msgid "shells"
+msgstr ""
+
+#: qcsrc/common/items/item/armor.qh:42
+msgid "Small armor"
+msgstr ""
+
+#: qcsrc/common/items/item/armor.qh:80
+msgid "Medium armor"
+msgstr ""
+
+#: qcsrc/common/items/item/armor.qh:118 qcsrc/common/items/item/armor.qh:121
+msgid "Big armor"
+msgstr ""
+
+#: qcsrc/common/items/item/armor.qh:158 qcsrc/common/items/item/armor.qh:161
+msgid "Mega armor"
+msgstr ""
+
+#: qcsrc/common/items/item/health.qh:42
+msgid "Small health"
+msgstr ""
+
+#: qcsrc/common/items/item/health.qh:80
+msgid "Medium health"
+msgstr ""
+
+#: qcsrc/common/items/item/health.qh:118 qcsrc/common/items/item/health.qh:121
+msgid "Big health"
+msgstr ""
+
+#: qcsrc/common/items/item/health.qh:158 qcsrc/common/items/item/health.qh:161
+msgid "Mega health"
+msgstr ""
+
+#: qcsrc/common/items/item/jetpack.qh:38 qcsrc/common/items/item/jetpack.qh:41
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:91
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:215
+msgid "Jetpack"
+msgstr ""
+
+#: qcsrc/common/items/item/jetpack.qh:71
+msgid "fuel"
+msgstr ""
+
+#: qcsrc/common/items/item/jetpack.qh:96
+msgid "Fuel regenerator"
+msgstr ""
+
+#: qcsrc/common/items/item/jetpack.qh:99
+msgid "Fuel regen"
+msgstr ""
+
+#: qcsrc/common/items/item/powerup.qh:43 qcsrc/common/items/item/powerup.qh:46
+msgid "Strength"
+msgstr ""
+
+#: qcsrc/common/items/item/powerup.qh:79 qcsrc/common/items/item/powerup.qh:82
+msgid "Shield"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qc:626
+#, no-c-format
+msgid "@!#%'n Tuba Throwing"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:72 qcsrc/common/mapinfo.qh:334
+#: qcsrc/common/mapinfo.qh:529
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:105
+msgid "Frag limit:"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:72 qcsrc/common/mapinfo.qh:334
+#: qcsrc/common/mapinfo.qh:529
+msgid "The amount of frags needed before the match will end"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:115
+msgid "Deathmatch"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:115
+msgid "Score as many frags as you can"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:128
+msgid "Last Man Standing"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:128
+msgid "Survive and kill until the enemies have no lives left"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:137
+msgid "Lives:"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:149
+msgid "Race"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:149
+msgid "Race against other players to the finish line"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:176
+msgid "Laps:"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:189
+msgid "Race CTS"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:189
+msgid "Race for fastest time."
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:206 qcsrc/common/mapinfo.qh:257
+#: qcsrc/common/mapinfo.qh:373 qcsrc/common/mapinfo.qh:416
+#: qcsrc/common/mapinfo.qh:442 qcsrc/common/mapinfo.qh:462
+#: qcsrc/common/mapinfo.qh:582
+msgid "Point limit:"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:219
+msgid "Help your team score the most frags against the enemy team"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:219
+msgid "Team Deathmatch"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:257 qcsrc/common/mapinfo.qh:373
+#: qcsrc/common/mapinfo.qh:416
+msgid "The amount of points needed before the match will end"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:271
+msgid "Capture the Flag"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:271
+msgid ""
+"Find and bring the enemy flag to your base to capture it, defend your base "
+"from the other team"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:289
+msgid "Capture limit:"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:289
+msgid "The amount of captures needed before the match will end"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:306
+msgid "Clan Arena"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:306
+msgid "Kill all enemy teammates to win the round"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:350
+msgid "Capture and defend all the control points to win"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:350
+msgid "Domination"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:388
+msgid "Gather all the keys to win the round"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:388
+msgid "Key Hunt"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:428
+msgid "Assault"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:428
+msgid ""
+"Destroy obstacles to find and destroy the enemy power core before time runs "
+"out"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:452
+msgid "Capture control points to reach and destroy the enemy generator"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:452
+msgid "Onslaught"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:474
+msgid "Nexball"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:474
+msgid "Shoot and kick the ball into the enemies goal, keep your goal clean"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:488
+msgid "Goals:"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:488
+msgid "The amount of goals needed before the match will end"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:501
+msgid "Freeze Tag"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:501
+msgid ""
+"Kill enemies to freeze them, stand next to frozen teammates to revive them; "
+"freeze all enemies to win"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:545
+msgid "Hold the ball to get points for kills"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:545
+msgid "Keepaway"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:560
+msgid "Invasion"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:560
+msgid "Survive against waves of monsters"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:590
+msgid "Duel"
+msgstr ""
+
+#: qcsrc/common/mapinfo.qh:590
+msgid "Fight in a one versus one arena battle to decide the winner"
+msgstr ""
+
+#: qcsrc/common/minigames/cl_minigames.qc:383
+msgid "It's your turn"
+msgstr ""
+
+#: qcsrc/common/minigames/cl_minigames_hud.qc:366
+#: qcsrc/menu/xonotic/dialog_quit.qh:6
+msgid "Quit"
+msgstr ""
+
+#: qcsrc/common/minigames/cl_minigames_hud.qc:371
+msgid "Invite"
+msgstr ""
+
+#: qcsrc/common/minigames/cl_minigames_hud.qc:410
+msgid "Current Game"
+msgstr ""
+
+#: qcsrc/common/minigames/cl_minigames_hud.qc:435
+msgid "Exit Menu"
+msgstr ""
+
+#: qcsrc/common/minigames/cl_minigames_hud.qc:447
+#: qcsrc/menu/xonotic/dialog_multiplayer.qc:16
+msgid "Create"
+msgstr ""
+
+#: qcsrc/common/minigames/cl_minigames_hud.qc:450
+msgid "Join"
+msgstr ""
+
+#: qcsrc/common/minigames/cl_minigames_hud.qc:526
+msgid "Minigames"
+msgstr ""
+
+#: qcsrc/common/minigames/cl_minigames_hud.qc:587
+msgid "Minigame message"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/bd.qc:2
+msgid "Bulldozer"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/bd.qc:1092
+#: qcsrc/common/minigames/minigame/ps.qc:421
+#: qcsrc/common/minigames/minigame/ps.qc:427
+msgid "Game over!"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/bd.qc:1095
+msgid "Well done! Click 'Next Level' to continue"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/bd.qc:1162
+msgid "Better luck next time!"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/bd.qc:1167
+msgid "Tubular! Press \"Next Level\" to continue!"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/bd.qc:1169
+msgid "Wicked! Press \"Next Level\" to continue!"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/bd.qc:1173
+msgid "Press the space bar to change your currently selected tile"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/bd.qc:1176
+msgid "Push the boulders onto the targets"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/bd.qc:1403
+msgid "Next Level"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/bd.qc:1404
+msgid "Restart"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/bd.qc:1405
+msgid "Editor"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/bd.qc:1406
+#: qcsrc/menu/xonotic/dialog_settings_input_userbind.qc:37
+msgid "Save"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/c4.qc:2
+msgid "Connect Four"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/c4.qc:311
+#: qcsrc/common/minigames/minigame/c4.qc:317
+#: qcsrc/common/minigames/minigame/nmm.qc:491
+#: qcsrc/common/minigames/minigame/nmm.qc:497
+#: qcsrc/common/minigames/minigame/pp.qc:362
+#: qcsrc/common/minigames/minigame/pp.qc:368
+#, c-format
+msgid "%s^7 won the game!"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/c4.qc:373
+#: qcsrc/common/minigames/minigame/pp.qc:438
+#: qcsrc/common/minigames/minigame/ttt.qc:319
+msgid "Draw"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/c4.qc:378
+#: qcsrc/common/minigames/minigame/nmm.qc:606
+#: qcsrc/common/minigames/minigame/pp.qc:444
+#: qcsrc/common/minigames/minigame/ttt.qc:326
+msgid "You lost the game!"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/c4.qc:379
+#: qcsrc/common/minigames/minigame/nmm.qc:607
+#: qcsrc/common/minigames/minigame/pp.qc:445
+#: qcsrc/common/minigames/minigame/ttt.qc:327
+msgid "You win!"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/c4.qc:383
+#: qcsrc/common/minigames/minigame/nmm.qc:611
+#: qcsrc/common/minigames/minigame/pp.qc:456
+#: qcsrc/common/minigames/minigame/ttt.qc:338
+msgid "Wait for your opponent to make their move"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/c4.qc:386
+#: qcsrc/common/minigames/minigame/nmm.qc:613
+#: qcsrc/common/minigames/minigame/pp.qc:459
+#: qcsrc/common/minigames/minigame/ttt.qc:341
+msgid "Click on the game board to place your piece"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/nmm.qc:7
+msgid "Nine Men's Morris"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/nmm.qc:615
+msgid ""
+"You can select one of your pieces to move it in one of the surrounding places"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/nmm.qc:617
+msgid "You can select one of your pieces to move it anywhere on the board"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/nmm.qc:619
+msgid "You can take one of the opponent's pieces"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/pong.qc:2
+msgid "Pong"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/pong.qc:589
+#: qcsrc/common/minigames/minigame/ttt.qc:299
+msgid "AI"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/pong.qc:606
+msgid "Press ^1Start Match^7 to start the match with the current players"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/pong.qc:679
+msgid "Start Match"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/pong.qc:680
+msgid "Add AI player"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/pong.qc:681
+msgid "Remove AI player"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/pp.qc:2
+msgid "Push-Pull"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/pp.qc:444
+#: qcsrc/common/minigames/minigame/ttt.qc:326
+msgid "Select \"^1Next Match^7\" on the menu for a rematch!"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/pp.qc:445
+#: qcsrc/common/minigames/minigame/pp.qc:451
+#: qcsrc/common/minigames/minigame/ttt.qc:327
+#: qcsrc/common/minigames/minigame/ttt.qc:333
+msgid "Select \"^1Next Match^7\" on the menu to start a new match!"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/pp.qc:452
+#: qcsrc/common/minigames/minigame/ttt.qc:334
+msgid "Wait for your opponent to confirm the rematch"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/pp.qc:587
+#: qcsrc/common/minigames/minigame/ttt.qc:671
+msgid "Next Match"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/ps.qc:2
+msgid "Peg Solitaire"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/ps.qc:414
+msgid "All pieces cleared!"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/ps.qc:416
+msgid "Remaining pieces:"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/ps.qc:481
+#, c-format
+msgid "Pieces left: %s"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/ps.qc:491
+msgid "No more valid moves"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/ps.qc:494
+msgid "Well done, you win!"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/ps.qc:497
+msgid "Jump a piece over another to capture it"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/ttt.qc:2
+msgid "Tic Tac Toe"
+msgstr ""
+
+#: qcsrc/common/minigames/minigame/ttt.qc:672
+msgid "Single Player"
+msgstr ""
+
+#: qcsrc/common/monsters/monster/mage.qh:17
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:18
+msgid "Mage"
+msgstr ""
+
+#: qcsrc/common/monsters/monster/mage.qh:29
+msgid "Mage spike"
+msgstr ""
+
+#: qcsrc/common/monsters/monster/shambler.qh:17
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:17
+msgid "Shambler"
+msgstr ""
+
+#: qcsrc/common/monsters/monster/spider.qh:17
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:16
+msgid "Spider"
+msgstr ""
+
+#: qcsrc/common/monsters/monster/spider.qh:28
+msgid "Spider attack"
+msgstr ""
+
+#: qcsrc/common/monsters/monster/wyvern.qh:17
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:19
+msgid "Wyvern"
+msgstr ""
+
+#: qcsrc/common/monsters/monster/wyvern.qh:28
+msgid "Wyvern attack"
+msgstr ""
+
+#: qcsrc/common/monsters/monster/zombie.qh:17
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:15
+msgid "Zombie"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:16
+msgid "Ammo"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:25
+msgid "Resistance"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:34
+#: qcsrc/common/mutators/mutator/instagib/items.qh:126
+#: qcsrc/common/mutators/mutator/instagib/items.qh:129
+msgid "Speed"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:44
+msgid "Medic"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:54
+msgid "Bash"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:63
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:83
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:184
+msgid "Vampire"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:71
+msgid "Disability"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:79
+msgid "Vengeance"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:87
+msgid "Jump"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:96
+msgid "Invisible"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:105
+msgid "Inferno"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:113
+msgid "Swapper"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:121
+msgid "Magnet"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:129
+msgid "Luck"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/all.inc:137
+msgid "Flight"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/buffs/buffs.qh:11
+msgid "Buff"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/damagetext/ui_damagetext.qc:8
+msgid "Damage text"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/damagetext/ui_damagetext.qc:18
+msgid "Draw damage numbers"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/damagetext/ui_damagetext.qc:20
+msgid "Font size minimum:"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/damagetext/ui_damagetext.qc:25
+msgid "Font size maximum:"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/damagetext/ui_damagetext.qc:30
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:55
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:102
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:60
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:109
+#: qcsrc/menu/xonotic/util.qc:775
+msgid "Color:"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/damagetext/ui_damagetext.qc:36
+msgid "Draw damage numbers for friendly fire"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/instagib/items.qh:33
+msgid "Vaporizer ammo"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/instagib/items.qh:59
+#: qcsrc/common/mutators/mutator/instagib/items.qh:62
+msgid "Extra life"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/instagib/items.qh:91
+#: qcsrc/common/mutators/mutator/instagib/items.qh:94
+msgid "Invisibility"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/nades/nades.inc:18
+msgid "Napalm grenade"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/nades/nades.inc:26
+msgid "Ice grenade"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/nades/nades.inc:34
+msgid "Translocate grenade"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/nades/nades.inc:42
+msgid "Spawn grenade"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/nades/nades.inc:50
+msgid "Heal grenade"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/nades/nades.inc:58
+msgid "Monster grenade"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/nades/nades.inc:66
+msgid "Entrap grenade"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/nades/nades.inc:74
+msgid "Veil grenade"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/nades/nades.qh:33
+msgid "Grenade"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/overkill/okhmg.qh:20
+msgid "Overkill Heavy Machine Gun"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/overkill/okmachinegun.qh:18
+msgid "Overkill MachineGun"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/overkill/oknex.qh:19
+msgid "Overkill Nex"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/overkill/okrpc.qh:20
+msgid "Overkill Rocket Propelled Chainsaw"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/overkill/okshotgun.qh:18
+msgid "Overkill Shotgun"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:3
+msgid "Waypoint"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:4
+msgid "Help me!"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:5
+msgid "Here"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:6
+msgid "DANGER"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:8
+msgid "Frozen!"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:10
+msgid "Item"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:12
+msgid "Checkpoint"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:13
+#: qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc:240
+msgid "Finish"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:14
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:15
+#: qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc:240
+msgid "Start"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:17
+msgid "Defend"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:18
+msgid "Destroy"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:19
+msgid "Push"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:21
+msgid "Flag carrier"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:22
+msgid "Enemy carrier"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:23
+msgid "Dropped flag"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:24
+msgid "White base"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:25
+msgid "Red base"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:26
+msgid "Blue base"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:27
+msgid "Yellow base"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:28
+msgid "Pink base"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:29
+msgid "Return flag here"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:31
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:32
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:33
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:34
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:35
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:51
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:52
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:53
+msgid "Control point"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:37
+msgid "Dropped key"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:38
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:40
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:41
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:42
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:43
+msgid "Key carrier"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:39
+msgid "Run here"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:45
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:48
+msgid "Ball"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:46
+msgid "Ball carrier"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:49
+msgid "Goal"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:54
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:55
+msgid "Generator"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:57
+msgid "Weapon"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:59
+msgid "Monster"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:61
+msgid "Vehicle"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:62
+msgid "Intruder!"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/all.inc:64
+msgid "Tagged"
+msgstr ""
+
+#: qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc:697
+#, c-format
+msgid "%s needing help!"
+msgstr ""
+
+#: qcsrc/common/net_notice.qc:90
+msgid "^1Server notices:"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:230
+msgid "^F4NOTE: ^BGSpectator chat is not sent to players during the match"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:232
+#, c-format
+msgid "^BG%s^BG captured the ^TC^TT^BG flag"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:233
+#, c-format
+msgid ""
+"^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds, breaking ^BG"
+"%s^BG's previous record of ^F2%s^BG seconds"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:234
+#, c-format
+msgid "^BG%s^BG captured the flag"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:235
+#, c-format
+msgid "^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:236
+#, c-format
+msgid ""
+"^BG%s^BG captured the ^TC^TT^BG flag in ^F2%s^BG seconds, failing to break "
+"^BG%s^BG's previous record of ^F1%s^BG seconds"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:237
+msgid "^BGThe ^TC^TT^BG flag was returned to base by its owner"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:238
+msgid "^BGThe flag was returned by its owner"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:239
+msgid "^BGThe ^TC^TT^BG flag was destroyed and returned to base"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:240
+msgid "^BGThe flag was destroyed and returned to base"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:241
+msgid "^BGThe ^TC^TT^BG flag was dropped in the base and returned itself"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:242
+msgid "^BGThe flag was dropped in the base and returned itself"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:243
+msgid ""
+"^BGThe ^TC^TT^BG flag fell somewhere it couldn't be reached and returned to "
+"base"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:244
+msgid "^BGThe flag fell somewhere it couldn't be reached and returned to base"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:245
+#, c-format
+msgid ""
+"^BGThe ^TC^TT^BG flag became impatient after ^F1%.2f^BG seconds and returned "
+"itself"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:246
+#, c-format
+msgid ""
+"^BGThe flag became impatient after ^F1%.2f^BG seconds and returned itself"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:247
+msgid "^BGThe ^TC^TT^BG flag has returned to the base"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:248
+msgid "^BGThe flag has returned to the base"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:249
+#, c-format
+msgid "^BG%s^BG lost the ^TC^TT^BG flag"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:250
+#, c-format
+msgid "^BG%s^BG lost the flag"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:251
+#, c-format
+msgid "^BG%s^BG got the ^TC^TT^BG flag"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:252
+#, c-format
+msgid "^BG%s^BG got the flag"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:253
+#: qcsrc/common/notifications/all.inc:254
+#, c-format
+msgid "^BG%s^BG returned the ^TC^TT^BG flag"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:256
+#: qcsrc/common/notifications/all.inc:544
+#, c-format
+msgid "^F2Throwing coin... Result: %s^F2!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:258
+msgid "^BGYou don't have any fuel for the ^F1Jetpack"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:260
+msgid "^F2You lack a UID, superspec options will not be saved/restored"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:262
+msgid "^F1Round already started, you will join the game in the next round"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:263
+msgid "^F2You will spectate in the next round"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:265
+#, c-format
+msgid "^BG%s%s^K1 was killed by ^BG%s^K1's ^BG%s^K1 buff ^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:265
+#, c-format
+msgid "^BG%s%s^K1 was scored against by ^BG%s^K1's ^BG%s^K1 buff ^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:266
+#, c-format
+msgid "^BG%s%s^K1 was unfairly eliminated by ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:267
+#, c-format
+msgid "^BG%s%s^K1 was drowned by ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:268
+#, c-format
+msgid "^BG%s%s^K1 was grounded by ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:269
+#, c-format
+msgid "^BG%s%s^K1 felt a little hot from ^BG%s^K1's fire^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:269
+#, c-format
+msgid "^BG%s%s^K1 was burnt up into a crisp by ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:270
+#, c-format
+msgid "^BG%s%s^K1 was cooked by ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:271
+#, c-format
+msgid "^BG%s%s^K1 was pushed in front of a monster by ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:272
+#, c-format
+msgid "^BG%s%s^K1 was blown up by ^BG%s^K1's Nade%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:273
+#, c-format
+msgid "^BG%s%s^K1 got too close to a napalm explosion%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:273
+#, c-format
+msgid "^BG%s%s^K1 was burned to death by ^BG%s^K1's Napalm Nade%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:274
+#, c-format
+msgid "^BG%s%s^K1 was blown up by ^BG%s^K1's Ice Nade%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:275
+#, c-format
+msgid "^BG%s%s^K1 was frozen to death by ^BG%s^K1's Ice Nade%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:276
+#, c-format
+msgid "^BG%s%s^K1 has not been healed by ^BG%s^K1's Healing Nade%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:277
+#, c-format
+msgid "^BG%s%s^K1 was shot into space by ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:278
+#, c-format
+msgid "^BG%s%s^K1 was slimed by ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:279
+#, c-format
+msgid "^BG%s%s^K1 was preserved by ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:280
+#, c-format
+msgid "^BG%s%s^K1 tried to occupy ^BG%s^K1's teleport destination space%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:280
+#, c-format
+msgid "^BG%s%s^K1 was telefragged by ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:281
+#, c-format
+msgid "^BG%s%s^K1 died in an accident with ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:282
+#, c-format
+msgid ""
+"^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Bumblebee exploded%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:283
+#, c-format
+msgid "^BG%s%s^K1 saw the pretty lights of ^BG%s^K1's Bumblebee gun%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:284
+#, c-format
+msgid "^BG%s%s^K1 was crushed by ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:285
+#, c-format
+msgid "^BG%s%s^K1 was cluster bombed by ^BG%s^K1's Raptor%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:286
+#, c-format
+msgid "^BG%s%s^K1 couldn't resist ^BG%s^K1's purple blobs%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:287
+#, c-format
+msgid "^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Raptor exploded%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:288
+#, c-format
+msgid ""
+"^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Spiderbot exploded%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:289
+#, c-format
+msgid "^BG%s%s^K1 got shredded by ^BG%s^K1's Spiderbot%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:290
+#, c-format
+msgid "^BG%s%s^K1 was blasted to bits by ^BG%s^K1's Spiderbot%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:291
+#, c-format
+msgid "^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Racer exploded%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:292
+#, c-format
+msgid "^BG%s%s^K1 was bolted down by ^BG%s^K1's Racer%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:293
+#, c-format
+msgid "^BG%s%s^K1 couldn't find shelter from ^BG%s^K1's Racer%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:294
+#, c-format
+msgid "^BG%s%s^K1 was thrown into a world of hurt by ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:296
+#, c-format
+msgid "^BG%s^K1 was moved into the %s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:297
+#, c-format
+msgid "^BG%s^K1 became enemies with the Lord of Teamplay%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:298
+#, c-format
+msgid "^BG%s^K1 thought they found a nice camping ground%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:299
+#, c-format
+msgid "^BG%s^K1 unfairly eliminated themself%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:301
+#, c-format
+msgid "^BG%s^K1 couldn't catch their breath%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:301
+#, c-format
+msgid "^BG%s^K1 was in the water for too long%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:302
+#, c-format
+msgid "^BG%s^K1 hit the ground with a bit too much force%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:302
+#, c-format
+msgid "^BG%s^K1 hit the ground with a crunch%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:303
+#, c-format
+msgid "^BG%s^K1 became a bit too crispy%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:303
+#, c-format
+msgid "^BG%s^K1 felt a little hot%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:304
+#, c-format
+msgid "^BG%s^K1 died%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:305
+#, c-format
+msgid "^BG%s^K1 found a hot place%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:305
+#, c-format
+msgid "^BG%s^K1 turned into hot slag%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:306
+#, c-format
+msgid "^BG%s^K1 was exploded by a Mage%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:307
+#, c-format
+msgid "^BG%s^K1's innards became outwards by a Shambler%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:308
+#, c-format
+msgid "^BG%s^K1 was smashed by a Shambler%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:309
+#, c-format
+msgid "^BG%s^K1 was zapped to death by a Shambler%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:310
+#, c-format
+msgid "^BG%s^K1 was bitten by a Spider%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:311
+#, c-format
+msgid "^BG%s^K1 was fireballed by a Wyvern%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:312
+#, c-format
+msgid "^BG%s^K1 joins the Zombies%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:313
+#, c-format
+msgid "^BG%s^K1 was given kung fu lessons by a Zombie%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:314
+#: qcsrc/common/notifications/all.inc:316
+#, c-format
+msgid "^BG%s^K1 mastered the art of self-nading%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:315
+#, c-format
+msgid ""
+"^BG%s^K1 decided to take a look at the results of their napalm explosion%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:315
+#, c-format
+msgid "^BG%s^K1 was burned to death by their own Napalm Nade%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:317
+#, c-format
+msgid "^BG%s^K1 felt a little chilly%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:317
+#, c-format
+msgid "^BG%s^K1 was frozen to death by their own Ice Nade%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:318
+#, c-format
+msgid "^BG%s^K1's Healing Nade didn't quite heal them%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:319
+#, c-format
+msgid "^BG%s^K1 died%s%s. What's the point of living without ammo?"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:319
+#, c-format
+msgid "^BG%s^K1 ran out of ammo%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:320
+#, c-format
+msgid "^BG%s^K1 rotted away%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:321
+#, c-format
+msgid "^BG%s^K1 became a shooting star%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:322
+#, c-format
+msgid "^BG%s^K1 was slimed%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:323
+#, c-format
+msgid "^BG%s^K1 couldn't take it anymore%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:324
+#, c-format
+msgid "^BG%s^K1 is now preserved for centuries to come%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:325
+#, c-format
+msgid "^BG%s^K1 switched to the %s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:326
+#, c-format
+msgid "^BG%s^K1 died in an accident%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:327
+#, c-format
+msgid "^BG%s^K1 ran into a turret%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:328
+#, c-format
+msgid "^BG%s^K1 was blasted away by an eWheel turret%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:329
+#, c-format
+msgid "^BG%s^K1 got caught up in the FLAC turret fire%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:330
+#, c-format
+msgid "^BG%s^K1 was blasted away by a Hellion turret%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:331
+#, c-format
+msgid "^BG%s^K1 could not hide from the Hunter turret%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:332
+#, c-format
+msgid "^BG%s^K1 was riddled full of holes by a Machinegun turret%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:333
+#, c-format
+msgid "^BG%s^K1 got turned into smoldering gibs by an MLRS turret%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:334
+#, c-format
+msgid "^BG%s^K1 was phased out by a turret%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:335
+#, c-format
+msgid "^BG%s^K1 got served some superheated plasma from a turret%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:336
+#, c-format
+msgid "^BG%s^K1 was electrocuted by a Tesla turret%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:337
+#, c-format
+msgid "^BG%s^K1 got served a lead enrichment by a Walker turret%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:338
+#, c-format
+msgid "^BG%s^K1 was impaled by a Walker turret%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:339
+#, c-format
+msgid "^BG%s^K1 was blasted away by a Walker turret%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:340
+#, c-format
+msgid "^BG%s^K1 got caught in the blast of a Bumblebee explosion%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:341
+#, c-format
+msgid "^BG%s^K1 was crushed by a vehicle%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:342
+#, c-format
+msgid "^BG%s^K1 was caught in a Raptor cluster bomb%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:343
+#, c-format
+msgid "^BG%s^K1 got caught in the blast of a Raptor explosion%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:344
+#, c-format
+msgid "^BG%s^K1 got caught in the blast of a Spiderbot explosion%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:345
+#, c-format
+msgid "^BG%s^K1 was blasted to bits by a Spiderbot rocket%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:346
+#, c-format
+msgid "^BG%s^K1 got caught in the blast of a Racer explosion%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:347
+#, c-format
+msgid "^BG%s^K1 couldn't find shelter from a Racer rocket%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:350
+#, c-format
+msgid "^BG%s^K1 was betrayed by ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:352
+#, c-format
+msgid "^BG%s^BG%s^BG (%s %s every %s seconds)"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:354
+#, c-format
+msgid "^BG%s^K1 was frozen by ^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:355
+#, c-format
+msgid "^BG%s^K3 was revived by ^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:356
+#, c-format
+msgid "^BG%s^K3 was revived by falling"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:357
+#, c-format
+msgid "^BG%s^K3 was revived by their Nade explosion"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:358
+#, c-format
+msgid "^BG%s^K3 was automatically revived after %s seconds"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:359
+#, c-format
+msgid "^BG%s^K1 froze themself"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:361
+#: qcsrc/common/notifications/all.inc:675
+msgid "^TC^TT^BG team wins the round"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:362
+#: qcsrc/common/notifications/all.inc:676
+#, c-format
+msgid "^BG%s^BG wins the round"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:363
+#: qcsrc/common/notifications/all.inc:539
+msgid "^BGRound tied"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:364
+#: qcsrc/common/notifications/all.inc:540
+msgid "^BGRound over, there's no winner"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:366
+#, c-format
+msgid "^BGGodmode saved you %s units of damage, cheater!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:368
+#, c-format
+msgid "^BG%s^BG got the %s^BG buff!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:369
+#, c-format
+msgid "^BG%s^BG lost the %s^BG buff!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:370
+#: qcsrc/common/notifications/all.inc:683
+#, c-format
+msgid "^BGYou dropped the %s^BG buff!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:371
+#: qcsrc/common/notifications/all.inc:684
+#, c-format
+msgid "^BGYou got the %s^BG buff!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:373
+#: qcsrc/common/notifications/all.inc:687
+#, c-format
+msgid "^BGYou do not have the ^F1%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:374
+#: qcsrc/common/notifications/all.inc:688
+#, c-format
+msgid "^BGYou dropped the ^F1%s^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:375
+#: qcsrc/common/notifications/all.inc:689
+#, c-format
+msgid "^BGYou got the ^F1%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:376
+#: qcsrc/common/notifications/all.inc:690
+#, c-format
+msgid "^BGYou don't have enough ammo for the ^F1%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:377
+#: qcsrc/common/notifications/all.inc:691
+#, c-format
+msgid "^F1%s %s^BG is unable to fire, but its ^F1%s^BG can"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:378
+#: qcsrc/common/notifications/all.inc:692
+#, c-format
+msgid "^F1%s^BG is ^F4not available^BG on this map"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:380
+#, c-format
+msgid "^BG%s^BG is connecting..."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:381
+#, c-format
+msgid "^BG%s^F3 connected"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:382
+#, c-format
+msgid "^BG%s^F3 is now playing"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:383
+#, c-format
+msgid "^BG%s^F3 is now playing on the ^TC^TT team"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:385
+#: qcsrc/common/notifications/all.inc:697
+#, c-format
+msgid "^BG%s^BG has dropped the ball!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:386
+#: qcsrc/common/notifications/all.inc:698
+#, c-format
+msgid "^BG%s^BG has picked up the ball!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:388
+#, c-format
+msgid "^BG%s^BG captured the keys for the ^TC^TT team"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:389
+#, c-format
+msgid "^BG%s^BG dropped the ^TC^TT Key"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:390
+#, c-format
+msgid "^BG%s^BG lost the ^TC^TT Key"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:391
+#, c-format
+msgid "^BG%s^BG pushed %s^BG causing the ^TC^TT Key ^BGdestruction"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:392
+#, c-format
+msgid "^BG%s^BG destroyed the ^TC^TT Key"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:393
+#, c-format
+msgid "^BG%s^BG picked up the ^TC^TT Key"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:395
+#, c-format
+msgid "^BG%s^F3 forfeited"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:396
+#, c-format
+msgid "^BG%s^F3 has no more lives left"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:398
+msgid "^BGMonsters are currently disabled"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:400
+msgid "^BGThe ^TC^TT^BG team held the ball for too long"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:402
+#, c-format
+msgid "^BG%s^BG captured %s^BG control point"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:403
+#, c-format
+msgid "^BG%s^BG captured a control point"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:404
+#, c-format
+msgid "^TC^TT^BG team %s^BG control point has been destroyed by %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:405
+#, c-format
+msgid "^TC^TT^BG team control point has been destroyed by %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:406
+msgid "^TC^TT^BG generator has been destroyed"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:407
+msgid "^TC^TT^BG generator spontaneously combusted due to overtime!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:409
+#, c-format
+msgid "^BG%s^K1 picked up Invisibility"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:410
+#, c-format
+msgid "^BG%s^K1 picked up Shield"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:411
+#, c-format
+msgid "^BG%s^K1 picked up Speed"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:412
+#, c-format
+msgid "^BG%s^K1 picked up Strength"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:414
+#, c-format
+msgid "^BG%s^F3 disconnected"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:415
+#, c-format
+msgid "^BG%s^F3 was kicked for idling"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:416
+msgid ""
+"^F2You were kicked from the server because you are a spectator and "
+"spectators aren't allowed at the moment."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:417
+#, c-format
+msgid "^BG%s^F3 was kicked for excessive teamkilling"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:418
+#, c-format
+msgid "^BG%s^F3 is now spectating"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:420
+#, c-format
+msgid "^BG%s^BG has abandoned the race"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:421
+#, c-format
+msgid "^BG%s^BG couldn't break their %s%s^BG place record of %s%s %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:422
+#, c-format
+msgid "^BG%s^BG couldn't break the %s%s^BG place record of %s%s %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:423
+#, c-format
+msgid "^BG%s^BG has finished the race"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:424
+#, c-format
+msgid "^BG%s^BG broke %s^BG's %s%s^BG place record with %s%s %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:425
+#, c-format
+msgid "^BG%s^BG improved their %s%s^BG place record with %s%s %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:426
+#, c-format
+msgid ""
+"^BG%s^BG scored a new record with ^F2%s^BG, but unfortunately lacks a UID "
+"and will be lost."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:427
+#, c-format
+msgid ""
+"^BG%s^BG scored a new record with ^F2%s^BG, but is anonymous and will be "
+"lost."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:428
+#, c-format
+msgid "^BG%s^BG set the %s%s^BG place record with %s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:430
+#, c-format
+msgid ""
+"^F4You have been invited by ^BG%s^F4 to join their game of ^F2%s^F4 "
+"(^F1%s^F4)"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:432
+msgid "^TC^TT ^BGteam scores!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:434
+#, c-format
+msgid ""
+"^F2You have to become a player within the next %s, otherwise you will be "
+"kicked, because spectating isn't allowed at this time!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:436
+#, c-format
+msgid "^BG%s^K1 picked up a Superweapon"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:438
+msgid "^BGYou cannot change to a larger team"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:439
+msgid "^BGYou are not allowed to change teams"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:441
+#, c-format
+msgid ""
+"^F4NOTE: ^BGThe server is running ^F1Xonotic %s (beta)^BG, you have "
+"^F2Xonotic %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:442
+#, c-format
+msgid ""
+"^F4NOTE: ^BGThe server is running ^F1Xonotic %s^BG, you have ^F2Xonotic %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:443
+#, c-format
+msgid ""
+"^F4NOTE: ^F1Xonotic %s^BG is out, and you still have ^F2Xonotic %s^BG - get "
+"the update from ^F3http://www.xonotic.org/^BG!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:445
+#, c-format
+msgid "^F3SVQC Build information: ^F4%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:447
+#, c-format
+msgid ""
+"^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Accordeon%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:448
+#, c-format
+msgid "^BG%s^K1 hurt their own ears with the @!#%%'n Accordeon%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:449
+#, c-format
+msgid "^BG%s%s^K1 was electrocuted by ^BG%s^K1's Arc%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:450
+#, c-format
+msgid "^BG%s%s^K1 was blasted by ^BG%s^K1's Arc bolts%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:451
+#, c-format
+msgid "^BG%s%s^K1 was shot to death by ^BG%s^K1's Blaster%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:452
+#, c-format
+msgid "^BG%s^K1 shot themself to hell with their Blaster%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:453
+#, c-format
+msgid "^BG%s%s^K1 felt the strong pull of ^BG%s^K1's Crylink%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:454
+#, c-format
+msgid "^BG%s^K1 felt the strong pull of their Crylink%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:455
+#, c-format
+msgid "^BG%s%s^K1 ate ^BG%s^K1's rocket%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:456
+#, c-format
+msgid "^BG%s%s^K1 got too close to ^BG%s^K1's rocket%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:457
+#, c-format
+msgid "^BG%s^K1 blew themself up with their Devastator%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:458
+#, c-format
+msgid "^BG%s%s^K1 was blasted by ^BG%s^K1's Electro bolt%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:459
+#, c-format
+msgid "^BG%s%s^K1 felt the electrifying air of ^BG%s^K1's Electro combo%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:460
+#, c-format
+msgid "^BG%s%s^K1 got too close to ^BG%s^K1's Electro orb%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:461
+#, c-format
+msgid "^BG%s^K1 played with Electro bolts%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:462
+#, c-format
+msgid "^BG%s^K1 could not remember where they put their Electro orb%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:463
+#, c-format
+msgid "^BG%s%s^K1 got too close to ^BG%s^K1's fireball%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:464
+#, c-format
+msgid "^BG%s%s^K1 got burnt by ^BG%s^K1's firemine%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:465
+#, c-format
+msgid "^BG%s^K1 should have used a smaller gun%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:466
+#, c-format
+msgid "^BG%s^K1 forgot about their firemine%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:467
+#, c-format
+msgid "^BG%s%s^K1 was pummeled by a burst of ^BG%s^K1's Hagar rockets%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:468
+#, c-format
+msgid "^BG%s%s^K1 was pummeled by ^BG%s^K1's Hagar rockets%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:469
+#, c-format
+msgid "^BG%s^K1 played with tiny Hagar rockets%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:470
+#, c-format
+msgid "^BG%s%s^K1 was cut down with ^BG%s^K1's HLAC%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:471
+#, c-format
+msgid "^BG%s^K1 got a little jumpy with their HLAC%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:472
+#, c-format
+msgid "^BG%s%s^K1 was caught in ^BG%s^K1's Hook gravity bomb%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:473
+#, c-format
+msgid ""
+"^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Klein Bottle%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:474
+#, c-format
+msgid "^BG%s^K1 hurt their own ears with the @!#%%'n Klein Bottle%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:475
+#, c-format
+msgid "^BG%s%s^K1 was sniped by ^BG%s^K1's Machine Gun%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:476
+#, c-format
+msgid "^BG%s%s^K1 was riddled full of holes by ^BG%s^K1's Machine Gun%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:477
+#: qcsrc/common/notifications/all.inc:782
+#, c-format
+msgid "^BGYou cannot place more than ^F2%s^BG mines at a time"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:478
+#, c-format
+msgid "^BG%s%s^K1 got too close to ^BG%s^K1's mine%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:479
+#, c-format
+msgid "^BG%s^K1 forgot about their mine%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:480
+#, c-format
+msgid "^BG%s%s^K1 got too close to ^BG%s^K1's Mortar grenade%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:481
+#, c-format
+msgid "^BG%s%s^K1 ate ^BG%s^K1's Mortar grenade%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:482
+#, c-format
+msgid "^BG%s^K1 didn't see their own Mortar grenade%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:483
+#, c-format
+msgid "^BG%s^K1 blew themself up with their own Mortar%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:484
+#, c-format
+msgid "^BG%s%s^K1 was sniped by ^BG%s^K1's Overkill Heavy Machine Gun%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:485
+#, c-format
+msgid ""
+"^BG%s%s^K1 was torn to bits by ^BG%s^K1's Overkill Heavy Machine Gun%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:486
+#, c-format
+msgid ""
+"^BG%s%s^K1 was riddled full of holes by ^BG%s^K1's Overkill Machine Gun%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:487
+#, c-format
+msgid "^BG%s%s^K1 has been vaporized by ^BG%s^K1's Overkill Nex%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:488
+#, c-format
+msgid ""
+"^BG%s%s^K1 was sawn in half by ^BG%s^K1's Overkill Rocket Propelled Chainsaw"
+"%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:489
+#, c-format
+msgid ""
+"^BG%s%s^K1 almost dodged ^BG%s^K1's Overkill Rocket Propelled Chainsaw%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:490
+#, c-format
+msgid ""
+"^BG%s^K1 was sawn in half by their own Overkill Rocket Propelled Chainsaw%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:491
+#, c-format
+msgid ""
+"^BG%s^K1 blew themself up with their Overkill Rocket Propelled Chainsaw%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:493
+#, c-format
+msgid "^BG%s%s^K1 was gunned down by ^BG%s^K1's Overkill Shotgun%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:494
+#, c-format
+msgid "^BG%s%s^K1 was sniped with a Rifle by ^BG%s^K1%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:495
+#, c-format
+msgid "^BG%s%s^K1 died in ^BG%s^K1's Rifle bullet hail%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:496
+#, c-format
+msgid "^BG%s%s^K1 failed to hide from ^BG%s^K1's Rifle bullet hail%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:497
+#, c-format
+msgid "^BG%s%s^K1 failed to hide from ^BG%s^K1's Rifle%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:498
+#, c-format
+msgid "^BG%s%s^K1 was pummeled by ^BG%s^K1's Seeker rockets%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:499
+#, c-format
+msgid "^BG%s%s^K1 was tagged by ^BG%s^K1's Seeker%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:500
+#, c-format
+msgid "^BG%s^K1 played with tiny Seeker rockets%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:501
+#, c-format
+msgid "^BG%s%s^K1 was gunned down by ^BG%s^K1's Shockwave%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:502
+#, c-format
+msgid "^BG%s%s^K1 slapped ^BG%s^K1 around a bit with a large Shockwave%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:503
+#, c-format
+msgid "^BG%s%s^K1 was gunned down by ^BG%s^K1's Shotgun%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:504
+#, c-format
+msgid "^BG%s%s^K1 slapped ^BG%s^K1 around a bit with a large Shotgun%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:505
+#, c-format
+msgid "^BG%s^K1 is now thinking with portals%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:506
+#, c-format
+msgid "^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Tuba%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:507
+#, c-format
+msgid "^BG%s^K1 hurt their own ears with the @!#%%'n Tuba%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:508
+#, c-format
+msgid "^BG%s%s^K1 has been sublimated by ^BG%s^K1's Vaporizer%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:509
+#, c-format
+msgid "^BG%s%s^K1 has been vaporized by ^BG%s^K1's Vortex%s%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:528
+msgid "^F4You are now alone!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:530
+msgid "^BGYou are attacking!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:531
+msgid "^BGYou are defending!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:532
+#, c-format
+msgid "^BGObjective destroyed in ^F4%s^BG!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:534
+msgid "^F4Begin!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:535
+msgid "^F4Game starts in ^COUNT"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:536
+msgid "^F4Round starts in ^COUNT"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:537
+msgid "^F4Round cannot start"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:542
+msgid "^F2Don't camp!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:546
+msgid ""
+"^BGYou are now free.\n"
+"^BGFeel free to ^F2try to capture^BG the flag again\n"
+"^BGif you think you will succeed."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:547
+msgid "^BGThis flag is currently inactive"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:548
+msgid ""
+"^BGYou are now ^F1shielded^BG from the flag(s)\n"
+"^BGfor ^F2too many unsuccessful attempts^BG to capture.\n"
+"^BGMake some defensive scores before trying again."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:549
+msgid "^BGYou captured the ^TC^TT^BG flag!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:550
+msgid "^BGYou captured the flag!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:551
+#, c-format
+msgid "^BGToo many flag throws! Throwing disabled for %s."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:552
+#, c-format
+msgid "^BG%s^BG passed the ^TC^TT^BG flag to %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:553
+#, c-format
+msgid "^BG%s^BG passed the flag to %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:554
+#, c-format
+msgid "^BGYou received the ^TC^TT^BG flag from %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:555
+#, c-format
+msgid "^BGYou received the flag from %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:556
+#, c-format
+msgid "^BGPress ^F2%s^BG to receive the flag from %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:557
+#, c-format
+msgid "^BGRequesting %s^BG to pass you the flag"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:558
+#, c-format
+msgid "^BGYou passed the ^TC^TT^BG flag to %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:559
+#, c-format
+msgid "^BGYou passed the flag to %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:560
+msgid "^BGYou got the ^TC^TT^BG flag!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:561
+msgid "^BGYou got the flag!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:562
+#, c-format
+msgid "^BGYou got your %steam^BG's flag, return it!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:563
+#, c-format
+msgid "^BGYou got the %senemy^BG's flag, return it!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:564
+#, c-format
+msgid "^BGThe %senemy^BG got your flag! Retrieve it!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:565
+#, c-format
+msgid "^BGThe %senemy (^BG%s%s)^BG got your flag! Retrieve it!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:566
+#, c-format
+msgid "^BGThe %senemy^BG got the flag! Retrieve it!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:567
+#, c-format
+msgid "^BGThe %senemy (^BG%s%s)^BG got the flag! Retrieve it!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:568
+#, c-format
+msgid "^BGThe %senemy^BG got their flag! Retrieve it!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:569
+#, c-format
+msgid "^BGThe %senemy (^BG%s%s)^BG got their flag! Retrieve it!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:570
+#, c-format
+msgid "^BGYour %steam mate^BG got the ^TC^TT^BG flag! Protect them!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:571
+#, c-format
+msgid "^BGYour %steam mate (^BG%s%s)^BG got the ^TC^TT^BG flag! Protect them!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:572
+#, c-format
+msgid "^BGYour %steam mate^BG got the flag! Protect them!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:573
+#, c-format
+msgid "^BGYour %steam mate (^BG%s%s)^BG got the flag! Protect them!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:574
+msgid "^BGEnemies can now see you on radar!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:575
+msgid "^BGYou returned the ^TC^TT^BG flag!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:576
+msgid "^BGStalemate! Enemies can now see you on radar!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:577
+msgid "^BGStalemate! Flag carriers can now be seen by enemies on radar!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:581
+#, c-format
+msgid "^K3%sYou fragged ^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:582
+#: qcsrc/common/notifications/all.inc:591
+#: qcsrc/common/notifications/all.inc:600
+#, c-format
+msgid "^K3%sYou scored against ^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:583
+#, c-format
+msgid "^K1%sYou were fragged by ^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:584
+#: qcsrc/common/notifications/all.inc:593
+#: qcsrc/common/notifications/all.inc:602
+#, c-format
+msgid "^K1%sYou were scored against by ^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:590
+#, c-format
+msgid "^K3%sYou burned ^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:592
+#, c-format
+msgid "^K1%sYou were burned by ^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:599
+#, c-format
+msgid "^K3%sYou froze ^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:601
+#, c-format
+msgid "^K1%sYou were frozen by ^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:608
+#, c-format
+msgid "^K1%sYou typefragged ^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:609
+#, c-format
+msgid "^K1%sYou scored against ^BG%s^K1 while they were typing"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:610
+#, c-format
+msgid "^K1%sYou were typefragged by ^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:611
+#, c-format
+msgid "^K1%sYou were scored against by ^BG%s^K1 while typing"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:617
+#, c-format
+msgid "^BGPress ^F2%s^BG again to toss the nade!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:618
+msgid "^F2You got a ^K1BONUS GRENADE^F2!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:620
+#, c-format
+msgid ""
+"^BGYou have been moved into a different team\n"
+"You are now on: %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:621
+msgid "^K1Don't go against your team mates!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:621
+msgid "^K1Don't shoot your team mates!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:622
+msgid "^K1Die camper!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:622
+msgid "^K1Reconsider your tactics, camper!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:623
+msgid "^K1You unfairly eliminated yourself!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:624
+#, c-format
+msgid "^K1You were %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:625
+msgid "^K1You couldn't catch your breath!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:626
+msgid "^K1You hit the ground with a crunch!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:627
+msgid "^K1You felt a little too hot!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:627
+msgid "^K1You got a little bit too crispy!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:628
+msgid "^K1You killed your own dumb self!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:628
+msgid "^K1You need to be more careful!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:629
+msgid "^K1You couldn't stand the heat!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:630
+msgid "^K1You need to watch out for monsters!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:630
+msgid "^K1You were killed by a monster!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:631
+msgid "^K1Tastes like chicken!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:631
+msgid "^K1You forgot to put the pin back in!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:632
+msgid "^K1Hanging around a napalm explosion is bad!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:633
+msgid "^K1You felt a little chilly!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:633
+msgid "^K1You got a little bit too cold!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:634
+msgid "^K1Your Healing Nade is a bit defective"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:635
+msgid "^K1You are respawning for running out of ammo..."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:635
+msgid "^K1You were killed for running out of ammo..."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:636
+msgid "^K1You grew too old without taking your medicine"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:636
+msgid "^K1You need to preserve your health"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:637
+msgid "^K1You became a shooting star!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:638
+msgid "^K1You melted away in slime!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:639
+msgid "^K1You committed suicide!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:639
+msgid "^K1You ended it all!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:640
+msgid "^K1You got stuck in a swamp!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:641
+#, c-format
+msgid "^BGYou are now on: %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:642
+msgid "^K1You died in an accident!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:643
+msgid "^K1You had an unfortunate run in with a turret!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:643
+msgid "^K1You were fragged by a turret!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:644
+msgid "^K1You had an unfortunate run in with an eWheel turret!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:644
+msgid "^K1You were fragged by an eWheel turret!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:645
+msgid "^K1You had an unfortunate run in with a Walker turret!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:645
+msgid "^K1You were fragged by a Walker turret!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:646
+msgid "^K1You got caught in the blast of a Bumblebee explosion!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:647
+msgid "^K1You were crushed by a vehicle!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:648
+msgid "^K1You were caught in a Raptor cluster bomb!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:649
+msgid "^K1You got caught in the blast of a Raptor explosion!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:650
+msgid "^K1You got caught in the blast of a Spiderbot explosion!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:651
+msgid "^K1You were blasted to bits by a Spiderbot rocket!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:652
+msgid "^K1You got caught in the blast of a Racer explosion!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:653
+msgid "^K1You couldn't find shelter from a Racer rocket!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:654
+msgid "^K1Watch your step!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:656
+#, c-format
+msgid "^K1Moron! You fragged ^BG%s^K1, a team mate!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:656
+#, c-format
+msgid "^K1Moron! You went against ^BG%s^K1, a team mate!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:657
+#, c-format
+msgid "^K1You were fragged by ^BG%s^K1, a team mate"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:657
+#, c-format
+msgid "^K1You were scored against by ^BG%s^K1, a team mate"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:659
+msgid ""
+"^K1Stop idling!\n"
+"^BGDisconnecting in ^COUNT..."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:661
+#, c-format
+msgid "^BGYou need %s^BG!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:662
+#, c-format
+msgid "^BGYou also need %s^BG!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:663
+msgid "^BGDoor unlocked!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:665
+#, c-format
+msgid "^F2Extra lives taken: ^K1%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:667
+#, c-format
+msgid "^K3You revived ^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:668
+msgid "^K3You revived yourself"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:669
+#, c-format
+msgid "^K3You were revived by ^BG%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:670
+#, c-format
+msgid "^K3You were automatically revived after %s seconds"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:672
+msgid "^BGThe generator is under attack!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:674
+msgid "^TC^TT^BG team loses the round"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:678
+msgid "^K1You froze yourself"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:679
+msgid "^K1Round already started, you spawn as frozen"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:681
+#, c-format
+msgid "^K1A %s has arrived!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:685
+msgid "^BGYou got the ^F1Fuel regenerator"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:686
+msgid "^BGYou got the ^F1Jetpack"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:694
+msgid ""
+"^K1No spawnpoints available!\n"
+"Hope your team can fix it..."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:695
+msgid ""
+"^K1You may not join the game at this time.\n"
+"The player limit reached maximum capacity."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:699
+msgid "^BGYou picked up the ball"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:700
+msgid "^BGKilling people while you don't have the ball gives no points!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:702
+msgid ""
+"^BGAll keys are in your team's hands!\n"
+"Help the key carriers to meet!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:703
+msgid ""
+"^BGAll keys are in ^TC^TT team^BG's hands!\n"
+"Interfere ^F4NOW^BG!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:704
+msgid ""
+"^BGAll keys are in your team's hands!\n"
+"Meet the other key carriers ^F4NOW^BG!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:705
+msgid "^F4Round will start in ^COUNT"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:706
+msgid "^BGScanning frequency range..."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:707
+msgid "^BGYou are starting with the ^TC^TT Key"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:709
+msgid "^BGYou have no lives left, you must wait until the next match"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:711
+#, c-format
+msgid ""
+"^BGWaiting for players to join...\n"
+"Need active players for: %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:712
+#, c-format
+msgid "^BGWaiting for %s player(s) to join..."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:714
+msgid "^BGYour weapon has been downgraded until you find some ammo!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:715
+msgid "^F4^COUNT^BG left to find some ammo!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:716
+msgid "^BGGet some ammo or you'll be dead in ^F4^COUNT^BG!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:716
+msgid "^BGGet some ammo! ^F4^COUNT^BG left!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:717
+#, c-format
+msgid "^F2Extra lives remaining: ^K1%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:719 qcsrc/menu/xonotic/campaign.qc:244
+#, c-format
+msgid "Level %s: "
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:719
+#, c-format
+msgid "^BGPress ^F2%s^BG to enter the game"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:722
+#, c-format
+msgid ""
+"^F2^COUNT^BG until weapon change...\n"
+"Next weapon: ^F1%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:723
+#, c-format
+msgid "^F2Active weapon: ^F1%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:725
+#, c-format
+msgid "^BGYou captured %s^BG control point"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:726
+msgid "^BGYou captured a control point"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:727
+#, c-format
+msgid "^TC^TT^BG team captured %s^BG control point"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:728
+msgid "^TC^TT^BG team captured a control point"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:729
+msgid "^BGThis control point currently cannot be captured"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:730
+msgid ""
+"^BGThe enemy generator cannot be destroyed yet\n"
+"^F2Capture some control points to unshield it"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:731
+msgid "^BGThe ^TCenemy^BG generator is no longer shielded!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:732
+msgid ""
+"^K1Your generator is NOT shielded!\n"
+"^BGRe-capture control points to shield it!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:733
+#, c-format
+msgid "^BGPress ^F2%s^BG to teleport"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:734
+#, c-format
+msgid "^BGTeleporting disabled for %s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:736
+msgid ""
+"^F2Now playing ^F4OVERTIME^F2!\n"
+"Keep fragging until we have a winner!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:736
+msgid ""
+"^F2Now playing ^F4OVERTIME^F2!\n"
+"Keep scoring until we have a winner!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:737
+msgid ""
+"^F2Now playing ^F4OVERTIME^F2!\n"
+"\n"
+"Generators are now decaying.\n"
+"The more control points your team holds,\n"
+"the faster the enemy generator decays"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:738
+#, c-format
+msgid ""
+"^F2Now playing ^F4OVERTIME^F2!\n"
+"^BGAdded ^F4%s^BG to the game!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:740
+msgid "^K1In^BG-portal created"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:741
+msgid "^F3Out^BG-portal created"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:742
+msgid "^F1Portal creation failed"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:744
+msgid "^F2Strength infuses your weapons with devastating power"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:745
+msgid "^F2Strength has worn off"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:747
+msgid "^F2Shield surrounds you"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:748
+msgid "^F2Shield has worn off"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:750
+msgid "^F2You are on speed"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:751
+msgid "^F2Speed has worn off"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:753
+msgid "^F2You are invisible"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:754
+msgid "^F2Invisibility has worn off"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:756
+msgid "^F2The race is over, finish your lap!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:758
+msgid "^BGSequence completed!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:759
+msgid "^BGThere are more to go..."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:760
+#, c-format
+msgid "^BGOnly %s^BG more to go..."
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:762
+msgid "^F2Superweapons have broken down"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:763
+msgid "^F2Superweapons have been lost"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:764
+msgid "^F2You now have a superweapon"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:766
+msgid "^K1Changing to ^TC^TT^K1 in ^COUNT"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:767
+msgid "^K1Changing team in ^COUNT"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:768
+msgid "^K1Spectating in ^COUNT"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:769
+msgid "^K1Suicide in ^COUNT"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:771
+msgid "^F4Timeout begins in ^COUNT"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:772
+msgid "^F4Timeout ends in ^COUNT"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:774
+msgid "^K1Cannot join given minigame session!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:776
+#, c-format
+msgid "^BGPress ^F2%s^BG to enter/exit the vehicle"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:777
+#, c-format
+msgid "^BGPress ^F2%s^BG to enter the vehicle gunner"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:778
+#, c-format
+msgid "^BGPress ^F2%s^BG to steal this vehicle"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:779
+msgid ""
+"^F2The enemy is stealing one of your vehicles!\n"
+"^F4Stop them!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.inc:780
+msgid "^F2Intruder detected, disabling shields!"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:198
+msgid "Notification dump command only works with cl_cmd and sv_cmd."
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:408 qcsrc/common/notifications/all.qh:409
+#, c-format
+msgid " (near %s)"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:416 qcsrc/common/notifications/all.qh:417
+msgid "primary"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:416 qcsrc/common/notifications/all.qh:417
+msgid "secondary"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:419
+msgid "point"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:419
+msgid "points"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:428
+msgid "drop flag"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:429
+msgid "throw nade"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:455
+#, c-format
+msgid "%s^K1 made a TRIPLE FRAG! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:455
+#, c-format
+msgid "%s^K1 made a TRIPLE SCORE! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:455
+msgid "TRIPLE FRAG! "
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:456
+#, c-format
+msgid "%s^K1 made FIVE SCORES IN A ROW! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:456
+#, c-format
+msgid "%s^K1 unlocked RAGE! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:456
+msgid "RAGE! "
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:457
+#, c-format
+msgid "%s^K1 made TEN SCORES IN A ROW! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:457
+#, c-format
+msgid "%s^K1 started a MASSACRE! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:457
+msgid "MASSACRE! "
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:458
+#, c-format
+msgid "%s^K1 executed MAYHEM! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:458
+#, c-format
+msgid "%s^K1 made FIFTEEN SCORES IN A ROW! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:458
+msgid "MAYHEM! "
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:459
+#, c-format
+msgid "%s^K1 is a BERSERKER! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:459
+#, c-format
+msgid "%s^K1 made TWENTY SCORES IN A ROW! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:459
+msgid "BERSERKER! "
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:460
+#, c-format
+msgid "%s^K1 inflicts CARNAGE! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:460
+#, c-format
+msgid "%s^K1 made TWENTY FIVE SCORES IN A ROW! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:460
+msgid "CARNAGE! "
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:461
+#, c-format
+msgid "%s^K1 made THIRTY SCORES IN A ROW! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:461
+#, c-format
+msgid "%s^K1 unleashes ARMAGEDDON! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:461
+msgid "ARMAGEDDON! "
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:468
+#, c-format
+msgid "%s(^F1Bot^BG)"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:470
+#, c-format
+msgid "%s(Ping ^F1%d^BG)"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:477
+#, c-format
+msgid ""
+"\n"
+"(Health ^1%d^BG / Armor ^2%d^BG)%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:479
+#, c-format
+msgid ""
+"\n"
+"(^F4Dead^BG)%s"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:500 qcsrc/common/notifications/all.qh:513
+#, c-format
+msgid "%d score spree! "
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:512
+#, c-format
+msgid "%d frag spree! "
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:525
+msgid "First blood! "
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:525
+msgid "First score! "
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:529
+msgid "First casualty! "
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:529
+msgid "First victim! "
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:570
+#, c-format
+msgid "%s^K1 has %d frags in a row! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:571
+#, c-format
+msgid "%s^K1 made %d scores in a row! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:589
+#, c-format
+msgid "%s^K1 drew first blood! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:590
+#, c-format
+msgid "%s^K1 got the first score! %s^BG"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:606
+#, c-format
+msgid ", ending their %d frag spree"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:607
+#, c-format
+msgid ", ending their %d score spree"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:621
+#, c-format
+msgid ", losing their %d frag spree"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:622
+#, c-format
+msgid ", losing their %d score spree"
+msgstr ""
+
+#: qcsrc/common/notifications/all.qh:647
+#, c-format
+msgid " with %d %s"
+msgstr ""
+
+#: qcsrc/common/teams.qh:31
+msgid "TEAM^Red"
+msgstr ""
+
+#: qcsrc/common/teams.qh:32
+msgid "TEAM^Blue"
+msgstr ""
+
+#: qcsrc/common/teams.qh:33
+msgid "TEAM^Yellow"
+msgstr ""
+
+#: qcsrc/common/teams.qh:34
+msgid "TEAM^Pink"
+msgstr ""
+
+#: qcsrc/common/teams.qh:35
+msgid "Team"
+msgstr ""
+
+#: qcsrc/common/teams.qh:36
+msgid "Neutral"
+msgstr ""
+
+#: qcsrc/common/teams.qh:39
+msgid "KEY^Red"
+msgstr ""
+
+#: qcsrc/common/teams.qh:40
+msgid "KEY^Blue"
+msgstr ""
+
+#: qcsrc/common/teams.qh:41
+msgid "KEY^Yellow"
+msgstr ""
+
+#: qcsrc/common/teams.qh:42
+msgid "KEY^Pink"
+msgstr ""
+
+#: qcsrc/common/teams.qh:43
+msgid "FLAG^Red"
+msgstr ""
+
+#: qcsrc/common/teams.qh:44
+msgid "FLAG^Blue"
+msgstr ""
+
+#: qcsrc/common/teams.qh:45
+msgid "FLAG^Yellow"
+msgstr ""
+
+#: qcsrc/common/teams.qh:46
+msgid "FLAG^Pink"
+msgstr ""
+
+#: qcsrc/common/teams.qh:47
+msgid "GENERATOR^Red"
+msgstr ""
+
+#: qcsrc/common/teams.qh:48
+msgid "GENERATOR^Blue"
+msgstr ""
+
+#: qcsrc/common/teams.qh:49
+msgid "GENERATOR^Yellow"
+msgstr ""
+
+#: qcsrc/common/teams.qh:50
+msgid "GENERATOR^Pink"
+msgstr ""
+
+#: qcsrc/common/turrets/all.qh:95
+msgid "Turrets dump command only works with sv_cmd."
+msgstr ""
+
+#: qcsrc/common/turrets/cl_turrets.qc:125
+#, c-format
+msgid "%s under attack!"
+msgstr ""
+
+#: qcsrc/common/turrets/turret.qh:11
+msgid "Turret"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/ewheel.qh:15
+msgid "eWheel Turret"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/ewheel_weapon.qh:7
+msgid "eWheel"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/flac.qh:13
+msgid "FLAC Cannon"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/flac_weapon.qh:7
+msgid "FLAC"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/fusionreactor.qh:11
+msgid "Fusion Reactor"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/hellion.qh:13
+msgid "Hellion Missile Turret"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/hellion_weapon.qh:7
+msgid "Hellion"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/hk.qh:15
+msgid "Hunter-Killer Turret"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/hk_weapon.qh:7
+msgid "Hunter-Killer"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/machinegun.qh:13
+msgid "Machinegun Turret"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/machinegun_weapon.qh:7
+msgid "Machinegun"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/mlrs.qh:13
+msgid "MLRS Turret"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/mlrs_weapon.qh:7
+msgid "MLRS"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/phaser.qh:13
+msgid "Phaser Cannon"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/phaser_weapon.qh:7
+msgid "Phaser"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/plasma.qh:13
+msgid "Plasma Cannon"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/plasma_dual.qh:8
+msgid "Dual plasma"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/plasma_dual.qh:20
+msgid "Dual Plasma Cannon"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/plasma_weapon.qh:7
+msgid "Plasma"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/tesla.qh:13
+#: qcsrc/common/turrets/turret/tesla_weapon.qh:7
+msgid "Tesla Coil"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/walker.qh:15
+msgid "Walker Turret"
+msgstr ""
+
+#: qcsrc/common/turrets/turret/walker_weapon.qh:7
+msgid "Walker"
+msgstr ""
+
+#: qcsrc/common/util.qc:1390
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:176
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:186
+msgid "Male"
+msgstr ""
+
+#: qcsrc/common/util.qc:1391
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:175
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:185
+msgid "Female"
+msgstr ""
+
+#: qcsrc/common/util.qc:1392
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:174
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:187
+msgid "Undisclosed"
+msgstr ""
+
+#: qcsrc/common/util.qc:1439
+msgid "<KEY NOT FOUND>"
+msgstr ""
+
+#: qcsrc/common/util.qc:1440
+msgid "<UNKNOWN KEYNUM>"
+msgstr ""
+
+#: qcsrc/common/util.qc:1445
+msgid "TAB"
+msgstr ""
+
+#: qcsrc/common/util.qc:1446 qcsrc/common/util.qc:1517
+#, c-format
+msgid "ENTER"
+msgstr ""
+
+#: qcsrc/common/util.qc:1447
+msgid "ESCAPE"
+msgstr ""
+
+#: qcsrc/common/util.qc:1448
+msgid "SPACE"
+msgstr ""
+
+#: qcsrc/common/util.qc:1450
+msgid "BACKSPACE"
+msgstr ""
+
+#: qcsrc/common/util.qc:1451 qcsrc/common/util.qc:1508
+#, c-format
+msgid "UPARROW"
+msgstr ""
+
+#: qcsrc/common/util.qc:1452 qcsrc/common/util.qc:1503
+#, c-format
+msgid "DOWNARROW"
+msgstr ""
+
+#: qcsrc/common/util.qc:1453 qcsrc/common/util.qc:1505
+#, c-format
+msgid "LEFTARROW"
+msgstr ""
+
+#: qcsrc/common/util.qc:1454 qcsrc/common/util.qc:1506
+#, c-format
+msgid "RIGHTARROW"
+msgstr ""
+
+#: qcsrc/common/util.qc:1456
+msgid "ALT"
+msgstr ""
+
+#: qcsrc/common/util.qc:1457
+msgid "CTRL"
+msgstr ""
+
+#: qcsrc/common/util.qc:1458
+msgid "SHIFT"
+msgstr ""
+
+#: qcsrc/common/util.qc:1460 qcsrc/common/util.qc:1501
+#, c-format
+msgid "INS"
+msgstr ""
+
+#: qcsrc/common/util.qc:1461 qcsrc/common/util.qc:1511
+#, c-format
+msgid "DEL"
+msgstr ""
+
+#: qcsrc/common/util.qc:1462 qcsrc/common/util.qc:1504
+#, c-format
+msgid "PGDN"
+msgstr ""
+
+#: qcsrc/common/util.qc:1463 qcsrc/common/util.qc:1509
+#, c-format
+msgid "PGUP"
+msgstr ""
+
+#: qcsrc/common/util.qc:1464 qcsrc/common/util.qc:1507
+#, c-format
+msgid "HOME"
+msgstr ""
+
+#: qcsrc/common/util.qc:1465 qcsrc/common/util.qc:1502
+#, c-format
+msgid "END"
+msgstr ""
+
+#: qcsrc/common/util.qc:1467
+msgid "PAUSE"
+msgstr ""
+
+#: qcsrc/common/util.qc:1469
+msgid "NUMLOCK"
+msgstr ""
+
+#: qcsrc/common/util.qc:1470
+msgid "CAPSLOCK"
+msgstr ""
+
+#: qcsrc/common/util.qc:1471
+msgid "SCROLLOCK"
+msgstr ""
+
+#: qcsrc/common/util.qc:1473
+msgid "SEMICOLON"
+msgstr ""
+
+#: qcsrc/common/util.qc:1474
+msgid "TILDE"
+msgstr ""
+
+#: qcsrc/common/util.qc:1475
+msgid "BACKQUOTE"
+msgstr ""
+
+#: qcsrc/common/util.qc:1476
+msgid "QUOTE"
+msgstr ""
+
+#: qcsrc/common/util.qc:1477
+msgid "APOSTROPHE"
+msgstr ""
+
+#: qcsrc/common/util.qc:1478
+msgid "BACKSLASH"
+msgstr ""
+
+#: qcsrc/common/util.qc:1486
+#, c-format
+msgid "F%d"
+msgstr ""
+
+#: qcsrc/common/util.qc:1496
+#, c-format
+msgid "KP_%d"
+msgstr ""
+
+#: qcsrc/common/util.qc:1501 qcsrc/common/util.qc:1502
+#: qcsrc/common/util.qc:1503 qcsrc/common/util.qc:1504
+#: qcsrc/common/util.qc:1505 qcsrc/common/util.qc:1506
+#: qcsrc/common/util.qc:1507 qcsrc/common/util.qc:1508
+#: qcsrc/common/util.qc:1509 qcsrc/common/util.qc:1510
+#: qcsrc/common/util.qc:1511 qcsrc/common/util.qc:1512
+#: qcsrc/common/util.qc:1513 qcsrc/common/util.qc:1514
+#: qcsrc/common/util.qc:1515 qcsrc/common/util.qc:1516
+#: qcsrc/common/util.qc:1517 qcsrc/common/util.qc:1518
+#, c-format
+msgid "KP_%s"
+msgstr ""
+
+#: qcsrc/common/util.qc:1510
+#, c-format
+msgid "PERIOD"
+msgstr ""
+
+#: qcsrc/common/util.qc:1512
+#, c-format
+msgid "DIVIDE"
+msgstr ""
+
+#: qcsrc/common/util.qc:1513
+#, c-format
+msgid "SLASH"
+msgstr ""
+
+#: qcsrc/common/util.qc:1514
+#, c-format
+msgid "MULTIPLY"
+msgstr ""
+
+#: qcsrc/common/util.qc:1515
+#, c-format
+msgid "MINUS"
+msgstr ""
+
+#: qcsrc/common/util.qc:1516
+#, c-format
+msgid "PLUS"
+msgstr ""
+
+#: qcsrc/common/util.qc:1518
+#, c-format
+msgid "EQUALS"
+msgstr ""
+
+#: qcsrc/common/util.qc:1523
+msgid "PRINTSCREEN"
+msgstr ""
+
+#: qcsrc/common/util.qc:1526
+#, c-format
+msgid "MOUSE%d"
+msgstr ""
+
+#: qcsrc/common/util.qc:1528
+msgid "MWHEELUP"
+msgstr ""
+
+#: qcsrc/common/util.qc:1529
+msgid "MWHEELDOWN"
+msgstr ""
+
+#: qcsrc/common/util.qc:1532
+#, c-format
+msgid "JOY%d"
+msgstr ""
+
+#: qcsrc/common/util.qc:1535
+#, c-format
+msgid "AUX%d"
+msgstr ""
+
+#: qcsrc/common/util.qc:1542
+#, c-format
+msgid "DPAD_UP"
+msgstr ""
+
+#: qcsrc/common/util.qc:1542 qcsrc/common/util.qc:1543
+#: qcsrc/common/util.qc:1544 qcsrc/common/util.qc:1545
+#: qcsrc/common/util.qc:1546 qcsrc/common/util.qc:1547
+#: qcsrc/common/util.qc:1548 qcsrc/common/util.qc:1549
+#: qcsrc/common/util.qc:1550 qcsrc/common/util.qc:1551
+#: qcsrc/common/util.qc:1552 qcsrc/common/util.qc:1553
+#: qcsrc/common/util.qc:1554 qcsrc/common/util.qc:1555
+#: qcsrc/common/util.qc:1556 qcsrc/common/util.qc:1557
+#: qcsrc/common/util.qc:1558 qcsrc/common/util.qc:1559
+#: qcsrc/common/util.qc:1560 qcsrc/common/util.qc:1561
+#, c-format
+msgid "X360_%s"
+msgstr ""
+
+#: qcsrc/common/util.qc:1543
+#, c-format
+msgid "DPAD_DOWN"
+msgstr ""
+
+#: qcsrc/common/util.qc:1544
+#, c-format
+msgid "DPAD_LEFT"
+msgstr ""
+
+#: qcsrc/common/util.qc:1545
+#, c-format
+msgid "DPAD_RIGHT"
+msgstr ""
+
+#: qcsrc/common/util.qc:1546
+#, c-format
+msgid "START"
+msgstr ""
+
+#: qcsrc/common/util.qc:1547
+#, c-format
+msgid "BACK"
+msgstr ""
+
+#: qcsrc/common/util.qc:1548
+#, c-format
+msgid "LEFT_THUMB"
+msgstr ""
+
+#: qcsrc/common/util.qc:1549
+#, c-format
+msgid "RIGHT_THUMB"
+msgstr ""
+
+#: qcsrc/common/util.qc:1550
+#, c-format
+msgid "LEFT_SHOULDER"
+msgstr ""
+
+#: qcsrc/common/util.qc:1551
+#, c-format
+msgid "RIGHT_SHOULDER"
+msgstr ""
+
+#: qcsrc/common/util.qc:1552
+#, c-format
+msgid "LEFT_TRIGGER"
+msgstr ""
+
+#: qcsrc/common/util.qc:1553
+#, c-format
+msgid "RIGHT_TRIGGER"
+msgstr ""
+
+#: qcsrc/common/util.qc:1554
+#, c-format
+msgid "LEFT_THUMB_UP"
+msgstr ""
+
+#: qcsrc/common/util.qc:1555
+#, c-format
+msgid "LEFT_THUMB_DOWN"
+msgstr ""
+
+#: qcsrc/common/util.qc:1556
+#, c-format
+msgid "LEFT_THUMB_LEFT"
+msgstr ""
+
+#: qcsrc/common/util.qc:1557
+#, c-format
+msgid "LEFT_THUMB_RIGHT"
+msgstr ""
+
+#: qcsrc/common/util.qc:1558
+#, c-format
+msgid "RIGHT_THUMB_UP"
+msgstr ""
+
+#: qcsrc/common/util.qc:1559
+#, c-format
+msgid "RIGHT_THUMB_DOWN"
+msgstr ""
+
+#: qcsrc/common/util.qc:1560
+#, c-format
+msgid "RIGHT_THUMB_LEFT"
+msgstr ""
+
+#: qcsrc/common/util.qc:1561
+#, c-format
+msgid "RIGHT_THUMB_RIGHT"
+msgstr ""
+
+#: qcsrc/common/util.qc:1571 qcsrc/common/util.qc:1572
+#: qcsrc/common/util.qc:1573 qcsrc/common/util.qc:1574
+#, c-format
+msgid "JOY_%s"
+msgstr ""
+
+#: qcsrc/common/util.qc:1571
+#, c-format
+msgid "UP"
+msgstr ""
+
+#: qcsrc/common/util.qc:1572
+#, c-format
+msgid "DOWN"
+msgstr ""
+
+#: qcsrc/common/util.qc:1573
+#, c-format
+msgid "LEFT"
+msgstr ""
+
+#: qcsrc/common/util.qc:1574
+#, c-format
+msgid "RIGHT"
+msgstr ""
+
+#: qcsrc/common/util.qc:1580
+#, c-format
+msgid "MIDINOTE%d"
+msgstr ""
+
+#: qcsrc/common/vehicles/cl_vehicles.qc:190
+#, c-format
+msgid "Press %s"
+msgstr ""
+
+#: qcsrc/common/vehicles/vehicle/bumblebee.qc:954
+msgid "No right gunner!"
+msgstr ""
+
+#: qcsrc/common/vehicles/vehicle/bumblebee.qc:960
+msgid "No left gunner!"
+msgstr ""
+
+#: qcsrc/common/vehicles/vehicle/bumblebee.qh:19
+msgid "Bumblebee"
+msgstr ""
+
+#: qcsrc/common/vehicles/vehicle/racer.qh:19
+msgid "Racer"
+msgstr ""
+
+#: qcsrc/common/vehicles/vehicle/racer_weapon.qh:9
+msgid "Racer cannon"
+msgstr ""
+
+#: qcsrc/common/vehicles/vehicle/raptor.qh:19
+msgid "Raptor"
+msgstr ""
+
+#: qcsrc/common/vehicles/vehicle/raptor_weapons.qh:9
+msgid "Raptor cannon"
+msgstr ""
+
+#: qcsrc/common/vehicles/vehicle/raptor_weapons.qh:17
+msgid "Raptor bomb"
+msgstr ""
+
+#: qcsrc/common/vehicles/vehicle/raptor_weapons.qh:25
+msgid "Raptor flare"
+msgstr ""
+
+#: qcsrc/common/vehicles/vehicle/spiderbot.qh:19
+msgid "Spiderbot"
+msgstr ""
+
+#: qcsrc/common/weapons/all.qh:76
+msgid "Weapons dump command only works with sv_cmd."
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/arc.qh:18
+msgid "Arc"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/blaster.qh:18
+msgid "Blaster"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/crylink.qh:18
+msgid "Crylink"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/devastator.qh:18
+msgid "Devastator"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/electro.qh:18
+msgid "Electro"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/fireball.qh:18
+msgid "Fireball"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/hagar.qh:18
+msgid "Hagar"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/hlac.qh:18
+msgid "Heavy Laser Assault Cannon"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/hook.qh:18
+msgid "Grappling Hook"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/machinegun.qh:18
+msgid "MachineGun"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/minelayer.qh:18
+msgid "Mine Layer"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/mortar.qh:18
+msgid "Mortar"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/porto.qh:18
+msgid "Port-O-Launch"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/rifle.qh:19
+msgid "Rifle"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/seeker.qh:18
+msgid "T.A.G. Seeker"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/shockwave.qh:18
+msgid "Shockwave"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/shotgun.qh:18
+msgid "Shotgun"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/tuba.qh:18
+#, no-c-format
+msgid "@!#%'n Tuba"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/vaporizer.qh:19
+msgid "Vaporizer"
+msgstr ""
+
+#: qcsrc/common/weapons/weapon/vortex.qh:19
+msgid "Vortex"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:9
+#, c-format
+msgid "CI_DEC^%s years"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:12
+#, c-format
+msgid "CI_ZER^%d years"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:13
+#, c-format
+msgid "CI_FIR^%d year"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:14
+#, c-format
+msgid "CI_SEC^%d years"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:15
+#, c-format
+msgid "CI_THI^%d years"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:16
+#, c-format
+msgid "CI_MUL^%d years"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:18
+#, c-format
+msgid "CI_DEC^%s weeks"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:21
+#, c-format
+msgid "CI_ZER^%d weeks"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:22
+#, c-format
+msgid "CI_FIR^%d week"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:23
+#, c-format
+msgid "CI_SEC^%d weeks"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:24
+#, c-format
+msgid "CI_THI^%d weeks"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:25
+#, c-format
+msgid "CI_MUL^%d weeks"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:27
+#, c-format
+msgid "CI_DEC^%s days"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:30
+#, c-format
+msgid "CI_ZER^%d days"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:31
+#, c-format
+msgid "CI_FIR^%d day"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:32
+#, c-format
+msgid "CI_SEC^%d days"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:33
+#, c-format
+msgid "CI_THI^%d days"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:34
+#, c-format
+msgid "CI_MUL^%d days"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:36
+#, c-format
+msgid "CI_DEC^%s hours"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:39
+#, c-format
+msgid "CI_ZER^%d hours"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:40
+#, c-format
+msgid "CI_FIR^%d hour"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:41
+#, c-format
+msgid "CI_SEC^%d hours"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:42
+#, c-format
+msgid "CI_THI^%d hours"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:43
+#, c-format
+msgid "CI_MUL^%d hours"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:46
+#, c-format
+msgid "CI_DEC^%s minutes"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:49
+#, c-format
+msgid "CI_ZER^%d minutes"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:50
+#, c-format
+msgid "CI_FIR^%d minute"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:51
+#, c-format
+msgid "CI_SEC^%d minutes"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:52
+#, c-format
+msgid "CI_THI^%d minutes"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:53
+#, c-format
+msgid "CI_MUL^%d minutes"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:55
+#, c-format
+msgid "CI_DEC^%s seconds"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:58
+#, c-format
+msgid "CI_ZER^%d seconds"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:59
+#, c-format
+msgid "CI_FIR^%d second"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:60
+#, c-format
+msgid "CI_SEC^%d seconds"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:61
+#, c-format
+msgid "CI_THI^%d seconds"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:62
+#, c-format
+msgid "CI_MUL^%d seconds"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:79
+#, c-format
+msgid "%dst"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:80
+#, c-format
+msgid "%dnd"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:81
+#, c-format
+msgid "%drd"
+msgstr ""
+
+#: qcsrc/lib/counting.qh:85
+#, c-format
+msgid "%dth"
+msgstr ""
+
+#: qcsrc/lib/oo.qh:324
+msgid "No description"
+msgstr ""
+
+#: qcsrc/lib/spawnfunc.qh:248
+#, c-format
+msgid ""
+"Entity field %s.%s (%s) is not whitelisted. If you believe this is an error, "
+"please file an issue."
+msgstr ""
+
+#: qcsrc/lib/string.qh:81
+#, c-format
+msgid "%d days, %02d:%02d:%02d"
+msgstr ""
+
+#: qcsrc/lib/string.qh:82
+#, c-format
+msgid "%02d:%02d:%02d"
+msgstr ""
+
+#: qcsrc/menu/command/menu_cmd.qc:48
+msgid "Usage: menu_cmd command..., where possible commands are:"
+msgstr ""
+
+#: qcsrc/menu/command/menu_cmd.qc:49
+msgid "  sync - reloads all cvars on the current menu page"
+msgstr ""
+
+#: qcsrc/menu/command/menu_cmd.qc:50
+msgid "  directmenu ITEM - select a menu item as main item"
+msgstr ""
+
+#: qcsrc/menu/command/menu_cmd.qc:51
+msgid "  dumptree - dump the state of the menu as a tree to the console"
+msgstr ""
+
+#: qcsrc/menu/command/menu_cmd.qc:81
+msgid "Available options:"
+msgstr ""
+
+#: qcsrc/menu/command/menu_cmd.qc:130
+msgid "Invalid command. For a list of supported commands, try menu_cmd help."
+msgstr ""
+
+#: qcsrc/menu/item/listbox.qc:413
+#, c-format
+msgid "Item %d"
+msgstr ""
+
+#: qcsrc/menu/item/textslider.qc:11 qcsrc/menu/item/textslider.qc:12
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:115
+msgid "Custom"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:4
+msgid "Core Team"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:15
+msgid "Extended Team"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:46
+msgid "Website"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:51
+msgid "Stats"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:55
+msgid "Art"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:63
+msgid "Animation"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:67
+msgid "Level Design"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:90
+msgid "Music / Sound FX"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:106
+msgid "Game Code"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:114
+msgid "Marketing / PR"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:120
+msgid "Legal"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:125
+msgid "Game Engine"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:129
+msgid "Engine Additions"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:135
+msgid "Compiler"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:141
+msgid "Other Active Contributors"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:148
+msgid "Translators"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:150
+msgid "Asturian"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:155
+msgid "Belarusian"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:158
+msgid "Bulgarian"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:165
+msgid "Chinese (China)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:171
+msgid "Chinese (Taiwan)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:176
+msgid "Cornish"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:179
+msgid "Czech"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:184
+msgid "Dutch"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:191
+msgid "English (Australia)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:196
+msgid "Finnish"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:201
+msgid "French"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:209
+msgid "German"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:220
+msgid "Greek"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:226
+msgid "Hungarian"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:230
+msgid "Irish"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:233
+msgid "Italian"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:239
+msgid "Kazakh"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:242
+msgid "Korean"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:246
+msgid "Polish"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:254
+msgid "Portuguese"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:260
+msgid "Romanian"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:267
+msgid "Russian"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:278
+msgid "Scottish Gaelic"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:281
+msgid "Serbian"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:287
+msgid "Spanish"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:298
+msgid "Swedish"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:302
+msgid "Ukrainian"
+msgstr ""
+
+#: qcsrc/menu/xonotic/credits.qc:309
+msgid "Past Contributors"
+msgstr ""
+
+#: qcsrc/menu/xonotic/cvarlist.qc:73
+msgid "forced to be saved to config.cfg"
+msgstr ""
+
+#: qcsrc/menu/xonotic/cvarlist.qc:79 qcsrc/menu/xonotic/cvarlist.qc:89
+msgid "will not be saved"
+msgstr ""
+
+#: qcsrc/menu/xonotic/cvarlist.qc:84
+msgid "will be saved to config.cfg"
+msgstr ""
+
+#: qcsrc/menu/xonotic/cvarlist.qc:93
+msgid "private"
+msgstr ""
+
+#: qcsrc/menu/xonotic/cvarlist.qc:95
+msgid "engine setting"
+msgstr ""
+
+#: qcsrc/menu/xonotic/cvarlist.qc:97
+msgid "read only"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_credits.qc:13
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:38
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:303
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:85
+#: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc:75
+#: qcsrc/menu/xonotic/dialog_singleplayer_winner.qc:14
+msgid "OK"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_credits.qh:7
+msgid "Credits"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_credits.qh:8
+msgid "The Xonotic credits"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_disconnect.qc:16
+msgid "Are you sure to disconnect from server?"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_disconnect.qc:19
+msgid "I would disconnect from server..."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_disconnect.qc:22
+msgid "I would play more!"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_disconnect.qh:6
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qh:6
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qh:6
+msgid "Disconnect"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_disconnect.qh:7
+msgid "Disconnect from the server you are connected to"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_firstrun.qc:39
+msgid ""
+"Welcome to Xonotic, please select your language preference and enter your "
+"player name to get started.  You can change these options later through the "
+"menu system."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_firstrun.qc:45
+#: qcsrc/menu/xonotic/dialog_settings_input_userbind.qc:28
+msgid "Name:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_firstrun.qc:53
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:62
+msgid "Name under which you will appear in the game"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_firstrun.qc:69
+msgid "Text language:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_firstrun.qc:78
+msgid "Allow player statistics to use your nickname at stats.xonotic.org?"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_firstrun.qc:84
+msgid "Undecided"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_firstrun.qc:88
+msgid "Save settings"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_firstrun.qh:6
+msgid "Welcome"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc:18
+msgid "Ammunition display:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc:21
+msgid "Show only current ammo type"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc:24
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:46
+msgid "Noncurrent alpha:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc:28
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:50
+msgid "Noncurrent scale:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc:32
+#: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:24
+msgid "Align icon:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc:33
+#: qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc:32
+#: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:25
+#: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:37
+#: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:25
+#: qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc:23
+#: qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc:35
+#: qcsrc/menu/xonotic/dialog_hudpanel_quickmenu.qc:21
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:57
+msgid "Left"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc:34
+#: qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc:34
+#: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:27
+#: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:38
+#: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:26
+#: qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc:25
+#: qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc:36
+#: qcsrc/menu/xonotic/dialog_hudpanel_quickmenu.qc:23
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:59
+msgid "Right"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_ammo.qh:6
+msgid "Ammo Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc:19
+msgid "Message duration:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc:23
+msgid "Fade time:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc:27
+msgid "Flip messages order"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc:29
+#: qcsrc/menu/xonotic/dialog_hudpanel_quickmenu.qc:18
+msgid "Text alignment:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc:33
+#: qcsrc/menu/xonotic/dialog_hudpanel_quickmenu.qc:22
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:70
+msgid "Center"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc:37
+msgid "Font scale:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qh:6
+msgid "Centerprint Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_chat.qc:17
+msgid "Chat entries:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_chat.qc:20
+msgid "Chat size:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_chat.qc:24
+msgid "Chat lifetime:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_chat.qc:28
+msgid "Chat beep sound"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_chat.qh:6
+msgid "Chat Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_engineinfo.qc:16
+msgid "Engine info:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_engineinfo.qc:19
+msgid "Use an averaging algorithm for fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_engineinfo.qh:6
+msgid "Engine Info Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:17
+msgid "Combine health and armor"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:19
+#: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:28
+#: qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc:17
+msgid "Enable status bar"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:21
+#: qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc:19
+msgid "Status bar alignment:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:29
+#: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:39
+#: qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc:27
+#: qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc:37
+msgid "Inward"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:31
+#: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:40
+#: qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc:29
+#: qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc:38
+msgid "Outward"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:34
+#: qcsrc/menu/xonotic/dialog_hudpanel_powerups.qc:32
+msgid "Icon alignment:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:42
+msgid "Flip health and armor positions"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qh:6
+msgid "Health/Armor Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_infomessages.qc:16
+msgid "Info messages:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_infomessages.qc:19
+msgid "Flip align"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_infomessages.qh:6
+msgid "Info Messages Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:16
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:15
+#: qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qc:14
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:15
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:50
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:62
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:77
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:116
+#: qcsrc/menu/xonotic/util.qc:770 qcsrc/menu/xonotic/util.qc:786
+#: qcsrc/menu/xonotic/util.qc:803
+msgid "Disable"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:17
+#: qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qc:15
+msgid "Enable spectating"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:18
+msgid "Enable even playing in warmup"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:29
+msgid "Reduced"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:32
+msgid "Text/icon ratio:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:35
+msgid "Hide spawned items"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:37
+msgid "Hide big armor and health"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:39
+msgid "Dynamic size"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qh:6
+msgid "Items Time Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_modicons.qh:6
+msgid "Mod Icons Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_notification.qc:17
+msgid "Notifications:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_notification.qc:20
+msgid "Also print notifications to the console"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_notification.qc:23
+msgid "Flip notify order"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_notification.qc:26
+msgid "Entry lifetime:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_notification.qc:30
+msgid "Entry fadetime:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_notification.qh:6
+msgid "Notification Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:16
+#: qcsrc/menu/xonotic/util.qc:758
+msgid "Enable"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:17
+msgid "Enable even observing"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:18
+msgid "Enable only in Race/CTS"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:24
+msgid "Status bar"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:26
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:67
+msgid "Left align"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:27
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:73
+msgid "Right align"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:28
+msgid "Inward align"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:29
+msgid "Outward align"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:33
+msgid "Flip speed/acceleration positions"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:37
+msgid "Speed:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:38
+msgid "Include vertical speed"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:49
+msgid "Speed unit:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:51
+msgid "qu/s"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:52
+msgid "m/s"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:53
+msgid "km/h"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:54
+msgid "mph"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:55
+msgid "knots"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:57
+msgid "Show"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:60
+msgid "Top speed"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:66
+msgid "Acceleration:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:67
+msgid "Include vertical acceleration"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_physics.qh:6
+msgid "Physics Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_powerups.qh:6
+msgid "Powerups Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qc:16
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:17
+msgid "Always enable"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qc:23
+msgid "Forced aspect:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qh:6
+msgid "Pressed Keys Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_quickmenu.qh:6
+msgid "Quick Menu Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_racetimer.qh:6
+msgid "Race Timer Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:16
+msgid "Enable in team games"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:23
+msgid "Radar:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:26
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:68
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:107
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:54
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:87
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:103
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:45
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:70
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:124
+#: qcsrc/menu/xonotic/util.qc:792
+msgid "Alpha:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:30
+msgid "Rotation:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:32
+msgid "Forward"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:33
+msgid "West"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:34
+msgid "South"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:35
+msgid "East"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:36
+msgid "North"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:40
+msgid "Scale:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:44
+msgid "Zoom mode:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:46
+msgid "Zoomed in"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:47
+msgid "Zoomed out"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:48
+msgid "Always zoomed"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:49
+msgid "Never zoomed"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_radar.qh:6
+msgid "Radar Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_score.qc:17
+msgid "Score:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_score.qc:20
+msgid "Rankings:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_score.qc:21
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:58
+msgid "Off"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_score.qc:22
+msgid "And me"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_score.qc:23
+msgid "Pure"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_score.qh:6
+msgid "Score Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_timer.qc:16
+msgid "Timer:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_timer.qc:19
+msgid "Show elapsed time"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_timer.qh:6
+msgid "Timer Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_vote.qc:17
+msgid "Alpha after voting:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_vote.qh:6
+msgid "Vote Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:22
+msgid "Fade out after:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:24
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:167
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:145
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:55
+msgid "Never"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:26
+#, c-format
+msgid "%ds"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:30
+msgid "Fade effect:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:33
+msgid "EF^None"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:34
+msgid "Alpha"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:35
+msgid "Slide"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:36
+msgid "EF^Both"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:40
+msgid "Weapon icons:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:43
+msgid "Show only owned weapons"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:54
+msgid "Show weapon ID as:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:55
+msgid "SHOWAS^None"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:56
+msgid "Number"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:57
+msgid "Bind"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:60
+msgid "Weapon ID scale:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:66
+msgid "Show Accuracy"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:67
+msgid "Show Ammo"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:70
+msgid "Ammo bar alpha:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:76
+msgid "Ammo bar color:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qh:6
+msgid "Weapons Panel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:19
+msgid "HUD skins"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:22
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
+#: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:32
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:42
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:25
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc:33
+msgid "Filter:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:30
+#: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:54
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc:43
+msgid "Refresh"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:33
+#: qcsrc/menu/xonotic/dialog_settings_user.qc:28
+msgid "Set skin"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:37
+msgid "Save current skin"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:46
+msgid "Panel background defaults:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:48
+#: qcsrc/menu/xonotic/util.qc:767
+msgid "Background:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:60
+#: qcsrc/menu/xonotic/util.qc:783
+msgid "Border size:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:75
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:114
+msgid "Team color:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:83
+#: qcsrc/menu/xonotic/util.qc:809
+msgid "Test team color in configure mode"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:86
+#: qcsrc/menu/xonotic/util.qc:812
+msgid "Padding:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:93
+msgid "HUD Dock:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:95
+msgid "DOCK^Disabled"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:96
+msgid "DOCK^Small"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:97
+msgid "DOCK^Medium"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:98
+msgid "DOCK^Large"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:121
+msgid "Grid settings:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:124
+msgid "Snap panels to grid"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:127
+msgid "Grid size:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:129
+msgid "X:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:136
+msgid "Y:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:145
+msgid "Exit setup"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_hudsetup_exit.qh:6
+msgid "Panel HUD Setup"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:13
+msgid "Monster:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:22
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:20
+msgid "Spawn"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:23
+msgid "Remove"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:25
+msgid "Move target:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:26
+msgid "Follow"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:27
+msgid "Wander"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:28
+msgid "Spawnpoint"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:29
+msgid "No moving"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:31
+msgid "Colors:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_monstertools.qc:33
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:39
+msgid "Set skin:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_monstertools.qh:6
+msgid "Monster Tools"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer.qc:14
+msgid "Servers"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer.qc:15
+msgid "Find servers to play on"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer.qc:17
+msgid "Host your own game"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer.qc:18
+msgid "Media"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer.qc:19
+msgid "Profile"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer.qh:6
+msgid "Multiplayer"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer.qh:7
+msgid ""
+"Play online, against your friends in LAN, view demos or change player "
+"settings"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:38
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
+#: qcsrc/menu/xonotic/skinlist.qc:88 qcsrc/menu/xonotic/util.qc:769
+#: qcsrc/menu/xonotic/util.qc:785 qcsrc/menu/xonotic/util.qc:794
+#: qcsrc/menu/xonotic/util.qc:802 qcsrc/menu/xonotic/util.qc:814
+msgid "Default"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:40
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:60
+msgid "Unlimited"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:74
+msgid "Gametype"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:79
+msgid "Time limit:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
+msgid "Timelimit in minutes that when hit, will end the match"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
+#, c-format
+msgid "%d minutes"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
+msgid "TIMLIM^Default"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
+msgid "1 minute"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
+msgid "TIMLIM^Infinite"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
+msgid "Teams:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
+msgid "2 teams"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
+msgid "3 teams"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:114
+msgid "4 teams"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
+msgid "Player slots:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:119
+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:121
+msgid "Number of bots:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
+msgid "Amount of bots on your server"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
+msgid "Bot skill:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
+msgid "Specify how experienced the bots will be"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
+msgid "Botlike"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:130
+msgid "Beginner"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:131
+msgid "You will win"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:132
+msgid "You can win"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:133
+msgid "You might win"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:134
+msgid "Advanced"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:135
+msgid "Expert"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:136
+msgid "Pro"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:137
+msgid "Assassin"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:138
+msgid "Unhuman"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:139
+msgid "Godlike"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:155
+msgid "Mutators..."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:156
+msgid "Mutators and weapon arenas"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:165
+msgid "Maplist"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:175
+msgid ""
+"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:184
+msgid "Add shown"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
+msgid "Add the maps shown in the list to your selection"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
+msgid "Remove shown"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:189
+msgid "Remove the maps shown in the list from your selection"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
+msgid "Add all"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
+msgid "Add every available map to your selection"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
+msgid "Remove all"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:199
+msgid "Remove all the maps from your selection"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:206
+msgid "Start Multiplayer!"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc:50
+msgid "Title:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc:56
+msgid "Author:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc:62
+msgid "Game types:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc:85
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:257
+msgid "Close"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc:88
+msgid "MAP^Play"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qh:7
+msgid "Map Information"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:28
+msgid "All Weapons Arena"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:30
+msgid "Most Weapons Arena"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:46
+#, c-format
+msgid "%s Arena"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:57
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:163
+msgid "Dodging"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:59
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:283
+msgid "InstaGib"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:61
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:224
+msgid "New Toys"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:63
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:288
+msgid "NIX"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:65
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:229
+msgid "Rocket Flying"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:67
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:219
+msgid "Invincible Projectiles"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:71
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:298
+msgid "No start weapons"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:73
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:202
+msgid "Low gravity"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:75
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:171
+msgid "Cloaked"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:77
+msgid "Hook"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:79
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:180
+msgid "Midair"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:81
+msgid "Melee only"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:85
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:234
+msgid "Piñata"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:87
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:239
+msgid "Weapons stay"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:89
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:191
+msgid "Blood loss"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:93
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:175
+msgid "Buffs"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:95
+msgid "Overkill"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:97
+msgid "No powerups"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:99
+msgid "Powerups"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:101
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:167
+msgid "Touch explode"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:103
+msgid "Wall jumping"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:105
+msgid "MUT^None"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:160
+msgid "Gameplay mutators:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:164
+msgid ""
+"Enable dodging (quick acceleration in a given direction). Double-tap a "
+"directional key to dodge"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:168
+msgid "An explosion occurs when two players collide"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:172
+msgid "All players are almost invisible"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:176
+msgid ""
+"Enable buff pickups (random bonuses like Medic, Invisible, etc.) on the maps "
+"that support it"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:181
+msgid "Only possible to inflict damage on your enemy while they're airborne"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:185
+msgid "Damage done to your enemy gets added to your own health"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:190
+msgid ""
+"Amount of health below which players start bleeding out (health rots and "
+"they can't jump)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:199
+msgid "Make things fall to the ground slower (percentage of normal gravity)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:208
+msgid "Weapon & item mutators:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:211
+msgid "Grappling hook"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:212
+msgid "Players spawn with the grappling hook. Press the 'hook' key to use it"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:216
+msgid ""
+"Players spawn with the jetpack. Double-tap 'jump' or press the 'jetpack' key "
+"to use it"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:220
+msgid ""
+"Projectiles can't be destroyed. However, you can still explode Electro orbs "
+"with the Electro primary fire"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:225
+msgid ""
+"Some weapon spawns will be randomly replaced with new weapons: Heavy Laser "
+"Assault Cannon, Mine Layer, Rifle, T.A.G. Seeker"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:230
+msgid ""
+"Devastator rockets can be detonated instantly (otherwise, there's a short "
+"delay). This allows players to fire and detonate a Devastator rocket while "
+"in the air for a strong mid-air boost even while moving fast"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:235
+msgid "Players will drop all weapons they possessed when they are killed"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:240
+msgid "Weapons stay after they are picked up"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:245
+msgid "Regular (no arena)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:246
+msgid ""
+"Players will be given a set of weapons at spawn as well as unlimited ammo, "
+"without weapon pickups"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:248
+msgid "Weapon arenas:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:251
+msgid "Custom weapons"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:273
+msgid "Most weapons"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:277
+msgid "All weapons"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:280
+msgid "Special arenas:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:284
+msgid ""
+"Players will be given only one weapon, which can instantly kill the opponent "
+"with a single shot. If the player runs out of ammo, he will have 10 seconds "
+"to find some or if he fails to do so, face death. The secondary fire mode "
+"does not inflict any damage but is good for doing trickjumps."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:289
+msgid ""
+"No items Xonotic - instead of pickup items, everyone plays with the same "
+"weapon. After some time, a countdown will start, after which everyone will "
+"switch to another weapon."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:293
+msgid "with blaster"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:294
+msgid "Always carry the blaster as an additional weapon in Nix"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qh:9
+msgid "Mutators"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:39
+msgid "SRVS^Categories"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:42
+msgid "SRVS^Empty"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:43
+msgid "Show empty servers"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:47
+msgid "SRVS^Full"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:48
+msgid "Show full servers that have no slots available"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:52
+msgid "Pause"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:53
+msgid ""
+"Pause updating the server list to prevent servers from \"jumping around\""
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:54
+msgid "Reload the server list"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:68
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:184
+msgid "Address:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:79
+msgid "Info..."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:80
+msgid "Show more information about the currently highlighted server"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:92
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:264
+msgid "Join!"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:114
+#: qcsrc/menu/xonotic/serverlist.qc:1020
+msgid "MOD^Default"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:121
+#, c-format
+msgid "%d modified"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:121
+msgid "Official"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:129
+msgid "N/A (auth library missing, can't connect)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:131
+msgid "N/A (auth library missing)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:137
+msgid "Not supported (can't connect)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:139
+msgid "Not supported (won't encrypt)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:143
+msgid "Supported (will encrypt)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:145
+msgid "Supported (won't encrypt)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:149
+msgid "Requested (will encrypt)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:151
+msgid "Requested (won't encrypt)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:155
+msgid "Required (can't connect)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:157
+msgid "Required (will encrypt)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:161
+msgid "Use the `crypto_aeslevel` cvar to change your preferences"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:178
+msgid "Hostname:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:192
+msgid "Gametype:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:197
+msgid "Map:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:202
+msgid "Mod:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:207
+msgid "Version:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:212
+msgid "Settings:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:219
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:251
+msgid "Players:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:224
+msgid "Bots:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:229
+msgid "Free slots:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:235
+msgid "Encryption:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:240
+msgid "ID:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:245
+msgid "Key:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qh:7
+msgid "Server Information"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:25
+msgid "Demos"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:26
+msgid "Screenshots"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:27
+msgid "Music Player"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:48
+msgid "Auto record demos"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:57
+msgid "Timedemo"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:58
+msgid "Benchmark how fast your computer can run the highlighted demo"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:62
+msgid "DEMO^Play"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qc:13
+msgid "Playing a demo will disconnect you from the current match."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qc:15
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qc:15
+msgid "Do you really wish to disconnect now?"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qc:13
+msgid "Timing a demo will disconnect you from the current match."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:37
+msgid "MUSICPL^Add"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:40
+msgid "MUSICPL^Add all"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:44
+msgid "Set as menu track"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:48
+msgid "Reset default menu track"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:54
+msgid "Playlist:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:55
+msgid "Random order"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:60
+msgid "MUSICPL^Stop"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:63
+msgid "MUSICPL^Play"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:66
+msgid "MUSICPL^Pause"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:69
+msgid "MUSICPL^Prev"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:72
+msgid "MUSICPL^Next"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:76
+msgid "MUSICPL^Remove"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:79
+msgid "MUSICPL^Remove all"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc:41
+msgid "Auto screenshot scoreboard"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc:62
+msgid "Open in the viewer"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc:137
+msgid "Reset"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc:142
+msgid "Previous"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc:145
+msgid "Next"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc:150
+msgid "Slide show"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:38
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:21
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:37
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:26
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:21
+msgid "Apply immediately"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:50
+msgid "Name"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:79
+msgid "Model"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:98
+msgid "Glowing color"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:108
+msgid "Detail color"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:123
+msgid "Statistics"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:127
+msgid "Allow player statistics to track your client"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:131
+msgid "Allow player statistics to use your nickname"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:136
+msgid "Allow player statistics to rank you in leaderboards"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:152
+msgid "Country"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:156
+msgid "Select language..."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:172
+msgid "Gender:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:179
+msgid "Gender"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_quit.qc:11
+msgid "Are you sure you want to quit?"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_quit.qc:15
+msgid "Back to work..."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_quit.qc:17
+msgid "I got some more fragging to do!"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_quit.qh:7
+msgid "Quit the game"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:15
+msgid "Model:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:21
+msgid "Remove *"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:23
+msgid "Copy *"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:24
+msgid "Paste"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:26
+msgid "Bone:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:31
+msgid "Set * as child"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:32
+msgid "Attach to *"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:34
+msgid "Detach from *"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:37
+msgid "Visual object properties for *:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:41
+msgid "Set alpha:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:44
+msgid "Set color main:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:46
+msgid "Set color glow:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:50
+msgid "Set frame:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:54
+msgid "Physical object properties for *:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:56
+msgid "Set material:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:62
+msgid "Set solidity:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:63
+msgid "Non-solid"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:64
+msgid "Solid"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:65
+msgid "Set physics:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:66
+msgid "Static"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:67
+msgid "Movable"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:68
+msgid "Physical"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:70
+msgid "Set scale:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:72
+msgid "Set force:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:76
+msgid "Claim *"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:78
+msgid "* object info"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:79
+msgid "* mesh info"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:80
+msgid "* attachment info"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:81
+msgid "Show help"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qc:82
+msgid "* is the object you are facing"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_sandboxtools.qh:6
+msgid "Sandbox Tools"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings.qc:18
+msgid "Video"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings.qc:19
+msgid "Effects"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings.qc:20
+msgid "Audio"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings.qc:22
+msgid "Game"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings.qc:23
+msgid "Input"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings.qc:24
+msgid "User"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings.qc:25
+#: qcsrc/menu/xonotic/keybinder.qc:119
+msgid "Misc"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings.qh:6
+msgid "Settings"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings.qh:7
+msgid "Change the game settings"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
+msgid "Master:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:35
+msgid "Music:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:43
+msgid "VOL^Ambient:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:50
+msgid "Info:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:57
+msgid "Items:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:64
+msgid "Pain:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:71
+msgid "Player:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:78
+msgid "Shots:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:85
+msgid "Voice:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:93
+msgid "Weapons:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:99
+msgid "New style sound attenuation"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:102
+msgid "Mute sounds when not active"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:105
+msgid "Frequency:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:107
+msgid "Sound output frequency"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:108
+msgid "8 kHz"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:109
+msgid "11.025 kHz"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:110
+msgid "16 kHz"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:111
+msgid "22.05 kHz"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:112
+msgid "24 kHz"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:113
+msgid "32 kHz"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:114
+msgid "44.1 kHz"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:115
+msgid "48 kHz"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:119
+msgid "Channels:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:121
+msgid "Number of channels for the sound output"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:122
+msgid "Mono"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:123
+msgid "Stereo"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:124
+msgid "2.1"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:125
+msgid "4"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:126
+msgid "5"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:127
+msgid "5.1"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:128
+msgid "6.1"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:129
+msgid "7.1"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:134
+msgid "Swap stereo output channels"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:135
+msgid "Swap left/right channels"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:138
+msgid "Headphone friendly mode"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:139
+msgid ""
+"Enable spatialization (blend the right and left channel slightly to decrease "
+"stereo separation a bit for headphones)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:143
+msgid "Hit indication sound"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:144
+msgid "Play a hit indicator sound when your shot hits an enemy"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:147
+msgid "Chat message sound"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:149
+msgid "Menu sounds"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:150
+msgid "Play sounds when clicking menu items"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:151
+msgid "Focus sounds"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:152
+msgid "Play sounds when hovering over menu items too"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:156
+msgid "Time announcer:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:158
+msgid "WRN^Disabled"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:160
+msgid "5 minutes"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:161
+msgid "WRN^Both"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:164
+msgid "Automatic taunts:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:166
+msgid "Automatically taunt enemies after fragging them"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:168
+msgid "Sometimes"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:169
+msgid "Often"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:170
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:147
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:57
+msgid "Always"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_audio.qc:176
+msgid "Debug info about sounds"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_bindings_reset.qc:11
+msgid "Are you sure you want to reset all key bindings?"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_bindings_reset.qh:6
+msgid "Reset key bindings"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:41
+msgid "Quality preset:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:45
+msgid "PRE^OMG!"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:48
+msgid "PRE^Low"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:50
+msgid "PRE^Medium"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:52
+msgid "PRE^Normal"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:54
+msgid "PRE^High"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:56
+msgid "PRE^Ultra"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:60
+msgid "PRE^Ultimate"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:65
+msgid "Geometry detail:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:67
+msgid "Change the smoothness of the curves on the map"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:68
+msgid "DET^Lowest"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:69
+msgid "DET^Low"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:70
+msgid "DET^Normal"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:71
+msgid "DET^Good"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:72
+msgid "DET^Best"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:73
+msgid "DET^Insane"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:77
+msgid "Player detail:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:79
+msgid "PDET^Low"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:80
+msgid "PDET^Medium"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:81
+msgid "PDET^Normal"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:82
+msgid "PDET^Good"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:83
+msgid "PDET^Best"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:87
+msgid "Texture resolution:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:91
+msgid "RES^Leet"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:92
+msgid "RES^Lowest"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:93
+msgid "RES^Very low"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:94
+msgid "RES^Low"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:95
+msgid "RES^Normal"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:96
+msgid "RES^Good"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:97
+msgid "RES^Best"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:115
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:120
+msgid "Avoid lossy texture compression"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:129
+msgid "Disable sky for performance and visibility"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:129
+msgid "Show sky"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:132
+msgid "Show surfaces"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:133
+msgid ""
+"Disable textures completely for very slow hardware. This gives a huge "
+"performance boost, but looks very ugly."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:136
+msgid "Use lightmaps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:137
+msgid ""
+"Use high resolution lightmaps, which will look pretty but use up some extra "
+"video memory"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:139
+msgid "Deluxe mapping"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:140
+msgid "Use per-pixel lighting effects"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:142
+msgid "Gloss"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:143
+msgid "Enable the use of glossmaps on textures supporting it"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:146
+msgid "Offset mapping"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:147
+msgid ""
+"Offset mapping effect that will make textures with bumpmaps appear like they "
+"\"pop out\" of the flat 2D surface"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:149
+msgid "Relief mapping"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:150
+msgid ""
+"Higher quality offset mapping, which also has a huge impact on performance"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:153
+msgid "Reflections:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:154
+msgid ""
+"Reflection and refraction quality, has a huge impact on performance on maps "
+"with reflecting surfaces"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:157
+msgid "Resolution of reflections/refractions"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:158
+msgid "Blurred"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:159
+msgid "REFL^Good"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:160
+msgid "Sharp"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:164
+msgid "Decals"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:165
+msgid "Enable decals (bullet holes and blood)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:166
+msgid "Decals on models"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:170
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:254
+msgid "Distance:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:173
+msgid "Decals further away than this will not be drawn"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:177
+msgid "Time:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:180
+msgid "Time in seconds before decals fade away"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:184
+msgid "Damage effects:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:186
+msgid "DMGFX^Disabled"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:187
+msgid "Skeletal"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:188
+msgid "DMGFX^All"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:192
+msgid "No dynamic lighting"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:193
+msgid "Enable corona flares around certain lights"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:195
+msgid "Fake corona lighting"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:196
+msgid ""
+"Enable faster but uglier dynamic lights by rendering bright coronas instead "
+"of real dynamic lights"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:199
+msgid "Realtime dynamic lighting"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:200
+msgid "Enable rendering of dynamic lights such as explosions and rocket lights"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:202
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:208
+msgid "Shadows"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:203
+msgid "Enable rendering of shadows from dynamic lights"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:206
+msgid "Realtime world lighting"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:207
+msgid ""
+"Enable rendering of full realtime world lighting on maps that support it. "
+"Note that this might have a big impact on performance."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:209
+msgid "Enable rendering of shadows from realtime world lights"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:213
+msgid "Use normal maps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:214
+msgid "Enable use of directional shading on textures"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:216
+msgid "Soft shadows"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
+msgid "Fade corona according to visibility"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:221
+msgid "Fade coronas according to visibility"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:225
+msgid "Bloom"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:226
+msgid ""
+"Enable bloom effect, which brightens the neighboring pixels of very bright "
+"pixels. Has a big impact on performance."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:227
+msgid "Extra postprocessing effects"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:228
+msgid ""
+"Enables special postprocessing effects for when damaged or under water or "
+"using a powerup"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
+msgid "Motion blur strength - 0.4 recommended"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:234
+msgid "Motion blur:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:240
+msgid "Particles"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:241
+msgid "Spawnpoint effects"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:242
+msgid "Particles effects at all spawn points and whenever a player spawns"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:247
+msgid "Quality:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:250
+#: qcsrc/menu/xonotic/slider_particles.qc:13
+msgid ""
+"Multiplier for amount of particles. Less means less particles, which in turn "
+"gives for better performance"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_effects.qc:257
+msgid "Particles further away than this will not be drawn"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:31
+msgid "No crosshair"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:33
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:62
+msgid "Per weapon"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:34
+msgid ""
+"Set a different crosshair for each weapon, good if you play without weapon "
+"models"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:48
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:81
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:97
+msgid "Size:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:64
+msgid "By health"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:76
+msgid "Use rings to indicate weapon status"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:93
+msgid "Enable center crosshair dot"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:111
+msgid "Use normal crosshair color"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:122
+msgid "Smooth effects of crosshairs"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:125
+msgid "Hit testing:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:128
+msgid ""
+"None: do not do hit tests for the crosshair; TrueAim: blur the crosshair "
+"when there's an obstacle between your gun and the target; Enemies: also "
+"enlarge the crosshair when you would hit an enemy"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:129
+msgid "HTTST^Disabled"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:130
+msgid "HTTST^TrueAim"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:131
+msgid "HTTST^Enemies"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:136
+msgid "Blur crosshair if the shot is obstructed"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:140
+msgid "Enlarge crosshair if targeting an enemy"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:143
+msgid "Animate crosshair when hitting an enemy"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:146
+msgid "Animate crosshair when picking up an item"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qh:7
+msgid "Crosshair"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:43
+msgid "Scoreboard"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:48
+msgid "Fading speed:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:51
+msgid "Enable rows / columns highlighting"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:53
+msgid "Show accuracy underneath scoreboard"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:55
+msgid "Show team sizes:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:56
+msgid ""
+"Team size position: Off=do not show; Left=on the left side of the scoreboard "
+"and move team scores to the right; Right=on the right of the scoreboard"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:64
+msgid "Waypoints"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:66
+msgid "Display waypoint markers for objectives on the map"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:67
+msgid "Show various gametype specific waypoints"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:73
+msgid "Control transparency of the waypoints"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:77
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:130
+msgid "Fontsize:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:83
+msgid "Edge offset:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:91
+msgid "Fade when near the crosshair"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:95
+msgid "Display names instead of icons"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:100
+msgid "Damage"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:102
+msgid "Overlay:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:105
+msgid "Factor:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:110
+msgid "Fade rate:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:118
+msgid "Player Names"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:120
+msgid "Show names above players"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:136
+msgid "Max distance:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:142
+msgid "Decolorize:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:146
+#: qcsrc/menu/xonotic/keybinder.qc:113
+msgid "Teamplay"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:154
+msgid "Only when near crosshair"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:158
+msgid "Display health and armor"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:163
+msgid "Damage overlay:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:166
+msgid "Dynamic HUD"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:167
+msgid "HUD moves around following player's movement"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:169
+msgid "Shake the HUD when hurt"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:173
+#: qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qh:6
+msgid "Enter HUD editor"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hud.qh:7
+msgid "HUD"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qc:21
+msgid "In order for the HUD editor to show, you must first be in game."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qc:23
+msgid "Do you wish to start a local game to set up the HUD?"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:24
+msgid "Frag Information"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:26
+msgid "Display information about killing sprees"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:29
+msgid "Only display sprees if they are achievements"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:34
+msgid "Show spree information in centerprints"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:38
+msgid "Show spree information in death messages"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:43
+msgid "Sprees in info messages:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:46
+msgid "SPREES^Disabled"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:47
+msgid "Target"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:48
+msgid "Attacker"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:49
+msgid "SPREES^Both"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:55
+msgid "Print on a seperate line"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:58
+msgid "Add extra frag information to centerprint when available"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:62
+msgid "Add frag location to death messages when available"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:65
+msgid "Gamemode Settings"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:67
+msgid "Display capture times in Capture The Flag"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:71
+msgid "Display name of flag stealer in Capture The Flag"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:92
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:126
+msgid "Other"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:78
+msgid "Display console messages in the top left corner"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:80
+msgid "Display all info messages in the chatbox"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:82
+msgid "Display player statuses in the chatbox"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:86
+msgid "Powerup notifications"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:89
+msgid "Weapon centerprint notifications"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:92
+msgid "Weapon info message notifications"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:96
+msgid "Announcers"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:98
+msgid "Respawn countdown sounds"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:101
+msgid "Killstreak sounds"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:104
+msgid "Achievement sounds"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_messages.qh:7
+msgid "Messages"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:30
+msgid "Items"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:32
+msgid "Use simple 2D images instead of item models"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:34
+msgid "Unavailable alpha:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:37
+msgid "Unavailable color:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:39
+msgid "GHOITEMS^Black"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:40
+msgid "GHOITEMS^Dark"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:41
+msgid "GHOITEMS^Tinted"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:42
+msgid "GHOITEMS^Normal"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:43
+msgid "GHOITEMS^Blue"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:49
+#: qcsrc/menu/xonotic/serverlist.qc:737
+msgid "Players"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:51
+msgid "Force player models to mine"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:53
+msgid "Force player colors to mine"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:56
+msgid "In non teamplay modes only"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:60
+msgid "Body fading:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:63
+msgid "Gibs:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:65
+msgid "GIBS^None"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:66
+msgid "GIBS^Few"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:67
+msgid "GIBS^Many"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qc:68
+msgid "GIBS^Lots"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qh:7
+msgid "Models"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_model.qh:8
+msgid "Customize how players and items are displayed in game"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:26
+msgid "1st person perspective"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:29
+msgid "Slide to third person upon death"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:33
+msgid "Smooth the view when landing from a jump"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:37
+msgid "Smooth the view while crouching"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:41
+msgid "View waving while idle"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:45
+msgid "View bobbing while walking around"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:50
+msgid "3rd person perspective"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:53
+msgid "Back distance"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:59
+msgid "Up distance"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:65
+msgid "Allow passing through walls while spectating"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:69
+msgid "Field of view:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:71
+msgid "Field of vision in degrees"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:75
+msgid "ZOOM^Zoom factor:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:77
+msgid "How big the zoom factor is when the zoom button is pressed"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:80
+msgid "ZOOM^Zoom speed:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:82
+msgid "How fast the view will be zoomed, disable to zoom instantly"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:91
+msgid "ZOOM^Instant"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:95
+msgid "ZOOM^Zoom sensitivity:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:97
+msgid ""
+"How zoom changes sensitivity, from 0 (lower sensitivity) to 1 (no "
+"sensitivity change)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:100
+msgid "Velocity zoom"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:101
+msgid "Forward movement only"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:105
+msgid "VZOOM^Factor"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:112
+msgid "Display reticle 2D overlay while zooming"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:115
+msgid "Release zoom when you die or respawn"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qc:119
+msgid "Release zoom when you switch weapons"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_view.qh:7
+#: qcsrc/menu/xonotic/keybinder.qc:83
+msgid "View"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:33
+msgid "Weapon Priority List (* = mutator weapon)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:39
+msgid "Up"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:43
+msgid "Down"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:49
+msgid "Use priority list for weapon cycling"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:50
+msgid ""
+"Make use of the list above when cycling through weapons with the mouse wheel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:52
+msgid "Cycle through only usable weapon selections"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:56
+msgid "Auto switch weapons on pickup"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:57
+msgid ""
+"Automatically switch to newly picked up weapons if they are better than what "
+"you are carrying"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:60
+msgid "Release attack buttons when you switch weapons"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:63
+msgid "Draw 1st person weapon model"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:64
+msgid "Draw the weapon model"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:68
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:71
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:74
+msgid "Position of the weapon model; requires reconnect"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:77
+msgid "Weapon model opacity:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:91
+msgid "Gun model swaying"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:96
+msgid "Gun model bobbing"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_game_weapons.qh:7
+#: qcsrc/menu/xonotic/keybinder.qc:51
+msgid "Weapons"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:34
+msgid "Key Bindings"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:38
+msgid "Change key..."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:42
+msgid "Edit..."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:48
+msgid "Clear"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:53
+msgid "Reset all"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:58
+msgid "Mouse"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:60
+msgid "Sensitivity:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:62
+msgid "Mouse speed multiplier"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:64
+msgid "Smooth aiming"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:65
+msgid "Smoothes the mouse movement, but makes aiming slightly less responsive"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:67
+msgid "Invert aiming"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:68
+msgid "Invert mouse movement on the Y-axis"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:70
+msgid "Use system mouse positioning"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:75
+msgid "Enable built in mouse acceleration"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:79
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:83
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:86
+msgid "Disable system mouse acceleration"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:80
+msgid "Make use of DGA mouse input"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:94
+msgid "Pressing \"enter console\" key also closes it"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:95
+msgid "Allow the console toggling bind to also close the console"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:97
+msgid "Automatically repeat jumping if holding jump"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:100
+msgid "Jetpack on jump:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:102
+msgid "JPJUMP^Disabled"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:103
+msgid "Air only"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:104
+msgid "JPJUMP^All"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:115
+#: qcsrc/menu/xonotic/dialog_settings_input.qc:120
+msgid "Use joystick input"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input_userbind.qc:31
+msgid "Command when pressed:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input_userbind.qc:34
+msgid "Command when released:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input_userbind.qc:40
+msgid "Cancel"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_input_userbind.qh:7
+msgid "User defined key bind"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:11
+#, c-format
+msgid "%d fps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:12
+#, c-format
+msgid "%d KB/s"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:13
+#, c-format
+msgid "%d MB/s"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
+msgid "Network"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
+msgid "Client UDP port:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
+msgid "Force client to use chosen port unless it is set to 0"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
+msgid "Bandwidth:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
+msgid "Specify your network speed"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
+msgid "56k"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
+msgid "ISDN"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
+msgid "Slow ADSL"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
+msgid "Fast ADSL"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
+msgid "Broadband"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
+msgid "Server queries/s:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
+msgid "Downloads:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:50
+msgid "Maximum number of concurrent HTTP/FTP downloads"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
+msgid "Download speed:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:65
+msgid "Local latency:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
+msgid "Show netgraph"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:70
+msgid "Show a graph of packet sizes and other information"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:72
+msgid "Client-side movement prediction"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:74
+msgid "Movement error compensation"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:78
+msgid "Use encryption (AES) when available"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:81
+msgid "Framerate"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:83
+msgid "Maximum:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:93
+msgid "MAXFPS^Unlimited"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:96
+msgid "Target:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:98
+msgid "TRGT^Disabled"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:109
+msgid "Idle limit:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:115
+msgid "IDLFPS^Unlimited"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:119
+msgid "Save processing time for other apps"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:122
+msgid "Show frames per second"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:123
+msgid "Show your rendered frames per second"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:128
+msgid "Menu tooltips:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:130
+msgid ""
+"Menu tooltips: disabled, standard or advanced (also shows cvar or console "
+"command bound to the menu item)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:131
+msgid "TLTIP^Disabled"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:132
+msgid "TLTIP^Standard"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:133
+msgid "TLTIP^Advanced"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:136
+msgid "Show current date and time"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:137
+msgid "Show current date and time of day, useful on screenshots"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:140
+msgid "Enable developer mode"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:144
+msgid "Advanced settings..."
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:145
+msgid "Advanced settings where you can tweak every single variable of the game"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc.qc:150
+#: qcsrc/menu/xonotic/dialog_settings_misc_reset.qh:6
+msgid "Factory reset"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc:31
+msgid "Cvar filter:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc:38
+msgid "Modified cvars only"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc:45
+msgid "Setting:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc:49
+msgid "Type:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc:53
+msgid "Value:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc:70
+msgid "Description:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qh:7
+msgid "Advanced settings"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc_reset.qc:11
+msgid "Are you sure you want to reset all settings?"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_misc_reset.qc:13
+msgid "This will create a backup config in your data directory"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_user.qc:23
+msgid "Menu Skins"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_user.qc:62
+msgid "Text Language"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_user.qc:67
+msgid "Set language"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_user.qc:72
+msgid "Disable gore effects and harsh language"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_user.qc:73
+msgid "Replace blood and gibs with content that does not have any gore effects"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc:10
+msgid "While connected language changes will be applied only to the menu,"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc:12
+msgid "full language changes will take effect starting from the next game"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc:16
+msgid "Disconnect now"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc:17
+msgid "Switch language"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qh:6
+msgid "Warning"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:33
+msgid "Resolution:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:37
+msgid "Font/UI size:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:39
+msgid "SZ^Unreadable"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:40
+msgid "SZ^Tiny"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:41
+msgid "SZ^Little"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:42
+msgid "SZ^Small"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:43
+msgid "SZ^Medium"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:44
+msgid "SZ^Large"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:45
+msgid "SZ^Huge"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:46
+msgid "SZ^Gigantic"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:47
+msgid "SZ^Colossal"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:51
+msgid "Color depth:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:53
+msgid "How many bits per pixel (BPP) to render at, 32 is recommended"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:54
+msgid "16bit"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:55
+msgid "32bit"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:59
+msgid "Full screen"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:61
+msgid "Vertical Synchronization"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:62
+msgid ""
+"Enable vertical synchronization to prevent tearing, will cap your fps to the "
+"screen refresh rate"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:67
+msgid "Flip view horizontally"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:68
+msgid "Poor man's left handed mode"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:71
+msgid "Anisotropy:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:73
+msgid "Anisotropic filtering quality"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:74
+msgid "ANISO^Disabled"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:75
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:86
+msgid "2x"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:76
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:87
+msgid "4x"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:77
+msgid "8x"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:78
+msgid "16x"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:81
+msgid "Antialiasing:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:84
+msgid ""
+"Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
+"might decrease performance by quite a lot"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:85
+msgid "AA^Disabled"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:92
+msgid "High-quality frame buffer"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:97
+msgid "Depth first:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:99
+msgid ""
+"Eliminate overdraw by rendering a depth-only version of the scene before the "
+"normal rendering starts"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:100
+msgid "DF^Disabled"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:101
+msgid "DF^World"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:102
+msgid "DF^All"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:105
+msgid "Vertex Buffer Objects (VBOs)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:108
+msgid "VBO^Off"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:109
+msgid "Vertices, some Tris (compatible)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:110
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:114
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:116
+msgid ""
+"Make use of Vertex Buffer Objects to store static geometry in video memory "
+"for faster rendering"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:113
+msgid "Vertices"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:115
+msgid "Vertices and Triangles"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:119
+msgid "Brightness:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:121
+msgid "Brightness of black"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:123
+msgid "Contrast:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:125
+msgid "Brightness of white"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:127
+msgid "Gamma:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:130
+msgid ""
+"Inverse gamma correction value, a brightness effect that does not affect "
+"white or black"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:133
+msgid "Contrast boost:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:136
+msgid "By how much to multiply the contrast in dark areas"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:139
+msgid "Saturation:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:142
+msgid ""
+"Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
+"requires GLSL color control"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:146
+msgid "LIT^Ambient:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:148
+msgid ""
+"Ambient lighting, if set too high it tends to make light on maps look dull "
+"and flat"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:150
+msgid "Intensity:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:152
+msgid "Global rendering brightness"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:155
+msgid "Wait for GPU to finish each frame"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:156
+msgid ""
+"Make the CPU wait for the GPU to finish each frame, can help with some "
+"strange input or video lag on some machines"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:158
+msgid "Use OpenGL 2.0 shaders (GLSL)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:163
+msgid "Psycho coloring (easter egg)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_settings_video.qc:166
+msgid "Trippy vertices (easter egg)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_singleplayer.qc:109
+msgid "Instant action! (random map with bots)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_singleplayer.qc:116
+msgid "???"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_singleplayer.qc:129
+msgid "Campaign Difficulty:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_singleplayer.qc:130
+msgid "CSKL^Easy"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_singleplayer.qc:131
+msgid "CSKL^Medium"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_singleplayer.qc:132
+msgid "CSKL^Hard"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_singleplayer.qc:134
+msgid "Start Singleplayer!"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_singleplayer.qh:6
+msgid "Singleplayer"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_singleplayer.qh:7
+msgid "Play the singleplayer campaign or instant action matches against bots"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_singleplayer_winner.qh:7
+msgid "Winner"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_teamselect.qc:32
+msgid "join 'best' team (auto-select)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_teamselect.qc:33
+msgid "Autoselect team (recommended)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_teamselect.qc:37
+msgid "red"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_teamselect.qc:38
+msgid "blue"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_teamselect.qc:39
+msgid "yellow"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_teamselect.qc:40
+msgid "pink"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_teamselect.qc:43
+#: qcsrc/menu/xonotic/keybinder.qc:116
+msgid "spectate"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_teamselect.qh:7
+msgid "Team Selection"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_uid2name.qc:10
+msgid "Allow player statistics to use your nickname?"
+msgstr ""
+
+#: qcsrc/menu/xonotic/dialog_uid2name.qc:12
+msgid "Answering \"No\" you will appear as \"Anonymous player\""
+msgstr ""
+
+#: qcsrc/menu/xonotic/gametypelist.qc:87
+msgid "teamplay"
+msgstr ""
+
+#: qcsrc/menu/xonotic/gametypelist.qc:89
+msgid "free for all"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:35
+msgid "Moving"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:36
+msgid "forward"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:37
+msgid "backpedal"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:38
+msgid "strafe left"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:39
+msgid "strafe right"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:40
+msgid "jump / swim"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:41
+msgid "crouch / sink"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:42
+msgid "off-hand hook"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:43
+msgid "jetpack"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:46
+msgid "Attacking"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:52
+msgid "WEAPON^previous"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:53
+msgid "WEAPON^next"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:54
+msgid "WEAPON^previously used"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:55
+msgid "WEAPON^best"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:56
+msgid "reload"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:57
+msgid "drop weapon / throw nade"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:84
+msgid "hold zoom"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:85
+msgid "toggle zoom"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:86
+msgid "show scores"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:87
+msgid "screen shot"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:88
+msgid "maximize radar"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:89
+msgid "3rd person view"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:90
+msgid "enter spectator mode"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:93
+msgid "Communication"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:94
+msgid "public chat"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:95
+msgid "team chat"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:96
+msgid "show chat history"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:97
+msgid "vote YES"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:98
+msgid "vote NO"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:102
+msgid "Client"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:106 qcsrc/menu/xonotic/keybinder.qc:108
+msgid "enter console"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:109
+msgid "disconnect"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:110
+msgid "quit"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:114
+msgid "auto-join team"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:120
+msgid "drop key/flag, exit vehicle"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:121
+msgid "suicide / respawn"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:122
+msgid "quick menu"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:125
+msgid "User defined"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:132
+msgid "Development"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:133
+msgid "sandbox menu"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:134
+msgid "drag object (sandbox)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/keybinder.qc:135
+msgid "waypoint editor menu"
+msgstr ""
+
+#: qcsrc/menu/xonotic/mainwindow.qc:96 qcsrc/menu/xonotic/mainwindow.qc:99
+msgid "Do not press this button again!"
+msgstr ""
+
+#: qcsrc/menu/xonotic/maplist.qc:288
+msgid ""
+"Huh? Can't play this (m is NULL). Refiltering so this won't happen again."
+msgstr ""
+
+#: qcsrc/menu/xonotic/maplist.qc:296
+#, c-format
+msgid "%s's Xonotic Server"
+msgstr ""
+
+#: qcsrc/menu/xonotic/maplist.qc:301
+msgid ""
+"Huh? Can't play this (invalid game type). Refiltering so this won't happen "
+"again."
+msgstr ""
+
+#: qcsrc/menu/xonotic/playerlist.qc:102 qcsrc/menu/xonotic/playerlist.qc:112
+msgid "spectator"
+msgstr ""
+
+#: qcsrc/menu/xonotic/playermodel.qc:161
+msgid "<no model found>"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:256
+msgid "SERVER^Remove favorite"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:257
+msgid "Remove the currently highlighted server from bookmarks"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:261
+msgid "SERVER^Favorite"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:262
+msgid ""
+"Bookmark the currently highlighted server so that it's faster to find in the "
+"future"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:733
+msgid "Ping"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:734
+msgid "Hostname"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:735
+msgid "Map"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:736
+msgid "Type"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:1019
+#, c-format
+msgid "AES level %d"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:1019
+msgid "ENC^none"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:1019
+msgid "encryption:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:1020
+#, c-format
+msgid "mod: %s"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:1022
+#, c-format
+msgid "modified settings"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:1022
+#, c-format
+msgid "official settings"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:1024
+msgid "stats disabled"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qc:1024
+msgid "stats enabled"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qh:152
+msgid "SLCAT^Favorites"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qh:153
+msgid "SLCAT^Recommended"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qh:154
+msgid "SLCAT^Normal Servers"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qh:155
+msgid "SLCAT^Servers"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qh:156
+msgid "SLCAT^Competitive Mode"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qh:157
+msgid "SLCAT^Modified Servers"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qh:158
+msgid "SLCAT^Overkill"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qh:159
+msgid "SLCAT^InstaGib"
+msgstr ""
+
+#: qcsrc/menu/xonotic/serverlist.qh:160
+msgid "SLCAT^Defrag Mode"
+msgstr ""
+
+#: qcsrc/menu/xonotic/skinlist.qc:70
+msgid "<TITLE>"
+msgstr ""
+
+#: qcsrc/menu/xonotic/skinlist.qc:71
+msgid "<AUTHOR>"
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_decibels.qc:72
+msgid "VOL^MAX"
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_decibels.qc:74
+msgid "VOL^OFF"
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_decibels.qc:82
+#, c-format
+msgid "%s dB"
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_particles.qc:14
+msgid "PART^OMG"
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_particles.qc:15
+msgid "PART^Low"
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_particles.qc:16
+msgid "PART^Medium"
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_particles.qc:17
+#: qcsrc/menu/xonotic/slider_sbfadetime.qc:14
+msgid "PART^Normal"
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_particles.qc:18
+msgid "PART^High"
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_particles.qc:19
+msgid "PART^Ultra"
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_particles.qc:20
+msgid "PART^Ultimate"
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_picmip.qc:13
+msgid ""
+"Change the sharpness of the textures. Lowering it will effectively reduce "
+"texture memory usage, but make the textures appear very blurry."
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_resolution.qc:115
+msgid "Screen resolution"
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_sbfadetime.qc:13
+msgid "PART^Slow"
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_sbfadetime.qc:15
+msgid "PART^Fast"
+msgstr ""
+
+#: qcsrc/menu/xonotic/slider_sbfadetime.qc:16
+msgid "PART^Instant"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:29
+msgid "January"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:30
+msgid "February"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:31
+msgid "March"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:32
+msgid "April"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:33
+msgid "May"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:34
+msgid "June"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:35
+msgid "July"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:36
+msgid "August"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:37
+msgid "September"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:38
+msgid "October"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:39
+msgid "November"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:40
+msgid "December"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:46
+#, no-c-format
+msgid "DATE^%m %d, %Y"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:97
+msgid "Joined:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:104
+msgid "Last match:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:111
+msgid "Time played:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:118 qcsrc/menu/xonotic/statslist.qc:231
+msgid "Favorite map:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:150 qcsrc/menu/xonotic/statslist.qc:202
+#: qcsrc/menu/xonotic/statslist.qc:245
+#, c-format
+msgid "Matches:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:155
+#, c-format
+msgid "Wins/Losses:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:156
+#, c-format
+msgid "Win percentage:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:167
+#, c-format
+msgid "Kills/Deaths:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:173
+#, c-format
+msgid "Kill ratio:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:208
+msgid "ELO:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:215
+msgid "Rank:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:222
+msgid "Percentile:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/statslist.qc:247
+#, c-format
+msgid "%d (unranked)"
+msgstr ""
+
+#: qcsrc/menu/xonotic/util.qc:420
+msgid "Update can be downloaded at:"
+msgstr ""
+
+#: qcsrc/menu/xonotic/util.qc:528
+msgid "Autogenerating mapinfo for newly added maps..."
+msgstr ""
+
+#: qcsrc/menu/xonotic/util.qc:566
+#, c-format
+msgid "Update to %s now!"
+msgstr ""
+
+#: qcsrc/menu/xonotic/util.qc:650
+msgid ""
+"^1ERROR: Texture compression is required but not supported.\n"
+"^1Expect visual problems."
+msgstr ""
+
+#: qcsrc/menu/xonotic/util.qc:780
+msgid "Use default"
+msgstr ""
+
+#: qcsrc/menu/xonotic/util.qc:800
+msgid "Team Color:"
+msgstr ""
index ec6eaa06537d5e11adebba25f130a7fce08d147e..910bf2ea5390bbb15f5382c0a15afbb9bc6adfee 100644 (file)
@@ -6,12 +6,13 @@
 # Antoni Das <Antonidas159@gmail.com>, 2015
 # Antoni Das <Antonidas159@gmail.com>, 2015,2017
 # sapphireliu <balancedliu@gmail.com>, 2014
+# CodingJellyfish <dumaosen_main01@outlook.com>, 2018
 # kalawore <kalawore@outlook.com>, 2015
 # Liang Liu <dxkliu@126.com>, 2019
 # Losier Blackheath <losier.cc@gmail.com>, 2018
 # sapphireliu <balancedliu@gmail.com>, 2014
-# 杜茂森 <dumaosen_main01@outlook.com>, 2018-2020
-# 杜茂森 <dumaosen_main01@outlook.com>, 2018
+# CodingJellyfish <dumaosen_main01@outlook.com>, 2018-2020
+# CodingJellyfish <dumaosen_main01@outlook.com>, 2018
 # 韬 刘 <jiegushijia@gmail.com>, 2019
 msgid ""
 msgstr ""
@@ -19,7 +20,7 @@ msgstr ""
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2020-06-07 07:23+0200\n"
 "PO-Revision-Date: 2020-07-25 11:27+0000\n"
-"Last-Translator: 杜茂森 <dumaosen_main01@outlook.com>\n"
+"Last-Translator: CodingJellyfish <dumaosen_main01@outlook.com>\n"
 "Language-Team: Chinese (China) (http://www.transifex.com/team-xonotic/"
 "xonotic/language/zh_CN/)\n"
 "Language: zh_CN\n"
index ade4a92f205dfcba574d55e01a799d4deaac0f7e..5e3ca40562f3ea13fd54bab5e7ef7b92080f8534 100644 (file)
@@ -274,7 +274,7 @@ seta hud_panel_centerprint_bg_padding ""
 seta hud_panel_centerprint_align "0.5"
 seta hud_panel_centerprint_flip "0"
 seta hud_panel_centerprint_fontscale "1"
-seta hud_panel_centerprint_fontscale_bold "1.8"
+seta hud_panel_centerprint_fontscale_bold "1.4"
 seta hud_panel_centerprint_time "3"
 seta hud_panel_centerprint_fade_in "0.2"
 seta hud_panel_centerprint_fade_out "0.5"
index 7e7ae540dcf83d08f3d124c9c3057e2c0e2de69a..5b0f9e05612f9a778a756aab555dc1816214ad7f 100644 (file)
@@ -274,7 +274,7 @@ seta hud_panel_centerprint_bg_padding ""
 seta hud_panel_centerprint_align "0.5"
 seta hud_panel_centerprint_flip "0"
 seta hud_panel_centerprint_fontscale "1"
-seta hud_panel_centerprint_fontscale_bold "1.8"
+seta hud_panel_centerprint_fontscale_bold "1.4"
 seta hud_panel_centerprint_time "3"
 seta hud_panel_centerprint_fade_in "0.2"
 seta hud_panel_centerprint_fade_out "0.5"
index a6c201ef3b1831ca869caa5d7129e5248db04112..1e1845ed73d555359698c1dda420270dfc196205 100644 (file)
@@ -274,7 +274,7 @@ seta hud_panel_centerprint_bg_padding ""
 seta hud_panel_centerprint_align "0.5"
 seta hud_panel_centerprint_flip "0"
 seta hud_panel_centerprint_fontscale "1"
-seta hud_panel_centerprint_fontscale_bold "1.8"
+seta hud_panel_centerprint_fontscale_bold "1.4"
 seta hud_panel_centerprint_time "3"
 seta hud_panel_centerprint_fade_in "0.2"
 seta hud_panel_centerprint_fade_out "0.5"
index 2cb300545a3030288e946b86fa7ea74293ee1bcb..7995bc1638d26e94fbd34b83bda2020c04bfc3b4 100644 (file)
@@ -274,7 +274,7 @@ seta hud_panel_centerprint_bg_padding ""
 seta hud_panel_centerprint_align "0.5"
 seta hud_panel_centerprint_flip "0"
 seta hud_panel_centerprint_fontscale "1"
-seta hud_panel_centerprint_fontscale_bold "1.8"
+seta hud_panel_centerprint_fontscale_bold "1.4"
 seta hud_panel_centerprint_time "3"
 seta hud_panel_centerprint_fade_in "0.2"
 seta hud_panel_centerprint_fade_out "0.5"
index a842dcd35da8ecffd1ac4a09588e68430f3c8e01..c303f227969aac102571b6295a752a3cdd00ddf6 100644 (file)
@@ -274,7 +274,7 @@ seta hud_panel_centerprint_bg_padding ""
 seta hud_panel_centerprint_align "0.5"
 seta hud_panel_centerprint_flip "0"
 seta hud_panel_centerprint_fontscale "1"
-seta hud_panel_centerprint_fontscale_bold "1.8"
+seta hud_panel_centerprint_fontscale_bold "1.4"
 seta hud_panel_centerprint_time "3"
 seta hud_panel_centerprint_fade_in "0.2"
 seta hud_panel_centerprint_fade_out "0.5"
index da4f4d2b21ce43af8b870f796fbbdb08f47dffe8..62e843301fef13ec7fb8b2ad56e066d2890a52bf 100644 (file)
@@ -274,7 +274,7 @@ seta hud_panel_centerprint_bg_padding ""
 seta hud_panel_centerprint_align "0.5"
 seta hud_panel_centerprint_flip "0"
 seta hud_panel_centerprint_fontscale "1"
-seta hud_panel_centerprint_fontscale_bold "1.8"
+seta hud_panel_centerprint_fontscale_bold "1.4"
 seta hud_panel_centerprint_time "3"
 seta hud_panel_centerprint_fade_in "0.2"
 seta hud_panel_centerprint_fade_out "0.5"
index 820c46d2d0c39c7ce4046b9e97e0bbb450b6cf0e..3481c748f905949ef7d5166754f0324e904e9c59 100644 (file)
@@ -16,7 +16,7 @@ ro    "Romanian" "Romana" 74%
 fi    "Finnish" "Suomi" 100%
 el    "Greek" "Ελληνική" 47%
 be    "Belarusian" "Беларуская" 54%
-bg    "Bulgarian" "Български" 59%
+bg    "Bulgarian" "Български" 63%
 ru    "Russian" "Русский" 100%
 sr    "Serbian" "Српски" 64%
 uk    "Ukrainian" "Українська" 50%
index ab9184b9b9efccf44caaaa393a6bace1bf0f6e8e..ec82018a3a520810bb443a95848ca8afb2e31b70 100644 (file)
@@ -11,7 +11,8 @@
 #include <client/teamradar.qc>
 #include <client/view.qc>
 
-#include <client/commands/_mod.inc>
+#include <client/command/_mod.inc>
 #include <client/hud/_mod.inc>
+#include <client/items/_mod.inc>
 #include <client/mutators/_mod.inc>
 #include <client/weapons/_mod.inc>
index 971cc01de6afaf6e3a002942cfac832a15b9d165..85d9c1204a57220e9382a0a3c7abbebfe76cc41a 100644 (file)
@@ -11,7 +11,8 @@
 #include <client/teamradar.qh>
 #include <client/view.qh>
 
-#include <client/commands/_mod.qh>
+#include <client/command/_mod.qh>
 #include <client/hud/_mod.qh>
+#include <client/items/_mod.qh>
 #include <client/mutators/_mod.qh>
 #include <client/weapons/_mod.qh>
index 5c04cf5ea4a087a2a5cb2503ec5a798dca2ab555..347da5de121ce77739b3acb704ed67f60c5c5bcd 100644 (file)
@@ -244,7 +244,7 @@ float autocvar_hud_panel_centerprint_fade_subsequent_minfontsize = 0.75;
 float autocvar_hud_panel_centerprint_fade_minfontsize = 0;
 bool autocvar_hud_panel_centerprint_flip;
 float autocvar_hud_panel_centerprint_fontscale;
-float autocvar_hud_panel_centerprint_fontscale_bold = 1.8;
+float autocvar_hud_panel_centerprint_fontscale_bold = 1.4;
 float autocvar_hud_panel_centerprint_time;
 bool autocvar_hud_panel_chat;
 bool autocvar_hud_panel_engineinfo;
index 02739194a858b799752f06dca40e36b8aade1bae..c864f0d6a15af48299e9387afa24a07f1a5fe31a 100644 (file)
@@ -2,7 +2,6 @@
 
 #include <common/util.qh>
 #include <client/autocvars.qh>
-#include <client/defs.qh>
 #include <client/main.qh>
 
 #define CONSTANT_SPEED_DECAY
index a3044d537cd3200bedd070f38be867b801456e9e..18679ebb86dc9a744a92a54c38e1ea1cfd35b277 100644 (file)
@@ -1,15 +1,10 @@
 #pragma once
 
-entityclass(BGMScript);
-classfield(BGMScript) .string bgmscript;
-classfield(BGMScript) .float bgmscriptattack;
-classfield(BGMScript) .float bgmscriptdecay;
-classfield(BGMScript) .float bgmscriptsustain;
-classfield(BGMScript) .float bgmscriptrelease;
+#include <common/mapobjects/bgmscript.qh>
 
 classfield(BGMScript) .float just_toggled;
 
-#ifdef CSQC
+float bgmtime;
+
 void BGMScript_InitEntity(entity e);
 float doBGMScript(entity e);
-#endif
diff --git a/qcsrc/client/command/_mod.inc b/qcsrc/client/command/_mod.inc
new file mode 100644 (file)
index 0000000..1212949
--- /dev/null
@@ -0,0 +1,4 @@
+// generated file; do not modify
+#ifdef CSQC
+    #include <client/command/cl_cmd.qc>
+#endif
diff --git a/qcsrc/client/command/_mod.qh b/qcsrc/client/command/_mod.qh
new file mode 100644 (file)
index 0000000..8120643
--- /dev/null
@@ -0,0 +1,4 @@
+// generated file; do not modify
+#ifdef CSQC
+    #include <client/command/cl_cmd.qh>
+#endif
diff --git a/qcsrc/client/command/cl_cmd.qc b/qcsrc/client/command/cl_cmd.qc
new file mode 100644 (file)
index 0000000..127f404
--- /dev/null
@@ -0,0 +1,648 @@
+#include "cl_cmd.qh"
+// ==============================================
+//  CSQC client commands code, written by Samual
+//  Last updated: December 28th, 2011
+// ==============================================
+
+#include <common/command/_mod.qh>
+#include "cl_cmd.qh"
+
+#include "../autocvars.qh"
+#include <client/hud/_mod.qh>
+#include <client/hud/panel/quickmenu.qh>
+#include <client/hud/panel/radar.qh>
+#include <client/hud/panel/scoreboard.qh>
+#include <client/hud/panel/vote.qh>
+#include "../main.qh"
+#include "../mapvoting.qh"
+#include "../miscfunctions.qh"
+#include <client/view.qh>
+
+#include <client/mutators/_mod.qh>
+
+#include <common/minigames/cl_minigames_hud.qh>
+
+#include <common/mapinfo.qh>
+
+void DrawDebugModel(entity this)
+{
+       if (time - floor(time) > 0.5)
+       {
+               PolyDrawModel(this);
+               this.drawmask = 0;
+       }
+       else
+       {
+               this.renderflags = 0;
+               this.drawmask = MASK_NORMAL;
+       }
+}
+
+
+// =======================
+//  Command Sub-Functions
+// =======================
+
+void LocalCommand_blurtest(int request)
+{
+       TC(int, request);
+       // Simple command to work with postprocessing temporarily... possibly completely pointless, the glsl shader is used for a real feature now...
+       // Anyway, to enable it, just compile the client with -DBLURTEST and then you can use the command.
+
+       #ifdef BLURTEST
+       switch (request)
+       {
+               case CMD_REQUEST_COMMAND:
+               {
+                       blurtest_time0 = time;
+                       blurtest_time1 = time + stof(argv(1));
+                       blurtest_radius = stof(argv(2));
+                       blurtest_power = stof(argv(3));
+                       LOG_INFO("Enabled blurtest");
+                       return;
+               }
+
+               default:
+               case CMD_REQUEST_USAGE:
+               {
+                       LOG_HELP("Usage:^3 cl_cmd blurtest");
+                       LOG_HELP("  No arguments required.");
+                       return;
+               }
+       }
+       #else
+       if (request)
+       {
+               LOG_INFO("Blurtest is not enabled on this client.");
+               return;
+       }
+       #endif
+}
+
+void LocalCommand_boxparticles(int request, int argc)
+{
+       TC(int, request); TC(int, argc);
+       switch (request)
+       {
+               case CMD_REQUEST_COMMAND:
+               {
+                       if (argc == 9)
+                       {
+                               int effect = _particleeffectnum(argv(1));
+                               if (effect >= 0)
+                               {
+                                       int index = stoi(argv(2));
+                                       entity own;
+                                       if (index <= 0)
+                                               own = entitybyindex(-index);
+                                       else
+                                               own = findfloat(NULL, entnum, index);
+                                       vector org_from = stov(argv(3));
+                                       vector org_to = stov(argv(4));
+                                       vector dir_from = stov(argv(5));
+                                       vector dir_to = stov(argv(6));
+                                       int countmultiplier = stoi(argv(7));
+                                       int flags = stoi(argv(8));
+                                       boxparticles(effect, own, org_from, org_to, dir_from, dir_to, countmultiplier, flags);
+                                       return;
+                               }
+                       }
+               }
+
+               default:
+                       LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
+               case CMD_REQUEST_USAGE:
+               {
+                       LOG_HELP(
+                               "Usage:^3 cl_cmd boxparticles effectname own org_from org_to, dir_from, dir_to, countmultiplier, flags\n"
+                               "  'effectname' is the name of a particle effect in effectinfo.txt\n"
+                               "  'own' is the entity number of the owner (negative for csqc ent, positive for svqc ent)\n"
+                               "  'org_from' is the starting origin of the box\n"
+                               "  'org_to' is the ending origin of the box\n"
+                               "  'dir_from' is the minimum velocity\n"
+                               "  'dir_to' is the maximum velocity\n"
+                               "  'countmultiplier' defines a multiplier for the particle count (affects count only, not countabsolute or trailspacing)\n"
+                               "  'flags' can contain:\n"
+                               "    1 to respect globals particles_alphamin, particles_alphamax (set right before via prvm_globalset client)\n"
+                               "    2 to respect globals particles_colormin, particles_colormax (set right before via prvm_globalset client)\n"
+                               "    4 to respect globals particles_fade (set right before via prvm_globalset client)\n"
+                               "    128 to draw a trail, not a box"
+                       );
+                       return;
+               }
+       }
+}
+
+void LocalCommand_create_scrshot_ent(int request)
+{
+       TC(int, request);
+       switch (request)
+       {
+               case CMD_REQUEST_COMMAND:
+               {
+                       string path = ((argv(1) == "") ? "" : strcat(argv(1), "/"));
+                       string filename = strcat(path, MapInfo_Map_bspname, "_scrshot_ent.txt");
+                       int fh = fopen(filename, FILE_APPEND);
+
+                       if (fh >= 0)
+                       {
+                               fputs(fh, "{\n");
+                               fputs(fh, strcat("\"classname\" \"info_autoscreenshot\"\n"));
+                               fputs(fh, strcat("\"origin\" \"", strcat(ftos(view_origin.x), " ", ftos(view_origin.y), " ", ftos(view_origin.z)), "\"\n"));
+                               fputs(fh, strcat("\"angles\" \"", strcat(ftos(view_angles.x), " ", ftos(view_angles.y), " ", ftos(view_angles.z)), "\"\n"));
+                               fputs(fh, "}\n");
+
+                               LOG_INFO("Completed screenshot entity dump in ^2data/data/", path, MapInfo_Map_bspname, "_scrshot_ent.txt^7.");
+
+                               fclose(fh);
+                       }
+                       else
+                       {
+                               LOG_INFO("^1Error: ^7Could not dump to file!");
+                       }
+                       return;
+               }
+
+               default:
+               case CMD_REQUEST_USAGE:
+               {
+                       LOG_HELP("Usage:^3 cl_cmd create_scrshot_ent [path]");
+                       LOG_HELP("  Where 'path' can be the subdirectory of data/data in which the file is saved.");
+                       return;
+               }
+       }
+}
+
+void LocalCommand_debugmodel(int request, int argc)
+{
+       TC(int, request); TC(int, argc);
+       switch (request)
+       {
+               case CMD_REQUEST_COMMAND:
+               {
+                       string modelname = argv(1);
+
+                       entity debugmodel_entity = new(debugmodel);
+                       precache_model(modelname);
+                       _setmodel(debugmodel_entity, modelname);
+                       setorigin(debugmodel_entity, view_origin);
+                       debugmodel_entity.angles = view_angles;
+                       debugmodel_entity.draw = DrawDebugModel;
+                       IL_PUSH(g_drawables, debugmodel_entity);
+
+                       return;
+               }
+
+               default:
+               case CMD_REQUEST_USAGE:
+               {
+                       LOG_HELP("Usage:^3 cl_cmd debugmodel model");
+                       LOG_HELP("  Where 'model' is a string of the model name to use for the debug model.");
+                       return;
+               }
+       }
+}
+
+void LocalCommand_handlevote(int request, int argc)
+{
+       TC(int, request); TC(int, argc);
+       switch (request)
+       {
+               case CMD_REQUEST_COMMAND:
+               {
+                       int vote_selection;
+                       string vote_string;
+
+                       if (InterpretBoolean(argv(1)))
+                       {
+                               vote_selection = 2;
+                               vote_string = "yes";
+                       }
+                       else
+                       {
+                               vote_selection = 1;
+                               vote_string = "no";
+                       }
+
+                       if (vote_selection)
+                       {
+                               if (uid2name_dialog)  // handled by "uid2name" option
+                               {
+                                       vote_active = 0;
+                                       vote_prev = 0;
+                                       vote_change = -9999;
+                                       localcmd(strcat("setreport cl_allow_uid2name ", ftos(vote_selection - 1), "\n"));
+                                       uid2name_dialog = 0;
+                               }
+                               else { localcmd(strcat("cmd vote ", vote_string, "\n")); }
+
+                               return;
+                       }
+               }
+
+               default:
+                       LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
+               case CMD_REQUEST_USAGE:
+               {
+                       LOG_HELP("Usage:^3 cl_cmd handlevote vote");
+                       LOG_HELP("  Where 'vote' is the selection for either the current poll or uid2name.");
+                       return;
+               }
+       }
+}
+
+void LocalCommand_hud(int request, int argc)
+{
+       TC(int, request); TC(int, argc);
+       switch (request)
+       {
+               case CMD_REQUEST_COMMAND:
+               {
+                       if(MUTATOR_CALLHOOK(HUD_Command, argc))
+                               return;
+
+                       switch (argv(1))
+                       {
+                               case "configure":
+                               {
+                                       cvar_set("_hud_configure", ftos(!autocvar__hud_configure));
+                                       return;
+                               }
+
+                               case "quickmenu":
+                               {
+                                       if (argv(2) == "help")
+                                       {
+                                               LOG_HELP(" quickmenu [[default | file | \"\"] submenu file]");
+                                               LOG_HELP("Called without options (or with \"\") loads either the default quickmenu or a quickmenu file if hud_panel_quickmenu_file is set to a valid filename.");
+                                               LOG_HELP("A submenu name can be given to open the quickmenu directly in a submenu; it requires to specify 'default', 'file' or '\"\"' option.");
+                                               LOG_HELP("A file name can also be given to open a different quickmenu");
+                                               return;
+                                       }
+                                       string file = ((argv(4) == "") ? autocvar_hud_panel_quickmenu_file : argv(4));
+                                       if (QuickMenu_IsOpened())
+                                               QuickMenu_Close();
+                                       else
+                                               QuickMenu_Open(argv(2), argv(3), file);  // mode, submenu
+                                       return;
+                               }
+
+                               case "save":
+                               {
+                                       if (argv(2))
+                                       {
+                                               HUD_Panel_ExportCfg(argv(2));
+                                               return;
+                                       }
+                                       else
+                                       {
+                                               break;  // go to usage, we're missing the paramater needed here.
+                                       }
+                               }
+
+                               case "scoreboard_columns_set":
+                               {
+                                       Cmd_Scoreboard_SetFields(argc);
+                                       return;
+                               }
+
+                               case "scoreboard_columns_help":
+                               {
+                                       Cmd_Scoreboard_Help();
+                                       return;
+                               }
+
+                               case "radar":
+                               {
+                                       if (argv(2))
+                                               HUD_Radar_Show_Maximized(InterpretBoolean(argv(2)), 0);
+                                       else
+                                               HUD_Radar_Show_Maximized(!hud_panel_radar_maximized, 0);
+                                       return;
+                               }
+
+                               case "clickradar":
+                               {
+                                       if(!isdemo())
+                                               HUD_Radar_Show_Maximized(!hud_panel_radar_mouse, 1);
+                                       return;
+                               }
+                       }
+               }
+
+               default:
+                       LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
+               case CMD_REQUEST_USAGE:
+               {
+                       LOG_HELP("Usage:^3 cl_cmd hud action [configname | radartoggle | layout]");
+                       LOG_HELP("  Where 'action' is the command to complete,");
+                       LOG_HELP("  'configname' is the name to save to for \"save\" action,");
+                       LOG_HELP("  'radartoggle' is to control hud_panel_radar_maximized for \"radar\" action,");
+                       LOG_HELP("  and 'layout' is how to organize the scoreboard columns for the set action.");
+                       LOG_HELP("  Full list of commands here: \"configure, quickmenu, minigame, save, scoreboard_columns_help, scoreboard_columns_set, radar.\"");
+                       return;
+               }
+       }
+}
+
+void LocalCommand_localprint(int request, int argc)
+{
+       TC(int, request); TC(int, argc);
+       switch (request)
+       {
+               case CMD_REQUEST_COMMAND:
+               {
+                       if (argv(1))
+                       {
+                               centerprint_AddStandard(argv(1));
+                               return;
+                       }
+               }
+
+               default:
+                       LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
+               case CMD_REQUEST_USAGE:
+               {
+                       LOG_HELP("Usage:^3 cl_cmd localprint \"message\"");
+                       LOG_HELP("  'message' is the centerprint message to send to yourself.");
+                       return;
+               }
+       }
+}
+
+void LocalCommand_mv_download(int request, int argc)
+{
+       TC(int, request); TC(int, argc);
+       switch (request)
+       {
+               case CMD_REQUEST_COMMAND:
+               {
+                       if (argv(1))
+                       {
+                               Cmd_MapVote_MapDownload(argc);
+                               return;
+                       }
+               }
+
+               default:
+                       LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
+               case CMD_REQUEST_USAGE:
+               {
+                       LOG_HELP("Usage:^3 cl_cmd mv_download mapid");
+                       LOG_HELP("  Where 'mapid' is the id number of the map to request an image of on the map vote selection menu.");
+                       return;
+               }
+       }
+}
+
+void LocalCommand_sendcvar(int request, int argc)
+{
+       TC(int, request); TC(int, argc);
+       switch (request)
+       {
+               case CMD_REQUEST_COMMAND:
+               {
+                       if (argv(1))
+                       {
+                               // W_FixWeaponOrder will trash argv, so save what we need.
+                               string thiscvar = string_null; strcpy(thiscvar, argv(1));
+                               string s = cvar_string(thiscvar);
+
+                               if (thiscvar == "cl_weaponpriority")
+                                       s = W_FixWeaponOrder(W_NumberWeaponOrder(s), 1);
+                               else if (substring(thiscvar, 0, 17) == "cl_weaponpriority" && strlen(thiscvar) == 18)
+                                       s = W_FixWeaponOrder(W_NumberWeaponOrder(s), 0);
+
+                               localcmd("cmd sentcvar ", thiscvar, " \"", s, "\"\n");
+                               strfree(thiscvar);
+                               return;
+                       }
+               }
+
+               default:
+                       LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
+               case CMD_REQUEST_USAGE:
+               {
+                       LOG_HELP("Usage:^3 cl_cmd sendcvar <cvar>");
+                       LOG_HELP("  Where 'cvar' is the cvar to send to the server.");
+                       return;
+               }
+       }
+}
+
+/* use this when creating a new command, making sure to place it in alphabetical order... also,
+** ADD ALL NEW COMMANDS TO commands.cfg WITH PROPER ALIASES IN THE SAME FASHION!
+void LocalCommand_(int request)
+{
+    switch(request)
+    {
+        case CMD_REQUEST_COMMAND:
+        {
+
+            return;
+        }
+
+        default:
+        case CMD_REQUEST_USAGE:
+        {
+            LOG_HELP("Usage:^3 cl_cmd ");
+            LOG_HELP("  No arguments required.");
+            return;
+        }
+    }
+}
+*/
+
+
+// ==================================
+//  Macro system for client commands
+// ==================================
+
+// Normally do not hard code aliases for these, instead create them in commands.cfg... also: keep in alphabetical order, please ;)
+CLIENT_COMMAND(blurtest, "Feature for testing blur postprocessing") { LocalCommand_blurtest(request); }
+CLIENT_COMMAND(boxparticles, "Spawn particles manually") { LocalCommand_boxparticles(request, arguments); }
+CLIENT_COMMAND(create_scrshot_ent, "Create an entity at this location for automatic screenshots") { LocalCommand_create_scrshot_ent(request); }
+CLIENT_COMMAND(debugmodel, "Spawn a debug model manually") { LocalCommand_debugmodel(request, arguments); }
+CLIENT_COMMAND(handlevote, "System to handle selecting a vote or option") { LocalCommand_handlevote(request, arguments); }
+CLIENT_COMMAND(hud, "Commands regarding/controlling the HUD system") { LocalCommand_hud(request, arguments); }
+CLIENT_COMMAND(localprint, "Create your own centerprint sent to yourself") { LocalCommand_localprint(request, arguments); }
+CLIENT_COMMAND(mv_download, "Retrieve mapshot picture from the server") { LocalCommand_mv_download(request, arguments); }
+CLIENT_COMMAND(sendcvar, "Send a cvar to the server (like cl_weaponpriority)") { LocalCommand_sendcvar(request, arguments); }
+
+void LocalCommand_macro_help()
+{
+       FOREACH(CLIENT_COMMANDS, true, LOG_HELPF("  ^2%s^7: %s", it.m_name, it.m_description));
+}
+
+bool LocalCommand_macro_command(int argc, string command)
+{
+       string c = strtolower(argv(0));
+       FOREACH(CLIENT_COMMANDS, it.m_name == c, {
+               it.m_invokecmd(it, CMD_REQUEST_COMMAND, NULL, argc, command);
+               return true;
+       });
+       return false;
+}
+
+bool LocalCommand_macro_usage(int argc)
+{
+       string c = strtolower(argv(1));
+       FOREACH(CLIENT_COMMANDS, it.m_name == c, {
+               it.m_invokecmd(it, CMD_REQUEST_USAGE, NULL, argc, "");
+               return true;
+       });
+       return false;
+}
+
+void LocalCommand_macro_write_aliases(int fh)
+{
+       FOREACH(CLIENT_COMMANDS, true, CMD_Write_Alias("qc_cmd_cl", it.m_name, it.m_description));
+}
+
+
+// =========================================
+//  Main Function Called By Engine (cl_cmd)
+// =========================================
+// If this function exists, client code handles gamecommand instead of the engine code.
+
+void GameCommand(string command)
+{
+       int argc = tokenize_console(command);
+
+       // Guide for working with argc arguments by example:
+       // argc:   1    - 2      - 3     - 4
+       // argv:   0    - 1      - 2     - 3
+       // cmd     vote - master - login - password
+       string s = strtolower(argv(0));
+       if (s == "help")
+       {
+               if (argc == 1)
+               {
+                       LOG_HELP("Client console commands:");
+                       LocalCommand_macro_help();
+
+                       LOG_HELP("\nGeneric commands shared by all programs:");
+                       GenericCommand_macro_help();
+
+                       LOG_HELP("\nUsage:^3 cl_cmd COMMAND...^7, where possible commands are listed above.");
+                       LOG_HELP("For help about a specific command, type cl_cmd help COMMAND");
+
+                       return;
+               }
+               else if (GenericCommand_macro_usage(argc))  // Instead of trying to call a command, we're going to see detailed information about it
+               {
+                       return;
+               }
+               else if (LocalCommand_macro_usage(argc))  // now try for normal commands too
+               {
+                       return;
+               }
+       }
+       // continue as usual and scan for normal commands
+       if (GenericCommand(command)                                    // handled by common/command/generic.qc
+           || LocalCommand_macro_command(argc, command)               // handled by one of the above LocalCommand_* functions
+           || MUTATOR_CALLHOOK(CSQC_ConsoleCommand, s, argc, command) // handled by a mutator
+          ) return;
+
+       // nothing above caught the command, must be invalid
+       LOG_INFO(((command != "") ? strcat("Unknown client command \"", command, "\"") : "No command provided"), ". For a list of supported commands, try cl_cmd help.");
+}
+
+
+// ===================================
+//  Macro system for console commands
+// ===================================
+
+// These functions are here specifically to add special + - commands to the game, and are not really normal commands.
+// Please add client commands to the function above this, as this is only for special reasons.
+// NOTE: showaccuracy is kept as legacy command
+#define CONSOLE_COMMANDS_NORMAL() \
+       CONSOLE_COMMAND("+showscores", { scoreboard_showscores = true; }) \
+       CONSOLE_COMMAND("-showscores", { scoreboard_showscores = false; }) \
+       CONSOLE_COMMAND("+showaccuracy", { }) \
+       CONSOLE_COMMAND("-showaccuracy", { }) \
+       /* nothing */
+
+#define CONSOLE_COMMANDS_MOVEMENT() \
+       CONSOLE_COMMAND("+forward", { ++camera_direction.x; }) \
+       CONSOLE_COMMAND("-forward", { --camera_direction.x; }) \
+       CONSOLE_COMMAND("+back", { --camera_direction.x; }) \
+       CONSOLE_COMMAND("-back", { ++camera_direction.x; }) \
+       CONSOLE_COMMAND("+moveup", { ++camera_direction.z; }) \
+       CONSOLE_COMMAND("-moveup", { --camera_direction.z; }) \
+       CONSOLE_COMMAND("+movedown", { --camera_direction.z; }) \
+       CONSOLE_COMMAND("-movedown", { ++camera_direction.z; }) \
+       CONSOLE_COMMAND("+moveright", { --camera_direction.y; }) \
+       CONSOLE_COMMAND("-moveright", { ++camera_direction.y; }) \
+       CONSOLE_COMMAND("+moveleft", { ++camera_direction.y; }) \
+       CONSOLE_COMMAND("-moveleft", { --camera_direction.y; }) \
+       CONSOLE_COMMAND("+roll_right", { ++camera_roll; }) \
+       CONSOLE_COMMAND("-roll_right", { --camera_roll; }) \
+       CONSOLE_COMMAND("+roll_left", { --camera_roll; }) \
+       CONSOLE_COMMAND("-roll_left", { ++camera_roll; }) \
+       /* nothing */
+
+void ConsoleCommand_macro_init()
+{
+       // first init normal commands
+       #define CONSOLE_COMMAND(name, execution) \
+               { registercommand(name); }
+
+       CONSOLE_COMMANDS_NORMAL();
+       #undef CONSOLE_COMMAND
+
+       // then init movement commands
+       #ifndef CAMERATEST
+       if (isdemo())
+       {
+       #endif
+       #define CONSOLE_COMMAND(name, execution) \
+               registercommand(name);
+
+       CONSOLE_COMMANDS_MOVEMENT();
+               #undef CONSOLE_COMMAND
+       #ifndef CAMERATEST
+}
+       #endif
+}
+
+bool ConsoleCommand_macro_normal(string s, int argc)
+{
+       #define CONSOLE_COMMAND(name, execution) \
+               { if (name == s) { { execution } return true; } }
+
+       CONSOLE_COMMANDS_NORMAL();
+       #undef CONSOLE_COMMAND
+
+       return false;
+}
+
+bool ConsoleCommand_macro_movement(string s, int argc)
+{
+       if (camera_active)
+       {
+               #define CONSOLE_COMMAND(name, execution) \
+                       { if (name == s) { { execution } return true; } }
+
+               CONSOLE_COMMANDS_MOVEMENT();
+               #undef CONSOLE_COMMAND
+       }
+
+       return false;
+}
+
+
+// ======================================================
+//  Main Function Called By Engine (registered commands)
+// ======================================================
+// Used to parse commands in the console that have been registered with the "registercommand" function
+
+bool CSQC_ConsoleCommand(string command)
+{
+       int argc = tokenize_console(command);
+       string s = strtolower(argv(0));
+       // Return value should be true if CSQC handled the command, otherwise return false to have the engine handle it.
+       return ConsoleCommand_macro_normal(s, argc)
+              || ConsoleCommand_macro_movement(s, argc)
+       ;
+}
diff --git a/qcsrc/client/command/cl_cmd.qh b/qcsrc/client/command/cl_cmd.qh
new file mode 100644 (file)
index 0000000..725baa4
--- /dev/null
@@ -0,0 +1,26 @@
+#pragma once
+
+void Cmd_Scoreboard_SetFields(int);
+void Cmd_Scoreboard_Help();
+void ConsoleCommand_macro_init();
+
+// used by common/command/generic.qc:GenericCommand_dumpcommands to list all commands into a .txt file
+void LocalCommand_macro_write_aliases(int fh);
+
+REGISTRY(CLIENT_COMMANDS, BITS(7))
+REGISTER_REGISTRY(CLIENT_COMMANDS)
+REGISTRY_SORT(CLIENT_COMMANDS)
+
+REGISTRY_DEFINE_GET(CLIENT_COMMANDS, NULL)
+
+#define CLIENT_COMMAND(id, description) \
+       CLASS(clientcommand_##id, Command) \
+               ATTRIB(clientcommand_##id, m_name, string, #id); \
+       ATTRIB(clientcommand_##id, m_description, string, description); \
+       ENDCLASS(clientcommand_##id) \
+    REGISTER(CLIENT_COMMANDS, CMD_CL, id, m_id, NEW(clientcommand_##id)); \
+       METHOD(clientcommand_##id, m_invokecmd, void(clientcommand_##id this, int request, entity caller, int arguments, string command))
+
+STATIC_INIT(CLIENT_COMMANDS_aliases) {
+       FOREACH(CLIENT_COMMANDS, true, localcmd(sprintf("alias %1$s \"%2$s %1$s ${* ?}\"\n", it.m_name, "qc_cmd_cl")));
+}
diff --git a/qcsrc/client/commands/_mod.inc b/qcsrc/client/commands/_mod.inc
deleted file mode 100644 (file)
index dcfc6ec..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-// generated file; do not modify
-#ifdef CSQC
-    #include <client/commands/cl_cmd.qc>
-#endif
diff --git a/qcsrc/client/commands/_mod.qh b/qcsrc/client/commands/_mod.qh
deleted file mode 100644 (file)
index 7829965..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-// generated file; do not modify
-#ifdef CSQC
-    #include <client/commands/cl_cmd.qh>
-#endif
diff --git a/qcsrc/client/commands/cl_cmd.qc b/qcsrc/client/commands/cl_cmd.qc
deleted file mode 100644 (file)
index 7735815..0000000
+++ /dev/null
@@ -1,646 +0,0 @@
-#include "cl_cmd.qh"
-// ==============================================
-//  CSQC client commands code, written by Samual
-//  Last updated: December 28th, 2011
-// ==============================================
-
-#include <common/command/_mod.qh>
-#include "cl_cmd.qh"
-
-#include "../autocvars.qh"
-#include "../defs.qh"
-#include <client/hud/_mod.qh>
-#include <client/hud/panel/quickmenu.qh>
-#include <client/hud/panel/radar.qh>
-#include "../main.qh"
-#include "../mapvoting.qh"
-#include "../miscfunctions.qh"
-
-#include <client/mutators/_mod.qh>
-
-#include <common/minigames/cl_minigames_hud.qh>
-
-#include <common/mapinfo.qh>
-
-void DrawDebugModel(entity this)
-{
-       if (time - floor(time) > 0.5)
-       {
-               PolyDrawModel(this);
-               this.drawmask = 0;
-       }
-       else
-       {
-               this.renderflags = 0;
-               this.drawmask = MASK_NORMAL;
-       }
-}
-
-
-// =======================
-//  Command Sub-Functions
-// =======================
-
-void LocalCommand_blurtest(int request)
-{
-       TC(int, request);
-       // Simple command to work with postprocessing temporarily... possibly completely pointless, the glsl shader is used for a real feature now...
-       // Anyway, to enable it, just compile the client with -DBLURTEST and then you can use the command.
-
-       #ifdef BLURTEST
-       switch (request)
-       {
-               case CMD_REQUEST_COMMAND:
-               {
-                       blurtest_time0 = time;
-                       blurtest_time1 = time + stof(argv(1));
-                       blurtest_radius = stof(argv(2));
-                       blurtest_power = stof(argv(3));
-                       LOG_INFO("Enabled blurtest");
-                       return;
-               }
-
-               default:
-               case CMD_REQUEST_USAGE:
-               {
-                       LOG_HELP("Usage:^3 cl_cmd blurtest");
-                       LOG_HELP("  No arguments required.");
-                       return;
-               }
-       }
-       #else
-       if (request)
-       {
-               LOG_INFO("Blurtest is not enabled on this client.");
-               return;
-       }
-       #endif
-}
-
-void LocalCommand_boxparticles(int request, int argc)
-{
-       TC(int, request); TC(int, argc);
-       switch (request)
-       {
-               case CMD_REQUEST_COMMAND:
-               {
-                       if (argc == 9)
-                       {
-                               int effect = _particleeffectnum(argv(1));
-                               if (effect >= 0)
-                               {
-                                       int index = stoi(argv(2));
-                                       entity own;
-                                       if (index <= 0)
-                                               own = entitybyindex(-index);
-                                       else
-                                               own = findfloat(NULL, entnum, index);
-                                       vector org_from = stov(argv(3));
-                                       vector org_to = stov(argv(4));
-                                       vector dir_from = stov(argv(5));
-                                       vector dir_to = stov(argv(6));
-                                       int countmultiplier = stoi(argv(7));
-                                       int flags = stoi(argv(8));
-                                       boxparticles(effect, own, org_from, org_to, dir_from, dir_to, countmultiplier, flags);
-                                       return;
-                               }
-                       }
-               }
-
-               default:
-                       LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
-               case CMD_REQUEST_USAGE:
-               {
-                       LOG_HELP(
-                               "Usage:^3 cl_cmd boxparticles effectname own org_from org_to, dir_from, dir_to, countmultiplier, flags\n"
-                               "  'effectname' is the name of a particle effect in effectinfo.txt\n"
-                               "  'own' is the entity number of the owner (negative for csqc ent, positive for svqc ent)\n"
-                               "  'org_from' is the starting origin of the box\n"
-                               "  'org_to' is the ending origin of the box\n"
-                               "  'dir_from' is the minimum velocity\n"
-                               "  'dir_to' is the maximum velocity\n"
-                               "  'countmultiplier' defines a multiplier for the particle count (affects count only, not countabsolute or trailspacing)\n"
-                               "  'flags' can contain:\n"
-                               "    1 to respect globals particles_alphamin, particles_alphamax (set right before via prvm_globalset client)\n"
-                               "    2 to respect globals particles_colormin, particles_colormax (set right before via prvm_globalset client)\n"
-                               "    4 to respect globals particles_fade (set right before via prvm_globalset client)\n"
-                               "    128 to draw a trail, not a box"
-                       );
-                       return;
-               }
-       }
-}
-
-void LocalCommand_create_scrshot_ent(int request)
-{
-       TC(int, request);
-       switch (request)
-       {
-               case CMD_REQUEST_COMMAND:
-               {
-                       string path = ((argv(1) == "") ? "" : strcat(argv(1), "/"));
-                       string filename = strcat(path, MapInfo_Map_bspname, "_scrshot_ent.txt");
-                       int fh = fopen(filename, FILE_APPEND);
-
-                       if (fh >= 0)
-                       {
-                               fputs(fh, "{\n");
-                               fputs(fh, strcat("\"classname\" \"info_autoscreenshot\"\n"));
-                               fputs(fh, strcat("\"origin\" \"", strcat(ftos(view_origin.x), " ", ftos(view_origin.y), " ", ftos(view_origin.z)), "\"\n"));
-                               fputs(fh, strcat("\"angles\" \"", strcat(ftos(view_angles.x), " ", ftos(view_angles.y), " ", ftos(view_angles.z)), "\"\n"));
-                               fputs(fh, "}\n");
-
-                               LOG_INFO("Completed screenshot entity dump in ^2data/data/", path, MapInfo_Map_bspname, "_scrshot_ent.txt^7.");
-
-                               fclose(fh);
-                       }
-                       else
-                       {
-                               LOG_INFO("^1Error: ^7Could not dump to file!");
-                       }
-                       return;
-               }
-
-               default:
-               case CMD_REQUEST_USAGE:
-               {
-                       LOG_HELP("Usage:^3 cl_cmd create_scrshot_ent [path]");
-                       LOG_HELP("  Where 'path' can be the subdirectory of data/data in which the file is saved.");
-                       return;
-               }
-       }
-}
-
-void LocalCommand_debugmodel(int request, int argc)
-{
-       TC(int, request); TC(int, argc);
-       switch (request)
-       {
-               case CMD_REQUEST_COMMAND:
-               {
-                       string modelname = argv(1);
-
-                       entity debugmodel_entity = new(debugmodel);
-                       precache_model(modelname);
-                       _setmodel(debugmodel_entity, modelname);
-                       setorigin(debugmodel_entity, view_origin);
-                       debugmodel_entity.angles = view_angles;
-                       debugmodel_entity.draw = DrawDebugModel;
-                       IL_PUSH(g_drawables, debugmodel_entity);
-
-                       return;
-               }
-
-               default:
-               case CMD_REQUEST_USAGE:
-               {
-                       LOG_HELP("Usage:^3 cl_cmd debugmodel model");
-                       LOG_HELP("  Where 'model' is a string of the model name to use for the debug model.");
-                       return;
-               }
-       }
-}
-
-void LocalCommand_handlevote(int request, int argc)
-{
-       TC(int, request); TC(int, argc);
-       switch (request)
-       {
-               case CMD_REQUEST_COMMAND:
-               {
-                       int vote_selection;
-                       string vote_string;
-
-                       if (InterpretBoolean(argv(1)))
-                       {
-                               vote_selection = 2;
-                               vote_string = "yes";
-                       }
-                       else
-                       {
-                               vote_selection = 1;
-                               vote_string = "no";
-                       }
-
-                       if (vote_selection)
-                       {
-                               if (uid2name_dialog)  // handled by "uid2name" option
-                               {
-                                       vote_active = 0;
-                                       vote_prev = 0;
-                                       vote_change = -9999;
-                                       localcmd(strcat("setreport cl_allow_uid2name ", ftos(vote_selection - 1), "\n"));
-                                       uid2name_dialog = 0;
-                               }
-                               else { localcmd(strcat("cmd vote ", vote_string, "\n")); }
-
-                               return;
-                       }
-               }
-
-               default:
-                       LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
-               case CMD_REQUEST_USAGE:
-               {
-                       LOG_HELP("Usage:^3 cl_cmd handlevote vote");
-                       LOG_HELP("  Where 'vote' is the selection for either the current poll or uid2name.");
-                       return;
-               }
-       }
-}
-
-void LocalCommand_hud(int request, int argc)
-{
-       TC(int, request); TC(int, argc);
-       switch (request)
-       {
-               case CMD_REQUEST_COMMAND:
-               {
-                       if(MUTATOR_CALLHOOK(HUD_Command, argc))
-                               return;
-
-                       switch (argv(1))
-                       {
-                               case "configure":
-                               {
-                                       cvar_set("_hud_configure", ftos(!autocvar__hud_configure));
-                                       return;
-                               }
-
-                               case "quickmenu":
-                               {
-                                       if (argv(2) == "help")
-                                       {
-                                               LOG_HELP(" quickmenu [[default | file | \"\"] submenu file]");
-                                               LOG_HELP("Called without options (or with \"\") loads either the default quickmenu or a quickmenu file if hud_panel_quickmenu_file is set to a valid filename.");
-                                               LOG_HELP("A submenu name can be given to open the quickmenu directly in a submenu; it requires to specify 'default', 'file' or '\"\"' option.");
-                                               LOG_HELP("A file name can also be given to open a different quickmenu");
-                                               return;
-                                       }
-                                       string file = ((argv(4) == "") ? autocvar_hud_panel_quickmenu_file : argv(4));
-                                       if (QuickMenu_IsOpened())
-                                               QuickMenu_Close();
-                                       else
-                                               QuickMenu_Open(argv(2), argv(3), file);  // mode, submenu
-                                       return;
-                               }
-
-                               case "save":
-                               {
-                                       if (argv(2))
-                                       {
-                                               HUD_Panel_ExportCfg(argv(2));
-                                               return;
-                                       }
-                                       else
-                                       {
-                                               break;  // go to usage, we're missing the paramater needed here.
-                                       }
-                               }
-
-                               case "scoreboard_columns_set":
-                               {
-                                       Cmd_Scoreboard_SetFields(argc);
-                                       return;
-                               }
-
-                               case "scoreboard_columns_help":
-                               {
-                                       Cmd_Scoreboard_Help();
-                                       return;
-                               }
-
-                               case "radar":
-                               {
-                                       if (argv(2))
-                                               HUD_Radar_Show_Maximized(InterpretBoolean(argv(2)), 0);
-                                       else
-                                               HUD_Radar_Show_Maximized(!hud_panel_radar_maximized, 0);
-                                       return;
-                               }
-
-                               case "clickradar":
-                               {
-                                       if(!isdemo())
-                                               HUD_Radar_Show_Maximized(!hud_panel_radar_mouse, 1);
-                                       return;
-                               }
-                       }
-               }
-
-               default:
-                       LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
-               case CMD_REQUEST_USAGE:
-               {
-                       LOG_HELP("Usage:^3 cl_cmd hud action [configname | radartoggle | layout]");
-                       LOG_HELP("  Where 'action' is the command to complete,");
-                       LOG_HELP("  'configname' is the name to save to for \"save\" action,");
-                       LOG_HELP("  'radartoggle' is to control hud_panel_radar_maximized for \"radar\" action,");
-                       LOG_HELP("  and 'layout' is how to organize the scoreboard columns for the set action.");
-                       LOG_HELP("  Full list of commands here: \"configure, quickmenu, minigame, save, scoreboard_columns_help, scoreboard_columns_set, radar.\"");
-                       return;
-               }
-       }
-}
-
-void LocalCommand_localprint(int request, int argc)
-{
-       TC(int, request); TC(int, argc);
-       switch (request)
-       {
-               case CMD_REQUEST_COMMAND:
-               {
-                       if (argv(1))
-                       {
-                               centerprint_AddStandard(argv(1));
-                               return;
-                       }
-               }
-
-               default:
-                       LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
-               case CMD_REQUEST_USAGE:
-               {
-                       LOG_HELP("Usage:^3 cl_cmd localprint \"message\"");
-                       LOG_HELP("  'message' is the centerprint message to send to yourself.");
-                       return;
-               }
-       }
-}
-
-void LocalCommand_mv_download(int request, int argc)
-{
-       TC(int, request); TC(int, argc);
-       switch (request)
-       {
-               case CMD_REQUEST_COMMAND:
-               {
-                       if (argv(1))
-                       {
-                               Cmd_MapVote_MapDownload(argc);
-                               return;
-                       }
-               }
-
-               default:
-                       LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
-               case CMD_REQUEST_USAGE:
-               {
-                       LOG_HELP("Usage:^3 cl_cmd mv_download mapid");
-                       LOG_HELP("  Where 'mapid' is the id number of the map to request an image of on the map vote selection menu.");
-                       return;
-               }
-       }
-}
-
-void LocalCommand_sendcvar(int request, int argc)
-{
-       TC(int, request); TC(int, argc);
-       switch (request)
-       {
-               case CMD_REQUEST_COMMAND:
-               {
-                       if (argv(1))
-                       {
-                               // W_FixWeaponOrder will trash argv, so save what we need.
-                               string thiscvar = string_null; strcpy(thiscvar, argv(1));
-                               string s = cvar_string(thiscvar);
-
-                               if (thiscvar == "cl_weaponpriority")
-                                       s = W_FixWeaponOrder(W_NumberWeaponOrder(s), 1);
-                               else if (substring(thiscvar, 0, 17) == "cl_weaponpriority" && strlen(thiscvar) == 18)
-                                       s = W_FixWeaponOrder(W_NumberWeaponOrder(s), 0);
-
-                               localcmd("cmd sentcvar ", thiscvar, " \"", s, "\"\n");
-                               strfree(thiscvar);
-                               return;
-                       }
-               }
-
-               default:
-                       LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
-               case CMD_REQUEST_USAGE:
-               {
-                       LOG_HELP("Usage:^3 cl_cmd sendcvar <cvar>");
-                       LOG_HELP("  Where 'cvar' is the cvar to send to the server.");
-                       return;
-               }
-       }
-}
-
-/* use this when creating a new command, making sure to place it in alphabetical order... also,
-** ADD ALL NEW COMMANDS TO commands.cfg WITH PROPER ALIASES IN THE SAME FASHION!
-void LocalCommand_(int request)
-{
-    switch(request)
-    {
-        case CMD_REQUEST_COMMAND:
-        {
-
-            return;
-        }
-
-        default:
-        case CMD_REQUEST_USAGE:
-        {
-            LOG_HELP("Usage:^3 cl_cmd ");
-            LOG_HELP("  No arguments required.");
-            return;
-        }
-    }
-}
-*/
-
-
-// ==================================
-//  Macro system for client commands
-// ==================================
-
-// Normally do not hard code aliases for these, instead create them in commands.cfg... also: keep in alphabetical order, please ;)
-CLIENT_COMMAND(blurtest, "Feature for testing blur postprocessing") { LocalCommand_blurtest(request); }
-CLIENT_COMMAND(boxparticles, "Spawn particles manually") { LocalCommand_boxparticles(request, arguments); }
-CLIENT_COMMAND(create_scrshot_ent, "Create an entity at this location for automatic screenshots") { LocalCommand_create_scrshot_ent(request); }
-CLIENT_COMMAND(debugmodel, "Spawn a debug model manually") { LocalCommand_debugmodel(request, arguments); }
-CLIENT_COMMAND(handlevote, "System to handle selecting a vote or option") { LocalCommand_handlevote(request, arguments); }
-CLIENT_COMMAND(hud, "Commands regarding/controlling the HUD system") { LocalCommand_hud(request, arguments); }
-CLIENT_COMMAND(localprint, "Create your own centerprint sent to yourself") { LocalCommand_localprint(request, arguments); }
-CLIENT_COMMAND(mv_download, "Retrieve mapshot picture from the server") { LocalCommand_mv_download(request, arguments); }
-CLIENT_COMMAND(sendcvar, "Send a cvar to the server (like cl_weaponpriority)") { LocalCommand_sendcvar(request, arguments); }
-
-void LocalCommand_macro_help()
-{
-       FOREACH(CLIENT_COMMANDS, true, LOG_HELPF("  ^2%s^7: %s", it.m_name, it.m_description));
-}
-
-bool LocalCommand_macro_command(int argc, string command)
-{
-       string c = strtolower(argv(0));
-       FOREACH(CLIENT_COMMANDS, it.m_name == c, {
-               it.m_invokecmd(it, CMD_REQUEST_COMMAND, NULL, argc, command);
-               return true;
-       });
-       return false;
-}
-
-bool LocalCommand_macro_usage(int argc)
-{
-       string c = strtolower(argv(1));
-       FOREACH(CLIENT_COMMANDS, it.m_name == c, {
-               it.m_invokecmd(it, CMD_REQUEST_USAGE, NULL, argc, "");
-               return true;
-       });
-       return false;
-}
-
-void LocalCommand_macro_write_aliases(int fh)
-{
-       FOREACH(CLIENT_COMMANDS, true, CMD_Write_Alias("qc_cmd_cl", it.m_name, it.m_description));
-}
-
-
-// =========================================
-//  Main Function Called By Engine (cl_cmd)
-// =========================================
-// If this function exists, client code handles gamecommand instead of the engine code.
-
-void GameCommand(string command)
-{
-       int argc = tokenize_console(command);
-
-       // Guide for working with argc arguments by example:
-       // argc:   1    - 2      - 3     - 4
-       // argv:   0    - 1      - 2     - 3
-       // cmd     vote - master - login - password
-       string s = strtolower(argv(0));
-       if (s == "help")
-       {
-               if (argc == 1)
-               {
-                       LOG_HELP("Client console commands:");
-                       LocalCommand_macro_help();
-
-                       LOG_HELP("\nGeneric commands shared by all programs:");
-                       GenericCommand_macro_help();
-
-                       LOG_HELP("\nUsage:^3 cl_cmd COMMAND...^7, where possible commands are listed above.");
-                       LOG_HELP("For help about a specific command, type cl_cmd help COMMAND");
-
-                       return;
-               }
-               else if (GenericCommand_macro_usage(argc))  // Instead of trying to call a command, we're going to see detailed information about it
-               {
-                       return;
-               }
-               else if (LocalCommand_macro_usage(argc))  // now try for normal commands too
-               {
-                       return;
-               }
-       }
-       // continue as usual and scan for normal commands
-       if (GenericCommand(command)                                    // handled by common/command/generic.qc
-           || LocalCommand_macro_command(argc, command)               // handled by one of the above LocalCommand_* functions
-           || MUTATOR_CALLHOOK(CSQC_ConsoleCommand, s, argc, command) // handled by a mutator
-          ) return;
-
-       // nothing above caught the command, must be invalid
-       LOG_INFO(((command != "") ? strcat("Unknown client command \"", command, "\"") : "No command provided"), ". For a list of supported commands, try cl_cmd help.");
-}
-
-
-// ===================================
-//  Macro system for console commands
-// ===================================
-
-// These functions are here specifically to add special + - commands to the game, and are not really normal commands.
-// Please add client commands to the function above this, as this is only for special reasons.
-// NOTE: showaccuracy is kept as legacy command
-#define CONSOLE_COMMANDS_NORMAL() \
-       CONSOLE_COMMAND("+showscores", { scoreboard_showscores = true; }) \
-       CONSOLE_COMMAND("-showscores", { scoreboard_showscores = false; }) \
-       CONSOLE_COMMAND("+showaccuracy", { }) \
-       CONSOLE_COMMAND("-showaccuracy", { }) \
-       /* nothing */
-
-#define CONSOLE_COMMANDS_MOVEMENT() \
-       CONSOLE_COMMAND("+forward", { ++camera_direction.x; }) \
-       CONSOLE_COMMAND("-forward", { --camera_direction.x; }) \
-       CONSOLE_COMMAND("+back", { --camera_direction.x; }) \
-       CONSOLE_COMMAND("-back", { ++camera_direction.x; }) \
-       CONSOLE_COMMAND("+moveup", { ++camera_direction.z; }) \
-       CONSOLE_COMMAND("-moveup", { --camera_direction.z; }) \
-       CONSOLE_COMMAND("+movedown", { --camera_direction.z; }) \
-       CONSOLE_COMMAND("-movedown", { ++camera_direction.z; }) \
-       CONSOLE_COMMAND("+moveright", { --camera_direction.y; }) \
-       CONSOLE_COMMAND("-moveright", { ++camera_direction.y; }) \
-       CONSOLE_COMMAND("+moveleft", { ++camera_direction.y; }) \
-       CONSOLE_COMMAND("-moveleft", { --camera_direction.y; }) \
-       CONSOLE_COMMAND("+roll_right", { ++camera_roll; }) \
-       CONSOLE_COMMAND("-roll_right", { --camera_roll; }) \
-       CONSOLE_COMMAND("+roll_left", { --camera_roll; }) \
-       CONSOLE_COMMAND("-roll_left", { ++camera_roll; }) \
-       /* nothing */
-
-void ConsoleCommand_macro_init()
-{
-       // first init normal commands
-       #define CONSOLE_COMMAND(name, execution) \
-               { registercommand(name); }
-
-       CONSOLE_COMMANDS_NORMAL();
-       #undef CONSOLE_COMMAND
-
-       // then init movement commands
-       #ifndef CAMERATEST
-       if (isdemo())
-       {
-       #endif
-       #define CONSOLE_COMMAND(name, execution) \
-               registercommand(name);
-
-       CONSOLE_COMMANDS_MOVEMENT();
-               #undef CONSOLE_COMMAND
-       #ifndef CAMERATEST
-}
-       #endif
-}
-
-bool ConsoleCommand_macro_normal(string s, int argc)
-{
-       #define CONSOLE_COMMAND(name, execution) \
-               { if (name == s) { { execution } return true; } }
-
-       CONSOLE_COMMANDS_NORMAL();
-       #undef CONSOLE_COMMAND
-
-       return false;
-}
-
-bool ConsoleCommand_macro_movement(string s, int argc)
-{
-       if (camera_active)
-       {
-               #define CONSOLE_COMMAND(name, execution) \
-                       { if (name == s) { { execution } return true; } }
-
-               CONSOLE_COMMANDS_MOVEMENT();
-               #undef CONSOLE_COMMAND
-       }
-
-       return false;
-}
-
-
-// ======================================================
-//  Main Function Called By Engine (registered commands)
-// ======================================================
-// Used to parse commands in the console that have been registered with the "registercommand" function
-
-bool CSQC_ConsoleCommand(string command)
-{
-       int argc = tokenize_console(command);
-       string s = strtolower(argv(0));
-       // Return value should be true if CSQC handled the command, otherwise return false to have the engine handle it.
-       return ConsoleCommand_macro_normal(s, argc)
-              || ConsoleCommand_macro_movement(s, argc)
-       ;
-}
diff --git a/qcsrc/client/commands/cl_cmd.qh b/qcsrc/client/commands/cl_cmd.qh
deleted file mode 100644 (file)
index 725baa4..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#pragma once
-
-void Cmd_Scoreboard_SetFields(int);
-void Cmd_Scoreboard_Help();
-void ConsoleCommand_macro_init();
-
-// used by common/command/generic.qc:GenericCommand_dumpcommands to list all commands into a .txt file
-void LocalCommand_macro_write_aliases(int fh);
-
-REGISTRY(CLIENT_COMMANDS, BITS(7))
-REGISTER_REGISTRY(CLIENT_COMMANDS)
-REGISTRY_SORT(CLIENT_COMMANDS)
-
-REGISTRY_DEFINE_GET(CLIENT_COMMANDS, NULL)
-
-#define CLIENT_COMMAND(id, description) \
-       CLASS(clientcommand_##id, Command) \
-               ATTRIB(clientcommand_##id, m_name, string, #id); \
-       ATTRIB(clientcommand_##id, m_description, string, description); \
-       ENDCLASS(clientcommand_##id) \
-    REGISTER(CLIENT_COMMANDS, CMD_CL, id, m_id, NEW(clientcommand_##id)); \
-       METHOD(clientcommand_##id, m_invokecmd, void(clientcommand_##id this, int request, entity caller, int arguments, string command))
-
-STATIC_INIT(CLIENT_COMMANDS_aliases) {
-       FOREACH(CLIENT_COMMANDS, true, localcmd(sprintf("alias %1$s \"%2$s %1$s ${* ?}\"\n", it.m_name, "qc_cmd_cl")));
-}
index f08378b6a86b27546eed52fe92434375c9615b5b..82b045801429a2f750c2513db28fa0b148d552b8 100644 (file)
@@ -1,12 +1,17 @@
 #include "csqcmodel_hooks.qh"
 #include "autocvars.qh"
+#include "main.qh"
 #include "miscfunctions.qh"
 #include <client/mutators/_mod.qh>
+#include <client/main.qh>
 #include "player_skeleton.qh"
 #include "weapons/projectile.qh"
 #include <common/animdecide.qh>
 #include <common/ent_cs.qh>
+#include <common/gamemodes/_mod.qh>
+#include <common/mapinfo.qh>
 #include <common/physics/movetypes/movetypes.qh>
+#include <common/physics/player.qh>
 #include <common/viewloc.qh>
 #include <common/effects/all.qh>
 #include <common/effects/all.inc>
@@ -242,7 +247,8 @@ void CSQCPlayer_ModelAppearance_Apply(entity this, bool islocalplayer)
 
                if(autocvar_cl_forcemyplayercolors)
                        forcecolor_friend = 1024 + autocvar_cl_forcemyplayercolors;
-               if(autocvar_cl_forceplayercolors == 2 && team_count == 2)
+               if((autocvar_cl_forceplayercolors == 2 && team_count == 2)
+                       || (autocvar_cl_forceplayercolors == 3 && IS_GAMETYPE(DUEL)))
                        forcecolor_enemy = 1024 + autocvar__cl_color;
 
                if(forcecolor_enemy && !forcecolor_friend)
@@ -525,9 +531,15 @@ void CSQCModel_Effects_Apply(entity this)
        if(eff & EF_FULLBRIGHT)
                this.renderflags |= RF_FULLBRIGHT;
        if(eff & EF_FLAME)
-               pointparticles(EFFECT_EF_FLAME, this.origin, '0 0 0', bound(0, frametime, 0.1));
+       {
+               boxparticles(particleeffectnum(EFFECT_EF_FLAME), this, this.absmin, this.absmax, this.velocity, this.velocity, bound(0, frametime, 0.1), 0);
+               //pointparticles(EFFECT_EF_FLAME, this.origin, '0 0 0', bound(0, frametime, 0.1));
+       }
        if(eff & EF_STARDUST)
-               pointparticles(EFFECT_EF_STARDUST, this.origin, '0 0 0', bound(0, frametime, 0.1));
+       {
+               boxparticles(particleeffectnum(EFFECT_EF_STARDUST), this, this.absmin, this.absmax, this.velocity, this.velocity, bound(0, frametime, 0.1), 0);
+               //pointparticles(EFFECT_EF_STARDUST, this.origin, '0 0 0', bound(0, frametime, 0.1));
+       }
        if(eff & EF_NOSHADOW)
                this.renderflags |= RF_NOSHADOW;
        if(eff & EF_NODEPTHTEST)
index f952d0b0a02dcc652482733f72d2debff38c919a..14b171b6c2a53bbc318c88963e48b9b97d5e0563 100644 (file)
@@ -23,6 +23,8 @@ const int MF_TRACER3 =  BIT(7);  // purple trail
 .int csqcmodel_modelflags;
 .int csqcmodel_traileffect;
 
+.bool csqcmodel_isdead; // used by shownames and miscfunctions (entcs_IsDead) to know when a player is dead
+
 .int isplayermodel;
 
 void CSQCModel_Effects_Apply(entity this);
diff --git a/qcsrc/client/defs.qh b/qcsrc/client/defs.qh
deleted file mode 100644 (file)
index 0cf7129..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-#pragma once
-
-// Additional OPTIONAL Fields and Globals
-//float                intermission;
-float          scoreboard_showscores;
-.string                message;
-.float         renderflags;
-// float               coop;
-// float               deathmatch;
-
-float          dmg_take;
-// float               dmg_save;
-// vector              dmg_origin;
-
-// Darkplaces Render Modifications
-#if 0
-.float alpha;
-.vector colormod;
-.float scale;
-#endif
-
-// Basic variables
-.int enttype; // entity type sent from server
-.int sv_entnum; // entity number sent from server
-.int team;
-.int team_size;
-
-float vid_conheight;
-int binddb;
-
-// QUALIFYING
-float race_checkpoint;
-float race_time;
-float race_laptime;
-float race_checkpointtime;
-float race_previousbesttime;
-float race_mypreviousbesttime;
-string race_previousbestname;
-float race_nextcheckpoint;
-float race_nextbesttime;
-float race_mybesttime;
-string race_nextbestname;
-float race_penaltyaccumulator; // qualifying: total penalty time in tenths
-float race_penaltyeventtime; // time when the player got the penalty
-float race_penaltytime; // duration of penalty time, in tenths
-string race_penaltyreason; // reason for penalty
-float race_server_record; // server record
-float race_speedaward;
-string race_speedaward_holder;
-string race_speedaward_unit;
-float race_speedaward_alltimebest;
-string race_speedaward_alltimebest_holder;
-string race_speedaward_alltimebest_unit;
-
-// RACE
-float race_mycheckpoint;
-float race_mycheckpointtime;
-float race_mycheckpointdelta;
-float race_mycheckpointlapsdelta;
-string race_mycheckpointenemy;
-float race_othercheckpoint;
-float race_othercheckpointtime;
-float race_othercheckpointdelta;
-float race_othercheckpointlapsdelta;
-string race_othercheckpointenemy;
-float scoreboard_showscores_force;
-float race_status;
-string race_status_name;
-float race_myrank;
-
-// Nexball
-float nb_pb_period;
-
-// Spectating
-// -1 - observing
-// 0 - playing
-// >0 - id of spectated player
-float spectatee_status;
-float spectatee_status_changed_time;
-
-// short mapname
-string shortmapname;
-
-// database for misc stuff
-int tempdb;
-int ClientProgsDB;
-vector hook_shotorigin[4];
-vector lightning_shotorigin[4];
-
-
-#ifdef BLURTEST
-float blurtest_time0, blurtest_time1, blurtest_radius, blurtest_power;
-#endif
-
-float serverprevtime, serverdeltatime;
-
-float ticrate;
-
-.float damageforcescale;
-const float MIN_DAMAGEEXTRARADIUS = 2;
-const float MAX_DAMAGEEXTRARADIUS = 16;
-.float damageextraradius;
-.void(entity this, float thisdmg, int hittype, vector org, vector thisforce) event_damage;
-
-// weapons
-.bool silent;
-
-int w_deathtype;
-float w_issilent, w_random;
-vector w_org, w_backoff;
-
-float autoswitch;
-bool cvar_cl_allow_uid2name;
-bool cvar_cl_allow_uidranking;
-float cvar_cl_autoscreenshot;
-float cvar_cl_autotaunt;
-float cvar_cl_clippedspectating;
-int cvar_cl_gunalign;
-float cvar_cl_handicap;
-float cvar_cl_jetpack_jump;
-float cvar_cl_movement_track_canjump;
-float cvar_cl_noantilag;
-string cvar_cl_physics;
-float cvar_cl_voice_directional;
-float cvar_cl_voice_directional_taunt_attenuation;
-float cvar_cl_weaponimpulsemode;
-string cvar_g_xonoticversion;
-float cvar_cl_cts_noautoswitch;
-bool cvar_cl_weapon_switch_reload;
-bool cvar_cl_weapon_switch_fallback_to_impulse;
-
-REPLICATE(autoswitch, bool, "cl_autoswitch");
-REPLICATE(cvar_cl_allow_uid2name, bool, "cl_allow_uid2name");
-REPLICATE(cvar_cl_allow_uidranking, bool, "cl_allow_uidranking");
-REPLICATE(cvar_cl_autoscreenshot, int, "cl_autoscreenshot");
-REPLICATE(cvar_cl_autotaunt, float, "cl_autotaunt");
-REPLICATE(cvar_cl_clippedspectating, bool, "cl_clippedspectating");
-REPLICATE(cvar_cl_gunalign, int, "cl_gunalign");
-REPLICATE(cvar_cl_handicap, float, "cl_handicap");
-REPLICATE(cvar_cl_jetpack_jump, bool, "cl_jetpack_jump");
-REPLICATE(cvar_cl_movement_track_canjump, bool, "cl_movement_track_canjump");
-REPLICATE(cvar_cl_noantilag, bool, "cl_noantilag");
-REPLICATE(cvar_cl_physics, string, "cl_physics");
-REPLICATE(cvar_cl_voice_directional, int, "cl_voice_directional");
-REPLICATE(cvar_cl_voice_directional_taunt_attenuation, float, "cl_voice_directional_taunt_attenuation");
-REPLICATE(cvar_cl_weaponimpulsemode, int, "cl_weaponimpulsemode");
-REPLICATE(cvar_g_xonoticversion, string, "g_xonoticversion");
-REPLICATE(cvar_cl_cts_noautoswitch, bool, "cl_cts_noautoswitch");
-REPLICATE(cvar_cl_weapon_switch_reload, bool, "cl_weapon_switch_reload");
-REPLICATE(cvar_cl_weapon_switch_fallback_to_impulse, bool, "cl_weapon_switch_fallback_to_impulse");
-/*
-// cvar cl_newusekeysupported doesn't exist
-float cvar_cl_newusekeysupported;
-REPLICATE(cvar_cl_newusekeysupported, bool, "cl_newusekeysupported");
-*/
-string cvar_cl_allow_uidtracking;
-REPLICATE(cvar_cl_allow_uidtracking, string, "cl_allow_uidtracking");
-
-string cvar_cl_weaponpriority;
-REPLICATE(cvar_cl_weaponpriority, string, "cl_weaponpriority");
-
-string cvar_cl_weaponpriorities[10];
-REPLICATE(cvar_cl_weaponpriorities[0], string, "cl_weaponpriority0");
-REPLICATE(cvar_cl_weaponpriorities[1], string, "cl_weaponpriority1");
-REPLICATE(cvar_cl_weaponpriorities[2], string, "cl_weaponpriority2");
-REPLICATE(cvar_cl_weaponpriorities[3], string, "cl_weaponpriority3");
-REPLICATE(cvar_cl_weaponpriorities[4], string, "cl_weaponpriority4");
-REPLICATE(cvar_cl_weaponpriorities[5], string, "cl_weaponpriority5");
-REPLICATE(cvar_cl_weaponpriorities[6], string, "cl_weaponpriority6");
-REPLICATE(cvar_cl_weaponpriorities[7], string, "cl_weaponpriority7");
-REPLICATE(cvar_cl_weaponpriorities[8], string, "cl_weaponpriority8");
-REPLICATE(cvar_cl_weaponpriorities[9], string, "cl_weaponpriority9");
-
-float bgmtime;
-
-float vortex_charge_movingavg;
-
-int serverflags;
-
-float uid2name_dialog;
-
-float intermission_time;
-
-.bool csqcmodel_isdead; // used by shownames and miscfunctions (entcs_IsDead) to know when a player is dead
-
-#define player_currententnum (spectatee_status > 0 ? spectatee_status : player_localnum + 1)
index f485628280dfa6e45151ade24e5401e37335df6a..8de5e5a38bc59f85fc04d44e80561d307443f360 100644 (file)
@@ -1,5 +1,7 @@
 #pragma once
 
+float vortex_charge_movingavg; // WEAPONTODO
+
 vector crosshair_getcolor(entity this, float health_stat);
 void TrueAim_Init();
 void HUD_Crosshair(entity this);
index b00020fe50880a1194791bafe706d9aece0dab1c..114b44823201041dacda11b18eb1d8367bbe69a5 100644 (file)
@@ -1,6 +1,6 @@
 #include "hud.qh"
 
-#include <client/defs.qh>
+#include <client/items/items.qh>
 #include <client/miscfunctions.qh>
 #include <client/view.qh>
 #include "panel/scoreboard.qh"
@@ -8,7 +8,6 @@
 #include "../mapvoting.qh"
 #include "../teamradar.qh"
 #include <common/minigames/cl_minigames.qh>
-#include <common/t_items.qh>
 #include <common/deathtypes/all.qh>
 #include <common/ent_cs.qh>
 #include <common/items/_mod.qh>
index 9b768e0258ddcfe566b60b456cca7c119f84b1bd..32c7889cac866ef5266d8a3d11cf7300ff1483eb 100644 (file)
@@ -3,7 +3,6 @@
 #include "hud.qh"
 #include "panel/scoreboard.qh"
 #include <client/autocvars.qh>
-#include <client/defs.qh>
 #include <client/miscfunctions.qh>
 #include <client/view.qh>
 
index 5abbbf036bc4e2c9b1dae289c8595f83fec6e7d0..b75c3ebabdb5fa0a154f6cf239911390f4d9d819 100644 (file)
@@ -1,10 +1,10 @@
 #include "ammo.qh"
 
 #include <client/autocvars.qh>
-#include <client/defs.qh>
+#include <client/items/items.qh>
+#include <client/main.qh>
 #include <client/miscfunctions.qh>
 #include <client/view.qh>
-#include <common/t_items.qh>
 #include <common/wepent.qh>
 #include <common/mutators/mutator/nades/nades.qh>
 
index 0ddf5f347dbeb11e23c834c12cd3f79c8bfe2e3e..2fcf130fadadb920a7ca9f0b656efc47355b8c59 100644 (file)
@@ -2,7 +2,6 @@
 
 #include "scoreboard.qh"
 #include <common/notifications/all.qh>
-#include <client/defs.qh>
 #include <client/miscfunctions.qh>
 
 // CenterPrint (#16)
index 78cc6a0ef9066ae8291d52d3f0ea7f34a49b0c34..d46aa81b8269a29960a4b6a5b475b3fc44d4b6b4 100644 (file)
@@ -1,7 +1,6 @@
 #include "chat.qh"
 
 #include <client/autocvars.qh>
-#include <client/defs.qh>
 #include <client/miscfunctions.qh>
 
 // Chat (#12)
index d6bf99fd60494d31670feee9dff583e02920c0cb..48b852bf95a1f79d538f42829f580c31be410d91 100644 (file)
@@ -1,6 +1,6 @@
 #include "healtharmor.qh"
 
-#include <client/defs.qh>
+#include <client/main.qh>
 #include <client/miscfunctions.qh>
 
 #include <common/deathtypes/all.qh>
index 83897dfd3f250541e3f2d56e67f9cf391698faa2..03465cce56185d26267368b5c6043f57a435fc0d 100644 (file)
@@ -1,6 +1,7 @@
 #include "infomessages.qh"
 
 #include <client/autocvars.qh>
+#include <client/main.qh>
 #include <client/miscfunctions.qh>
 
 #include <common/ent_cs.qh>
index 139f29c3099f83ec00c969c7c8e59436929e91de..a60821909b04512c92bedf4e7816639d691979ea 100644 (file)
@@ -1,7 +1,6 @@
 #include "physics.qh"
 
 #include <client/autocvars.qh>
-#include <client/defs.qh>
 #include <client/miscfunctions.qh>
 #include <client/main.qh>
 #include <lib/csqcmodel/cl_player.qh>
index 1662415edda0e77e51cbea992f25cbbb54ec96ff..75fb0c2aaaf4009c80647750de6cbc8013413592 100644 (file)
@@ -1,9 +1,10 @@
 #include "powerups.qh"
 
 #include <client/autocvars.qh>
-#include <client/defs.qh>
+#include <client/main.qh>
 #include <client/miscfunctions.qh>
 #include <common/items/_mod.qh>
+#include <common/util.qh>
 
 // Powerups (#2)
 
index 73bd583bcd5b44b85d62c3dc45b6f1457c299346..f29978c2d0da0527dc2a3112510bfe1cad5c8c74 100644 (file)
@@ -1,7 +1,7 @@
 #include "pressedkeys.qh"
 
 #include <client/autocvars.qh>
-#include <client/defs.qh>
+#include <client/main.qh>
 #include <client/miscfunctions.qh>
 
 // Pressed keys (#11)
index 66ee555b43910b1472ba1b59555741972c90f176..6e3c185c8d29383043264a444007a7cb0d65e696 100644 (file)
@@ -1,7 +1,7 @@
 #include "quickmenu.qh"
 
 #include <client/autocvars.qh>
-#include <client/defs.qh>
+#include <client/main.qh>
 #include <client/miscfunctions.qh>
 #include <common/ent_cs.qh>
 #include <common/minigames/cl_minigames.qh>
index a0a971cb1f1732b95ddafae8b136303b6f1db0f5..0703c4f2dcb9eaecd29a70f49213f091f08591d3 100644 (file)
@@ -1,7 +1,7 @@
 #include "racetimer.qh"
 
 #include <client/autocvars.qh>
-#include <client/defs.qh>
+#include <client/main.qh>
 #include <client/miscfunctions.qh>
 
 // Race timer (#8)
index 6db88c68b39ee50fce1f8acce9c778465a3223ae..27cf20e875fc3463e6c52b6fc8a232e2deefd38e 100644 (file)
@@ -1,2 +1,42 @@
 #pragma once
 #include "../panel.qh"
+
+// QUALIFYING
+float race_checkpoint;
+float race_time;
+float race_laptime;
+float race_checkpointtime;
+float race_previousbesttime;
+float race_mypreviousbesttime;
+string race_previousbestname;
+float race_nextcheckpoint;
+float race_nextbesttime;
+float race_mybesttime;
+string race_nextbestname;
+float race_penaltyaccumulator; // qualifying: total penalty time in tenths
+float race_penaltyeventtime; // time when the player got the penalty
+float race_penaltytime; // duration of penalty time, in tenths
+string race_penaltyreason; // reason for penalty
+float race_server_record; // server record
+float race_speedaward;
+string race_speedaward_holder;
+string race_speedaward_unit;
+float race_speedaward_alltimebest;
+string race_speedaward_alltimebest_holder;
+string race_speedaward_alltimebest_unit;
+
+// RACE
+float race_mycheckpoint;
+float race_mycheckpointtime;
+float race_mycheckpointdelta;
+float race_mycheckpointlapsdelta;
+string race_mycheckpointenemy;
+float race_othercheckpoint;
+float race_othercheckpointtime;
+float race_othercheckpointdelta;
+float race_othercheckpointlapsdelta;
+string race_othercheckpointenemy;
+float scoreboard_showscores_force;
+float race_status;
+string race_status_name;
+float race_myrank;
index 59bfa1a95ae9c256319b26b04518583ade31e31a..66665498e07c6ced0a88d11371c4567c7aea4eee 100644 (file)
@@ -1,7 +1,7 @@
 #include "radar.qh"
 
 #include <client/autocvars.qh>
-#include <client/defs.qh>
+#include <client/main.qh>
 #include <client/miscfunctions.qh>
 #include <common/ent_cs.qh>
 #include <client/mapvoting.qh>
index a6ec774b870a1cf85623115e79927e7f39289ca7..553283e5bc4ab3bc2e15de5fde1eca5f9f94914f 100644 (file)
@@ -1,7 +1,7 @@
 #include "score.qh"
 
 #include <client/autocvars.qh>
-#include <client/defs.qh>
+#include <client/main.qh>
 #include <client/miscfunctions.qh>
 #include "scoreboard.qh"
 #include <common/ent_cs.qh>
index 47e08cbd835be0905cdd6689fe292d6a21e36df8..05715bd6cf78dd3ae6dd9f6aa3d283a1064eca68 100644 (file)
@@ -1,9 +1,9 @@
 #include "scoreboard.qh"
 
 #include <client/autocvars.qh>
-#include <client/defs.qh>
 #include <client/main.qh>
 #include <client/miscfunctions.qh>
+#include <client/hud/panel/racetimer.qh>
 #include "quickmenu.qh"
 #include <common/ent_cs.qh>
 #include <common/constants.qh>
index f585b480fe70b119f2491c3df712d5475aa2f3b3..ded11c2606d412db930036a30ca011149a817215 100644 (file)
@@ -1,6 +1,8 @@
 #pragma once
 #include "../panel.qh"
 
+bool scoreboard_showscores;
+
 bool scoreboard_active;
 float scoreboard_fade_alpha;
 float scoreboard_acc_fade_alpha;
index 8bb4ade6a17f49aca0f69be10c5ffa303069af2f..e49c777db2491eeb25e0fa81bfa4d88ef001e1aa 100644 (file)
@@ -1,8 +1,8 @@
 #include "timer.qh"
 
 #include <client/autocvars.qh>
-#include <client/defs.qh>
 #include <client/miscfunctions.qh>
+#include <client/view.qh>
 
 // Timer (#5)
 
index 60f8394900203204be439257a509e5f46cc7af8c..2b2c7fa969c90f087b33bb086a97cbf78cb243ff 100644 (file)
@@ -1,7 +1,7 @@
 #include "vote.qh"
 
 #include <client/autocvars.qh>
-#include <client/defs.qh>
+#include <client/main.qh>
 #include <client/miscfunctions.qh>
 
 // Vote (#9)
index 6db88c68b39ee50fce1f8acce9c778465a3223ae..3a6f45f80d7b230dd0471175a7e70eb4595b8e76 100644 (file)
@@ -1,2 +1,4 @@
 #pragma once
 #include "../panel.qh"
+
+float uid2name_dialog;
index 633e37b55d6181daf041a37c1cea40a38ea3308f..03be211a23b82277d35575bab89baef212bc99d1 100644 (file)
@@ -1,7 +1,7 @@
 #include "weapons.qh"
 
 #include <client/autocvars.qh>
-#include <client/defs.qh>
+#include <client/main.qh>
 #include <client/miscfunctions.qh>
 #include <client/view.qh>
 #include <common/wepent.qh>
diff --git a/qcsrc/client/items/_mod.inc b/qcsrc/client/items/_mod.inc
new file mode 100644 (file)
index 0000000..781cf2a
--- /dev/null
@@ -0,0 +1,2 @@
+// generated file; do not modify
+#include <client/items/items.qc>
diff --git a/qcsrc/client/items/_mod.qh b/qcsrc/client/items/_mod.qh
new file mode 100644 (file)
index 0000000..39d72e2
--- /dev/null
@@ -0,0 +1,2 @@
+// generated file; do not modify
+#include <client/items/items.qh>
diff --git a/qcsrc/client/items/items.qc b/qcsrc/client/items/items.qc
new file mode 100644 (file)
index 0000000..06135a9
--- /dev/null
@@ -0,0 +1,274 @@
+#include "items.qh"
+
+#include <common/items/_mod.qh>
+
+#include <client/main.qh>
+#include <common/physics/movetypes/movetypes.qh>
+#include <common/weapons/_all.qh>
+#include <lib/csqcmodel/cl_model.qh>
+#include <lib/csqcmodel/common.qh>
+#include <lib/warpzone/common.qh>
+
+bool autocvar_cl_ghost_items_vehicle = true;
+.vector item_glowmod;
+.bool item_simple; // probably not really needed, but better safe than sorry
+.float alpha;
+.bool pushable;
+void Item_SetAlpha(entity this)
+{
+       bool veh_hud = (hud && autocvar_cl_ghost_items_vehicle);
+
+       if(!veh_hud && (this.ItemStatus & ITS_AVAILABLE))
+       {
+               this.alpha = 1;
+               this.colormod = '1 1 1';
+               this.glowmod = this.item_glowmod;
+       }
+       else
+       {
+               this.alpha = autocvar_cl_ghost_items;
+               this.colormod = this.glowmod = autocvar_cl_ghost_items_color;
+       }
+
+       if((!veh_hud) && (this.ItemStatus & ITS_STAYWEP))
+       {
+               this.colormod = this.glowmod = autocvar_cl_weapon_stay_color;
+               this.alpha = autocvar_cl_weapon_stay_alpha;
+       }
+
+       this.drawmask = ((this.alpha <= 0) ? 0 : MASK_NORMAL);
+}
+
+void ItemDraw(entity this)
+{
+    if(this.gravity)
+    {
+        Movetype_Physics_MatchServer(this, false);
+        if(IS_ONGROUND(this))
+        { // For some reason avelocity gets set to '0 0 0' here ...
+            this.oldorigin = this.origin;
+            this.gravity = 0;
+
+            if(autocvar_cl_animate_items)
+            { // ... so reset it if animations are requested.
+                if(this.ItemStatus & ITS_ANIMATE1)
+                    this.avelocity = '0 180 0';
+
+                if(this.ItemStatus & ITS_ANIMATE2)
+                    this.avelocity = '0 -90 0';
+            }
+
+            // delay is for blocking item's position for a while;
+            // it's a workaround for dropped weapons that receive the position
+            // another time right after they spawn overriding animation position
+            this.onground_time = time + 0.5;
+        }
+    }
+    else if (autocvar_cl_animate_items && !this.item_simple) // no bobbing applied to simple items, for consistency's sake (no visual difference between ammo and weapons)
+    {
+        if(this.ItemStatus & ITS_ANIMATE1)
+        {
+               this.angles += this.avelocity * frametime;
+            float fade_in = bound(0, time - this.onground_time, 1);
+            setorigin(this, this.oldorigin + fade_in * ('0 0 10' + '0 0 8' * sin((time - this.onground_time) * 2)));
+        }
+
+        if(this.ItemStatus & ITS_ANIMATE2)
+        {
+               this.angles += this.avelocity * frametime;
+            float fade_in = bound(0, time - this.onground_time, 1);
+            setorigin(this, this.oldorigin + fade_in * ('0 0 8' + '0 0 4' * sin((time - this.onground_time) * 3)));
+        }
+    }
+
+    Item_SetAlpha(this);
+}
+
+void Item_PreDraw(entity this)
+{
+       if(warpzone_warpzones_exist)
+       {
+               setpredraw(this, func_null); // no need to keep running this
+               return;
+       }
+       float alph;
+       vector org = getpropertyvec(VF_ORIGIN);
+       //if(!checkpvs(org, this)) // this makes sense as long as we don't support recursive warpzones
+               //alph = 0; // this shouldn't be needed, since items behind walls are culled anyway
+       if(this.fade_start)
+       {
+               if(vdist(org - this.origin, >, this.fade_end))
+                       alph = 0; // save on some processing
+               else if(vdist(org - this.origin, <, this.fade_start))
+                       alph = 1; // more processing saved
+               else
+                       alph = bound(0, (this.fade_end - vlen(org - this.origin - 0.5 * (this.mins + this.maxs))) / (this.fade_end - this.fade_start), 1);
+       }
+       else
+               alph = 1;
+       //printf("%v <-> %v\n", view_origin, this.origin + 0.5 * (this.mins + this.maxs));
+       if(!hud && (this.ItemStatus & ITS_AVAILABLE))
+               this.alpha = alph;
+       if(alph <= 0)
+               this.drawmask = 0;
+       //else
+               //this.drawmask = MASK_NORMAL; // reset by the setalpha function
+}
+
+void ItemRemove(entity this)
+{
+       strfree(this.mdl);
+}
+
+HashMap ENT_CLIENT_ITEM_simple;
+STATIC_INIT(ENT_CLIENT_ITEM_simple)
+{
+       HM_NEW(ENT_CLIENT_ITEM_simple);
+}
+SHUTDOWN(ENT_CLIENT_ITEM_simple)
+{
+       HM_DELETE(ENT_CLIENT_ITEM_simple);
+}
+
+NET_HANDLE(ENT_CLIENT_ITEM, bool isnew)
+{
+    int sf = ReadByte();
+
+    if(sf & ISF_LOCATION)
+    {
+        this.origin = ReadVector();
+        setorigin(this, this.origin);
+        this.oldorigin = this.origin;
+    }
+
+    if(sf & ISF_ANGLES)
+    {
+        this.angles = ReadAngleVector();
+    }
+
+    if(sf & ISF_SIZE)
+    {
+        setsize(this, '-16 -16 0', '16 16 48');
+    }
+
+    if(sf & ISF_STATUS) // need to read/write status first so model can handle simple, fb etc.
+    {
+        this.ItemStatus = ReadByte();
+
+        Item_SetAlpha(this);
+
+        if(this.ItemStatus & ITS_ALLOWFB)
+            this.effects |= EF_FULLBRIGHT;
+        else
+            this.effects &= ~EF_FULLBRIGHT;
+
+        if(this.ItemStatus & ITS_GLOW)
+        {
+            if(this.ItemStatus & ITS_AVAILABLE)
+                this.effects |= (EF_ADDITIVE | EF_FULLBRIGHT);
+            else
+                this.effects &= ~(EF_ADDITIVE | EF_FULLBRIGHT);
+        }
+    }
+
+    if(sf & ISF_MODEL)
+    {
+        this.drawmask  = MASK_NORMAL;
+               set_movetype(this, MOVETYPE_TOSS);
+               if (isnew) IL_PUSH(g_drawables, this);
+        this.draw       = ItemDraw;
+        this.solid = SOLID_TRIGGER;
+        //this.flags |= FL_ITEM;
+
+        this.fade_end = ReadShort();
+        this.fade_start = ReadShort();
+        if(!warpzone_warpzones_exist && this.fade_start && !autocvar_cl_items_nofade)
+               setpredraw(this, Item_PreDraw);
+
+               strfree(this.mdl);
+
+        string _fn = ReadString();
+        this.item_simple = false; // reset it!
+
+        if(autocvar_cl_simple_items && (this.ItemStatus & ITS_ALLOWSI))
+        {
+            string _fn2 = substring(_fn, 0 , strlen(_fn) -4);
+            this.item_simple = true;
+
+                       #define extensions(x) \
+                               x(md3) \
+                               x(dpm) \
+                               x(iqm) \
+                               x(mdl) \
+                               /**/
+                       #define tryext(ext) { \
+                               string s = strcat(_fn2, autocvar_cl_simpleitems_postfix, "." #ext); \
+                               string cached = HM_gets(ENT_CLIENT_ITEM_simple, s); \
+                               if (cached == "") { \
+                                       HM_sets(ENT_CLIENT_ITEM_simple, s, cached = fexists(s) ? "1" : "0"); \
+                               } \
+                               if (cached != "0") { \
+                                       strcpy(this.mdl, s); \
+                                       break; \
+                               } \
+                       }
+                       do {
+                               extensions(tryext);
+                               this.item_simple = false;
+                LOG_TRACEF("Simple item requested for %s but no model exists for it", _fn);
+                       } while (0);
+                       #undef tryext
+                       #undef extensions
+        }
+
+        if(!this.item_simple)
+            strcpy(this.mdl, _fn);
+
+        if(this.mdl == "")
+            LOG_WARNF("this.mdl is unset for item %s", this.classname);
+
+        precache_model(this.mdl);
+        _setmodel(this, this.mdl);
+
+        setsize(this, '-16 -16 0', '16 16 48');
+    }
+
+    if(sf & ISF_COLORMAP)
+    {
+        this.colormap = ReadShort();
+        this.item_glowmod_x = ReadByte() / 255.0;
+        this.item_glowmod_y = ReadByte() / 255.0;
+        this.item_glowmod_z = ReadByte() / 255.0;
+    }
+
+    if(sf & ISF_DROP)
+    {
+        this.gravity = 1;
+        this.pushable = true;
+        //this.angles = '0 0 0';
+        set_movetype(this, MOVETYPE_TOSS);
+        this.velocity = ReadVector();
+        setorigin(this, this.oldorigin);
+
+        if(!this.move_time)
+        {
+            this.move_time = time;
+            this.spawntime = time;
+        }
+        else
+            this.move_time = max(this.move_time, time);
+    }
+
+    if(autocvar_cl_animate_items)
+    {
+        if(this.ItemStatus & ITS_ANIMATE1)
+            this.avelocity = '0 180 0';
+
+        if(this.ItemStatus & ITS_ANIMATE2)
+            this.avelocity = '0 -90 0';
+    }
+
+    this.entremove = ItemRemove;
+
+    return true;
+}
diff --git a/qcsrc/client/items/items.qh b/qcsrc/client/items/items.qh
new file mode 100644 (file)
index 0000000..78e109d
--- /dev/null
@@ -0,0 +1,19 @@
+#pragma once
+
+const int AMMO_COUNT = 4; // amount of ammo types to show in the ammo panel
+
+.float onground_time;
+
+bool   autocvar_cl_items_nofade;
+float  autocvar_cl_animate_items = 1;
+float  autocvar_cl_ghost_items = 0.45;
+vector autocvar_cl_ghost_items_color = '-1 -1 -1';
+vector autocvar_cl_weapon_stay_color = '2 0.5 0.5';
+float  autocvar_cl_weapon_stay_alpha = 0.75;
+float  autocvar_cl_simple_items = 0;
+string autocvar_cl_simpleitems_postfix = "_simple";
+.float  spawntime;
+.float  gravity;
+.vector colormod;
+
+void ItemDraw(entity this);
index 4d187e23cf02f12a800cffbd02a5328fa511bb73..ad11dbd296254b5bdbf580109d0b9b3276278d2e 100644 (file)
@@ -1,6 +1,6 @@
 #include "main.qh"
 
-#include "defs.qh"
+#include <client/items/items.qh>
 #include <common/ent_cs.qh>
 #include "miscfunctions.qh"
 #include <common/effects/effect.qh>
@@ -8,7 +8,7 @@
 #include <common/effects/all.qh>
 #include <common/effects/all.inc>
 #include "hud/_mod.qh"
-#include "commands/cl_cmd.qh"
+#include "command/cl_cmd.qh"
 #include "mapvoting.qh"
 #include <client/mutators/_mod.qh>
 #include "hud/panel/centerprint.qh"
 #include "hud/panel/quickmenu.qh"
 #include "shownames.qh"
 #include "view.qh"
-#include <common/t_items.qh>
 #include "weapons/projectile.qh"
 #include <common/deathtypes/all.qh>
 #include <common/items/_mod.qh>
+#include <common/gamemodes/gamemode/nexball/cl_nexball.qh>
 #include <common/mapinfo.qh>
 #include <common/minigames/cl_minigames.qh>
 #include <common/minigames/cl_minigames_hud.qh>
@@ -474,12 +474,19 @@ NET_HANDLE(ENT_CLIENT_CLIENTDATA, bool isnew)
                for(i = 0; i < MAX_SPECTATORS; ++i)
                        spectatorlist[i] = 0; // reset list first
 
-               for(i = 0; i < num_spectators; ++i)
+               int limit = min(num_spectators, MAX_SPECTATORS);
+               for(i = 0; i < limit; ++i)
                {
                        slot = ReadByte();
                        spectatorlist[i] = slot - 1;
                }
        }
+       else
+       {
+               for(int j = 0; j < MAX_SPECTATORS; ++j)
+                       spectatorlist[j] = 0; // reset list if showspectators has been turned off
+               num_spectators = 0;
+       }
 
        return = true;
 
index 12fc6180a1f08e04db5f4df8ea46c6b4c08b996c..784ecb9c99edf37d308a6e3aa14e8a9cc74d2e3b 100644 (file)
@@ -57,6 +57,7 @@ STATIC_INIT(main)
 float drawframetime;
 vector view_origin, view_forward, view_right, view_up;
 
+.float renderflags; // engine field
 
 bool button_zoom;
 bool spectatorbutton_zoom;
@@ -114,3 +115,35 @@ int framecount;
 
 float GetSpeedUnitFactor(int speed_unit);
 string GetSpeedUnit(int speed_unit);
+
+.int enttype; // entity type sent from server
+.int sv_entnum; // entity number sent from server
+
+.int team;
+.int team_size;
+
+int binddb;
+
+// Spectating
+// -1 - observing
+// 0 - playing
+// >0 - id of spectated player
+float spectatee_status;
+float spectatee_status_changed_time;
+
+#define player_currententnum (spectatee_status > 0 ? spectatee_status : player_localnum + 1)
+
+// short mapname
+string shortmapname;
+
+// database for misc stuff
+int tempdb;
+int ClientProgsDB;
+vector hook_shotorigin[4]; // WEAPONTODO
+vector lightning_shotorigin[4]; // TODO: unused
+
+float serverprevtime, serverdeltatime;
+
+float ticrate;
+
+int serverflags;
index 2129b7802735149564d8891117e29ed61db9ce4e..a38bb76cfc5b4bd4300bbcd5a3405f5f765e5c30 100644 (file)
@@ -1,12 +1,13 @@
 #include "mapvoting.qh"
 
 #include "autocvars.qh"
+#include "main.qh"
 #include "miscfunctions.qh"
-#include "defs.qh"
 #include "hud/_mod.qh"
 #include "hud/panel/scoreboard.qh"
 
 #include <common/mapinfo.qh>
+#include <common/util.qh>
 
 // MapVote (#21)
 
index e6f036842c0fe81c723ebdb5988cc74b3b18d0d2..a653f4bf1e5ca0af486b06dd58d6f61aafd143a1 100644 (file)
@@ -1,8 +1,8 @@
 #include "miscfunctions.qh"
 
 #include "autocvars.qh"
-#include "defs.qh"
 #include "hud/_mod.qh"
+#include "main.qh"
 
 #include <common/command/_mod.qh>
 
index d4a221cbc8a09c238faa5d44b4b7930fd8c2239a..bee9a2b454880597402cfcc09145f62e53c7c501 100644 (file)
@@ -1,6 +1,7 @@
 #include "shownames.qh"
 
 #include "autocvars.qh"
+#include "main.qh"
 #include "miscfunctions.qh"
 #include "resources.qh"
 #include "hud/_mod.qh"
index cdb8894a8dab6dab3872e191c7340afeb48206dc..2e6ddba229d8ff46cc0228251df2ed8ad41a881c 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "autocvars.qh"
 #include "hud/_mod.qh"
+#include <client/main.qh>
 
 #include <common/mutators/mutator/waypoints/all.qh>
 
index c9ad52ef93bf66cdd64ee0a04c2065bd244af937..d7dc3996f8913615e7f0707c0e30e6dfdf5b9af2 100644 (file)
@@ -4,6 +4,7 @@
 #include "miscfunctions.qh"
 #include "announcer.qh"
 #include "hud/_mod.qh"
+#include "main.qh"
 #include "mapvoting.qh"
 #include "shownames.qh"
 #include "hud/panel/scoreboard.qh"
@@ -44,8 +45,6 @@
 #include <lib/warpzone/client.qh>
 #include <lib/warpzone/common.qh>
 
-#define EFMASK_CHEAP (EF_ADDITIVE | EF_DOUBLESIDED | EF_FULLBRIGHT | EF_NODEPTHTEST | EF_NODRAW | EF_NOSHADOW | EF_SELECTABLE | EF_TELEPORT_BIT)
-
 float autocvar_cl_viewmodel_scale;
 float autocvar_cl_viewmodel_alpha = 1;
 
index cb6302f1f0930cd71fad5c31c45c11680380a1e2..7b73e5ae4994e9f9c720b4a5eca7c49eb38fb473 100644 (file)
@@ -20,3 +20,13 @@ const int CURSOR_RESIZE2 = 3;
 float drawtime;
 float unaccounted_damage = 0;
 float zoomscript_caught;
+
+float dmg_take;
+// float dmg_save;
+// vector dmg_origin;
+
+#ifdef BLURTEST
+float blurtest_time0, blurtest_time1, blurtest_radius, blurtest_power;
+#endif
+
+float intermission_time;
index fcdac111e401aedbbd01c54a14a82bf294179385..cb5b4240c956795910a50596ee69fbd21e30b0e0 100644 (file)
@@ -1,7 +1,6 @@
 #include "projectile.qh"
 
 #include "../autocvars.qh"
-#include "../defs.qh"
 #include "../main.qh"
 #include <client/mutators/_mod.qh>
 
index eaa80d05f0a6ae2b9b6d5ebefb0c6041473b6488..0686c058257ee51e6c2252122e422330732e19a5 100644 (file)
@@ -29,5 +29,3 @@ void Projectile_Draw(entity this);
 void loopsound(entity e, int ch, Sound samp, float vol, float attn);
 
 void Ent_RemoveProjectile(entity this);
-
-const int FL_PROJECTILE = BIT(15);
index 9d7c68a8eea3f58bdfb771e62b0df73e34bd20c6..fa80064c9aeeaf86ca9227c377e8b0be0980b82a 100644 (file)
@@ -39,7 +39,6 @@ noref float autocvar_net_connecttimeout = 30;
 #include "effects/all.qc"
 #include "impulses/all.qc"
 #include "notifications/all.qc"
-#include "t_items.qc"
 #endif
 
 #include "items/_mod.inc"
index 0ac07a19aa1e86e7e7b8682c5ff33687892b00b7..4a45c1edb0123b87fa606dbf2d1d916a62df9717 100644 (file)
@@ -7,8 +7,8 @@
 #include <common/mapinfo.qc>
 #include <common/net_notice.qc>
 #include <common/playerstats.qc>
+#include <common/replicate.qc>
 #include <common/state.qc>
-#include <common/t_items.qc>
 #include <common/util.qc>
 #include <common/viewloc.qc>
 #include <common/wepent.qc>
index 3e16f9cbe8e4c024b45dc8e3f252f6e7b42fff5e..f8461f41e2d2148b4ed5f856cbc8360332ca68f0 100644 (file)
@@ -7,8 +7,8 @@
 #include <common/mapinfo.qh>
 #include <common/net_notice.qh>
 #include <common/playerstats.qh>
+#include <common/replicate.qh>
 #include <common/state.qh>
-#include <common/t_items.qh>
 #include <common/util.qh>
 #include <common/viewloc.qh>
 #include <common/wepent.qh>
index 69fe458269845c7e0acf7b3eaa17c3008cd5581d..136e4d436669695d88000651798fac34834a8cf8 100644 (file)
@@ -4,7 +4,8 @@
 
 #if defined(SVQC)
     #include "util.qh"
-    #include "../server/defs.qh"
+    #include <common/weapons/_all.qh>
+    #include <common/stats.qh>
 #endif
 
 bool monsters_animoverride(entity this)
index bd149e7895139f2ea021d73bca8c24642c9cc749..7ef5cb64e5fad9d336c929c0150887c61511dbef 100644 (file)
@@ -12,7 +12,7 @@
 #endif
 
 #ifdef CSQC
-       #include <client/commands/cl_cmd.qh>
+       #include <client/command/cl_cmd.qh>
 #endif
 
 #ifdef SVQC
index a7e7da546e0b05337766b8247b2832be94c7438c..344eec48cee50401790682864c2e79e97abfcd13 100644 (file)
@@ -1,5 +1,30 @@
 #pragma once
 
+const int FRAGS_PLAYER = 0;
+const int FRAGS_SPECTATOR = -666;
+const int FRAGS_PLAYER_OUT_OF_GAME = -616;
+
+///////////////////////////
+// cvar constants
+
+const int CVAR_SAVE = 1;
+const int CVAR_NOTIFY = 2;
+const int CVAR_READONLY = 4;
+
+// server flags
+const int SERVERFLAG_ALLOW_FULLBRIGHT = 1;
+const int SERVERFLAG_TEAMPLAY = 2;
+const int SERVERFLAG_PLAYERSTATS = 4;
+
+const int SPECIES_HUMAN = 0;
+const int SPECIES_ROBOT_SOLID = 1;
+const int SPECIES_ALIEN = 2;
+const int SPECIES_ANIMAL = 3;
+const int SPECIES_ROBOT_RUSTY = 4;
+const int SPECIES_ROBOT_SHINY = 5;
+const int SPECIES_RESERVED = 15;
+
+#ifdef GAMEQC
 const int RANKINGS_CNT = 99;
 
 ///////////////////////////
@@ -13,13 +38,6 @@ const int KEY_CROUCH = BIT(5);
 const int KEY_ATCK = BIT(6);
 const int KEY_ATCK2 = BIT(7);
 
-///////////////////////////
-// cvar constants
-
-const int CVAR_SAVE = 1;
-const int CVAR_NOTIFY = 2;
-const int CVAR_READONLY = 4;
-
 ///////////////////////////
 // csqc communication stuff
 
@@ -30,23 +48,6 @@ const int HUD_BUMBLEBEE_GUN = 25;
 // # of maps, I'll use arrays for them :P
 const int MAPVOTE_COUNT = 30;
 
-const int SPECIES_HUMAN = 0;
-const int SPECIES_ROBOT_SOLID = 1;
-const int SPECIES_ALIEN = 2;
-const int SPECIES_ANIMAL = 3;
-const int SPECIES_ROBOT_RUSTY = 4;
-const int SPECIES_ROBOT_SHINY = 5;
-const int SPECIES_RESERVED = 15;
-
-const int FRAGS_PLAYER = 0;
-const int FRAGS_SPECTATOR = -666;
-const int FRAGS_PLAYER_OUT_OF_GAME = -616;
-
-// server flags
-const int SERVERFLAG_ALLOW_FULLBRIGHT = 1;
-const int SERVERFLAG_TEAMPLAY = 2;
-const int SERVERFLAG_PLAYERSTATS = 4;
-
 // a bit more constant
 const vector PL_MAX_CONST = '16 16 45';
 const vector PL_MIN_CONST = '-16 -16 -24';
@@ -57,3 +58,35 @@ const vector PL_CROUCH_MIN_CONST = '-16 -16 -24';
 const int GTV_FORBIDDEN = 0; // Cannot be voted
 const int GTV_AVAILABLE = 1; // Can be voted
 const int GTV_CUSTOM    = 2; // Custom entry
+
+// generic entity flags
+// engine flags can't be redefined as they are used by the engine (unfortunately), they are listed here for posterity
+#ifdef CSQC
+const int FL_FLY                                       = 1; /* BIT(0) */
+const int FL_SWIM                                      = 2; /* BIT(1) */
+const int FL_CLIENT                                    = 8; /* BIT(2) */       // set for all client edicts
+const int FL_INWATER                           = 16; /* BIT(3) */      // for enter / leave water splash
+const int FL_MONSTER                           = 32; /* BIT(4) */
+const int FL_GODMODE                           = 64; /* BIT(5) */      // player cheat
+const int FL_NOTARGET                          = 128; /* BIT(6) */     // player cheat
+const int FL_ITEM                                      = 256; /* BIT(7) */     // extra wide size for bonus items
+const int FL_ONGROUND                          = 512; /* BIT(8) */     // standing on something
+const int FL_PARTIALGROUND                     = 1024; /* BIT(9) */    // not all corners are valid
+const int FL_WATERJUMP                         = 2048; /* BIT(10) */   // player jumping out of water
+const int FL_JUMPRELEASED                      = 4096; /* BIT(11) */   // for jump debouncing
+#endif
+const int FL_WEAPON                            = BIT(12);
+const int FL_POWERUP                           = BIT(13);
+const int FL_PROJECTILE                        = BIT(14);
+const int FL_TOSSED                            = BIT(15);
+const int FL_SPAWNING                          = BIT(16);
+const int FL_PICKUPITEMS                       = BIT(17);
+const int FL_DUCKED                            = BIT(18);
+const int FL_ONSLICK                           = BIT(19);
+#endif
+
+#if defined(SVQC)
+       #define EFMASK_CHEAP (EF_ADDITIVE | EF_DOUBLESIDED | EF_FULLBRIGHT | EF_NODEPTHTEST | EF_NODRAW | EF_NOGUNBOB | EF_NOSHADOW | EF_LOWPRECISION | EF_SELECTABLE | EF_TELEPORT_BIT)
+#elif defined(CSQC)
+       #define EFMASK_CHEAP (EF_ADDITIVE | EF_DOUBLESIDED | EF_FULLBRIGHT | EF_NODEPTHTEST | EF_NODRAW | EF_NOSHADOW | EF_SELECTABLE | EF_TELEPORT_BIT)
+#endif
index f342bdde7f0fe29d4406e220d8ec0b81fc3e2d59..503cc1f22df278ac676f075a10f84287eac5ef03 100644 (file)
 
 # define ALPHA m_alpha
 .float m_alpha;
+
+# define GROUNDENTITY_NAME ground_networkentity
+# define GROUNDENTITY_TYPE float
+.float ground_networkentity;
 #else
 # define TAG_ENTITY_NAME tag_entity
 # define TAG_ENTITY_TYPE entity
@@ -29,6 +33,9 @@
 # define TAG_VIEWLOC_TYPE entity
 
 # define ALPHA alpha
+
+# define GROUNDENTITY_NAME groundentity
+# define GROUNDENTITY_TYPE entity
 #endif
 
 // add properties you want networked to CSQC here
@@ -66,6 +73,9 @@
        CSQCMODEL_PROPERTY(BIT(14), TAG_VIEWLOC_TYPE, ReadShort, WriteEntity, TAG_VIEWLOC_NAME) \
        CSQCMODEL_PROPERTY(BIT(16), int, ReadByte, WriteByte, multijump_count) \
        CSQCMODEL_PROPERTY(BIT(16), int, ReadByte, WriteByte, move_movetype) \
+       CSQCMODEL_IF(isplayer) \
+               CSQCMODEL_PROPERTY(BIT(17), GROUNDENTITY_TYPE, ReadShort, WriteEntity, GROUNDENTITY_NAME) \
+       CSQCMODEL_ENDIF \
        CSQCMODEL_PROPERTY(BIT(17), int, ReadByte, WriteByte, clipgroup)
 // TODO get rid of colormod/glowmod here; also get rid of some useless properties on non-players that only exist for CopyBody
 
index 68eccb461227c1e7797adab66a7985b320ee1c31..f68b5af413f1b6ea082937444e70ba3a606a31ae 100644 (file)
@@ -1,5 +1,6 @@
 #include "casings.qh"
 
+#include <common/replicate.qh>
 #include <common/util.qh>
 
 #ifdef CSQC
index 17f48136a6c0a4126f1ae96bf172c89fc63b9d4d..c532e6a29a7cc9392f62d5695cff3087e71c2896 100644 (file)
@@ -54,6 +54,8 @@ void Damage_DamageInfo(vector org, float coredamage, float edgedamage, float rad
 .float cnt;
 .int state;
 
+.bool silent;
+
 void DamageEffect_Think(entity this)
 {
        // if particle distribution is enabled, slow ticrate by total number of damages
index 68b43b17608094c8cdddcd2725a3f607765940e4..3629639c21b4a4ac4941126f02a689d6f9ccd7a3 100644 (file)
@@ -6,4 +6,14 @@
 #include <client/mutators/_mod.qh>
 #include <common/vehicles/all.qh>
 #include <common/weapons/_all.qh>
+
+int w_deathtype;
+float w_issilent, w_random;
+vector w_org, w_backoff;
+
+.float damageforcescale;
+const float MIN_DAMAGEEXTRARADIUS = 2;
+const float MAX_DAMAGEEXTRARADIUS = 16;
+.float damageextraradius;
+.void(entity this, float thisdmg, int hittype, vector org, vector thisforce) event_damage;
 #endif
index 06b8baa1a325999039f6ebe76da88534d82f63c2..afc366ba0c2796bba55a73860224bf8c420a861c 100644 (file)
@@ -7,6 +7,9 @@
        #ifdef SVQC
                #include <server/player.qh>
        #endif
+       #ifdef CSQC
+               #include <client/main.qh>
+       #endif
 
        REGISTER_NET_TEMP(globalsound)
        REGISTER_NET_TEMP(playersound)
index 9849b5be73f8ebf3d1aef3ff5b1e61ec4dfea2d0..41eee445c61b9616a2e76444b0bb63431cdf5838 100644 (file)
@@ -30,15 +30,11 @@ bool modeleffect_SendEntity(entity this, entity to, int sf)
        }
        if(f & 2)
        {
-               WriteCoord(MSG_ENTITY, this.angles.x);
-               WriteCoord(MSG_ENTITY, this.angles.y);
-               WriteCoord(MSG_ENTITY, this.angles.z);
+               WriteAngleVector(MSG_ENTITY, this.angles);
        }
        if(f & 4)
        {
-               WriteCoord(MSG_ENTITY, this.avelocity.x);
-               WriteCoord(MSG_ENTITY, this.avelocity.y);
-               WriteCoord(MSG_ENTITY, this.avelocity.z);
+               WriteAngleVector(MSG_ENTITY, this.avelocity);
        }
        WriteShort(MSG_ENTITY, this.scale * 256.0);
        WriteShort(MSG_ENTITY, this.scale2 * 256.0);
@@ -128,15 +124,11 @@ NET_HANDLE(ENT_CLIENT_MODELEFFECT, bool isnew)
        }
        if(f & 2)
        {
-               e.angles_x = ReadAngle();
-               e.angles_y = ReadAngle();
-               e.angles_z = ReadAngle();
+               e.angles = ReadAngleVector();
        }
        if(f & 4)
        {
-               e.avelocity_x = ReadAngle();
-               e.avelocity_y = ReadAngle();
-               e.avelocity_z = ReadAngle();
+               e.avelocity = ReadAngleVector();
        }
        e.scale1 = ReadShort() / 256.0;
        e.scale2 = ReadShort() / 256.0;
index a7aa27961139530a73a9a7feda0d4ae1fe8d54f4..4ef6b2f793b819805c3a78c5f0fb0e32f190ab2d 100644 (file)
@@ -170,7 +170,7 @@ ENTCS_PROP(SOLID, true, sv_solid, solid, ENTCS_SET_NORMAL,
                do {
                        if (IS_PLAYER(player))
                        {
-                               if (radar_showennemies) break;
+                               if (radar_showenemies) break;
                                if (SAME_TEAM(to, player)) break;
                                if (!(IS_PLAYER(to) || to.caplayer) && time > game_starttime) break;
                        }
index 1546d7da49ab6aab437ac464c95789048ddcf331..8ae89fd3b6c49707e06a958ea31ae1700159a8b6 100644 (file)
@@ -1,7 +1,7 @@
 #pragma once
 
 #ifdef CSQC
-#include <client/defs.qh>
+#include <client/csqcmodel_hooks.qh>
 #endif
 
 REGISTER_NET_LINKED(ENT_CLIENT_ENTCS)
@@ -47,6 +47,8 @@ REGISTER_NET_TEMP(CLIENT_ENTCS)
 
        void entcs_force_origin(entity player);
 
+       bool radar_showenemies;
+
 #endif
 
 #ifdef CSQC
index 9a9a654de9c928d3ae5112a69c8308ebaaab4016..fcfcf32ff38cc082fd36e18f26f06f59fe19aefd 100644 (file)
@@ -1,6 +1,12 @@
 #include "sv_assault.qh"
 
+#include <server/command/vote.qh>
 #include <common/mapobjects/func/breakable.qh>
+#include <common/mapobjects/triggers.qh>
+#include <common/turrets/sv_turrets.qh>
+#include <server/damage.qh>
+#include <server/world.qh>
+#include <server/spawnpoints.qh>
 
 .entity sprite;
 #define AS_ROUND_DELAY 5
index 4721d5ef4e1524e174dc4a9ac113a4969ef0b8c8..7e436665953388366df74999cbcb7f2bdc5dbe3b 100644 (file)
@@ -1,8 +1,16 @@
 #include "sv_ctf.qh"
 
 #include <common/effects/all.qh>
+#include <common/mapobjects/teleporters.qh>
+#include <common/mapobjects/triggers.qh>
 #include <common/vehicles/all.qh>
+#include <server/command/vote.qh>
+#include <server/client.qh>
 #include <server/gamelog.qh>
+#include <server/damage.qh>
+#include <server/world.qh>
+#include <server/items/items.qh>
+#include <server/race.qh>
 #include <server/teamplay.qh>
 
 #include <lib/warpzone/common.qh>
@@ -535,10 +543,12 @@ void ctf_Handle_Throw(entity player, entity receiver, int droptype)
        ctf_CaptureShield_Update(player, 0); // shield player from picking up flag
 }
 
+#if 0
 void shockwave_spawn(string m, vector org, float sz, float t1, float t2)
 {
        return modeleffect_spawn(m, 0, 0, org, '0 0 0', '0 0 0', '0 0 0', 0, sz, 1, t1, t2);
 }
+#endif
 
 // ==============
 // Event Handlers
@@ -602,7 +612,9 @@ void ctf_Handle_Capture(entity flag, entity toucher, int capturetype)
 
        // 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);
+#if 0
+       shockwave_spawn("models/ctf/shockwavetransring.md3", flag.origin - '0 0 15', -0.8, 0, 1);
+#endif
 
        // other
        if(capturetype == CAPTURE_NORMAL)
@@ -2193,7 +2205,7 @@ MUTATOR_HOOKFUNCTION(ctf, PlayerPreThink)
                WaypointSprite_UpdateHealth(player.wps_flagcarrier, healtharmor_maxdamage(GetResource(player, RES_HEALTH), GetResource(player, RES_ARMOR), autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id).x);
 }
 
-MUTATOR_HOOKFUNCTION(ctf, Damage_Calculate) // for changing damage and force values that are applied to players in g_damage.qc
+MUTATOR_HOOKFUNCTION(ctf, Damage_Calculate) // for changing damage and force values that are applied to players in damage.qc
 {
        entity frag_attacker = M_ARGV(1, entity);
        entity frag_target = M_ARGV(2, entity);
@@ -2346,7 +2358,7 @@ MUTATOR_HOOKFUNCTION(ctf, PlayerUseKey)
                                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)
+                                       // if it's a player, use the view origin as reference (stolen from RadiusDamage functions in damage.qc)
                                        vector head_center = WarpZone_UnTransformOrigin(head, CENTER_OR_VIEWOFS(head));
                                        vector passer_center = CENTER_OR_VIEWOFS(player);
 
index 4cffb0c488a30a332b12235b228cd606e7c97af4..d0e13c132b603660d7bf5c9d75f9b349019595ad 100644 (file)
@@ -75,6 +75,9 @@ const float VEHICLE_FLAG_SCALE = 1.0;
 .float score_return;
 .float score_team_capture; // shouldn't be too high
 
+// property set on objects to point to the flag they're carrying (if any)
+.entity flagcarried;
+
 // effects
 .string toucheffect;
 .string passeffect;
index c08176cf8ddef8c5a751bc08c8a4375b308822a8..1550c8e8927878d1320270d8ee3e7470217a4a3d 100644 (file)
@@ -1,8 +1,12 @@
 #include "sv_cts.qh"
 
+#include <server/client.qh>
 #include <server/race.qh>
+#include <server/world.qh>
 #include <server/gamelog.qh>
-#include <server/items.qh>
+#include <server/items/spawning.qh>
+#include <server/weapons/common.qh>
+#include <common/mapobjects/triggers.qh>
 
 float autocvar_g_cts_finish_kill_delay;
 bool autocvar_g_cts_selfdamage;
index 6e333c17e119e81f75291b611b4f75fc11a4be3c..0a6ee791a6d91073353a1fca81e2dcb1d96c9816 100644 (file)
@@ -1,7 +1,13 @@
 #include "sv_domination.qh"
 
+#include <server/client.qh>
+#include <server/command/vote.qh>
+#include <server/damage.qh>
 #include <server/gamelog.qh>
+#include <server/items/items.qh>
 #include <server/teamplay.qh>
+#include <common/mapobjects/platforms.qh>
+#include <common/mapobjects/triggers.qh>
 
 bool g_domination;
 
index a215040507d5bafe17968fb2c83b07db25174ce7..d74c2dfc2d12e474b84efd4b15bb86dcfc4d7319 100644 (file)
@@ -1,9 +1,12 @@
 #include "sv_invasion.qh"
 
+#include <common/mapobjects/triggers.qh>
 #include <common/monsters/sv_spawn.qh>
 #include <common/monsters/sv_spawner.qh>
 #include <common/monsters/sv_monsters.qh>
 
+#include <server/bot/api.qh>
+#include <server/world.qh>
 #include <server/teamplay.qh>
 
 IntrusiveList g_invasion_roundends;
index 735b01b3072f763ae0636b8da49f1015243525dd..dda6185cf4366f5657e760cad907932c0a2732d6 100644 (file)
@@ -1,7 +1,10 @@
 #include "sv_keepaway.qh"
 
 #include <common/effects/all.qh>
+#include <server/client.qh>
 #include <server/gamelog.qh>
+#include <server/damage.qh>
+#include <server/items/items.qh>
 
 .entity ballcarried;
 
@@ -381,7 +384,7 @@ MUTATOR_HOOKFUNCTION(ka, PlayerUseKey)
        }
 }
 
-MUTATOR_HOOKFUNCTION(ka, Damage_Calculate) // for changing damage and force values that are applied to players in g_damage.qc
+MUTATOR_HOOKFUNCTION(ka, Damage_Calculate) // for changing damage and force values that are applied to players in damage.qc
 {
        entity frag_attacker = M_ARGV(1, entity);
        entity frag_target = M_ARGV(2, entity);
index 40870a7903c559a48841f5c641362140ad2057fb..d48c76f3943313648aa1a4f39743a3b42845efff 100644 (file)
@@ -1,6 +1,10 @@
 #include "sv_keyhunt.qh"
 
+#include <server/command/vote.qh>
 #include <server/gamelog.qh>
+#include <server/damage.qh>
+#include <server/items/items.qh>
+#include <common/mapobjects/triggers.qh>
 
 float autocvar_g_balance_keyhunt_damageforcescale;
 float autocvar_g_balance_keyhunt_delay_collect;
index 3a7bc1dfe8e1c9bc0f36398d8a93b0b4e6e325bc..1b7b527d8633dbde2a25f65004b245426b6042e6 100644 (file)
@@ -3,6 +3,8 @@
 #include <common/mutators/mutator/instagib/items.qh>
 #include <server/campaign.qh>
 #include <server/command/_mod.qh>
+#include <server/world.qh>
+#include <server/items/items.qh>
 
 int autocvar_g_lms_extra_lives;
 bool autocvar_g_lms_join_anytime;
index d0b3731bc57a550f8710143fbad36feabf6aadaa..b92c272063f99a88b6501671d2eb0ccffad9e971 100644 (file)
@@ -1,3 +1,5 @@
 #pragma once
 
 void HUD_Mod_NexBall(vector pos, vector mySize);
+
+float nb_pb_period;
index 079b181f034b69e1bb53ab3f5cb04dcd812af948..ba5911272cd99165fdab3eba8fe352416d4e8602 100644 (file)
@@ -1,6 +1,10 @@
 #include "sv_nexball.qh"
 
+#include <server/client.qh>
+#include <server/command/vote.qh>
 #include <server/gamelog.qh>
+#include <common/ent_cs.qh>
+#include <common/mapobjects/triggers.qh>
 
 .entity ballcarried;
 
@@ -953,7 +957,7 @@ REGISTER_MUTATOR(nb, false)
                CVTOV(g_nexball_delay_idle);                       //10
                CVTOV(g_nexball_football_physics);               //0
                */
-               radar_showennemies = autocvar_g_nexball_radar_showallplayers;
+               radar_showenemies = autocvar_g_nexball_radar_showallplayers;
 
                InitializeEntity(NULL, nb_delayedinit, INITPRIO_GAMETYPE);
                WEP_NEXBALL.spawnflags &= ~WEP_FLAG_MUTATORBLOCKED;
index d7cde3a7349454fa630ae70b0901c0efab4706ac..864e89138aef001775eb6434db52b55ac8a2f73d 100644 (file)
@@ -32,3 +32,5 @@ float nb_teams;
 .float nb_droptime;
 
 .float teamtime;
+
+float g_nexball_meter_period;
index 66ae14db424dfb64a0f36124c3ca7ba1e686c72f..f0a0046d8dfc6059ff700da0d73afcad96bce4b1 100644 (file)
@@ -12,9 +12,7 @@ NET_HANDLE(ENT_ONSCAMERA, bool isnew)
        this.origin = ReadVector();
        setorigin(this, this.origin);
 
-       this.angles_x = ReadAngle();
-       this.angles_y = ReadAngle();
-       this.angles_z = ReadAngle();
+       this.angles = ReadAngleVector();
 
        this.drawmask  = MASK_NORMAL;
        setmodel(this, MDL_Null); // give it a size for clientcamera
index 1f3e43378c71919fce84baf73f2d26e2e59d4587..1c87e9af684d01992334551b1f3937d002bcdba2 100644 (file)
@@ -2,6 +2,13 @@
 #include "sv_controlpoint.qh"
 #include "sv_generator.qh"
 
+#include <server/bot/api.qh>
+#include <server/command/vote.qh>
+#include <server/damage.qh>
+#include <server/items/items.qh>
+#include <common/mapobjects/defs.qh>
+#include <common/mapobjects/triggers.qh>
+
 bool g_onslaught;
 
 float autocvar_g_onslaught_teleport_wait;
@@ -39,9 +46,7 @@ bool clientcamera_send(entity this, entity to, int sf)
 
        WriteVector(MSG_ENTITY, this.origin);
 
-       WriteAngle(MSG_ENTITY, this.angles_x);
-       WriteAngle(MSG_ENTITY, this.angles_y);
-       WriteAngle(MSG_ENTITY, this.angles_z);
+       WriteAngleVector(MSG_ENTITY, this.angles);
 
        return true;
 }
@@ -84,14 +89,14 @@ void ons_CaptureShield_Reset(entity this)
        this.team = this.enemy.team;
 }
 
-void ons_CaptureShield_Spawn(entity generator, bool is_generator)
+void ons_CaptureShield_Spawn(entity this, Model shield_model)
 {
        entity shield = new(ons_captureshield);
        IL_PUSH(g_onsshields, shield);
 
-       shield.enemy = generator;
-       shield.team = generator.team;
-       shield.colormap = generator.colormap;
+       shield.enemy = this;
+       shield.team = this.team;
+       shield.colormap = this.colormap;
        shield.reset = ons_CaptureShield_Reset;
        settouch(shield, ons_CaptureShield_Touch);
        setcefc(shield, ons_CaptureShield_Customize);
@@ -99,13 +104,12 @@ void ons_CaptureShield_Spawn(entity generator, bool is_generator)
        set_movetype(shield, 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");
+       shield.scale = this.scale;
 
-       precache_model(shield.model);
-       setorigin(shield, generator.origin);
-       _setmodel(shield, shield.model);
-       setsize(shield, shield.scale * shield.mins, shield.scale * shield.maxs);
+       float shield_extra_size = 1.20; // hitbox is 20% larger than the object itself
+       setorigin(shield, this.origin);
+       setmodel(shield, shield_model);
+       setsize(shield, shield_extra_size * this.mins, shield_extra_size * this.maxs);
 }
 
 
@@ -760,7 +764,7 @@ void ons_DelayedControlPoint_Setup(entity this)
        onslaught_updatelinks();
 
        // captureshield setup
-       ons_CaptureShield_Spawn(this, false);
+       ons_CaptureShield_Spawn(this, MDL_ONS_CP_SHIELD);
 
        CSQCMODEL_AUTOINIT(this);
 }
@@ -876,6 +880,7 @@ void ons_camSetup(entity this)
 
        FOREACH_CLIENT(true, it.clientcamera = cam;);
 
+       // NOTE: engine networked
        WriteByte(MSG_ALL, SVC_SETVIEWANGLES);
        WriteAngle(MSG_ALL, cam.angles_x);
        WriteAngle(MSG_ALL, cam.angles_y);
@@ -1042,7 +1047,7 @@ void ons_DelayedGeneratorSetup(entity this)
        this.bot_basewaypoint = this.nearestwaypoint;
 
        // captureshield setup
-       ons_CaptureShield_Spawn(this, true);
+       ons_CaptureShield_Spawn(this, MDL_ONS_GEN_SHIELD);
 
        onslaught_updatelinks();
 
index baf2131c80784a8f80aefa6ff925c6da3a5cff91..5c6e52f397389e8b4e6f03b4b08d029d1a6819a6 100644 (file)
@@ -1,7 +1,11 @@
 #include "sv_race.qh"
 
+#include <server/client.qh>
+#include <server/world.qh>
 #include <server/gamelog.qh>
 #include <server/race.qh>
+#include <common/ent_cs.qh>
+#include <common/mapobjects/triggers.qh>
 
 #define autocvar_g_race_laps_limit cvar("g_race_laps_limit")
 float autocvar_g_race_qualifying_timelimit;
@@ -445,6 +449,7 @@ void race_Initialize()
        race_ScoreRules();
        if(g_race_qualifying == 2)
                warmup_stage = 0;
+       radar_showenemies = true;
 }
 
 void rc_SetLimits()
index a4a4bcd196deb0ac37eb3dad58e807a980908b89..c6048b808a21510bccf0f438a4f4afa3cbb618a3 100644 (file)
@@ -1,5 +1,6 @@
 #include "sv_rules.qh"
 
+#include <server/spawnpoints.qh>
 #include <server/teamplay.qh>
 
 void GameRules_teams(bool value)
index a8b8b46757f7359607d468aeafe15ecf349cc1b4..5c6ec494a3d33bd92536aa5a701d7d8da2971514 100644 (file)
@@ -8,9 +8,10 @@
 #endif
 
 #ifdef SVQC
-#include <server/items.qh>
+#include <server/items/spawning.qh>
 #endif
 
+#ifdef GAMEQC
 const int IT_UNLIMITED_AMMO                    =  BIT(0); // when this bit is set, using a weapon does not reduce ammo. Checkpoints can give this powerup.
 const int IT_UNLIMITED_SUPERWEAPONS            =  BIT(1); // when this bit is set, superweapons don't expire. Checkpoints can give this powerup.
 
@@ -23,8 +24,6 @@ const int IT_RESOURCE                         =  BIT(5); // bitflag to mark this item as a reso
 const int IT_KEY1                                              = BIT(6);
 const int IT_KEY2                                              = BIT(7);
 
-const int IT_CTF_SHIELDED                      = BIT(8); // set for the flag shield
-
 // special colorblend meaning in engine
 const int IT_INVISIBILITY                              = BIT(9);
 const int IT_INVINCIBLE                                = BIT(10);
@@ -34,6 +33,33 @@ const int IT_STRENGTH                                = BIT(12);
 // item masks
 const int IT_PICKUPMASK                        = IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPERWEAPONS | IT_JETPACK | IT_FUEL_REGEN; // strength and invincible are handled separately
 
+// item networking
+const int ISF_LOCATION          = BIT(1);
+const int ISF_MODEL             = BIT(2);
+const int ISF_STATUS            = BIT(3);
+const int ISF_COLORMAP          = BIT(4);
+const int ISF_DROP              = BIT(5);
+const int ISF_ANGLES            = BIT(6);
+const int ISF_SIZE              = BIT(7);
+
+REGISTER_NET_LINKED(ENT_CLIENT_ITEM)
+
+// item status
+.int ItemStatus;
+const int ITS_STAYWEP           = BIT(0);
+const int ITS_ANIMATE1          = BIT(1);
+const int ITS_ANIMATE2          = BIT(2);
+const int ITS_AVAILABLE         = BIT(3);
+const int ITS_ALLOWFB           = BIT(4);
+const int ITS_ALLOWSI           = BIT(5);
+const int ITS_GLOW              = BIT(6);
+
+.float fade_start;
+.float fade_end;
+
+.string mdl;
+#endif
+
 #ifdef SVQC
 .float strength_finished; // NOTE: this field is used only by map entities, it does not directly apply the strength stat
 .float invincible_finished; // ditto
index 22d2826fe7db98fe59b9c2a9e0c981ba02d17db1..187080b37bfc15f2dba8559be243322ed68a6c3a 100644 (file)
@@ -3,7 +3,7 @@
 #include "pickup.qh"
 #include <common/items/all.qh>
 #ifdef SVQC
-    #include <common/t_items.qh>
+    #include <server/items/items.qh>
     #include <server/resources.qh>
 #endif
 
index 4f605c2e606e645ec4f96d3897e85909a9bc8508..e5ae8e36bd3bd1860080dc39f05f1c0552dc8190 100644 (file)
@@ -11,7 +11,7 @@ CLASS(Armor, Pickup)
 ENDCLASS(Armor)
 
 #ifdef SVQC
-    #include <common/t_items.qh>
+    #include <server/items/items.qh>
 #endif
 
 #ifdef GAMEQC
index 869c1838f625de62245f9e769fcbccbfd2b4966a..27f5dafc6e2019e9d8ac13669e323a18451dd11c 100644 (file)
@@ -11,7 +11,7 @@ CLASS(Health, Pickup)
 ENDCLASS(Health)
 
 #ifdef SVQC
-    #include <common/t_items.qh>
+    #include <server/items/items.qh>
 #endif
 
 #ifdef GAMEQC
index 2099fdc6790faa4dc8f2c8a54efd7efd432967dc..962f16170b8d7268f7d7cd9ff79e6d77f2ed9b68 100644 (file)
@@ -1,7 +1,7 @@
 #pragma once
 
 #ifdef SVQC
-    #include <common/t_items.qh>
+    #include <server/items/items.qh>
 #endif
 
 #include "ammo.qh"
index 43414b3d06f68af39afcb97f5eb0ebb7f2cf43ee..bf4727a79fdba674faedc71be9c98414754914a2 100644 (file)
@@ -2,7 +2,7 @@
 
 #ifdef SVQC
     // For FL_POWERUP
-    #include <server/constants.qh>
+    #include <common/constants.qh>
 #endif
 
 #include "pickup.qh"
@@ -45,7 +45,9 @@ REGISTER_ITEM(Strength, Powerup) {
     this.m_color            =   '0 0 1';
     this.m_waypoint         =   _("Strength");
     this.m_waypointblink    =   2;
+#ifdef GAMEQC
     this.m_itemid           =   IT_STRENGTH;
+#endif
 #ifdef SVQC
     this.m_iteminit         =   powerup_strength_init;
 #endif
@@ -81,7 +83,9 @@ REGISTER_ITEM(Shield, Powerup) {
     this.m_color            =   '1 0 1';
     this.m_waypoint         =   _("Shield");
     this.m_waypointblink    =   2;
+#ifdef GAMEQC
     this.m_itemid           =   IT_INVINCIBLE;
+#endif
 #ifdef SVQC
     this.m_iteminit         =   powerup_shield_init;
 #endif
index 7efa09be64eaa5fae7ca04b80297291a034f6cf7..9e0648db4393580a8e79a8dd6af2460f9d653a1f 100644 (file)
@@ -1,6 +1,5 @@
 #include "mapinfo.qh"
 #if defined(CSQC)
-    #include "../client/defs.qh"
     #include "util.qh"
     #include <common/weapons/_all.qh>
 #elif defined(MENUQC)
index 1aab2b927ec628cecc4ed2465a522f68972001f8..ebcbac55d6ccc45e8fb15ce39cdfe54983db3054 100644 (file)
@@ -1,4 +1,5 @@
 // generated file; do not modify
+#include <common/mapobjects/bgmscript.qc>
 #include <common/mapobjects/models.qc>
 #include <common/mapobjects/platforms.qc>
 #include <common/mapobjects/subs.qc>
index ebb7a43252a61022fec03bae3cc8b184a0fab7d9..87321822584ef0ec5d1220ce5b99f6d772db35d2 100644 (file)
@@ -1,4 +1,5 @@
 // generated file; do not modify
+#include <common/mapobjects/bgmscript.qh>
 #include <common/mapobjects/models.qh>
 #include <common/mapobjects/platforms.qh>
 #include <common/mapobjects/subs.qh>
diff --git a/qcsrc/common/mapobjects/bgmscript.qc b/qcsrc/common/mapobjects/bgmscript.qc
new file mode 100644 (file)
index 0000000..939444d
--- /dev/null
@@ -0,0 +1 @@
+#include "bgmscript.qh"
diff --git a/qcsrc/common/mapobjects/bgmscript.qh b/qcsrc/common/mapobjects/bgmscript.qh
new file mode 100644 (file)
index 0000000..e64bbbf
--- /dev/null
@@ -0,0 +1,8 @@
+#pragma once
+
+entityclass(BGMScript);
+classfield(BGMScript) .string bgmscript;
+classfield(BGMScript) .float bgmscriptattack;
+classfield(BGMScript) .float bgmscriptdecay;
+classfield(BGMScript) .float bgmscriptsustain;
+classfield(BGMScript) .float bgmscriptrelease;
index 45afb51f9ac98ad5806f5ae41ed4ff9360c02596..40af5252e202d43f489751169447ee356783d3e8 100644 (file)
@@ -26,16 +26,15 @@ const int SF_TRIGGER_RESET = BIT(2);
 //----------------
 // STATES & ACTIVE
 //----------------
-#ifdef CSQC
-// this stuff is defined in the server side engine VM, so we must define it separately here
 const int STATE_TOP = 0;
 const int STATE_BOTTOM = 1;
 const int STATE_UP = 2;
 const int STATE_DOWN = 3;
 
+.int active;
+.void (entity this, int act_state) setactive;
 const int ACTIVE_NOT = 0;
 const int ACTIVE_ACTIVE = 1;
 const int ACTIVE_IDLE = 2;
 const int ACTIVE_BUSY = 2;
 const int ACTIVE_TOGGLE = 3;
-#endif
index 24d7139435dc9bc7dcb3c5e1bd1ece102611ea71..4db6516580a6212880148ae30f574505dc115c3d 100644 (file)
@@ -1,7 +1,7 @@
 #include "breakable.qh"
 #ifdef SVQC
 
-#include <server/g_damage.qh>
+#include <server/damage.qh>
 #include <server/bot/api.qh>
 #include <common/csqcmodel_settings.qh>
 #include <lib/csqcmodel/sv_model.qh>
index e087ba8410a341fb09d77f6fa338030a7d109b65..73542ae45cebb95cc9523ffe1c87ba6f1cc9b81f 100644 (file)
@@ -3,4 +3,9 @@
 IntrusiveList g_ladderents;
 STATIC_INIT(g_ladderents) { g_ladderents = IL_NEW(); }
 
+#ifdef SVQC
+IntrusiveList g_ladders;
+STATIC_INIT(g_ladders) { g_ladders = IL_NEW(); }
+#endif
+
 .entity ladder_entity;
index 53dbed02fa42a50580b69efe7ef80143ba0b0f5e..64275a357aaa216e28a34c528da312aaabd441dc 100644 (file)
@@ -31,9 +31,7 @@ float plat_send(entity this, entity to, float sf)
 
                WriteVector(MSG_ENTITY, this.size);
 
-               WriteAngle(MSG_ENTITY, this.mangle_x);
-               WriteAngle(MSG_ENTITY, this.mangle_y);
-               WriteAngle(MSG_ENTITY, this.mangle_z);
+               WriteAngleVector(MSG_ENTITY, this.mangle);
 
                WriteShort(MSG_ENTITY, this.speed);
                WriteShort(MSG_ENTITY, this.height);
@@ -152,9 +150,7 @@ NET_HANDLE(ENT_CLIENT_PLAT, bool isnew)
 
                this.size = ReadVector();
 
-               this.mangle_x = ReadAngle();
-               this.mangle_y = ReadAngle();
-               this.mangle_z = ReadAngle();
+               this.mangle = ReadAngleVector();
 
                this.speed = ReadShort();
                this.height = ReadShort();
index 1864b6dfe43062131b27f718971800b0414a97b0..cf1710249b0f30b70cf86aef2106a0f031246956 100644 (file)
@@ -55,7 +55,7 @@ void func_rotating_init_for_player(entity this, entity player)
 Brush model that spins in place on one axis (default Z).
 speed   : speed to rotate (in degrees per second)
 noise   : path/name of looping .wav file to play.
-dmg     : Do this mutch dmg every .dmgtime intervall when blocked
+dmg     : Do this much damage every .dmgtime interval when blocked
 dmgtime : See above.
 */
 
index 9c2fba8ada8ed27ca928ba17218beadffcd70111..12d8e3781bc7cc38ef5f6f9658ef82eb093bf179 100644 (file)
@@ -1,9 +1,19 @@
 #include "stardust.qh"
 #ifdef SVQC
+void func_stardust_think(entity this)
+{
+       this.nextthink = time + 0.25;
+       CSQCMODEL_AUTOUPDATE(this);
+}
 spawnfunc(func_stardust)
 {
+       if(this.model != "") { precache_model(this.model); _setmodel(this, this.model); }
+
        this.effects = EF_STARDUST;
 
        CSQCMODEL_AUTOINIT(this);
+
+       setthink(this, func_stardust_think);
+       this.nextthink = time + 0.25;
 }
 #endif
index 4e9c334562c97cc1bad305ccb2abf279a3d20fa4..4ee741d580b6ccfa18abfe502645f67f1aeb815e 100644 (file)
@@ -164,9 +164,7 @@ float train_send(entity this, entity to, float sf)
 
                WriteVector(MSG_ENTITY, this.view_ofs);
 
-               WriteAngle(MSG_ENTITY, this.mangle_x);
-               WriteAngle(MSG_ENTITY, this.mangle_y);
-               WriteAngle(MSG_ENTITY, this.mangle_z);
+               WriteAngleVector(MSG_ENTITY, this.mangle);
 
                WriteShort(MSG_ENTITY, this.speed);
                WriteShort(MSG_ENTITY, this.height);
@@ -303,9 +301,7 @@ NET_HANDLE(ENT_CLIENT_TRAIN, bool isnew)
 
                this.view_ofs = ReadVector();
 
-               this.mangle_x = ReadAngle();
-               this.mangle_y = ReadAngle();
-               this.mangle_z = ReadAngle();
+               this.mangle = ReadAngleVector();
 
                this.speed = ReadShort();
                this.height = ReadShort();
index 0b2a099c53576f46aff7a0968965b2dccccaad95..a25c33198bea51e4b96a8b0e36ec827f59398687 100644 (file)
@@ -4,7 +4,3 @@
 const int TRAIN_CURVE = BIT(0);
 const int TRAIN_TURN = BIT(1);
 const int TRAIN_NEEDACTIVATION = BIT(2);
-
-#ifdef CSQC
-.float dmgtime;
-#endif
index 4882fe37d83937798985bb545dd62c37783be626..bd1e14fb1671a3e307bd0e93ee0b3ae5d58d4c5b 100644 (file)
@@ -8,18 +8,16 @@
 
 vector func_vectormamamam_origin(entity o, float timestep)
 {
-       vector v, p;
-       float flags;
+       vector p;
        entity e;
-
-       flags = o.spawnflags;
-       v = '0 0 0';
+       int myflags = o.spawnflags;
+       vector v = '0 0 0';
 
        e = o.wp00;
        if(e)
        {
                p = e.origin + timestep * e.velocity;
-               if(flags & PROJECT_ON_TARGETNORMAL)
+               if(myflags & PROJECT_ON_TARGETNORMAL)
                        v = v + (p * o.targetnormal) * o.targetnormal * o.targetfactor;
                else
                        v = v + (p - (p * o.targetnormal) * o.targetnormal) * o.targetfactor;
@@ -29,7 +27,7 @@ vector func_vectormamamam_origin(entity o, float timestep)
        if(e)
        {
                p = e.origin + timestep * e.velocity;
-               if(flags & PROJECT_ON_TARGET2NORMAL)
+               if(myflags & PROJECT_ON_TARGET2NORMAL)
                        v = v + (p * o.target2normal) * o.target2normal * o.target2factor;
                else
                        v = v + (p - (p * o.target2normal) * o.target2normal) * o.target2factor;
@@ -39,7 +37,7 @@ vector func_vectormamamam_origin(entity o, float timestep)
        if(e)
        {
                p = e.origin + timestep * e.velocity;
-               if(flags & PROJECT_ON_TARGET3NORMAL)
+               if(myflags & PROJECT_ON_TARGET3NORMAL)
                        v = v + (p * o.target3normal) * o.target3normal * o.target3factor;
                else
                        v = v + (p - (p * o.target3normal) * o.target3normal) * o.target3factor;
@@ -49,7 +47,7 @@ vector func_vectormamamam_origin(entity o, float timestep)
        if(e)
        {
                p = e.origin + timestep * e.velocity;
-               if(flags & PROJECT_ON_TARGET4NORMAL)
+               if(myflags & PROJECT_ON_TARGET4NORMAL)
                        v = v + (p * o.target4normal) * o.target4normal * o.target4factor;
                else
                        v = v + (p - (p * o.target4normal) * o.target4normal) * o.target4factor;
@@ -60,7 +58,7 @@ vector func_vectormamamam_origin(entity o, float timestep)
 
 void func_vectormamamam_controller_think(entity this)
 {
-       this.nextthink = time + vectormamamam_timestep;
+       this.nextthink = time + VECTORMAMAMAM_TIMESTEP;
 
        if(this.owner.active != ACTIVE_ACTIVE)
        {
@@ -69,21 +67,21 @@ void func_vectormamamam_controller_think(entity this)
        }
 
        if(this.owner.classname == "func_vectormamamam") // don't brake stuff if the func_vectormamamam was killtarget'ed
-               this.owner.velocity = (this.owner.destvec + func_vectormamamam_origin(this.owner, vectormamamam_timestep) - this.owner.origin) * 10;
+               this.owner.velocity = (this.owner.destvec + func_vectormamamam_origin(this.owner, VECTORMAMAMAM_TIMESTEP) - this.owner.origin) * 10;
 }
 
 void func_vectormamamam_findtarget(entity this)
 {
-       if(this.target != "")
+       if(this.target && this.target != "")
                this.wp00 = find(NULL, targetname, this.target);
 
-       if(this.target2 != "")
+       if(this.target2 && this.target2 != "")
                this.wp01 = find(NULL, targetname, this.target2);
 
-       if(this.target3 != "")
+       if(this.target3 && this.target3 != "")
                this.wp02 = find(NULL, targetname, this.target3);
 
-       if(this.target4 != "")
+       if(this.target4 && this.target4 != "")
                this.wp03 = find(NULL, targetname, this.target4);
 
        if(!this.wp00 && !this.wp01 && !this.wp02 && !this.wp03)
@@ -91,8 +89,7 @@ void func_vectormamamam_findtarget(entity this)
 
        this.destvec = this.origin - func_vectormamamam_origin(this, 0);
 
-       entity controller;
-       controller = new(func_vectormamamam_controller);
+       entity controller = new(func_vectormamamam_controller);
        controller.owner = this;
        controller.nextthink = time + 1;
        setthink(controller, func_vectormamamam_controller_think);
@@ -164,9 +161,9 @@ spawnfunc(func_vectormamamam)
                this.target4normal = normalize(this.target4normal);
 
        setblocked(this, generic_plat_blocked);
-       if(this.dmg && (this.message == ""))
+       if(this.dmg && (!this.message || this.message == ""))
                this.message = " was squished";
-    if(this.dmg && (this.message == ""))
+    if(this.dmg && (!this.message2 || this.message2 == ""))
                this.message2 = "was squished by";
        if(this.dmg && (!this.dmgtime))
                this.dmgtime = 0.25;
index 7eb6b0a63b0f1be400212e81a94c1f41679cb2e5..c024160f78cc133f226ba46e68926af8ab1e4c71 100644 (file)
@@ -1,9 +1,8 @@
 #pragma once
 
-
 const int PROJECT_ON_TARGETNORMAL = BIT(0);
 const int PROJECT_ON_TARGET2NORMAL = BIT(1);
 const int PROJECT_ON_TARGET3NORMAL = BIT(2);
 const int PROJECT_ON_TARGET4NORMAL = BIT(3);
 
-const float vectormamamam_timestep = 0.1;
+const float VECTORMAMAMAM_TIMESTEP = 0.1;
index 6e9f02b874a2c51610282c881121da037dbfc2c5..96d99b592dab099dc4de76a696ed1a71738d155d 100644 (file)
@@ -1,7 +1,8 @@
 #include "dynlight.qh"
 
 #ifdef SVQC
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 #include <server/miscfunctions.qh>
 
 const float LOOP = 1;
index 403a4681328e7e92de5b13f110d94fce6aff06e4..77435e938b405cf5b013b07b56283f12383bb68f 100644 (file)
@@ -10,7 +10,6 @@
 REGISTER_NET_LINKED(ENT_CLIENT_LASER)
 
 #ifdef SVQC
-.float modelscale;
 void misc_laser_aim(entity this)
 {
        vector a;
@@ -162,8 +161,7 @@ bool laser_SendEntity(entity this, entity to, float sendflags)
                }
                else
                {
-                       WriteAngle(MSG_ENTITY, this.mangle_x);
-                       WriteAngle(MSG_ENTITY, this.mangle_y);
+                       WriteAngleVector2D(MSG_ENTITY, this.mangle);
                }
        }
        if(sendflags & SF_LASER_UPDATE_ACTIVE)
@@ -291,19 +289,6 @@ spawnfunc(misc_laser)
 }
 #elif defined(CSQC)
 
-// a laser goes from origin in direction angles
-// it has color 'beam_color'
-// and stops when something is in the way
-entityclass(Laser);
-classfield(Laser) .int cnt; // end effect
-classfield(Laser) .vector colormod;
-classfield(Laser) .int state; // on-off
-classfield(Laser) .int count; // flags for the laser
-classfield(Laser) .vector velocity; // laser endpoint if it is FINITE
-classfield(Laser) .float alpha;
-classfield(Laser) .float scale; // scaling factor of the thickness
-classfield(Laser) .float modelscale; // scaling factor of the dlight
-
 void Draw_Laser(entity this)
 {
        if(this.active == ACTIVE_NOT)
@@ -402,8 +387,7 @@ NET_HANDLE(ENT_CLIENT_LASER, bool isnew)
                }
                else
                {
-                       this.angles_x = ReadAngle();
-                       this.angles_y = ReadAngle();
+                       this.angles = ReadAngleVector2D();
                }
        }
        if(sendflags & SF_LASER_UPDATE_ACTIVE)
index 0ff57646ad760e1c3b8b884bec49c4b53b800ea3..d5b34f2e826a6cfad4fa396f3b44e700d06ae97d 100644 (file)
@@ -1,5 +1,17 @@
 #pragma once
 
+// a laser goes from origin in direction angles
+// it has color 'beam_color'
+// and stops when something is in the way
+entityclass(Laser);
+classfield(Laser) .int cnt; // end effect
+classfield(Laser) .vector colormod;
+classfield(Laser) .int state; // on-off
+classfield(Laser) .int count; // flags for the laser
+classfield(Laser) .vector velocity; // laser endpoint if it is FINITE
+classfield(Laser) .float alpha;
+classfield(Laser) .float scale; // scaling factor of the thickness
+classfield(Laser) .float modelscale; // scaling factor of the dlight
 
 const int LASER_FINITE = BIT(1);
 const int LASER_NOTRACE = BIT(2);
index 7402726d436a3dd8c06a8e4be045e32c853ab623..6bf95f24f6dfa8b2ccaa5824c1ce1bb7da839722 100644 (file)
@@ -14,10 +14,7 @@ bool teleport_dest_send(entity this, entity to, int sendflags)
                WriteCoord(MSG_ENTITY, this.speed);
                WriteString(MSG_ENTITY, this.targetname);
                WriteVector(MSG_ENTITY, this.origin);
-
-               WriteAngle(MSG_ENTITY, this.mangle_x);
-               WriteAngle(MSG_ENTITY, this.mangle_y);
-               WriteAngle(MSG_ENTITY, this.mangle_z);
+               WriteAngleVector(MSG_ENTITY, this.mangle);
        }
 
        return true;
@@ -72,10 +69,7 @@ NET_HANDLE(ENT_CLIENT_TELEPORT_DEST, bool isnew)
                this.speed = ReadCoord();
                this.targetname = strzone(ReadString());
                this.origin = ReadVector();
-
-               this.mangle_x = ReadAngle();
-               this.mangle_y = ReadAngle();
-               this.mangle_z = ReadAngle();
+               this.mangle = ReadAngleVector();
 
                setorigin(this, this.origin);
 
index 790978b99470eb6f98a554f7f8ea2340185f1707..6b272d1b1671f2afc7515d2b48a6ca978a1237aa 100644 (file)
@@ -1,23 +1,16 @@
 #include "models.qh"
 
 #ifdef SVQC
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 #include <server/miscfunctions.qh>
 #include <common/net_linked.qh>
 #include "subs.qh"
 #include "triggers.qh"
-
-entityclass(BGMScript);
-classfield(BGMScript) .string bgmscript;
-classfield(BGMScript) .float bgmscriptattack;
-classfield(BGMScript) .float bgmscriptdecay;
-classfield(BGMScript) .float bgmscriptsustain;
-classfield(BGMScript) .float bgmscriptrelease;
+#include "bgmscript.qh"
 
 #include <common/constants.qh>
-#include "../../lib/csqcmodel/sv_model.qh"
-
-.float modelscale;
+#include <lib/csqcmodel/sv_model.qh>
 
 void g_model_setcolormaptoactivator(entity this, entity actor, entity trigger)
 {
@@ -117,11 +110,7 @@ bool g_clientmodel_genericsendentity(entity this, entity to, int sf)
        if(sf & BIT(2))
        {
                if(sf & 0x10)
-               {
-                       WriteAngle(MSG_ENTITY, this.angles.x);
-                       WriteAngle(MSG_ENTITY, this.angles.y);
-                       WriteAngle(MSG_ENTITY, this.angles.z);
-               }
+                       WriteAngleVector(MSG_ENTITY, this.angles);
        }
 
        if(sf & BIT(3))
@@ -342,11 +331,7 @@ NET_HANDLE(ENT_CLIENT_WALL, bool isnew)
        if(f & 4)
        {
                if(f & 0x10)
-               {
-                       this.angles_x = ReadAngle();
-                       this.angles_y = ReadAngle();
-                       this.angles_z = ReadAngle();
-               }
+                       this.angles = ReadAngleVector();
                else
                        this.angles = '0 0 0';
        }
index 45346dc8ea70440affb817baa6e4ddd8e5888f5e..e1fb9095a16eebf15a537e19f16b4d134895aef3 100644 (file)
@@ -1,5 +1,7 @@
 #pragma once
 
+.float modelscale;
+
 #ifdef CSQC
 entityclass(Wall);
 classfield(Wall) .float lip;
@@ -8,6 +10,11 @@ classfield(Wall) .int lodmodelindex0, lodmodelindex1, lodmodelindex2;
 classfield(Wall) .float loddistance1, loddistance2;
 classfield(Wall) .vector saved;
 
+void Ent_Wall_Draw(entity this);
+
+void Ent_Wall_Remove(entity this);
+#endif
+
 // Needed for interactive clientwalls
 .bool inactive; // Clientwall disappears when inactive
 .float alpha_max, alpha_min;
@@ -15,8 +22,3 @@ classfield(Wall) .vector saved;
 // fade_vertical_offset is a vertival offset for player position
 .float fade_start, fade_end, fade_vertical_offset;
 .float default_solid;
-
-void Ent_Wall_Draw(entity this);
-
-void Ent_Wall_Remove(entity this);
-#endif
index 346cebc7163dfade8657cba5caa5e3cc455838c6..3276cf45380ac1db11c3b7808bb0057020d4395c 100644 (file)
@@ -3,13 +3,15 @@
 
 const int PLAT_LOW_TRIGGER = BIT(0);
 
+.float dmg;
+.float dmgtime;
 .float dmgtime2;
 
+.float phase;
+
 void plat_center_touch(entity this, entity toucher);
 void plat_outside_touch(entity this, entity toucher);
 void plat_trigger_use(entity this, entity actor, entity trigger);
 void plat_go_up(entity this);
 void plat_go_down(entity this);
 void plat_crush(entity this, entity blocker);
-
-.float dmg;
index 2751c600eaf2706694db02198a3b3e6a3b43d427..b10400c7e1e7de5c3b6f161226d74d914e42d795 100644 (file)
@@ -1,9 +1,11 @@
 #include "kill.qh"
-#include "location.qh"
-#ifdef SVQC
 
+#ifdef SVQC
 void target_kill_use(entity this, entity actor, entity trigger)
 {
+       if(this.active != ACTIVE_ACTIVE)
+               return;
+
        if(actor.takedamage == DAMAGE_NO)
                return;
 
@@ -13,14 +15,21 @@ void target_kill_use(entity this, entity actor, entity trigger)
        Damage(actor, this, trigger, 1000, DEATH_HURTTRIGGER.m_id, DMG_NOWEP, actor.origin, '0 0 0');
 }
 
-spawnfunc(target_kill)
+void target_kill_reset(entity this)
 {
-    this.classname = "target_kill";
+       this.active = ACTIVE_ACTIVE;
+}
 
+spawnfunc(target_kill)
+{
     if (this.message == "")
                this.message = "was in the wrong place";
 
+       if (this.message2 == "")
+               this.message2 = "was thrown into a world of hurt by";
+
     this.use = target_kill_use;
+    this.reset = target_kill_reset;
+    this.active = ACTIVE_ACTIVE;
 }
-
 #endif
index 6f70f09beec2219624baeca92e2cd7deaa104fb4..4388ad6db2046497c6ebbad86949c6696b51c725 100644 (file)
@@ -1 +1,6 @@
 #pragma once
+
+#ifdef SVQC
+IntrusiveList g_locations;
+STATIC_INIT(g_locations) { g_locations = IL_NEW(); }
+#endif
index 55ccf41fbf2db9da6b46b1e3008a027795d16878..30413c0c658f19dcf1e4b4bba86f440578203e73 100644 (file)
@@ -4,8 +4,8 @@
 #elif defined(SVQC)
     #include <common/constants.qh>
     #include <common/net_linked.qh>
-    #include <server/constants.qh>
-    #include <server/defs.qh>
+    #include <common/weapons/_all.qh>
+    #include <common/stats.qh>
 #endif
 
 REGISTER_NET_TEMP(TE_CSQC_TARGET_MUSIC)
index 9c999ed4df4758612b9052a34aeb22101b85b905..b96370d18e75839838a6c1a6900170dbc230b386 100644 (file)
@@ -3,7 +3,9 @@
 #elif defined(MENUQC)
 #elif defined(SVQC)
     #include <common/util.qh>
-    #include <server/defs.qh>
+    #include <common/weapons/_all.qh>
+    #include <common/stats.qh>
+    #include <server/world.qh>
 #endif
 
 #ifdef SVQC
index ab9c8dca570c1a3b196973b85515beb952489545..1fbe04b76aaef52aa9be6d48e037ab20b45e6146 100644 (file)
     #include "../util.qh"
     #include <server/weapons/csqcprojectile.qh>
     #include <server/autocvars.qh>
-    #include <server/constants.qh>
-    #include <server/defs.qh>
+    #include <common/weapons/_all.qh>
+    #include <common/stats.qh>
     #include "../deathtypes/all.qh"
+    #include <server/main.qh>
     #include "../turrets/sv_turrets.qh"
     #include "../vehicles/all.qh"
     #include <common/gamemodes/_mod.qh>
index f72f943d3612012c9c6bde5c9ecdc1507ee73c48..10c4fdfafc62cf6d5403561e59d6ff44f0d07a2a 100644 (file)
@@ -15,6 +15,7 @@ const int TELEPORT_FLAG_FORCE_TDEATH = BIT(3);
 #define TELEPORT_FLAGS_PORTAL     (TELEPORT_FLAG_SOUND | TELEPORT_FLAG_PARTICLES | TELEPORT_FLAG_TDEATH | TELEPORT_FLAG_FORCE_TDEATH)
 #define TELEPORT_FLAGS_TELEPORTER (TELEPORT_FLAG_SOUND | TELEPORT_FLAG_PARTICLES | TELEPORT_FLAG_TDEATH)
 
+.float teleportable;
 // types for .teleportable entity setting
 const int TELEPORT_NORMAL = 1; // play sounds/effects etc
 const int TELEPORT_SIMPLE = 2; // only do teleport, nothing special
index 44cbd9045307f844f473b15e0895c4a959aebfa2..765d3180e2619d118edeeeda0c521d5e6858a74c 100644 (file)
@@ -1,9 +1,11 @@
 #include "counter.qh"
-#ifdef SVQC
-void counter_reset(entity this);
 
+#ifdef SVQC
 void counter_use(entity this, entity actor, entity trigger)
 {
+       if(this.active != ACTIVE_ACTIVE)
+               return;
+
        entity store = this;
        if(this.spawnflags & COUNTER_PER_PLAYER)
        {
@@ -66,6 +68,7 @@ void counter_reset(entity this)
        setthink(this, func_null);
        this.nextthink = 0;
        this.counter_cnt = 0;
+       this.active = ACTIVE_ACTIVE;
 }
 
 /*QUAKED spawnfunc_trigger_counter (.5 .5 .5) ? nomessage COUNTER_FIRE_AT_COUNT
@@ -86,5 +89,6 @@ spawnfunc(trigger_counter)
        this.counter_cnt = 0;
        this.use = counter_use;
        this.reset = counter_reset;
+       this.active = ACTIVE_ACTIVE;
 }
 #endif
index 403a87a8920b45361bbbd404a1ff55588c19b6ae..a34e95b831fb85e97243686ada7d225ee6ccfd1e 100644 (file)
@@ -1,7 +1,7 @@
 #pragma once
 
 #ifdef SVQC
-spawnfunc(trigger_counter);
+void counter_reset(entity this);
 
 .float counter_cnt;
 
index 2cd4cfd1338ac0809f3f9ff451a65ee3f5a59f8d..7e593a56c0b7850934bf9c9fe4ad0fc12ef54ca5 100644 (file)
@@ -1,4 +1,5 @@
 #include "delay.qh"
+
 #ifdef SVQC
 void delay_delayeduse(entity this)
 {
@@ -8,6 +9,9 @@ void delay_delayeduse(entity this)
 
 void delay_use(entity this, entity actor, entity trigger)
 {
+       if(this.active != ACTIVE_ACTIVE)
+               return;
+
        this.enemy = actor;
        this.goalentity = trigger;
        setthink(this, delay_delayeduse);
@@ -19,6 +23,7 @@ void delay_reset(entity this)
        this.enemy = this.goalentity = NULL;
        setthink(this, func_null);
        this.nextthink = 0;
+       this.active = ACTIVE_ACTIVE;
 }
 
 spawnfunc(trigger_delay)
@@ -28,5 +33,6 @@ spawnfunc(trigger_delay)
 
     this.use = delay_use;
     this.reset = delay_reset;
+    this.active = ACTIVE_ACTIVE;
 }
 #endif
index 141f3ea9f19e513dcad6aeaa07e304efaec9dea8..84c4dd9357af639dd482b7d9a66a4bd55aefb560 100644 (file)
@@ -1,10 +1,14 @@
 #include "flipflop.qh"
+
 #ifdef SVQC
 /*QUAKED spawnfunc_trigger_flipflop (.5 .5 .5) (-8 -8 -8) (8 8 8) START_ENABLED
 "Flip-flop" trigger gate... lets only every second trigger event through
 */
 void flipflop_use(entity this, entity actor, entity trigger)
 {
+       if(this.active != ACTIVE_ACTIVE)
+               return;
+
     this.state = !this.state;
     if(this.state)
         SUB_UseTargets(this, actor, trigger);
@@ -12,12 +16,9 @@ void flipflop_use(entity this, entity actor, entity trigger)
 
 spawnfunc(trigger_flipflop)
 {
-    if(this.spawnflags & START_ENABLED)
-    {
-        this.state = true;
-    }
+       this.active = ACTIVE_ACTIVE;
+    this.state = (this.spawnflags & START_ENABLED);
     this.use = flipflop_use;
     this.reset = spawnfunc_trigger_flipflop; // perfect resetter
 }
-
 #endif
index 72d76d183326437bdd4f5bcd7a38393d0a578268..e7ed67c455c59b956643130fa0154bad56ba8844 100644 (file)
@@ -1,14 +1,10 @@
 #include "gamestart.qh"
+
 #ifdef SVQC
 void gamestart_use(entity this, entity actor, entity trigger)
 {
        SUB_UseTargets(this, this, trigger);
-       delete(this);
-}
-
-void gamestart_use_this(entity this)
-{
-       gamestart_use(this, NULL, NULL);
+       delete(this); // TODO: deleting this means it can't be used upon map reset!
 }
 
 spawnfunc(trigger_gamestart)
@@ -22,7 +18,6 @@ spawnfunc(trigger_gamestart)
                this.nextthink = game_starttime + this.wait;
        }
        else
-               InitializeEntity(this, gamestart_use_this, INITPRIO_FINDTARGET);
+               InitializeEntity(this, adaptor_think2use, INITPRIO_FINDTARGET);
 }
-
 #endif
index e992154aa97fd6a76cd6d7fc6d856ebb356eda4a..66f7568bd53e7f7d3a39b33a9ea2be4b8e16c864 100644 (file)
@@ -1,3 +1,7 @@
 #pragma once
 
+#ifdef SVQC
 const int HURT_SLOW = BIT(4);
+
+bool tracebox_hits_trigger_hurt(vector start, vector e_min, vector e_max, vector end);
+#endif
index 5138419d1ada9546081f6ce63549bd14a389a74c..5273179adfeb047faeea7f8d7c7ab518cebc9d60 100644 (file)
@@ -2,6 +2,7 @@
 // TODO: split target_push and put it in the target folder
 #ifdef SVQC
 #include <common/physics/movetypes/movetypes.qh>
+#include <server/main.qh>
 
 void trigger_push_use(entity this, entity actor, entity trigger)
 {
@@ -634,9 +635,7 @@ bool target_push_send(entity this, entity to, float sf)
        WriteString(MSG_ENTITY, this.targetname);
        WriteVector(MSG_ENTITY, this.origin);
 
-       WriteAngle(MSG_ENTITY, this.angles_x);
-       WriteAngle(MSG_ENTITY, this.angles_y);
-       WriteAngle(MSG_ENTITY, this.angles_z);
+       WriteAngleVector(MSG_ENTITY, this.angles);
 
        return true;
 }
@@ -726,9 +725,7 @@ NET_HANDLE(ENT_CLIENT_TARGET_PUSH, bool isnew)
        this.targetname = strzone(ReadString());
        this.origin = ReadVector();
 
-       this.angles_x = ReadAngle();
-       this.angles_y = ReadAngle();
-       this.angles_z = ReadAngle();
+       this.angles = ReadAngleVector();
 
        return = true;
 
index f7ecd7c1f1ab8c5c0e3afd1e202085c2e27fd460..626a588dcb880ff625f3a7d29f68994ee274f04a 100644 (file)
@@ -169,16 +169,6 @@ spawnfunc(trigger_keylock)
        trigger_keylock_link(this);
 }
 #elif defined(CSQC)
-void keylock_remove(entity this)
-{
-       strfree(this.target);
-       strfree(this.target2);
-       strfree(this.target3);
-       strfree(this.target4);
-       strfree(this.killtarget);
-       strfree(this.targetname);
-}
-
 NET_HANDLE(ENT_CLIENT_KEYLOCK, bool isnew)
 {
        this.itemkeys = ReadInt24_t();
@@ -189,6 +179,6 @@ NET_HANDLE(ENT_CLIENT_KEYLOCK, bool isnew)
        return = true;
 
        this.classname = "trigger_keylock";
-       this.entremove = keylock_remove;
+       this.entremove = trigger_remove_generic;
 }
 #endif
index df915a649695c34ade16a31051dc9bdb6ce02b32..9ce5f52cea877d9a1f556c9fa1ee88b06027fe08 100644 (file)
@@ -29,16 +29,7 @@ void multi_trigger(entity this)
                return; // only players
        }
 
-       // TODO: restructure this so that trigger_secret is more independent
-       if (this.classname == "trigger_secret")
-       {
-               if (!IS_PLAYER(this.enemy))
-                       return;
-               found_secrets = found_secrets + 1;
-               WriteByte (MSG_ALL, SVC_FOUNDSECRET);
-       }
-
-       if (this.noise)
+       if (this.noise && this.noise != "")
        {
                _sound (this.enemy, CH_TRIGGER, this.noise, VOL_BASE, ATTEN_NORM);
        }
@@ -167,7 +158,7 @@ spawnfunc(trigger_multiple)
        else if (this.sounds == 3)
                this.noise = "misc/trigger1.wav";
 
-       if(this.noise)
+       if(this.noise && this.noise != "")
                precache_sound(this.noise);
 
        if (!this.wait)
index 18c2a40d01d569bb48cb1ba054484d1e624c4cfc..2c891c2ac8c1dd95dca119874d0a58785c9ac06e 100644 (file)
@@ -1,7 +1,11 @@
 #include "relay_activators.qh"
+
 #ifdef SVQC
 void relay_activators_use(entity this, entity actor, entity trigger)
 {
+       if(this.active != ACTIVE_ACTIVE)
+               return;
+
        for(entity trg = NULL; (trg = find(trg, targetname, this.target)); )
        {
                if (trg.setactive)
@@ -14,21 +18,28 @@ void relay_activators_use(entity this, entity actor, entity trigger)
        }
 }
 
+void relay_activators_init(entity this)
+{
+       this.reset = relay_activators_init; // doubles as a reset function
+       this.active = ACTIVE_ACTIVE;
+       this.use = relay_activators_use;
+}
+
 spawnfunc(relay_activate)
 {
        this.cnt = ACTIVE_ACTIVE;
-       this.use = relay_activators_use;
+       relay_activators_init(this);
 }
 
 spawnfunc(relay_deactivate)
 {
        this.cnt = ACTIVE_NOT;
-       this.use = relay_activators_use;
+       relay_activators_init(this);
 }
 
 spawnfunc(relay_activatetoggle)
 {
        this.cnt = ACTIVE_TOGGLE;
-       this.use = relay_activators_use;
+       relay_activators_init(this);
 }
 #endif
index 7586bd338428ef644cef1f060ff3db537b630ac2..a8855f5508eb95cddc0f542dfcb76e42d4dac45c 100644 (file)
@@ -1,4 +1,5 @@
 #include "relay_if.qh"
+
 #ifdef SVQC
 void trigger_relay_if_use(entity this, entity actor, entity trigger)
 {
index 5291f529062b8dd57bfbcaa5d9beaa4342b0cf2b..217c0e4b02e86945d279249f399b5b15cd204833 100644 (file)
@@ -1,4 +1,5 @@
 #include "relay_teamcheck.qh"
+
 #ifdef SVQC
 void trigger_relay_teamcheck_use(entity this, entity actor, entity trigger)
 {
index e532f713c4c582705ca22632f89b48c18ca11319..d1277c87ba689dacfad7436fddb55df54b36e428 100644 (file)
@@ -3,18 +3,12 @@
 #elif defined(MENUQC)
 #elif defined(SVQC)
     #include <common/util.qh>
-    #include <server/defs.qh>
+    #include <common/weapons/_all.qh>
+    #include <common/stats.qh>
 #endif
 
 #ifdef SVQC
 
-void secrets_setstatus(entity this)
-{
-       // TODO: use global stats!
-       STAT(SECRETS_TOTAL, this) = secrets_total;
-       STAT(SECRETS_FOUND, this) = secrets_found;
-}
-
 /**
  * A secret has been found (maybe :P)
  */
@@ -24,21 +18,26 @@ void trigger_secret_touch(entity this, entity toucher)
        if (!IS_PLAYER(toucher))
                return;
 
+       EXACTTRIGGER_TOUCH(this, toucher);
+
        // update secrets found counter
        secrets_found += 1;
-       //print("Secret found: ", ftos(secret_counter.cnt), "/");
-       //print(ftos(secret_counter.count), "\n");
 
-       // centerprint message (multi_touch() doesn't always call centerprint())
-       centerprint(toucher, this.message);
-       this.message = "";
+       // message and noise handled by SUB_UseTargets
+       SUB_UseTargets(this, toucher, toucher);
 
-       // handle normal trigger features
-       multi_touch(this, toucher);
        // we can't just delete(this) here, because this is a touch function
        // called while C code is looping through area links...
-       //delete(this);
+       settouch(this, func_null);
+}
+
+#if 0
+void trigger_secret_reset(entity this)
+{
+       secrets_found = 0;
+       settouch(this, trigger_secret_touch);
 }
+#endif
 
 /*QUAKED trigger_secret (.5 .5 .5) ?
 Variable sized secret trigger. Can be targeted at one or more entities.
@@ -61,30 +60,32 @@ spawnfunc(trigger_secret)
        secrets_total += 1;
 
        // add default message
-       if (this.message == "")
+       if (!this.message || this.message == "")
                this.message = "You found a secret!";
 
        // set default sound
-       if (this.noise == "")
-       if (!this.sounds)
+       if ((!this.noise || this.noise == "") && !this.sounds)
                this.sounds = 1; // misc/secret.wav
 
-       // this entity can't be a target itself!!!!
-       this.targetname = "";
+       switch(this.sounds)
+       {
+               case 1: this.noise = "misc/secret.wav"; break;
+               case 2: this.noise = strzone(SND(TALK)); break;
+               case 3: this.noise = "misc/trigger1.wav"; break;
+       }
 
-       // you can't just shoot a room to find it, can you?
-       SetResourceExplicit(this, RES_HEALTH, 0);
+       if(this.noise && this.noise != "")
+               precache_sound(this.noise);
 
-       // a secret can not be delayed
+       // a secret cannot be delayed
        this.delay = 0;
 
-       // convert this trigger to trigger_once
-       //this.classname = "trigger_once";
-       spawnfunc_trigger_once(this);
+       EXACTTRIGGER_INIT;
 
-       // take over the touch() function, so we can mark secret as found
        settouch(this, trigger_secret_touch);
-       // ignore triggering;
-       this.use = func_null;
+// NOTE: old maps don't expect secrets to reset, so enabling resetting can cause issues!
+#if 0
+       this.reset = trigger_secret_reset;
+#endif
 }
 #endif
index fcc55c39597071e35f1929f5653b21e5650ca53a..f2ca25b2a79b37e5cb2121109223c6ab3ae3b498 100644 (file)
@@ -1,19 +1,9 @@
 #pragma once
-#ifdef SVQC
-
-/**
- * Total number of secrets on the map.
- */
-float secrets_total;
-
-/**
- * Total numbe of secrets found on the map.
- */
-float secrets_found;
 
+#ifdef SVQC
+// Total number of secrets on the map.
+int secrets_total;
 
-/**
- * update secrets status.
- */
-void secrets_setstatus(entity this);
+// Total numbe of secrets found on the map.
+int secrets_found;
 #endif
index 495deb7988693b565c3d5e9eec12816ec5d22853..3aa6134a9a3cef9cd8cf6cd57a0932c262e2729e 100644 (file)
@@ -4,7 +4,8 @@
 #elif defined(SVQC)
     #include <lib/warpzone/util_server.qh>
     #include <common/weapons/_all.qh>
-    #include <server/defs.qh>
+    #include <common/weapons/_all.qh>
+    #include <common/stats.qh>
     #include <common/deathtypes/all.qh>
 #endif
 
index ba5dcbe443ea4c26e955adfa68b9f997eb0f8d69..c8c0836117a519fb13f4066f688931a236cb8db6 100644 (file)
@@ -3,7 +3,9 @@
 #elif defined(MENUQC)
 #elif defined(SVQC)
     #include <lib/warpzone/util_server.qh>
-    #include <server/defs.qh>
+       #include <common/mapobjects/triggers.qh>
+    #include <common/weapons/_all.qh>
+    #include <common/stats.qh>
 #endif
 
 REGISTER_NET_LINKED(ENT_CLIENT_VIEWLOC)
@@ -125,9 +127,7 @@ bool viewloc_send(entity this, entity to, int sf)
 
        WriteVector(MSG_ENTITY, this.origin);
 
-       WriteAngle(MSG_ENTITY, this.angles_x);
-       WriteAngle(MSG_ENTITY, this.angles_y);
-       WriteAngle(MSG_ENTITY, this.angles_z);
+       WriteAngleVector(MSG_ENTITY, this.angles);
 
        return true;
 }
@@ -200,9 +200,7 @@ NET_HANDLE(ENT_CLIENT_VIEWLOC, bool isnew)
        this.origin = ReadVector();
        setorigin(this, this.origin);
 
-       this.movedir_x = ReadAngle();
-       this.movedir_y = ReadAngle();
-       this.movedir_z = ReadAngle();
+       this.movedir = ReadAngleVector();
 
        return = true;
 
index 73113b4b51c69b004e6eaf02e6d924a481fd815e..1fac7907a57b57fa9701738373d369d70b1ce5e0 100644 (file)
 
 .float lip;
 
+// handy fields used by a lot of the codebase, but more importantly used by map objects
+.float cnt;
+.float count;
+
 // used elsewhere (will fix)
 #ifdef SVQC
+.string message2;
+
 void trigger_common_write(entity this, bool withtarget);
 
 string trigger_magicear_processmessage_forallears(entity source, float teamsay, entity privatesay, string msgin);
@@ -46,7 +52,6 @@ void generic_netlinked_legacy_use(entity this, entity actor, entity trigger);
 void trigger_common_read(entity this, bool withtarget);
 void trigger_remove_generic(entity this);
 
-.float active;
 .string target;
 .string targetname;
 #endif
index 146f64d405533ca59aac5636f81720f16d922157..5d79c4a838a0e05e1227655c89b6d1c015ef07e6 100644 (file)
@@ -59,7 +59,7 @@ ENDCLASS(Monster)
 
 #ifdef SVQC
 #include "sv_monsters.qh"
-#include <server/g_damage.qh>
+#include <server/damage.qh>
 #include <server/bot/api.qh>
 #include <server/weapons/common.qh>
 #include <server/weapons/tracing.qh>
index b938b10ed60b9e5149e00803f771b1ce297be15b..d5bff8f0239f682727e8e09eac47c221329b3037 100644 (file)
@@ -8,15 +8,22 @@
 #include "../physics/movelib.qh"
 #include "../weapons/_mod.qh"
 #include <server/autocvars.qh>
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
+#include <server/damage.qh>
 #include "../deathtypes/all.qh"
+#include <server/items/items.qh>
 #include <server/mutators/_mod.qh>
 #include <server/steerlib.qh>
+#include <server/main.qh>
 #include "../turrets/sv_turrets.qh"
 #include "../turrets/util.qh"
 #include "../vehicles/all.qh"
 #include <server/campaign.qh>
+#include <server/cheats.qh>
 #include <server/command/_mod.qh>
+#include <common/items/_mod.qh>
+#include <common/mapobjects/teleporters.qh>
 #include "../mapobjects/triggers.qh"
 #include <lib/csqcmodel/sv_model.qh>
 #include <server/round_handler.qh>
@@ -128,7 +135,7 @@ entity Monster_FindTarget(entity this)
        {
                if(Monster_ValidTarget(this, it))
                {
-                       // if it's a player, use the view origin as reference (stolen from RadiusDamage functions in g_damage.qc)
+                       // if it's a player, use the view origin as reference (stolen from RadiusDamage functions in damage.qc)
                        vector targ_center = CENTER_OR_VIEWOFS(it);
 
                        if(closest_target)
@@ -512,7 +519,7 @@ bool Monster_Respawn_Check(entity this)
        return true;
 }
 
-void Monster_Respawn(entity this) { Monster_Spawn(this, true, this); }
+void Monster_Respawn(entity this) { Monster_Spawn(this, true, this.monsterdef); }
 
 .vector        pos1, pos2;
 
@@ -1145,7 +1152,7 @@ void Monster_Anim(entity this)
        int animbits = deadbits;
        if(STAT(FROZEN, this))
                animbits |= ANIMSTATE_FROZEN;
-       if(this.crouch)
+       if(IS_DUCKED(this))
                animbits |= ANIMSTATE_DUCK; // not that monsters can crouch currently...
        animdecide_setstate(this, animbits, false);
        animdecide_setimplicitstate(this, (IS_ONGROUND(this)));
index 755abaaf2c67f69950d4be432bd6f8c3c7cddad6..b6cab12b652872bc6f9a6af63079acad1c540315 100644 (file)
@@ -1,5 +1,7 @@
 #pragma once
 
+#include "all.qh"
+
 // stats networking
 int monsters_total;
 int monsters_killed;
@@ -110,3 +112,9 @@ ALLMONSTERSOUNDS
 #undef _MSOUND
 
 float GetMonsterSoundSampleField_notFound;
+
+IntrusiveList g_monsters;
+STATIC_INIT(g_monsters) { g_monsters = IL_NEW(); }
+
+IntrusiveList g_monster_targets;
+STATIC_INIT(g_monster_targets) { g_monster_targets = IL_NEW(); }
index f4ae76df8ce919049741f1763cb6a795c5857da2..4cdfb24e40038097dca08a5c4f7fe21a4cb160a0 100644 (file)
@@ -6,7 +6,9 @@
     #include "all.qh"
     #include "sv_monsters.qh"
     #include <server/autocvars.qh>
-    #include <server/defs.qh>
+    #include <common/weapons/_all.qh>
+    #include <common/stats.qh>
+    #include <server/weapons/common.qh>
 #endif
 entity spawnmonster (entity e, string monster, Monster monster_id, entity spawnedby, entity own, vector orig, bool respwn, bool removeifinvalid, int moveflag)
 {
index d12ee2bc6c184196a462a4d85ae218f80a9970b8..98222f6ac9b37e68531db26c8eca575ab0d1a118 100644 (file)
@@ -1,3 +1,4 @@
+#include "sv_monsters.qh"
 #include "sv_spawner.qh"
 #include "sv_spawn.qh"
 
index dc1bfefc264b20d7cd9f6606723facb78bee9980..c80b97d36b1d711dd575c94bf9123f2d1bd1a234 100644 (file)
@@ -1,7 +1,7 @@
 #include "sv_breakablehook.qh"
 
 #include <common/deathtypes/all.qh>
-#include <server/g_hook.qh>
+#include <server/hook.qh>
 
 REGISTER_MUTATOR(breakablehook, cvar("g_breakablehook"));
 
index fcbb399cbedee8e8e91e55a703f40d0ff9a29e1d..30cef339a69a4249785e6f04344b451f5427691b 100644 (file)
@@ -2,6 +2,8 @@
 
 #include <common/mapobjects/target/music.qh>
 #include <common/gamemodes/_mod.qh>
+#include <server/items/items.qh>
+#include <server/main.qh>
 
 void buffs_DelayedInit(entity this);
 
index c0aa8312186bd131c554b6dfddbba928449e1a9e..4724eda1735f5c37c80989854c4fe2ce0c2c71bc 100644 (file)
@@ -61,7 +61,9 @@ REGISTER_ITEM(ExtraLife, Powerup) {
     this.m_color                =   '1 0 0';
     this.m_waypoint             =   _("Extra life");
     this.m_waypointblink        =   2;
+#ifdef SVQC
     this.m_itemid               =   IT_RESOURCE;
+#endif
 }
 
 SPAWNFUNC_ITEM(item_extralife, ITEM_ExtraLife)
@@ -93,7 +95,9 @@ REGISTER_ITEM(Invisibility, Powerup) {
     this.m_color            =   '0 0 1';
     this.m_waypoint         =   _("Invisibility");
     this.m_waypointblink    =   2;
+#ifdef GAMEQC
     this.m_itemid           =   IT_STRENGTH;
+#endif
 #ifdef SVQC
     this.m_iteminit         =   powerup_invisibility_init;
 #endif
@@ -128,7 +132,9 @@ REGISTER_ITEM(Speed, Powerup) {
     this.m_color            =   '1 0 1';
     this.m_waypoint         =   _("Speed");
     this.m_waypointblink    =   2;
+#ifdef GAMEQC
     this.m_itemid           =   IT_INVINCIBLE;
+#endif
 #ifdef SVQC
     this.m_iteminit         =   powerup_speed_init;
 #endif
index 47e1c97a9a9a70f1df5a7214ac56e12e8080bbed..c3e0083785692ef3bf8073b2eb1c1a6db1570b87 100644 (file)
@@ -1,6 +1,7 @@
 #include "sv_new_toys.qh"
 
 #include "../random_items/sv_random_items.qh"
+#include <server/weapons/spawning.qh>
 
 /*
 
index b399d3c62f68893cc2822eb09ac23bf3a891a1aa..867da41d4ea840597c7b81b692e272740d6e3fa7 100644 (file)
@@ -1,5 +1,7 @@
 #include "sv_nix.qh"
 
+#include <server/weapons/selection.qh>
+
 //string autocvar_g_nix;
 int autocvar_g_balance_nix_ammo_cells;
 int autocvar_g_balance_nix_ammo_plasma;
index 2243c9872cba4d3ed6d1b1f4c47e25d7cf41a2e9..5c7505614e829734f2e074d4371abb824542bb1f 100644 (file)
@@ -1,5 +1,7 @@
 #include "sv_spawn_near_teammate.qh"
 
+#include <common/mapobjects/trigger/hurt.qh>
+
 #include <lib/float.qh>
 
 string autocvar_g_spawn_near_teammate;
index d6db436d0174b2fe672ef2da00a9dbe35aacec68..e7eaa7cb2ec658e3a6f7ffe3f5468e3d64d119e2 100644 (file)
@@ -7,8 +7,7 @@
        #include <common/net_linked.qh>
        #include <common/teams.qh>
        #include <server/autocvars.qh>
-       #include <server/constants.qh>
-       #include <server/defs.qh>
+       #include <server/world.qh>
        #include <server/mutators/_mod.qh>
 #endif
 
index 28af884dea59850713e39e202f6d149153f79c1d..eb57922b9d81020b76001a51474194432202035a 100644 (file)
@@ -504,7 +504,7 @@ int _Movetype_ContentsMask(entity this)  // SV_GenericHitSuperContentsMask
                        return this.dphitcontentsmask;
                else if(this.solid == SOLID_SLIDEBOX)
                {
-                       if(this.flags & 32) // TODO: FL_MONSTER
+                       if(this.flags & FL_MONSTER)
                                return DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_MONSTERCLIP;
                        else
                                return DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP;
@@ -755,12 +755,24 @@ void _Movetype_Physics_ClientFrame(entity this, float movedt)
 
 void Movetype_Physics_NoMatchTicrate(entity this, float movedt, bool isclient)  // to be run every move frame
 {
+       bool didmove = (this.move_time != 0);
        this.move_time = time;
 
        if(isclient)
                _Movetype_Physics_ClientFrame(this, movedt);
        else
+       {
+               // this doesn't apply to clients, and only applies to unmatched entities
+               // don't run think/move on newly spawned projectiles as it messes up
+               // movement interpolation and rocket trails, and is inconsistent with
+               // respect to entities spawned in the same frame
+               // (if an ent spawns a higher numbered ent, it moves in the same frame,
+               //  but if it spawns a lower numbered ent, it doesn't - this never moves
+               //  ents in the first frame regardless)
+               if(!didmove && GAMEPLAYFIX_DELAYPROJECTILES(this) > 0)
+                       return;
                _Movetype_Physics_Frame(this, movedt);
+       }
        if(wasfreed(this))
                return;
 
index 13867d1fbad9b62ae5eabb19e7d91a43dbd19e76..444e7f4423f011fba921c61ff395aa3eeb6a578e 100644 (file)
@@ -25,6 +25,7 @@ const int WATERLEVEL_SUBMERGED = 3;
 #define GAMEPLAYFIX_NOAIRBORNCORPSE(s)                 STAT(GAMEPLAYFIX_NOAIRBORNCORPSE)
 #define NOAIRBORNCORPSE_ALLOWSUSPENDED(s)      STAT(NOAIRBORNCORPSE_ALLOWSUSPENDED)
 #define UPWARD_VELOCITY_CLEARS_ONGROUND(s)  STAT(GAMEPLAYFIX_UPVELOCITYCLEARSONGROUND)
+#define GAMEPLAYFIX_DELAYPROJECTILES(s)        STAT(GAMEPLAYFIX_DELAYPROJECTILES)
 
 
 #define PHYS_STEPHEIGHT(s)                  STAT(MOVEVARS_STEPHEIGHT)
@@ -135,8 +136,6 @@ const int MOVETYPE_FOLLOW           = 12;
 const int MOVETYPE_PHYSICS          = 32;
 const int MOVETYPE_FLY_WORLDONLY    = 33;
 
-const int FL_ITEM                   = 256;
-const int FL_ONGROUND                          = 512;
 #elif defined(SVQC)
 const int MOVETYPE_ANGLENOCLIP      = 1;
 const int MOVETYPE_ANGLECLIP        = 2;
@@ -145,8 +144,6 @@ const int MOVETYPE_ANGLECLIP        = 2;
 const int MOVETYPE_QCPLAYER = 150; // QC-driven player physics, no think functions!
 const int MOVETYPE_QCENTITY = 151; // QC-driven entity physics, some think functions!
 
-const int FL_ONSLICK = BIT(20);
-
 const int MOVETYPE_FAKEPUSH         = 13;
 
 const int MOVEFLAG_VALID = BIT(23);
index 2fd66af671f54ea1bb85cbde7f8b7a04f0d3ba7a..ade9c4d6f8acc5a90f0411b680ab4ab34467dcf5 100644 (file)
@@ -4,8 +4,11 @@
 
 #ifdef SVQC
 
+#include <server/client.qh>
 #include <server/miscfunctions.qh>
+#include <common/mapobjects/defs.qh>
 #include "../mapobjects/trigger/viewloc.qh"
+#include <server/main.qh>
 
 // client side physics
 bool Physics_Valid(string thecvar)
@@ -40,7 +43,7 @@ void Physics_UpdateStats(entity this)
        STAT(MOVEVARS_HIGHSPEED, this) = autocvar_g_movement_highspeed;
 
        MUTATOR_CALLHOOK(PlayerPhysics_UpdateStats, this);
-       float maxspd_mod = PHYS_HIGHSPEED(this) * ((this.swampslug.active) ? this.swampslug.swamp_slowdown : 1);
+       float maxspd_mod = PHYS_HIGHSPEED(this) * ((this.swampslug.active == ACTIVE_ACTIVE) ? this.swampslug.swamp_slowdown : 1);
         STAT(MOVEVARS_MAXSPEED, this) = Physics_ClientOption(this, "maxspeed", autocvar_sv_maxspeed) * maxspd_mod; // also slow walking
         if (autocvar_g_movement_highspeed_q3_compat) {
           STAT(MOVEVARS_AIRACCEL_QW, this) = Physics_ClientOption(this, "airaccel_qw", autocvar_sv_airaccel_qw);
index fc11cfab263185de02d7ccd67f3ce06069693fe3..da45243b63ae0b3f6b9738a71b418e40cbea92a4 100644 (file)
@@ -155,6 +155,10 @@ STATIC_INIT(PHYS_INPUT_BUTTON)
 #define WAS_ONGROUND(s)                     boolean((s).lastflags & FL_ONGROUND)
 #define WAS_ONSLICK(s)                      boolean((s).lastflags & FL_ONSLICK)
 
+#define IS_DUCKED(s)                        (boolean((s).flags & FL_DUCKED))
+#define SET_DUCKED(s)                       ((s).flags |= FL_DUCKED)
+#define UNSET_DUCKED(s)                     ((s).flags &= ~FL_DUCKED)
+
 #define ITEMS_STAT(s)                       ((s).items)
 
 .float teleport_time;
@@ -166,9 +170,6 @@ STATIC_INIT(PHYS_INPUT_BUTTON)
        string autocvar_cl_jumpspeedcap_min;
        string autocvar_cl_jumpspeedcap_max;
 
-       const int FL_WATERJUMP = 2048;  // player jumping out of water
-       const int FL_JUMPRELEASED = 4096;  // for jump debouncing
-
        .float watertype;
        .float waterlevel;
        .int items;
@@ -224,10 +225,6 @@ STATIC_INIT(PHYS_INPUT_BUTTON)
        #define PHYS_INPUT_BUTTON_BUTTON15(s)       boolean(input_buttons & BIT(17))
        #define PHYS_INPUT_BUTTON_BUTTON16(s)       boolean(input_buttons & BIT(18))
 
-       #define IS_DUCKED(s)                        (boolean((s).flags & FL_DUCKED))
-       #define SET_DUCKED(s)                       ((s).flags |= FL_DUCKED)
-       #define UNSET_DUCKED(s)                     ((s).flags &= ~FL_DUCKED)
-
        #define PHYS_INVEHICLE(s)                                       (boolean(hud != HUD_NORMAL))
 
        #define PHYS_JUMPSPEEDCAP_MIN               autocvar_cl_jumpspeedcap_min
@@ -249,6 +246,9 @@ STATIC_INIT(PHYS_INPUT_BUTTON)
        .string jumpspeedcap_min;
        .string jumpspeedcap_max;
 
+       // footstep interval
+       .float nextstep;
+
        #define PHYS_INPUT_ANGLES(s)                ((s).v_angle)
        #define PHYS_WORLD_ANGLES(s)                ((s).angles)
 
@@ -278,10 +278,6 @@ STATIC_INIT(PHYS_INPUT_BUTTON)
        #define PHYS_INPUT_BUTTON_BUTTON15(s)       (CS(s).button15)
        #define PHYS_INPUT_BUTTON_BUTTON16(s)       (CS(s).button16)
 
-       #define IS_DUCKED(s)                        ((s).crouch)
-       #define SET_DUCKED(s)                       ((s).crouch = true)
-       #define UNSET_DUCKED(s)                     ((s).crouch = false)
-
        #define PHYS_INVEHICLE(s)                                       (boolean((s).vehicle != NULL))
 
        #define PHYS_JUMPSPEEDCAP_MIN               autocvar_sv_jumpspeedcap_min
index 511ac46e66eedc7a8b35ce447b328b56f1a89ff7..3b8c97c4b81626f6d292155e1831269540559b36 100644 (file)
@@ -5,9 +5,11 @@
     #include "constants.qh"
     #include "util.qh"
     #include <common/weapons/_all.qh>
+    #include <server/client.qh>
     #include "../server/anticheat.qh"
-    #include "../server/defs.qh"
+    #include <common/stats.qh>
     #include "../server/scores.qh"
+       #include <server/world.qh>
     #include "../server/weapons/accuracy.qh"
 #endif
 
@@ -294,7 +296,7 @@ void PlayerStats_GameReport_Handler(entity fh, entity pass, float status)
                 * G: game type
                 * O: mod name (icon request) as in server browser
                 * M: map name
-                * I: match ID (see "matchid" in g_world.qc)
+                * I: match ID (see "matchid" in world.qc)
                 * S: "hostname" of the server
                 * C: number of "unpure" cvar changes
                 * U: UDP port number of the server
diff --git a/qcsrc/common/replicate.qc b/qcsrc/common/replicate.qc
new file mode 100644 (file)
index 0000000..c9d495b
--- /dev/null
@@ -0,0 +1 @@
+#include "replicate.qh"
diff --git a/qcsrc/common/replicate.qh b/qcsrc/common/replicate.qh
new file mode 100644 (file)
index 0000000..304cf38
--- /dev/null
@@ -0,0 +1,103 @@
+#pragma once
+
+// TODO: sort/merge these!
+#if defined(CSQC)
+       float autoswitch;
+       bool cvar_cl_allow_uid2name;
+       float cvar_cl_allow_uidtracking;
+       bool cvar_cl_allow_uidranking;
+       float cvar_cl_autoscreenshot;
+       float cvar_cl_autotaunt;
+       float cvar_cl_clippedspectating;
+       int cvar_cl_gunalign;
+       float cvar_cl_handicap;
+       float cvar_cl_jetpack_jump;
+       float cvar_cl_movement_track_canjump;
+       float cvar_cl_noantilag;
+       string cvar_cl_physics;
+       float cvar_cl_voice_directional;
+       float cvar_cl_voice_directional_taunt_attenuation;
+       float cvar_cl_weaponimpulsemode;
+
+       string cvar_g_xonoticversion;
+       string cvar_cl_weaponpriority;
+       string cvar_cl_weaponpriorities[10];
+       float cvar_cl_cts_noautoswitch;
+       bool cvar_cl_weapon_switch_reload;
+       bool cvar_cl_weapon_switch_fallback_to_impulse;
+#elif defined(SVQC)
+       .float cvar_cl_handicap;
+       .int cvar_cl_gunalign;
+       .float cvar_cl_clippedspectating;
+       .float cvar_cl_autoscreenshot;
+       .float cvar_cl_jetpack_jump;
+       .float cvar_cl_movement_track_canjump;
+       //.float cvar_cl_newusekeysupported;
+       .float cvar_cl_cts_noautoswitch;
+       .bool cvar_cl_weapon_switch_reload;
+       .bool cvar_cl_weapon_switch_fallback_to_impulse;
+
+       .string cvar_g_xonoticversion;
+       .string cvar_cl_weaponpriority;
+       .string cvar_cl_weaponpriorities[10];
+       .float cvar_cl_noantilag;
+
+       // WEAPONTODO
+       .float autoswitch;
+       .float cvar_cl_weaponimpulsemode;
+
+       .float cvar_cl_allow_uid2name;
+       .float cvar_cl_allow_uidtracking;
+       .bool cvar_cl_allow_uidranking;
+
+       .string cvar_cl_physics;
+
+       // autotaunt system
+       .float cvar_cl_autotaunt;
+       .float cvar_cl_voice_directional;
+       .float cvar_cl_voice_directional_taunt_attenuation;
+#endif
+
+#ifdef GAMEQC
+REPLICATE(autoswitch, bool, "cl_autoswitch");
+REPLICATE(cvar_cl_allow_uid2name, bool, "cl_allow_uid2name");
+REPLICATE(cvar_cl_allow_uidranking, bool, "cl_allow_uidranking");
+REPLICATE(cvar_cl_autoscreenshot, int, "cl_autoscreenshot");
+REPLICATE(cvar_cl_autotaunt, float, "cl_autotaunt");
+REPLICATE(cvar_cl_clippedspectating, bool, "cl_clippedspectating");
+REPLICATE(cvar_cl_gunalign, int, "cl_gunalign");
+REPLICATE(cvar_cl_handicap, float, "cl_handicap");
+REPLICATE(cvar_cl_jetpack_jump, bool, "cl_jetpack_jump");
+REPLICATE(cvar_cl_movement_track_canjump, bool, "cl_movement_track_canjump");
+REPLICATE(cvar_cl_noantilag, bool, "cl_noantilag");
+REPLICATE(cvar_cl_physics, string, "cl_physics");
+REPLICATE(cvar_cl_voice_directional, int, "cl_voice_directional");
+REPLICATE(cvar_cl_voice_directional_taunt_attenuation, float, "cl_voice_directional_taunt_attenuation");
+REPLICATE(cvar_cl_weaponimpulsemode, int, "cl_weaponimpulsemode");
+REPLICATE(cvar_g_xonoticversion, string, "g_xonoticversion");
+REPLICATE(cvar_cl_cts_noautoswitch, bool, "cl_cts_noautoswitch");
+REPLICATE(cvar_cl_weapon_switch_reload, bool, "cl_weapon_switch_reload");
+REPLICATE(cvar_cl_weapon_switch_fallback_to_impulse, bool, "cl_weapon_switch_fallback_to_impulse");
+/*
+// cvar cl_newusekeysupported doesn't exist
+float cvar_cl_newusekeysupported;
+REPLICATE(cvar_cl_newusekeysupported, bool, "cl_newusekeysupported");
+*/
+#ifdef CSQC
+// handled specially on the server
+REPLICATE(cvar_cl_allow_uidtracking, float, "cl_allow_uidtracking");
+#endif
+
+REPLICATE(cvar_cl_weaponpriority, string, "cl_weaponpriority");
+
+REPLICATE(cvar_cl_weaponpriorities[0], string, "cl_weaponpriority0");
+REPLICATE(cvar_cl_weaponpriorities[1], string, "cl_weaponpriority1");
+REPLICATE(cvar_cl_weaponpriorities[2], string, "cl_weaponpriority2");
+REPLICATE(cvar_cl_weaponpriorities[3], string, "cl_weaponpriority3");
+REPLICATE(cvar_cl_weaponpriorities[4], string, "cl_weaponpriority4");
+REPLICATE(cvar_cl_weaponpriorities[5], string, "cl_weaponpriority5");
+REPLICATE(cvar_cl_weaponpriorities[6], string, "cl_weaponpriority6");
+REPLICATE(cvar_cl_weaponpriorities[7], string, "cl_weaponpriority7");
+REPLICATE(cvar_cl_weaponpriorities[8], string, "cl_weaponpriority8");
+REPLICATE(cvar_cl_weaponpriorities[9], string, "cl_weaponpriority9");
+#endif
index 9ecac9f7c0bdd0bf2ee59dad460c6beea9905fc0..cda98d54d73f75b7432ae1769ea3c738a27cf840 100644 (file)
@@ -3,6 +3,7 @@
 #ifdef SVQC
 #include <server/autocvars.qh>
 #include <server/client.qh>
+#include <common/mapobjects/trigger/secret.qh>
 #endif
 
 // Full list of all stat constants, included in a single location for easy reference
@@ -63,8 +64,8 @@ REGISTER_STAT(KH_KEYS, int)
 #ifdef SVQC
 float W_WeaponRateFactor(entity this);
 float game_stopped;
-float game_starttime;
-float round_starttime;
+float game_starttime; //point in time when the countdown to game start is over
+float round_starttime; //point in time when the countdown to round start is over
 bool autocvar_g_allow_oldvortexbeam;
 int autocvar_leadlimit;
 #endif
@@ -100,8 +101,8 @@ REGISTER_STAT(VEHICLESTAT_AMMO2, int)
 REGISTER_STAT(VEHICLESTAT_RELOAD2, int)
 REGISTER_STAT(VEHICLESTAT_W2MODE, int)
 REGISTER_STAT(NADE_TIMER, float)
-REGISTER_STAT(SECRETS_TOTAL, float)
-REGISTER_STAT(SECRETS_FOUND, float)
+REGISTER_STAT(SECRETS_TOTAL, int, secrets_total)
+REGISTER_STAT(SECRETS_FOUND, int, secrets_found)
 REGISTER_STAT(RESPAWN_TIME, float)
 REGISTER_STAT(ROUNDSTARTTIME, float, round_starttime)
 REGISTER_STAT(MONSTERS_TOTAL, int)
@@ -199,6 +200,7 @@ int autocvar_sv_gameplayfix_slidemoveprojectiles = 1;
 int autocvar_sv_gameplayfix_grenadebouncedownslopes = 1;
 int autocvar_sv_gameplayfix_noairborncorpse = 1;
 int autocvar_sv_gameplayfix_noairborncorpse_allowsuspendeditems = 1;
+int autocvar_sv_gameplayfix_delayprojectiles = 0;
 #endif
 REGISTER_STAT(GAMEPLAYFIX_DOWNTRACEONGROUND, int, autocvar_sv_gameplayfix_downtracesupportsongroundflag)
 REGISTER_STAT(GAMEPLAYFIX_EASIERWATERJUMP, int, autocvar_sv_gameplayfix_easierwaterjump)
@@ -212,6 +214,7 @@ REGISTER_STAT(GAMEPLAYFIX_SLIDEMOVEPROJECTILES, int, autocvar_sv_gameplayfix_sli
 REGISTER_STAT(GAMEPLAYFIX_GRENADEBOUNCESLOPES, int, autocvar_sv_gameplayfix_grenadebouncedownslopes)
 REGISTER_STAT(GAMEPLAYFIX_NOAIRBORNCORPSE, int, autocvar_sv_gameplayfix_noairborncorpse)
 REGISTER_STAT(NOAIRBORNCORPSE_ALLOWSUSPENDED, int, autocvar_sv_gameplayfix_noairborncorpse_allowsuspendeditems)
+REGISTER_STAT(GAMEPLAYFIX_DELAYPROJECTILES, int, autocvar_sv_gameplayfix_delayprojectiles)
 
 REGISTER_STAT(MOVEVARS_JUMPSTEP, int, cvar("sv_jumpstep"))
 REGISTER_STAT(NOSTEP, int, cvar("sv_nostep"))
diff --git a/qcsrc/common/t_items.qc b/qcsrc/common/t_items.qc
deleted file mode 100644 (file)
index ef2923b..0000000
+++ /dev/null
@@ -1,1924 +0,0 @@
-#include "t_items.qh"
-
-#include "items/_mod.qh"
-
-#if defined(SVQC)
-
-    #include "../server/bot/api.qh"
-
-    #include <server/mutators/_mod.qh>
-
-    #include "../server/weapons/common.qh"
-    #include "../server/weapons/selection.qh"
-    #include "../server/weapons/weaponsystem.qh"
-
-    #include "constants.qh"
-    #include <common/deathtypes/all.qh>
-    #include <common/notifications/all.qh>
-       #include "mapobjects/subs.qh"
-    #include "util.qh"
-
-    #include <common/monsters/_mod.qh>
-
-    #include <common/weapons/_all.qh>
-
-    #include <common/mutators/mutator/buffs/buffs.qh>
-       #include <common/mutators/mutator/buffs/sv_buffs.qh>
-
-    #include "../lib/warpzone/util_server.qh"
-#elif defined(CSQC)
-       #include "physics/movetypes/movetypes.qh"
-       #include <common/weapons/_all.qh>
-       #include "../lib/csqcmodel/cl_model.qh"
-       #include "../lib/csqcmodel/common.qh"
-#endif
-
-REGISTER_NET_LINKED(ENT_CLIENT_ITEM)
-
-#ifdef CSQC
-bool autocvar_cl_ghost_items_vehicle = true;
-.vector item_glowmod;
-.bool item_simple; // probably not really needed, but better safe than sorry
-void Item_SetAlpha(entity this)
-{
-       bool veh_hud = (hud && autocvar_cl_ghost_items_vehicle);
-
-       if(!veh_hud && (this.ItemStatus & ITS_AVAILABLE))
-       {
-               this.alpha = 1;
-               this.colormod = '1 1 1';
-               this.glowmod = this.item_glowmod;
-       }
-       else
-       {
-               this.alpha = autocvar_cl_ghost_items;
-               this.colormod = this.glowmod = autocvar_cl_ghost_items_color;
-       }
-
-       if((!veh_hud) && (this.ItemStatus & ITS_STAYWEP))
-       {
-               this.colormod = this.glowmod = autocvar_cl_weapon_stay_color;
-               this.alpha = autocvar_cl_weapon_stay_alpha;
-       }
-
-       this.drawmask = ((this.alpha <= 0) ? 0 : MASK_NORMAL);
-}
-
-void ItemDraw(entity this)
-{
-    if(this.gravity)
-    {
-        Movetype_Physics_MatchServer(this, false);
-        if(IS_ONGROUND(this))
-        { // For some reason avelocity gets set to '0 0 0' here ...
-            this.oldorigin = this.origin;
-            this.gravity = 0;
-
-            if(autocvar_cl_animate_items)
-            { // ... so reset it if animations are requested.
-                if(this.ItemStatus & ITS_ANIMATE1)
-                    this.avelocity = '0 180 0';
-
-                if(this.ItemStatus & ITS_ANIMATE2)
-                    this.avelocity = '0 -90 0';
-            }
-
-            // delay is for blocking item's position for a while;
-            // it's a workaround for dropped weapons that receive the position
-            // another time right after they spawn overriding animation position
-            this.onground_time = time + 0.5;
-        }
-    }
-    else if (autocvar_cl_animate_items && !this.item_simple) // no bobbing applied to simple items, for consistency's sake (no visual difference between ammo and weapons)
-    {
-        if(this.ItemStatus & ITS_ANIMATE1)
-        {
-               this.angles += this.avelocity * frametime;
-            float fade_in = bound(0, time - this.onground_time, 1);
-            setorigin(this, this.oldorigin + fade_in * ('0 0 10' + '0 0 8' * sin((time - this.onground_time) * 2)));
-        }
-
-        if(this.ItemStatus & ITS_ANIMATE2)
-        {
-               this.angles += this.avelocity * frametime;
-            float fade_in = bound(0, time - this.onground_time, 1);
-            setorigin(this, this.oldorigin + fade_in * ('0 0 8' + '0 0 4' * sin((time - this.onground_time) * 3)));
-        }
-    }
-
-    Item_SetAlpha(this);
-}
-
-void Item_PreDraw(entity this)
-{
-       if(warpzone_warpzones_exist)
-       {
-               setpredraw(this, func_null); // no need to keep running this
-               return;
-       }
-       float alph;
-       vector org = getpropertyvec(VF_ORIGIN);
-       //if(!checkpvs(org, this)) // this makes sense as long as we don't support recursive warpzones
-               //alph = 0; // this shouldn't be needed, since items behind walls are culled anyway
-       if(this.fade_start)
-       {
-               if(vdist(org - this.origin, >, this.fade_end))
-                       alph = 0; // save on some processing
-               else if(vdist(org - this.origin, <, this.fade_start))
-                       alph = 1; // more processing saved
-               else
-                       alph = bound(0, (this.fade_end - vlen(org - this.origin - 0.5 * (this.mins + this.maxs))) / (this.fade_end - this.fade_start), 1);
-       }
-       else
-               alph = 1;
-       //printf("%v <-> %v\n", view_origin, this.origin + 0.5 * (this.mins + this.maxs));
-       if(!hud && (this.ItemStatus & ITS_AVAILABLE))
-               this.alpha = alph;
-       if(alph <= 0)
-               this.drawmask = 0;
-       //else
-               //this.drawmask = MASK_NORMAL; // reset by the setalpha function
-}
-
-void ItemRemove(entity this)
-{
-       strfree(this.mdl);
-}
-
-HashMap ENT_CLIENT_ITEM_simple;
-STATIC_INIT(ENT_CLIENT_ITEM_simple)
-{
-       HM_NEW(ENT_CLIENT_ITEM_simple);
-}
-SHUTDOWN(ENT_CLIENT_ITEM_simple)
-{
-       HM_DELETE(ENT_CLIENT_ITEM_simple);
-}
-
-NET_HANDLE(ENT_CLIENT_ITEM, bool isnew)
-{
-    int sf = ReadByte();
-
-    if(sf & ISF_LOCATION)
-    {
-        this.origin = ReadVector();
-        setorigin(this, this.origin);
-        this.oldorigin = this.origin;
-    }
-
-    if(sf & ISF_ANGLES)
-    {
-        this.angles_x = ReadAngle();
-        this.angles_y = ReadAngle();
-        this.angles_z = ReadAngle();
-    }
-
-    if(sf & ISF_SIZE)
-    {
-        setsize(this, '-16 -16 0', '16 16 48');
-    }
-
-    if(sf & ISF_STATUS) // need to read/write status first so model can handle simple, fb etc.
-    {
-        this.ItemStatus = ReadByte();
-
-        Item_SetAlpha(this);
-
-        if(this.ItemStatus & ITS_ALLOWFB)
-            this.effects |= EF_FULLBRIGHT;
-        else
-            this.effects &= ~EF_FULLBRIGHT;
-
-        if(this.ItemStatus & ITS_GLOW)
-        {
-            if(this.ItemStatus & ITS_AVAILABLE)
-                this.effects |= (EF_ADDITIVE | EF_FULLBRIGHT);
-            else
-                this.effects &= ~(EF_ADDITIVE | EF_FULLBRIGHT);
-        }
-    }
-
-    if(sf & ISF_MODEL)
-    {
-        this.drawmask  = MASK_NORMAL;
-               set_movetype(this, MOVETYPE_TOSS);
-               if (isnew) IL_PUSH(g_drawables, this);
-        this.draw       = ItemDraw;
-        this.solid = SOLID_TRIGGER;
-        //this.flags |= FL_ITEM;
-
-        this.fade_end = ReadShort();
-        this.fade_start = ReadShort();
-        if(!warpzone_warpzones_exist && this.fade_start && !autocvar_cl_items_nofade)
-               setpredraw(this, Item_PreDraw);
-
-               strfree(this.mdl);
-
-        string _fn = ReadString();
-        this.item_simple = false; // reset it!
-
-        if(autocvar_cl_simple_items && (this.ItemStatus & ITS_ALLOWSI))
-        {
-            string _fn2 = substring(_fn, 0 , strlen(_fn) -4);
-            this.item_simple = true;
-
-                       #define extensions(x) \
-                               x(md3) \
-                               x(dpm) \
-                               x(iqm) \
-                               x(mdl) \
-                               /**/
-                       #define tryext(ext) { \
-                               string s = strcat(_fn2, autocvar_cl_simpleitems_postfix, "." #ext); \
-                               string cached = HM_gets(ENT_CLIENT_ITEM_simple, s); \
-                               if (cached == "") { \
-                                       HM_sets(ENT_CLIENT_ITEM_simple, s, cached = fexists(s) ? "1" : "0"); \
-                               } \
-                               if (cached != "0") { \
-                                       strcpy(this.mdl, s); \
-                                       break; \
-                               } \
-                       }
-                       do {
-                               extensions(tryext);
-                               this.item_simple = false;
-                LOG_TRACEF("Simple item requested for %s but no model exists for it", _fn);
-                       } while (0);
-                       #undef tryext
-                       #undef extensions
-        }
-
-        if(!this.item_simple)
-            strcpy(this.mdl, _fn);
-
-        if(this.mdl == "")
-            LOG_WARNF("this.mdl is unset for item %s", this.classname);
-
-        precache_model(this.mdl);
-        _setmodel(this, this.mdl);
-
-        setsize(this, '-16 -16 0', '16 16 48');
-    }
-
-    if(sf & ISF_COLORMAP)
-    {
-        this.colormap = ReadShort();
-        this.item_glowmod_x = ReadByte() / 255.0;
-        this.item_glowmod_y = ReadByte() / 255.0;
-        this.item_glowmod_z = ReadByte() / 255.0;
-    }
-
-    if(sf & ISF_DROP)
-    {
-        this.gravity = 1;
-        this.pushable = true;
-        //this.angles = '0 0 0';
-        set_movetype(this, MOVETYPE_TOSS);
-        this.velocity = ReadVector();
-        setorigin(this, this.oldorigin);
-
-        if(!this.move_time)
-        {
-            this.move_time = time;
-            this.spawntime = time;
-        }
-        else
-            this.move_time = max(this.move_time, time);
-    }
-
-    if(autocvar_cl_animate_items)
-    {
-        if(this.ItemStatus & ITS_ANIMATE1)
-            this.avelocity = '0 180 0';
-
-        if(this.ItemStatus & ITS_ANIMATE2)
-            this.avelocity = '0 -90 0';
-    }
-
-    this.entremove = ItemRemove;
-
-    return true;
-}
-
-#endif
-
-#ifdef SVQC
-bool ItemSend(entity this, entity to, int sf)
-{
-       if(this.gravity)
-               sf |= ISF_DROP;
-       else
-               sf &= ~ISF_DROP;
-
-       WriteHeader(MSG_ENTITY, ENT_CLIENT_ITEM);
-       WriteByte(MSG_ENTITY, sf);
-
-       //WriteByte(MSG_ENTITY, this.cnt);
-       if(sf & ISF_LOCATION)
-       {
-               WriteVector(MSG_ENTITY, this.origin);
-       }
-
-       if(sf & ISF_ANGLES)
-       {
-               WriteAngle(MSG_ENTITY, this.angles_x);
-               WriteAngle(MSG_ENTITY, this.angles_y);
-               WriteAngle(MSG_ENTITY, this.angles_z);
-       }
-
-       // sets size on the client, unused on server
-       //if(sf & ISF_SIZE)
-
-       if(sf & ISF_STATUS)
-               WriteByte(MSG_ENTITY, this.ItemStatus);
-
-       if(sf & ISF_MODEL)
-       {
-               WriteShort(MSG_ENTITY, this.fade_end);
-               WriteShort(MSG_ENTITY, this.fade_start);
-
-               if(this.mdl == "")
-                       LOG_TRACE("^1WARNING!^7 this.mdl is unset for item ", this.classname, "expect a crash just about now");
-
-               WriteString(MSG_ENTITY, this.mdl);
-       }
-
-
-       if(sf & ISF_COLORMAP)
-       {
-               WriteShort(MSG_ENTITY, this.colormap);
-               WriteByte(MSG_ENTITY, this.glowmod.x * 255.0);
-               WriteByte(MSG_ENTITY, this.glowmod.y * 255.0);
-               WriteByte(MSG_ENTITY, this.glowmod.z * 255.0);
-       }
-
-       if(sf & ISF_DROP)
-       {
-               WriteVector(MSG_ENTITY, this.velocity);
-       }
-
-       return true;
-}
-
-void ItemUpdate(entity this)
-{
-       this.oldorigin = this.origin;
-       this.SendFlags |= ISF_LOCATION;
-}
-
-void UpdateItemAfterTeleport(entity this)
-{
-       if(getSendEntity(this) == ItemSend)
-               ItemUpdate(this);
-}
-
-bool have_pickup_item(entity this)
-{
-       if(this.itemdef.instanceOfPowerup)
-       {
-               if(autocvar_g_powerups > 0)
-                       return true;
-               if(autocvar_g_powerups == 0)
-                       return false;
-       }
-       else
-       {
-               if(autocvar_g_pickup_items > 0)
-                       return true;
-               if(autocvar_g_pickup_items == 0)
-                       return false;
-               if(g_weaponarena)
-                       if(STAT(WEAPONS, this) || this.itemdef.instanceOfAmmo) // no item or ammo pickups in weaponarena
-                               return false;
-       }
-       return true;
-}
-
-void Item_Show(entity e, int mode)
-{
-       e.effects &= ~(EF_ADDITIVE | EF_STARDUST | EF_FULLBRIGHT | EF_NODEPTHTEST);
-       e.ItemStatus &= ~ITS_STAYWEP;
-       entity def = e.itemdef;
-       if (mode > 0)
-       {
-               // make the item look normal, and be touchable
-               e.model = e.mdl;
-               e.solid = SOLID_TRIGGER;
-               e.spawnshieldtime = 1;
-               e.ItemStatus |= ITS_AVAILABLE;
-       }
-       else if (mode < 0)
-       {
-               // hide the item completely
-               e.model = string_null;
-               e.solid = SOLID_NOT;
-               e.spawnshieldtime = 1;
-               e.ItemStatus &= ~ITS_AVAILABLE;
-       }
-       else
-       {
-               bool nostay = def.instanceOfWeaponPickup ? !!(def.m_weapon.m_wepset & WEPSET_SUPERWEAPONS) : false // no weapon-stay on superweapons
-                       || e.team // weapon stay isn't supported for teamed weapons
-                       ;
-               if(def.instanceOfWeaponPickup && !nostay && g_weapon_stay)
-               {
-                       // make the item translucent and not touchable
-                       e.model = e.mdl;
-                       e.solid = SOLID_TRIGGER; // can STILL be picked up!
-                       e.effects |= EF_STARDUST;
-                       e.spawnshieldtime = 0; // field indicates whether picking it up may give you anything other than the weapon
-                       e.ItemStatus |= (ITS_AVAILABLE | ITS_STAYWEP);
-               }
-               else
-               {
-                       //setmodel(e, "null");
-                       e.solid = SOLID_NOT;
-                       e.colormod = '0 0 0';
-                       //e.glowmod = e.colormod;
-                       e.spawnshieldtime = 1;
-                       e.ItemStatus &= ~ITS_AVAILABLE;
-               }
-       }
-
-       if (def.m_glow)
-               e.ItemStatus |= ITS_GLOW;
-
-       if (autocvar_g_nodepthtestitems)
-               e.effects |= EF_NODEPTHTEST;
-
-       if (autocvar_g_fullbrightitems)
-               e.ItemStatus |= ITS_ALLOWFB;
-       else
-               e.ItemStatus &= ~ITS_ALLOWFB;
-
-       if (autocvar_sv_simple_items)
-               e.ItemStatus |= ITS_ALLOWSI;
-
-       // relink entity (because solid may have changed)
-       setorigin(e, e.origin);
-       e.SendFlags |= ISF_STATUS;
-}
-
-void Item_Think(entity this)
-{
-       this.nextthink = time;
-       if(this.origin != this.oldorigin)
-               ItemUpdate(this);
-}
-
-bool Item_ItemsTime_SpectatorOnly(GameItem it);
-bool Item_ItemsTime_Allow(GameItem it);
-float Item_ItemsTime_UpdateTime(entity e, float t);
-void Item_ItemsTime_SetTime(entity e, float t);
-void Item_ItemsTime_SetTimesForAllPlayers();
-
-void Item_Respawn(entity this)
-{
-       Item_Show(this, 1);
-       sound(this, CH_TRIGGER, this.itemdef.m_respawnsound, VOL_BASE, ATTEN_NORM);     // play respawn sound
-       setorigin(this, this.origin);
-
-       if (Item_ItemsTime_Allow(this.itemdef) || (STAT(WEAPONS, this) & WEPSET_SUPERWEAPONS))
-       {
-               float t = Item_ItemsTime_UpdateTime(this, 0);
-               Item_ItemsTime_SetTime(this, t);
-               Item_ItemsTime_SetTimesForAllPlayers();
-       }
-
-       setthink(this, Item_Think);
-       this.nextthink = time;
-
-       //Send_Effect(EFFECT_ITEM_RESPAWN, this.origin + this.mins_z * '0 0 1' + '0 0 48', '0 0 0', 1);
-       Send_Effect(EFFECT_ITEM_RESPAWN, CENTER_OR_VIEWOFS(this), '0 0 0', 1);
-}
-
-void Item_RespawnCountdown(entity this)
-{
-       if(this.item_respawncounter >= ITEM_RESPAWN_TICKS)
-       {
-               if(this.waypointsprite_attached)
-                       WaypointSprite_Kill(this.waypointsprite_attached);
-               Item_Respawn(this);
-       }
-       else
-       {
-               this.nextthink = time + 1;
-               this.item_respawncounter += 1;
-               if(this.item_respawncounter == 1)
-               {
-                       do {
-                               {
-                                       entity wi = REGISTRY_GET(Weapons, this.weapon);
-                                       if (wi != WEP_Null) {
-                                               entity wp = WaypointSprite_Spawn(WP_Weapon, 0, 0, this, '0 0 64', NULL, 0, this, waypointsprite_attached, true, RADARICON_Weapon);
-                                               wp.wp_extra = wi.m_id;
-                                               break;
-                                       }
-                               }
-                               {
-                                       entity ii = this.itemdef;
-                                       if (ii != NULL) {
-                                               entity wp = WaypointSprite_Spawn(WP_Item, 0, 0, this, '0 0 64', NULL, 0, this, waypointsprite_attached, true, RADARICON_Item);
-                                               wp.wp_extra = ii.m_id;
-                                               break;
-                                       }
-                               }
-                       } while (0);
-                       bool mutator_returnvalue = MUTATOR_CALLHOOK(Item_RespawnCountdown, this);
-            if(this.waypointsprite_attached)
-            {
-                GameItem def = this.itemdef;
-                if (Item_ItemsTime_SpectatorOnly(def) && !mutator_returnvalue)
-                    WaypointSprite_UpdateRule(this.waypointsprite_attached, 0, SPRITERULE_SPECTATOR);
-                WaypointSprite_UpdateBuildFinished(this.waypointsprite_attached, time + ITEM_RESPAWN_TICKS);
-            }
-               }
-
-               if(this.waypointsprite_attached)
-               {
-                       FOREACH_CLIENT(IS_REAL_CLIENT(it), {
-                               if(this.waypointsprite_attached.waypointsprite_visible_for_player(this.waypointsprite_attached, it, it))
-                               {
-                                       msg_entity = it;
-                                       soundto(MSG_ONE, this, CH_TRIGGER, SND(ITEMRESPAWNCOUNTDOWN), VOL_BASE, ATTEN_NORM, 0); // play respawn sound
-                               }
-                       });
-
-                       WaypointSprite_Ping(this.waypointsprite_attached);
-                       //WaypointSprite_UpdateHealth(this.waypointsprite_attached, this.item_respawncounter);
-               }
-       }
-}
-
-void Item_RespawnThink(entity this)
-{
-       this.nextthink = time;
-       if(this.origin != this.oldorigin)
-               ItemUpdate(this);
-
-       if(time >= this.wait)
-               Item_Respawn(this);
-}
-
-void Item_ScheduleRespawnIn(entity e, float t)
-{
-       // if the respawn time is longer than 10 seconds, show a waypoint, otherwise, just respawn normally
-       if ((Item_ItemsTime_Allow(e.itemdef) || (STAT(WEAPONS, e) & WEPSET_SUPERWEAPONS) || MUTATOR_CALLHOOK(Item_ScheduleRespawn, e, t)) && (t - ITEM_RESPAWN_TICKS) > 0)
-       {
-               setthink(e, Item_RespawnCountdown);
-               e.nextthink = time + max(0, t - ITEM_RESPAWN_TICKS);
-               e.scheduledrespawntime = e.nextthink + ITEM_RESPAWN_TICKS;
-               e.item_respawncounter = 0;
-               if(Item_ItemsTime_Allow(e.itemdef) || (STAT(WEAPONS, e) & WEPSET_SUPERWEAPONS))
-               {
-                       t = Item_ItemsTime_UpdateTime(e, e.scheduledrespawntime);
-                       Item_ItemsTime_SetTime(e, t);
-                       Item_ItemsTime_SetTimesForAllPlayers();
-               }
-       }
-       else
-       {
-               setthink(e, Item_RespawnThink);
-               e.nextthink = time;
-               e.scheduledrespawntime = time + t;
-               e.wait = time + t;
-
-               if(Item_ItemsTime_Allow(e.itemdef) || (STAT(WEAPONS, e) & WEPSET_SUPERWEAPONS))
-               {
-                       t = Item_ItemsTime_UpdateTime(e, e.scheduledrespawntime);
-                       Item_ItemsTime_SetTime(e, t);
-                       Item_ItemsTime_SetTimesForAllPlayers();
-               }
-       }
-}
-
-AUTOCVAR(g_pickup_respawntime_scaling_reciprocal, float, 0.0, "Multiply respawn time by `reciprocal / (p + offset) + linear` where `p` is the current number of players, takes effect with 2 or more players present, `reciprocal` (with `offset` and `linear` set to 0) can be used to achieve a constant number of items spawned *per player*");
-AUTOCVAR(g_pickup_respawntime_scaling_offset, float, 0.0, "Multiply respawn time by `reciprocal / (p + offset) + linear` where `p` is the current number of players, takes effect with 2 or more players present, `offset` offsets the curve left or right - the results are not intuitive and I recommend plotting the respawn time and the number of items per player to see what's happening");
-AUTOCVAR(g_pickup_respawntime_scaling_linear, float, 1.0, "Multiply respawn time by `reciprocal / (p + offset) + linear` where `p` is the current number of players, takes effect with 2 or more players present, `linear` can be used to simply scale the respawn time linearly");
-
-/// Adjust respawn time according to the number of players.
-float adjust_respawntime(float normal_respawntime) {
-       float r = autocvar_g_pickup_respawntime_scaling_reciprocal;
-       float o = autocvar_g_pickup_respawntime_scaling_offset;
-       float l = autocvar_g_pickup_respawntime_scaling_linear;
-
-       if (r == 0 && l == 1) {
-               return normal_respawntime;
-       }
-
-       entity balance = TeamBalance_CheckAllowedTeams(NULL);
-       TeamBalance_GetTeamCounts(balance, NULL);
-       int players = 0;
-       for (int i = 1; i <= NUM_TEAMS; ++i)
-       {
-               if (TeamBalance_IsTeamAllowed(balance, i))
-               {
-                       players += TeamBalance_GetNumberOfPlayers(balance, i);
-               }
-       }
-       TeamBalance_Destroy(balance);
-
-       if (players >= 2) {
-               return normal_respawntime * (r / (players + o) + l);
-       } else {
-               return normal_respawntime;
-       }
-}
-
-void Item_ScheduleRespawn(entity e)
-{
-       if(e.respawntime > 0)
-       {
-               Item_Show(e, 0);
-
-               float adjusted_respawntime = adjust_respawntime(e.respawntime);
-               //LOG_INFOF("item %s will respawn in %f", e.classname, adjusted_respawntime);
-
-               // range: adjusted_respawntime - respawntimejitter .. adjusted_respawntime + respawntimejitter
-               float respawn_in = adjusted_respawntime + crandom() * e.respawntimejitter;
-               Item_ScheduleRespawnIn(e, respawn_in);
-       }
-       else // if respawntime is -1, this item does not respawn
-               Item_Show(e, -1);
-}
-
-AUTOCVAR(g_pickup_respawntime_initial_random, int, 1,
-       "For items that don't start spawned: 0: spawn after their normal respawntime; 1: spawn after `random * respawntime` with the *same* random; 2: same as 1 but each item has separate random");
-
-void Item_ScheduleInitialRespawn(entity e)
-{
-       Item_Show(e, 0);
-
-       float spawn_in;
-       if (autocvar_g_pickup_respawntime_initial_random == 0)
-       {
-               // range: respawntime .. respawntime + respawntimejitter
-               spawn_in = e.respawntime + random() * e.respawntimejitter;
-       }
-       else
-       {
-               float rnd;
-               if (autocvar_g_pickup_respawntime_initial_random == 1)
-               {
-                       static float shared_random = 0;
-                       // NOTE this code works only if items are scheduled at the same time (normal case)
-                       // NOTE2 random() can't return exactly 1 so this check always work as intended
-                       if (!shared_random || floor(time) > shared_random)
-                               shared_random = floor(time) + random();
-                       rnd = shared_random - floor(time);
-               }
-               else
-                       rnd = random();
-
-               // range:
-               // if respawntime >= ITEM_RESPAWN_TICKS: ITEM_RESPAWN_TICKS .. respawntime + respawntimejitter
-               // else: 0 .. ITEM_RESPAWN_TICKS
-               // this is to prevent powerups spawning unexpectedly without waypoints
-               spawn_in = ITEM_RESPAWN_TICKS + rnd * (e.respawntime + e.respawntimejitter - ITEM_RESPAWN_TICKS);
-       }
-
-       Item_ScheduleRespawnIn(e, max(0, game_starttime - time) + ((e.respawntimestart) ? e.respawntimestart : spawn_in));
-}
-
-void GiveRandomWeapons(entity receiver, int num_weapons, string weapon_names,
-       entity ammo_entity)
-{
-       if (num_weapons == 0)
-       {
-               return;
-       }
-       int num_potential_weapons = tokenize_console(weapon_names);
-       for (int give_attempt = 0; give_attempt < num_weapons; ++give_attempt)
-       {
-               RandomSelection_Init();
-               for (int weapon_index = 0; weapon_index < num_potential_weapons;
-                       ++weapon_index)
-               {
-                       string weapon = argv(weapon_index);
-                       FOREACH(Weapons, it != WEP_Null,
-                       {
-                               // Finding a weapon which player doesn't have.
-                               if (!(STAT(WEAPONS, receiver) & it.m_wepset) && (it.netname == weapon))
-                               {
-                                       RandomSelection_AddEnt(it, 1, 1);
-                                       break;
-                               }
-                       });
-               }
-               if (RandomSelection_chosen_ent == NULL)
-               {
-                       return;
-               }
-               STAT(WEAPONS, receiver) |= RandomSelection_chosen_ent.m_wepset;
-               if (RandomSelection_chosen_ent.ammo_type == RES_NONE)
-               {
-                       continue;
-               }
-               if (GetResource(receiver,
-                       RandomSelection_chosen_ent.ammo_type) != 0)
-               {
-                       continue;
-               }
-               GiveResource(receiver, RandomSelection_chosen_ent.ammo_type,
-                       GetResource(ammo_entity,
-                       RandomSelection_chosen_ent.ammo_type));
-       }
-}
-
-bool Item_GiveAmmoTo(entity item, entity player, int res_type, float ammomax)
-{
-       float amount = GetResource(item, res_type);
-       if (amount == 0)
-       {
-               return false;
-       }
-       float player_amount = GetResource(player, res_type);
-       if (item.spawnshieldtime)
-       {
-               if ((player_amount >= ammomax) && (item.pickup_anyway <= 0))
-                       return false;
-       }
-       else if (g_weapon_stay == 2)
-       {
-               ammomax = min(amount, ammomax);
-               if(player_amount >= ammomax)
-                       return false;
-       }
-       else
-               return false;
-       if (amount < 0)
-               TakeResourceWithLimit(player, res_type, -amount, ammomax);
-       else
-               GiveResourceWithLimit(player, res_type, amount, ammomax);
-       return true;
-}
-
-bool Item_GiveTo(entity item, entity player)
-{
-       // if nothing happens to player, just return without taking the item
-       int _switchweapon = 0;
-       // in case the player has autoswitch enabled do the following:
-       // if the player is using their best weapon before items are given, they
-       // probably want to switch to an even better weapon after items are given
-
-       if(CS(player).autoswitch)
-       {
-               for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
-               {
-                       .entity weaponentity = weaponentities[slot];
-                       if(player.(weaponentity).m_weapon != WEP_Null || slot == 0)
-                       {
-                               if(player.(weaponentity).m_switchweapon == w_getbestweapon(player, weaponentity))
-                                       _switchweapon |= BIT(slot);
-
-                               if(!(STAT(WEAPONS, player) & WepSet_FromWeapon(player.(weaponentity).m_switchweapon)))
-                                       _switchweapon |= BIT(slot);
-                       }
-               }
-       }
-       bool pickedup = false;
-       pickedup |= Item_GiveAmmoTo(item, player, RES_HEALTH, item.max_health);
-       pickedup |= Item_GiveAmmoTo(item, player, RES_ARMOR, item.max_armorvalue);
-       pickedup |= Item_GiveAmmoTo(item, player, RES_SHELLS, g_pickup_shells_max);
-       pickedup |= Item_GiveAmmoTo(item, player, RES_BULLETS, g_pickup_nails_max);
-       pickedup |= Item_GiveAmmoTo(item, player, RES_ROCKETS, g_pickup_rockets_max);
-       pickedup |= Item_GiveAmmoTo(item, player, RES_CELLS, g_pickup_cells_max);
-       pickedup |= Item_GiveAmmoTo(item, player, RES_PLASMA, g_pickup_plasma_max);
-       pickedup |= Item_GiveAmmoTo(item, player, RES_FUEL, g_pickup_fuel_max);
-       if (item.itemdef.instanceOfWeaponPickup)
-       {
-               WepSet w;
-               w = STAT(WEAPONS, item);
-               w &= ~STAT(WEAPONS, player);
-
-               if (w || (item.spawnshieldtime && item.pickup_anyway > 0))
-               {
-                       pickedup = true;
-                       FOREACH(Weapons, it != WEP_Null, {
-                               if(w & (it.m_wepset))
-                               {
-                                       for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
-                                       {
-                                               .entity weaponentity = weaponentities[slot];
-                                               if(player.(weaponentity).m_weapon != WEP_Null || slot == 0)
-                                                       W_DropEvent(wr_pickup, player, it.m_id, item, weaponentity);
-                                       }
-                                       W_GiveWeapon(player, it.m_id);
-                               }
-                       });
-               }
-       }
-
-       if (item.itemdef.instanceOfPowerup)
-       {
-               if ((item.itemdef == ITEM_JetpackRegen) && !(player.items & IT_FUEL_REGEN))
-                       Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_ITEM_FUELREGEN_GOT);
-               else if ((item.itemdef == ITEM_Jetpack) && !(player.items & IT_JETPACK))
-                       Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_ITEM_JETPACK_GOT);
-       }
-
-       int its;
-       if((its = (item.items - (item.items & player.items)) & IT_PICKUPMASK))
-       {
-               pickedup = true;
-               player.items |= its;
-               // TODO: we probably want to show a message in the console, but not this one!
-               //Send_Notification(NOTIF_ONE, player, MSG_INFO, INFO_ITEM_WEAPON_GOT, item.netname);
-       }
-
-       if (item.strength_finished)
-       {
-               pickedup = true;
-               STAT(STRENGTH_FINISHED, player) = max(STAT(STRENGTH_FINISHED, player), time) + item.strength_finished;
-       }
-       if (item.invincible_finished)
-       {
-               pickedup = true;
-               STAT(INVINCIBLE_FINISHED, player) = max(STAT(INVINCIBLE_FINISHED, player), time) + item.invincible_finished;
-       }
-       if (item.superweapons_finished)
-       {
-               pickedup = true;
-               STAT(SUPERWEAPONS_FINISHED, player) = max(STAT(SUPERWEAPONS_FINISHED, player), time) + item.superweapons_finished;
-       }
-
-       // always eat teamed entities
-       if(item.team)
-               pickedup = true;
-
-       if (!pickedup)
-               return false;
-
-       // crude hack to enforce switching weapons
-       if(g_cts && item.itemdef.instanceOfWeaponPickup && !CS(player).cvar_cl_cts_noautoswitch)
-       {
-               for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
-               {
-                       .entity weaponentity = weaponentities[slot];
-                       if(player.(weaponentity).m_weapon != WEP_Null || slot == 0)
-                               W_SwitchWeapon_Force(player, REGISTRY_GET(Weapons, item.weapon), weaponentity);
-               }
-               return true;
-       }
-
-       if(_switchweapon)
-       {
-               for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
-               {
-                       .entity weaponentity = weaponentities[slot];
-                       if(_switchweapon & BIT(slot))
-                       if(player.(weaponentity).m_switchweapon != w_getbestweapon(player, weaponentity))
-                               W_SwitchWeapon_Force(player, w_getbestweapon(player, weaponentity), weaponentity);
-               }
-       }
-
-       return true;
-}
-
-void Item_Touch(entity this, entity toucher)
-{
-       // remove the item if it's currnetly in a NODROP brush or hits a NOIMPACT surface (such as sky)
-       if (Item_IsLoot(this))
-       {
-               if (ITEM_TOUCH_NEEDKILL())
-               {
-                       delete(this);
-                       return;
-               }
-       }
-
-       if(!(toucher.flags & FL_PICKUPITEMS)
-       || STAT(FROZEN, toucher)
-       || IS_DEAD(toucher)
-       || (this.solid != SOLID_TRIGGER)
-       || (this.owner == toucher)
-       || (time < this.item_spawnshieldtime)
-       ) { return; }
-
-       switch (MUTATOR_CALLHOOK(ItemTouch, this, toucher))
-       {
-               case MUT_ITEMTOUCH_RETURN: { return; }
-               case MUT_ITEMTOUCH_PICKUP: { toucher = M_ARGV(1, entity); goto pickup; }
-       }
-
-       toucher = M_ARGV(1, entity);
-
-       if (Item_IsExpiring(this))
-       {
-               this.strength_finished = max(0, this.strength_finished - time);
-               this.invincible_finished = max(0, this.invincible_finished - time);
-               this.superweapons_finished = max(0, this.superweapons_finished - time);
-       }
-       bool gave = ITEM_HANDLE(Pickup, this.itemdef, this, toucher);
-       if (!gave)
-       {
-               if (Item_IsExpiring(this))
-               {
-                       // undo what we did above
-                       this.strength_finished += time;
-                       this.invincible_finished += time;
-                       this.superweapons_finished += time;
-               }
-               return;
-       }
-
-LABEL(pickup)
-
-       if(this.target && this.target != "" && this.target != "###item###") // defrag support
-               SUB_UseTargets(this, toucher, NULL);
-
-       STAT(LAST_PICKUP, toucher) = time;
-
-       Send_Effect(EFFECT_ITEM_PICKUP, CENTER_OR_VIEWOFS(this), '0 0 0', 1);
-       _sound (toucher, (this.itemdef.instanceOfPowerup ? CH_TRIGGER_SINGLE : CH_TRIGGER), (this.item_pickupsound ? this.item_pickupsound : Sound_fixpath(this.item_pickupsound_ent)), VOL_BASE, ATTEN_NORM);
-
-       MUTATOR_CALLHOOK(ItemTouched, this, toucher);
-       if (wasfreed(this))
-       {
-               return;
-       }
-
-       if (Item_IsLoot(this))
-       {
-               delete(this);
-               return;
-       }
-       if (!this.spawnshieldtime)
-       {
-               return;
-       }
-       entity e;
-       if (this.team)
-       {
-               RandomSelection_Init();
-               IL_EACH(g_items, it.team == this.team,
-               {
-                       if (it.itemdef) // is a registered item
-                       {
-                               Item_Show(it, -1);
-                               it.scheduledrespawntime = 0;
-                               RandomSelection_AddEnt(it, it.cnt, 0);
-                       }
-               });
-               e = RandomSelection_chosen_ent;
-               Item_Show(e, 1); // reset its state so it is visible (extra sendflags doesn't matter, this happens anyway)
-       }
-       else
-               e = this;
-       Item_ScheduleRespawn(e);
-}
-
-void Item_Reset(entity this)
-{
-       Item_Show(this, !this.state);
-       setorigin(this, this.origin);
-
-       if (Item_IsLoot(this))
-       {
-               return;
-       }
-       setthink(this, Item_Think);
-       this.nextthink = time;
-       if (this.waypointsprite_attached)
-       {
-               WaypointSprite_Kill(this.waypointsprite_attached);
-       }
-       if (this.itemdef.instanceOfPowerup || (STAT(WEAPONS, this) & WEPSET_SUPERWEAPONS)) // do not spawn powerups initially!
-       {
-               Item_ScheduleInitialRespawn(this);
-       }
-}
-
-void Item_FindTeam(entity this)
-{
-       entity e;
-
-       if(this.effects & EF_NODRAW)
-       {
-               // marker for item team search
-               LOG_TRACE("Initializing item team ", ftos(this.team));
-               RandomSelection_Init();
-               IL_EACH(g_items, it.team == this.team,
-               {
-                       if(it.itemdef) // is a registered item
-                               RandomSelection_AddEnt(it, it.cnt, 0);
-               });
-
-               e = RandomSelection_chosen_ent;
-               if (!e)
-                       return;
-
-               IL_EACH(g_items, it.team == this.team,
-               {
-                       if(it.itemdef) // is a registered item
-                       {
-                               if(it != e)
-                               {
-                                       // make it non-spawned
-                                       Item_Show(it, -1);
-                                       it.state = 1; // state 1 = initially hidden item, apparently
-                               }
-                               else
-                                       Item_Reset(it);
-                               it.effects &= ~EF_NODRAW;
-                       }
-               });
-       }
-}
-
-// Savage: used for item garbage-collection
-void RemoveItem(entity this)
-{
-       if(wasfreed(this) || !this) { return; }
-       Send_Effect(EFFECT_ITEM_PICKUP, CENTER_OR_VIEWOFS(this), '0 0 0', 1);
-       delete(this);
-}
-
-// pickup evaluation functions
-// these functions decide how desirable an item is to the bots
-
-float generic_pickupevalfunc(entity player, entity item) {return item.bot_pickupbasevalue;}
-
-float weapon_pickupevalfunc(entity player, entity item)
-{
-       // See if I have it already
-       if(STAT(WEAPONS, player) & STAT(WEAPONS, item))
-       {
-               // If I can pick it up
-               if(!item.spawnshieldtime)
-                       return 0;
-               return ammo_pickupevalfunc(player, item);
-       }
-
-       // reduce weapon value if bot already got a good arsenal
-       float c = 1;
-       int weapons_value = 0;
-       FOREACH(Weapons, it != WEP_Null && (STAT(WEAPONS, player) & it.m_wepset), {
-               weapons_value += it.bot_pickupbasevalue;
-       });
-       c -= bound(0, weapons_value / 20000, 1) * 0.5;
-
-       return item.bot_pickupbasevalue * c;
-}
-
-float ammo_pickupevalfunc(entity player, entity item)
-{
-       bool need_shells = false, need_nails = false, need_rockets = false, need_cells = false, need_plasma = false, need_fuel = false;
-       entity wpn = NULL;
-       float c = 0;
-       float rating = 0;
-
-       // Detect needed ammo
-       if(item.itemdef.instanceOfWeaponPickup)
-       {
-               entity ammo = NULL;
-               if(GetResource(item, RES_SHELLS))       { need_shells  = true; ammo = ITEM_Shells;      }
-               else if(GetResource(item, RES_BULLETS))   { need_nails   = true; ammo = ITEM_Bullets;     }
-               else if(GetResource(item, RES_ROCKETS)) { need_rockets = true; ammo = ITEM_Rockets;     }
-               else if(GetResource(item, RES_CELLS))   { need_cells   = true; ammo = ITEM_Cells;       }
-               else if(GetResource(item, RES_PLASMA))  { need_plasma  = true; ammo = ITEM_Plasma;      }
-               else if(GetResource(item, RES_FUEL))    { need_fuel    = true; ammo = ITEM_JetpackFuel; }
-
-               if(!ammo)
-                       return 0;
-               wpn = item;
-               rating = ammo.m_botvalue;
-       }
-       else
-       {
-               FOREACH(Weapons, it != WEP_Null, {
-                       if(!(STAT(WEAPONS, player) & (it.m_wepset)))
-                               continue;
-
-                       switch(it.ammo_type)
-                       {
-                               case RES_SHELLS:  need_shells  = true; break;
-                               case RES_BULLETS: need_nails   = true; break;
-                               case RES_ROCKETS: need_rockets = true; break;
-                               case RES_CELLS:   need_cells   = true; break;
-                               case RES_PLASMA:  need_plasma  = true; break;
-                               case RES_FUEL:    need_fuel    = true; break;
-                       }
-               });
-               rating = item.bot_pickupbasevalue;
-       }
-
-       float noammorating = 0.5;
-
-       if ((need_shells) && GetResource(item, RES_SHELLS) && (GetResource(player, RES_SHELLS) < g_pickup_shells_max))
-               c = GetResource(item, RES_SHELLS) / max(noammorating, GetResource(player, RES_SHELLS));
-
-       if ((need_nails) && GetResource(item, RES_BULLETS) && (GetResource(player, RES_BULLETS) < g_pickup_nails_max))
-               c = GetResource(item, RES_BULLETS) / max(noammorating, GetResource(player, RES_BULLETS));
-
-       if ((need_rockets) && GetResource(item, RES_ROCKETS) && (GetResource(player, RES_ROCKETS) < g_pickup_rockets_max))
-               c = GetResource(item, RES_ROCKETS) / max(noammorating, GetResource(player, RES_ROCKETS));
-
-       if ((need_cells) && GetResource(item, RES_CELLS) && (GetResource(player, RES_CELLS) < g_pickup_cells_max))
-               c = GetResource(item, RES_CELLS) / max(noammorating, GetResource(player, RES_CELLS));
-
-       if ((need_plasma) && GetResource(item, RES_PLASMA) && (GetResource(player, RES_PLASMA) < g_pickup_plasma_max))
-               c = GetResource(item, RES_PLASMA) / max(noammorating, GetResource(player, RES_PLASMA));
-
-       if ((need_fuel) && GetResource(item, RES_FUEL) && (GetResource(player, RES_FUEL) < g_pickup_fuel_max))
-               c = GetResource(item, RES_FUEL) / max(noammorating, GetResource(player, RES_FUEL));
-
-       rating *= min(c, 2);
-       if(wpn)
-               rating += wpn.bot_pickupbasevalue * 0.1;
-       return rating;
-}
-
-float healtharmor_pickupevalfunc(entity player, entity item)
-{
-       float c = 0;
-       float rating = item.bot_pickupbasevalue;
-
-       float itemarmor = GetResource(item, RES_ARMOR);
-       float itemhealth = GetResource(item, RES_HEALTH);
-
-       if(item.item_group)
-       {
-               itemarmor *= min(4, item.item_group_count);
-               itemhealth *= min(4, item.item_group_count);
-       }
-
-       if (itemarmor && (GetResource(player, RES_ARMOR) < item.max_armorvalue))
-               c = itemarmor / max(1, GetResource(player, RES_ARMOR) * 2/3 + GetResource(player, RES_HEALTH) * 1/3);
-
-       if (itemhealth && (GetResource(player, RES_HEALTH) < item.max_health))
-               c = itemhealth / max(1, GetResource(player, RES_HEALTH));
-
-       rating *= min(2, c);
-       return rating;
-}
-
-void Item_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
-{
-       if(ITEM_DAMAGE_NEEDKILL(deathtype))
-               RemoveItem(this);
-}
-
-void item_use(entity this, entity actor, entity trigger)
-{
-       // use the touch function to handle collection
-       gettouch(this)(this, actor);
-}
-
-void _StartItem(entity this, entity def, float defaultrespawntime, float defaultrespawntimejitter)
-{
-       string itemname = def.m_name;
-       Model itemmodel = def.m_model;
-       Sound pickupsound = def.m_sound;
-       float(entity player, entity item) pickupevalfunc = def.m_pickupevalfunc;
-       float pickupbasevalue = def.m_botvalue;
-       int itemflags = def.m_itemflags;
-
-       startitem_failed = false;
-
-       this.item_model_ent = itemmodel;
-       this.item_pickupsound_ent = pickupsound;
-
-       if(def.m_iteminit)
-               def.m_iteminit(def, this);
-
-       if(!this.respawntime) // both need to be set
-       {
-               this.respawntime = defaultrespawntime;
-               this.respawntimejitter = defaultrespawntimejitter;
-       }
-
-       if(!this.pickup_anyway && def.m_pickupanyway)
-               this.pickup_anyway = def.m_pickupanyway();
-
-       int itemid = def.m_itemid;
-       this.items = itemid;
-       int weaponid = def.instanceOfWeaponPickup ? def.m_weapon.m_id : 0;
-       this.weapon = weaponid;
-
-       if(!this.fade_end)
-       {
-               this.fade_start = autocvar_g_items_mindist;
-               this.fade_end = autocvar_g_items_maxdist;
-       }
-
-       if(weaponid)
-               STAT(WEAPONS, this) = WepSet_FromWeapon(REGISTRY_GET(Weapons, weaponid));
-
-       this.flags = FL_ITEM | itemflags;
-       IL_PUSH(g_items, this);
-
-       if(MUTATOR_CALLHOOK(FilterItem, this)) // error means we do not want the item
-       {
-               startitem_failed = true;
-               delete(this);
-               return;
-       }
-
-       precache_model(this.model);
-       precache_sound(this.item_pickupsound);
-
-       if (Item_IsLoot(this))
-       {
-               this.reset = SUB_Remove;
-               set_movetype(this, MOVETYPE_TOSS);
-
-               // Savage: remove thrown items after a certain period of time ("garbage collection")
-               setthink(this, RemoveItem);
-               this.nextthink = time + 20;
-
-               this.takedamage = DAMAGE_YES;
-               this.event_damage = Item_Damage;
-
-               if (Item_IsExpiring(this))
-               {
-                       // if item is worthless after a timer, have it expire then
-                       this.nextthink = max(this.strength_finished, this.invincible_finished, this.superweapons_finished);
-               }
-
-               // don't drop if in a NODROP zone (such as lava)
-               traceline(this.origin, this.origin, MOVE_NORMAL, this);
-               if (trace_dpstartcontents & DPCONTENTS_NODROP)
-               {
-                       startitem_failed = true;
-                       delete(this);
-                       return;
-               }
-       }
-       else
-       {
-               if(!have_pickup_item(this))
-               {
-                       startitem_failed = true;
-                       delete(this);
-                       return;
-               }
-
-               if(this.angles != '0 0 0')
-                       this.SendFlags |= ISF_ANGLES;
-
-               this.reset = Item_Reset;
-               // it's a level item
-               if(this.spawnflags & 1)
-                       this.noalign = 1;
-               if (this.noalign > 0)
-                       set_movetype(this, MOVETYPE_NONE);
-               else
-                       set_movetype(this, MOVETYPE_TOSS);
-               // do item filtering according to game mode and other things
-               if (this.noalign <= 0)
-               {
-                       // first nudge it off the floor a little bit to avoid math errors
-                       setorigin(this, this.origin + '0 0 1');
-                       // set item size before we spawn a spawnfunc_waypoint
-                       setsize(this, def.m_mins, def.m_maxs);
-                       this.SendFlags |= ISF_SIZE;
-                       // note droptofloor returns false if stuck/or would fall too far
-                       if (!this.noalign)
-                               droptofloor(this);
-                       waypoint_spawnforitem(this);
-               }
-
-               /*
-                * can't do it that way, as it would break maps
-                * TODO make a target_give like entity another way, that perhaps has
-                * the weapon name in a key
-               if(this.targetname)
-               {
-                       // target_give not yet supported; maybe later
-                       print("removed targeted ", this.classname, "\n");
-                       startitem_failed = true;
-                       delete(this);
-                       return;
-               }
-               */
-
-               if(this.targetname != "" && (this.spawnflags & 16))
-                       this.use = item_use;
-
-               if(autocvar_spawn_debug >= 2)
-               {
-            // why not flags & fl_item?
-                   FOREACH_ENTITY_RADIUS(this.origin, 3, it.is_item, {
-                LOG_TRACE("XXX Found duplicated item: ", itemname, vtos(this.origin));
-                LOG_TRACE(" vs ", it.netname, vtos(it.origin));
-                error("Mapper sucks.");
-            });
-                       this.is_item = true;
-               }
-
-               weaponsInMap |= WepSet_FromWeapon(REGISTRY_GET(Weapons, weaponid));
-
-               if (   def.instanceOfPowerup
-                       || def.instanceOfWeaponPickup
-                       || (def.instanceOfHealth && def != ITEM_HealthSmall)
-                       || (def.instanceOfArmor && def != ITEM_ArmorSmall)
-                       || (itemid & (IT_KEY1 | IT_KEY2))
-               )
-               {
-                       if(!this.target || this.target == "")
-                               this.target = "###item###"; // for finding the nearest item using findnearest
-               }
-
-               Item_ItemsTime_SetTime(this, 0);
-       }
-
-       this.bot_pickup = true;
-       this.bot_pickupevalfunc = pickupevalfunc;
-       this.bot_pickupbasevalue = pickupbasevalue;
-       this.mdl = this.model ? this.model : strzone(this.item_model_ent.model_str());
-       this.netname = itemname;
-       settouch(this, Item_Touch);
-       setmodel(this, MDL_Null); // precision set below
-       //this.effects |= EF_LOWPRECISION;
-
-       setsize (this, this.pos1 =  def.m_mins, this.pos2 = def.m_maxs);
-
-       this.SendFlags |= ISF_SIZE;
-
-       if (!(this.spawnflags & 1024)) {
-               if(def.instanceOfPowerup)
-                       this.ItemStatus |= ITS_ANIMATE1;
-
-               if(GetResource(this, RES_ARMOR) || GetResource(this, RES_HEALTH))
-                       this.ItemStatus |= ITS_ANIMATE2;
-       }
-
-       if(Item_IsLoot(this))
-               this.gravity = 1;
-
-       if(def.instanceOfWeaponPickup)
-       {
-               if (!Item_IsLoot(this)) // if dropped, colormap is already set up nicely
-                       this.colormap = 1024; // color shirt=0 pants=0 grey
-               if (!(this.spawnflags & 1024))
-                       this.ItemStatus |= ITS_ANIMATE1;
-               this.SendFlags |= ISF_COLORMAP;
-       }
-
-       this.state = 0;
-       if(this.team)
-       {
-               if(!this.cnt)
-                       this.cnt = 1; // item probability weight
-
-               this.effects |= EF_NODRAW; // marker for item team search
-               InitializeEntity(this, Item_FindTeam, INITPRIO_FINDTARGET);
-       }
-       else
-               Item_Reset(this);
-
-       Net_LinkEntity(this, !(def.instanceOfPowerup || def.instanceOfHealth || def.instanceOfArmor), 0, ItemSend);
-
-       // call this hook after everything else has been done
-       if (MUTATOR_CALLHOOK(Item_Spawn, this))
-       {
-               startitem_failed = true;
-               delete(this);
-               return;
-       }
-
-       setItemGroup(this);
-}
-
-void StartItem(entity this, GameItem def)
-{
-    def = def.m_spawnfunc_hookreplace(def, this);
-    if (def.spawnflags & ITEM_FLAG_MUTATORBLOCKED)
-    {
-        delete(this);
-        return;
-    }
-    this.classname = def.m_canonical_spawnfunc;
-    _StartItem(
-       this,
-       this.itemdef = def,
-       def.m_respawntime(), // defaultrespawntime
-       def.m_respawntimejitter() // defaultrespawntimejitter
-       );
-}
-
-#define IS_SMALL(def) ((def.instanceOfHealth && def == ITEM_HealthSmall) || (def.instanceOfArmor && def == ITEM_ArmorSmall))
-int group_count = 1;
-
-void setItemGroup(entity this)
-{
-       if(!IS_SMALL(this.itemdef) || Item_IsLoot(this))
-               return;
-
-       FOREACH_ENTITY_RADIUS(this.origin, 120, (it != this) && IS_SMALL(it.itemdef),
-       {
-               if(!this.item_group)
-               {
-                       if(!it.item_group)
-                       {
-                               it.item_group = group_count;
-                               group_count++;
-                       }
-                       this.item_group = it.item_group;
-               }
-               else // spawning item is already part of a item_group X
-               {
-                       if(!it.item_group)
-                               it.item_group = this.item_group;
-                       else if(it.item_group != this.item_group) // found an item near the spawning item that is part of a different item_group Y
-                       {
-                               int grY = it.item_group;
-                               // move all items of item_group Y to item_group X
-                               IL_EACH(g_items, IS_SMALL(it.itemdef),
-                               {
-                                       if(it.item_group == grY)
-                                               it.item_group = this.item_group;
-                               });
-                       }
-               }
-       });
-}
-
-void setItemGroupCount()
-{
-       for (int k = 1; k <= group_count; k++)
-       {
-               int count = 0;
-               IL_EACH(g_items, IS_SMALL(it.itemdef) && it.item_group == k, { count++; });
-               if (count)
-                       IL_EACH(g_items, IS_SMALL(it.itemdef) && it.item_group == k, { it.item_group_count = count; });
-       }
-}
-
-void target_items_use(entity this, entity actor, entity trigger)
-{
-       if(Item_IsLoot(actor))
-       {
-               EXACTTRIGGER_TOUCH(this, trigger);
-               delete(actor);
-               return;
-       }
-
-       if (!IS_PLAYER(actor) || IS_DEAD(actor))
-               return;
-
-       if(trigger.solid == SOLID_TRIGGER)
-       {
-               EXACTTRIGGER_TOUCH(this, trigger);
-       }
-
-       IL_EACH(g_items, it.enemy == actor && Item_IsLoot(it),
-       {
-               delete(it);
-       });
-
-       if(GiveItems(actor, 0, tokenize_console(this.netname)))
-               centerprint(actor, this.message);
-}
-
-spawnfunc(target_items)
-{
-       this.use = target_items_use;
-       if(!this.strength_finished)
-               this.strength_finished = autocvar_g_balance_powerup_strength_time;
-       if(!this.invincible_finished)
-               this.invincible_finished = autocvar_g_balance_powerup_invincible_time;
-       if(!this.superweapons_finished)
-               this.superweapons_finished = autocvar_g_balance_superweapons_time;
-
-       string str;
-       int n = tokenize_console(this.netname);
-       if(argv(0) == "give")
-       {
-               str = substring(this.netname, argv_start_index(1), argv_end_index(-1) - argv_start_index(1));
-       }
-       else
-       {
-               for(int j = 0; j < n; ++j)
-               {
-                       // this is from a time when unlimited superweapons were handled together with ammo in some parts of the code
-                       if     (argv(j) == "unlimited_ammo")         this.items |= IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPERWEAPONS;
-                       else if(argv(j) == "unlimited_weapon_ammo")  this.items |= IT_UNLIMITED_AMMO;
-                       else if(argv(j) == "unlimited_superweapons") this.items |= IT_UNLIMITED_SUPERWEAPONS;
-                       else if(argv(j) == "strength")               this.items |= ITEM_Strength.m_itemid;
-                       else if(argv(j) == "invincible")             this.items |= ITEM_Shield.m_itemid;
-                       else if(argv(j) == "superweapons")           this.items |= IT_SUPERWEAPON;
-                       else if(argv(j) == "jetpack")                this.items |= ITEM_Jetpack.m_itemid;
-                       else if(argv(j) == "fuel_regen")             this.items |= ITEM_JetpackRegen.m_itemid;
-                       else
-                       {
-                               FOREACH(Buffs, it != BUFF_Null,
-                               {
-                                       string s = Buff_UndeprecateName(argv(j));
-                                       if(s == it.netname)
-                                       {
-                                               STAT(BUFFS, this) |= (it.m_itemid);
-                                               if(!STAT(BUFF_TIME, this))
-                                                       STAT(BUFF_TIME, this) = it.m_time(it);
-                                               break;
-                                       }
-                               });
-                               FOREACH(Weapons, it != WEP_Null, {
-                                       string s = W_UndeprecateName(argv(j));
-                                       if(s == it.netname)
-                                       {
-                                               STAT(WEAPONS, this) |= (it.m_wepset);
-                                               if(this.spawnflags == 0 || this.spawnflags == 2)
-                                                       it.wr_init(it);
-                                               break;
-                                       }
-                               });
-                       }
-               }
-
-               string itemprefix, valueprefix;
-               if(this.spawnflags == 0)
-               {
-                       itemprefix = "";
-                       valueprefix = "";
-               }
-               else if(this.spawnflags == 1)
-               {
-                       itemprefix = "max ";
-                       valueprefix = "max ";
-               }
-               else if(this.spawnflags == 2)
-               {
-                       itemprefix = "min ";
-                       valueprefix = "min ";
-               }
-               else if(this.spawnflags == 4)
-               {
-                       itemprefix = "minus ";
-                       valueprefix = "max ";
-               }
-               else
-               {
-                       error("invalid spawnflags");
-                       itemprefix = valueprefix = string_null;
-               }
-
-               str = "";
-               str = sprintf("%s %s%d %s", str, itemprefix, boolean(this.items & IT_UNLIMITED_AMMO), "unlimited_weapon_ammo");
-               str = sprintf("%s %s%d %s", str, itemprefix, boolean(this.items & IT_UNLIMITED_SUPERWEAPONS), "unlimited_superweapons");
-               str = sprintf("%s %s%d %s", str, valueprefix, this.strength_finished * boolean(this.items & ITEM_Strength.m_itemid), "strength");
-               str = sprintf("%s %s%d %s", str, valueprefix, this.invincible_finished * boolean(this.items & ITEM_Shield.m_itemid), "invincible");
-               str = sprintf("%s %s%d %s", str, valueprefix, this.superweapons_finished * boolean(this.items & IT_SUPERWEAPON), "superweapons");
-               str = sprintf("%s %s%d %s", str, itemprefix, boolean(this.items & ITEM_Jetpack.m_itemid), "jetpack");
-               str = sprintf("%s %s%d %s", str, itemprefix, boolean(this.items & ITEM_JetpackRegen.m_itemid), "fuel_regen");
-               float res;
-               res = GetResource(this, RES_SHELLS);  if(res != 0) str = sprintf("%s %s%d %s", str, valueprefix, max(0, res), "shells");
-               res = GetResource(this, RES_BULLETS); if(res != 0) str = sprintf("%s %s%d %s", str, valueprefix, max(0, res), "nails");
-               res = GetResource(this, RES_ROCKETS); if(res != 0) str = sprintf("%s %s%d %s", str, valueprefix, max(0, res), "rockets");
-               res = GetResource(this, RES_CELLS);   if(res != 0) str = sprintf("%s %s%d %s", str, valueprefix, max(0, res), "cells");
-               res = GetResource(this, RES_PLASMA);  if(res != 0) str = sprintf("%s %s%d %s", str, valueprefix, max(0, res), "plasma");
-               res = GetResource(this, RES_FUEL);    if(res != 0) str = sprintf("%s %s%d %s", str, valueprefix, max(0, res), "fuel");
-               res = GetResource(this, RES_HEALTH);  if(res != 0) str = sprintf("%s %s%d %s", str, valueprefix, max(0, res), "health");
-               res = GetResource(this, RES_ARMOR);   if(res != 0) str = sprintf("%s %s%d %s", str, valueprefix, max(0, res), "armor");
-               // HACK: buffs share a single timer, so we need to include enabled buffs AFTER disabled ones to avoid loss
-               FOREACH(Buffs, it != BUFF_Null && !(STAT(BUFFS, this) & it.m_itemid), str = sprintf("%s %s%d %s", str, valueprefix, max(0, STAT(BUFF_TIME, this)), it.netname));
-               FOREACH(Buffs, it != BUFF_Null && (STAT(BUFFS, this) & it.m_itemid), str = sprintf("%s %s%d %s", str, valueprefix, max(0, STAT(BUFF_TIME, this)), it.netname));
-               FOREACH(Weapons, it != WEP_Null, str = sprintf("%s %s%d %s", str, itemprefix, !!(STAT(WEAPONS, this) & (it.m_wepset)), it.netname));
-       }
-       this.netname = strzone(str);
-
-       n = tokenize_console(this.netname);
-       for(int j = 0; j < n; ++j)
-       {
-               FOREACH(Weapons, it != WEP_Null && W_UndeprecateName(argv(j)) == it.netname, {
-                       it.wr_init(it);
-                       break;
-               });
-       }
-}
-
-float GiveWeapon(entity e, float wpn, float op, float val)
-{
-       WepSet v0, v1;
-       WepSet s = WepSet_FromWeapon(REGISTRY_GET(Weapons, wpn));
-       v0 = (STAT(WEAPONS, e) & s);
-       switch(op)
-       {
-               case OP_SET:
-                       if(val > 0)
-                               STAT(WEAPONS, e) |= s;
-                       else
-                               STAT(WEAPONS, e) &= ~s;
-                       break;
-               case OP_MIN:
-               case OP_PLUS:
-                       if(val > 0)
-                               STAT(WEAPONS, e) |= s;
-                       break;
-               case OP_MAX:
-                       if(val <= 0)
-                               STAT(WEAPONS, e) &= ~s;
-                       break;
-               case OP_MINUS:
-                       if(val > 0)
-                               STAT(WEAPONS, e) &= ~s;
-                       break;
-       }
-       v1 = (STAT(WEAPONS, e) & s);
-       return (v0 != v1);
-}
-
-bool GiveBuff(entity e, Buff thebuff, int op, int val)
-{
-       bool had_buff = (STAT(BUFFS, e) & thebuff.m_itemid);
-       float new_buff_time = ((had_buff) ? STAT(BUFF_TIME, e) : 0);
-       switch (op)
-       {
-               case OP_SET:
-                       new_buff_time = val;
-                       break;
-               case OP_MIN:
-                       new_buff_time = max(new_buff_time, val);
-                       break;
-               case OP_MAX:
-                       new_buff_time = min(new_buff_time, val);
-                       break;
-               case OP_PLUS:
-                       new_buff_time += val;
-                       break;
-               case OP_MINUS:
-                       new_buff_time -= val;
-                       break;
-       }
-       if(new_buff_time <= 0)
-       {
-               if(had_buff)
-                       STAT(BUFF_TIME, e) = new_buff_time;
-               STAT(BUFFS, e) &= ~thebuff.m_itemid;
-       }
-       else
-       {
-               STAT(BUFF_TIME, e) = new_buff_time;
-               STAT(BUFFS, e) = thebuff.m_itemid; // NOTE: replaces any existing buffs on the player!
-       }
-       bool have_buff = (STAT(BUFFS, e) & thebuff.m_itemid);
-       return (had_buff != have_buff);
-}
-
-void GiveSound(entity e, float v0, float v1, float t, Sound snd_incr, Sound snd_decr)
-{
-       if(v1 == v0)
-               return;
-       if(v1 <= v0 - t)
-       {
-               if(snd_decr != NULL)
-                       sound (e, CH_TRIGGER, snd_decr, VOL_BASE, ATTEN_NORM);
-       }
-       else if(v0 >= v0 + t)
-       {
-               if(snd_incr != NULL)
-                       sound (e, CH_TRIGGER, snd_incr, VOL_BASE, ATTEN_NORM);
-       }
-}
-
-void GiveRot(entity e, float v0, float v1, .float rotfield, float rottime, .float regenfield, float regentime)
-{
-       if(v0 < v1)
-               e.(rotfield) = max(e.(rotfield), time + rottime);
-       else if(v0 > v1)
-               e.(regenfield) = max(e.(regenfield), time + regentime);
-}
-bool GiveResourceValue(entity e, int res_type, int op, int val)
-{
-       int v0 = GetResource(e, res_type);
-       float new_val = 0;
-       switch (op)
-       {
-               // min 100 cells = at least 100 cells
-               case OP_SET: new_val = val; break;
-               case OP_MIN: new_val = max(v0, val); break;
-               case OP_MAX: new_val = min(v0, val); break;
-               case OP_PLUS: new_val = v0 + val; break;
-               case OP_MINUS: new_val = v0 - val; break;
-               default: return false;
-       }
-
-       return SetResourceExplicit(e, res_type, new_val);
-}
-
-float GiveItems(entity e, float beginarg, float endarg)
-{
-       float got, i, val, op;
-       string cmd;
-
-       val = 999;
-       op = OP_SET;
-
-       got = 0;
-
-       int _switchweapon = 0;
-
-       if(CS(e).autoswitch)
-       {
-               for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
-               {
-                       .entity weaponentity = weaponentities[slot];
-                       if(e.(weaponentity).m_weapon != WEP_Null || slot == 0)
-                       if(e.(weaponentity).m_switchweapon == w_getbestweapon(e, weaponentity))
-                               _switchweapon |= BIT(slot);
-               }
-       }
-
-       STAT(STRENGTH_FINISHED, e) = max(0, STAT(STRENGTH_FINISHED, e) - time);
-       STAT(INVINCIBLE_FINISHED, e) = max(0, STAT(INVINCIBLE_FINISHED, e) - time);
-       STAT(SUPERWEAPONS_FINISHED, e) = max(0, STAT(SUPERWEAPONS_FINISHED, e) - time);
-       STAT(BUFF_TIME, e) = max(0, STAT(BUFF_TIME, e) - time);
-
-       PREGIVE(e, items);
-       PREGIVE_WEAPONS(e);
-       PREGIVE(e, stat_STRENGTH_FINISHED);
-       PREGIVE(e, stat_INVINCIBLE_FINISHED);
-       PREGIVE(e, stat_SUPERWEAPONS_FINISHED);
-       PREGIVE_RESOURCE(e, RES_BULLETS);
-       PREGIVE_RESOURCE(e, RES_CELLS);
-       PREGIVE_RESOURCE(e, RES_PLASMA);
-       PREGIVE_RESOURCE(e, RES_SHELLS);
-       PREGIVE_RESOURCE(e, RES_ROCKETS);
-       PREGIVE_RESOURCE(e, RES_FUEL);
-       PREGIVE_RESOURCE(e, RES_ARMOR);
-       PREGIVE_RESOURCE(e, RES_HEALTH);
-
-       for(i = beginarg; i < endarg; ++i)
-       {
-               cmd = argv(i);
-
-               if(cmd == "0" || stof(cmd))
-               {
-                       val = stof(cmd);
-                       continue;
-               }
-               switch(cmd)
-               {
-                       case "no":
-                               op = OP_MAX;
-                               val = 0;
-                               continue;
-                       case "max":
-                               op = OP_MAX;
-                               continue;
-                       case "min":
-                               op = OP_MIN;
-                               continue;
-                       case "plus":
-                               op = OP_PLUS;
-                               continue;
-                       case "minus":
-                               op = OP_MINUS;
-                               continue;
-                       case "ALL":
-                               got += GiveBit(e, items, ITEM_JetpackRegen.m_itemid, op, val);
-                               got += GiveValue(e, stat_STRENGTH_FINISHED, op, val);
-                               got += GiveValue(e, stat_INVINCIBLE_FINISHED, op, val);
-                               got += GiveValue(e, stat_SUPERWEAPONS_FINISHED, op, val);
-                               got += GiveBit(e, items, IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPERWEAPONS, op, val);
-                       case "all":
-                               got += GiveBit(e, items, ITEM_Jetpack.m_itemid, op, val);
-                               got += GiveResourceValue(e, RES_HEALTH, op, val);
-                               got += GiveResourceValue(e, RES_ARMOR, op, val);
-                       case "allweapons":
-                               FOREACH(Weapons, it != WEP_Null && !(it.spawnflags & (WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_SPECIALATTACK)), got += GiveWeapon(e, it.m_id, op, val));
-                       //case "allbuffs": // all buffs makes a player god, do not want!
-                               //FOREACH(Buffs, it != BUFF_Null, got += GiveBuff(e, it.m_itemid, op, val));
-                       case "allammo":
-                               got += GiveResourceValue(e, RES_CELLS, op, val);
-                               got += GiveResourceValue(e, RES_PLASMA, op, val);
-                               got += GiveResourceValue(e, RES_SHELLS, op, val);
-                               got += GiveResourceValue(e, RES_BULLETS, op, val);
-                               got += GiveResourceValue(e, RES_ROCKETS, op, val);
-                               got += GiveResourceValue(e, RES_FUEL, op, val);
-                               break;
-                       case "unlimited_ammo":
-                               // this is from a time when unlimited superweapons were handled together with ammo in some parts of the code
-                               got += GiveBit(e, items, IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPERWEAPONS, op, val);
-                               break;
-                       case "unlimited_weapon_ammo":
-                               got += GiveBit(e, items, IT_UNLIMITED_AMMO, op, val);
-                               break;
-                       case "unlimited_superweapons":
-                               got += GiveBit(e, items, IT_UNLIMITED_SUPERWEAPONS, op, val);
-                               break;
-                       case "jetpack":
-                               got += GiveBit(e, items, ITEM_Jetpack.m_itemid, op, val);
-                               break;
-                       case "fuel_regen":
-                               got += GiveBit(e, items, ITEM_JetpackRegen.m_itemid, op, val);
-                               break;
-                       case "strength":
-                               got += GiveValue(e, stat_STRENGTH_FINISHED, op, val);
-                               break;
-                       case "invincible":
-                               got += GiveValue(e, stat_INVINCIBLE_FINISHED, op, val);
-                               break;
-                       case "superweapons":
-                               got += GiveValue(e, stat_SUPERWEAPONS_FINISHED, op, val);
-                               break;
-                       case "cells":
-                               got += GiveResourceValue(e, RES_CELLS, op, val);
-                               break;
-                       case "plasma":
-                               got += GiveResourceValue(e, RES_PLASMA, op, val);
-                               break;
-                       case "shells":
-                               got += GiveResourceValue(e, RES_SHELLS, op, val);
-                               break;
-                       case "nails":
-                       case "bullets":
-                               got += GiveResourceValue(e, RES_BULLETS, op, val);
-                               break;
-                       case "rockets":
-                               got += GiveResourceValue(e, RES_ROCKETS, op, val);
-                               break;
-                       case "health":
-                               got += GiveResourceValue(e, RES_HEALTH, op, val);
-                               break;
-                       case "armor":
-                               got += GiveResourceValue(e, RES_ARMOR, op, val);
-                               break;
-                       case "fuel":
-                               got += GiveResourceValue(e, RES_FUEL, op, val);
-                               break;
-                       default:
-                               FOREACH(Buffs, it != BUFF_Null && buff_Available(it) && Buff_UndeprecateName(cmd) == it.netname,
-                               {
-                                       got += GiveBuff(e, it, op, val);
-                                       break;
-                               });
-                               FOREACH(Weapons, it != WEP_Null && W_UndeprecateName(cmd) == it.netname, {
-                    got += GiveWeapon(e, it.m_id, op, val);
-                    break;
-                               });
-                               break;
-               }
-               val = 999;
-               op = OP_SET;
-       }
-
-       POSTGIVE_BIT(e, items, ITEM_JetpackRegen.m_itemid, SND_ITEMPICKUP, SND_Null);
-       POSTGIVE_BIT(e, items, IT_UNLIMITED_SUPERWEAPONS, SND_POWERUP, SND_POWEROFF);
-       POSTGIVE_BIT(e, items, IT_UNLIMITED_AMMO, SND_POWERUP, SND_POWEROFF);
-       POSTGIVE_BIT(e, items, ITEM_Jetpack.m_itemid, SND_ITEMPICKUP, SND_Null);
-       FOREACH(Weapons, it != WEP_Null, {
-               POSTGIVE_WEAPON(e, it, SND_WEAPONPICKUP, SND_Null);
-               if(!(save_weapons & (it.m_wepset)))
-                       if(STAT(WEAPONS, e) & (it.m_wepset))
-                               it.wr_init(it);
-       });
-       POSTGIVE_VALUE(e, stat_STRENGTH_FINISHED, 1, SND_POWERUP, SND_POWEROFF);
-       POSTGIVE_VALUE(e, stat_INVINCIBLE_FINISHED, 1, SND_Shield, SND_POWEROFF);
-       //POSTGIVE_VALUE(e, stat_SUPERWEAPONS_FINISHED, 1, SND_Null, SND_Null);
-       POSTGIVE_RESOURCE(e, RES_BULLETS, 0, SND_ITEMPICKUP, SND_Null);
-       POSTGIVE_RESOURCE(e, RES_CELLS, 0, SND_ITEMPICKUP, SND_Null);
-       POSTGIVE_RESOURCE(e, RES_PLASMA, 0, SND_ITEMPICKUP, SND_Null);
-       POSTGIVE_RESOURCE(e, RES_SHELLS, 0, SND_ITEMPICKUP, SND_Null);
-       POSTGIVE_RESOURCE(e, RES_ROCKETS, 0, SND_ITEMPICKUP, SND_Null);
-       POSTGIVE_RES_ROT(e, RES_FUEL, 1, pauserotfuel_finished, autocvar_g_balance_pause_fuel_rot, pauseregen_finished, autocvar_g_balance_pause_fuel_regen, SND_ITEMPICKUP, SND_Null);
-       POSTGIVE_RES_ROT(e, RES_ARMOR, 1, pauserotarmor_finished, autocvar_g_balance_pause_armor_rot, pauseregen_finished, autocvar_g_balance_pause_health_regen, SND_ARMOR25, SND_Null);
-       POSTGIVE_RES_ROT(e, RES_HEALTH, 1, pauserothealth_finished, autocvar_g_balance_pause_health_rot, pauseregen_finished, autocvar_g_balance_pause_health_regen, SND_MEGAHEALTH, SND_Null);
-
-       if(STAT(SUPERWEAPONS_FINISHED, e) <= 0)
-               if(!g_weaponarena && (STAT(WEAPONS, e) & WEPSET_SUPERWEAPONS))
-                       STAT(SUPERWEAPONS_FINISHED, e) = autocvar_g_balance_superweapons_time;
-
-       if(STAT(STRENGTH_FINISHED, e) <= 0)
-               STAT(STRENGTH_FINISHED, e) = 0;
-       else
-               STAT(STRENGTH_FINISHED, e) += time;
-       if(STAT(INVINCIBLE_FINISHED, e) <= 0)
-               STAT(INVINCIBLE_FINISHED, e) = 0;
-       else
-               STAT(INVINCIBLE_FINISHED, e) += time;
-       if(STAT(SUPERWEAPONS_FINISHED, e) <= 0)
-               STAT(SUPERWEAPONS_FINISHED, e) = 0;
-       else
-               STAT(SUPERWEAPONS_FINISHED, e) += time;
-       if(STAT(BUFF_TIME, e) <= 0)
-               STAT(BUFF_TIME, e) = 0;
-       else
-               STAT(BUFF_TIME, e) += time;
-
-       for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
-       {
-               .entity weaponentity = weaponentities[slot];
-               if(e.(weaponentity).m_weapon != WEP_Null || slot == 0)
-               if(!(STAT(WEAPONS, e) & WepSet_FromWeapon(e.(weaponentity).m_switchweapon)))
-                       _switchweapon |= BIT(slot);
-       }
-
-       if(_switchweapon)
-       {
-               for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
-               {
-                       .entity weaponentity = weaponentities[slot];
-                       if(_switchweapon & BIT(slot))
-                       {
-                               Weapon wep = w_getbestweapon(e, weaponentity);
-                               if(wep != e.(weaponentity).m_switchweapon)
-                                       W_SwitchWeapon_Force(e, wep, weaponentity);
-                       }
-               }
-       }
-
-       return got;
-}
-#endif
diff --git a/qcsrc/common/t_items.qh b/qcsrc/common/t_items.qh
deleted file mode 100644 (file)
index 7b0d760..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-#pragma once
-
-const int AMMO_COUNT = 4; // amount of ammo types to show in the ammo panel
-
-// item networking
-const int ISF_LOCATION                         = BIT(1);
-const int ISF_MODEL                            = BIT(2);
-const int ISF_STATUS                   = BIT(3);
-    const int ITS_STAYWEP                  = BIT(0);
-    const int ITS_ANIMATE1                 = BIT(1);
-    const int ITS_ANIMATE2                 = BIT(2);
-    const int ITS_AVAILABLE        = BIT(3);
-    const int ITS_ALLOWFB                  = BIT(4);
-    const int ITS_ALLOWSI                  = BIT(5);
-    const int ITS_GLOW                     = BIT(6);
-const int ISF_COLORMAP                         = BIT(4);
-const int ISF_DROP                             = BIT(5);
-const int ISF_ANGLES                   = BIT(6);
-const int ISF_SIZE                             = BIT(7);
-
-.int ItemStatus;
-
-.float onground_time;
-.float fade_start;
-.float fade_end;
-
-#ifdef SVQC
-void StartItem(entity this, entity a);
-.int item_group;
-.int item_group_count;
-#endif
-
-#ifdef CSQC
-
-bool   autocvar_cl_items_nofade;
-float  autocvar_cl_animate_items = 1;
-float  autocvar_cl_ghost_items = 0.45;
-vector autocvar_cl_ghost_items_color = '-1 -1 -1';
-vector autocvar_cl_weapon_stay_color = '2 0.5 0.5';
-float  autocvar_cl_weapon_stay_alpha = 0.75;
-float  autocvar_cl_simple_items = 0;
-string autocvar_cl_simpleitems_postfix = "_simple";
-.float  spawntime;
-.float  gravity;
-.vector colormod;
-
-void ItemDraw(entity this);
-
-#endif
-#ifdef SVQC
-
-float autocvar_sv_simple_items;
-bool ItemSend(entity this, entity to, int sf);
-
-bool have_pickup_item(entity this);
-
-const float ITEM_RESPAWN_TICKS = 10;
-
-.float max_armorvalue;
-.float pickup_anyway;
-
-.float item_respawncounter;
-
-void Item_Show (entity e, int mode);
-
-void Item_Respawn (entity this);
-
-void Item_RespawnCountdown(entity this);
-void Item_ScheduleRespawnIn(entity e, float t);
-
-void Item_ScheduleRespawn(entity e);
-
-void Item_ScheduleInitialRespawn(entity e);
-
-/// \brief Give several random weapons and ammo to the entity.
-/// \param[in,out] receiver Entity to give weapons to.
-/// \param[in] num_weapons Number of weapons to give.
-/// \param[in] weapon_names Names of weapons to give separated by spaces.
-/// \param[in] ammo Entity containing the ammo amount for each possible weapon.
-/// \return No return.
-void GiveRandomWeapons(entity receiver, int num_weapons, string weapon_names, entity ammo_entity);
-
-bool Item_GiveAmmoTo(entity item, entity player, int res_type, float ammomax);
-
-bool Item_GiveTo(entity item, entity player);
-
-void Item_Touch(entity this, entity toucher);
-
-void Item_Reset(entity this);
-
-void Item_FindTeam(entity this);
-// Savage: used for item garbage-collection
-
-bool ItemSend(entity this, entity to, int sf);
-void ItemUpdate(entity this);
-
-void UpdateItemAfterTeleport(entity this);
-
-// pickup evaluation functions
-// these functions decide how desirable an item is to the bots
-
-float generic_pickupevalfunc(entity player, entity item);// {return item.bot_pickupbasevalue;} // WEAPONTODO
-
-float weapon_pickupevalfunc(entity player, entity item);
-float ammo_pickupevalfunc(entity player, entity item);
-float healtharmor_pickupevalfunc(entity player, entity item);
-
-.bool is_item;
-.entity itemdef;
-void _StartItem(entity this, entity def, float defaultrespawntime, float defaultrespawntimejitter);
-
-void setItemGroup(entity this);
-void setItemGroupCount();
-
-float GiveWeapon(entity e, float wpn, float op, float val);
-
-float GiveBit(entity e, .float fld, float bit, float op, float val);
-
-float GiveValue(entity e, .float fld, float op, float val);
-
-void GiveSound(entity e, float v0, float v1, float t, Sound snd_incr, Sound snd_decr);
-
-void GiveRot(entity e, float v0, float v1, .float rotfield, float rottime, .float regenfield, float regentime);
-
-spawnfunc(target_items);
-
-#define PREGIVE_WEAPONS(e) WepSet save_weapons; save_weapons = STAT(WEAPONS, e)
-#define PREGIVE(e,f) float save_##f; save_##f = (e).f
-#define PREGIVE_RESOURCE(e,f) float save_##f = GetResource((e), (f))
-#define POSTGIVE_WEAPON(e,b,snd_incr,snd_decr) GiveSound((e), !!(save_weapons & WepSet_FromWeapon(b)), !!(STAT(WEAPONS, e) & WepSet_FromWeapon(b)), 0, snd_incr, snd_decr)
-#define POSTGIVE_BIT(e,f,b,snd_incr,snd_decr) GiveSound((e), save_##f & (b), (e).f & (b), 0, snd_incr, snd_decr)
-#define POSTGIVE_RESOURCE(e,f,t,snd_incr,snd_decr) GiveSound((e), save_##f, GetResource((e), (f)), t, snd_incr, snd_decr)
-#define POSTGIVE_RES_ROT(e,f,t,rotfield,rottime,regenfield,regentime,snd_incr,snd_decr) GiveRot((e),save_##f,GetResource((e),(f)),rotfield,rottime,regenfield,regentime);GiveSound((e),save_##f,GetResource((e),(f)),t,snd_incr,snd_decr)
-#define POSTGIVE_VALUE(e,f,t,snd_incr,snd_decr) GiveSound((e), save_##f, (e).f, t, snd_incr, snd_decr)
-#define POSTGIVE_VALUE_ROT(e,f,t,rotfield,rottime,regenfield,regentime,snd_incr,snd_decr) GiveRot((e), save_##f, (e).f, rotfield, rottime, regenfield, regentime); GiveSound((e), save_##f, (e).f, t, snd_incr, snd_decr)
-
-float GiveItems(entity e, float beginarg, float endarg);
-#endif
index df20e1ad2f2d8371638de205f191a458be3db41e..fca9f7f237c1936409298da55e5ea0becc87073b 100644 (file)
@@ -376,8 +376,7 @@ NET_HANDLE(ENT_CLIENT_TURRET, bool isnew)
                this.origin = ReadVector();
                setorigin(this, this.origin);
 
-               this.angles_x = ReadAngle();
-               this.angles_y = ReadAngle();
+               this.angles = ReadAngleVector2D();
 
                turret_construct(this, isnew);
                this.colormap = 1024;
index d8587b14a809954a433f033fe88e5e33245c49d8..e2a9ab2e4131bee26615108eb55873baef2c27a1 100644 (file)
@@ -1,6 +1,11 @@
 #include "sv_turrets.qh"
 #ifdef SVQC
 #include <server/autocvars.qh>
+#include <server/bot/api.qh>
+#include <server/damage.qh>
+#include <server/weapons/common.qh>
+#include <server/weapons/weaponsystem.qh>
+#include <common/mapobjects/defs.qh>
 
 // Generic aiming
 vector turret_aim_generic(entity this)
@@ -320,7 +325,6 @@ void turrets_setframe(entity this, float _frame, float client_only)
 
 bool turret_send(entity this, entity to, float sf)
 {
-
        WriteHeader(MSG_ENTITY, ENT_CLIENT_TURRET);
        WriteByte(MSG_ENTITY, sf);
        if(sf & TNSF_SETUP)
@@ -329,8 +333,7 @@ bool turret_send(entity this, entity to, float sf)
 
                WriteVector(MSG_ENTITY, this.origin);
 
-               WriteAngle(MSG_ENTITY, this.angles_x);
-               WriteAngle(MSG_ENTITY, this.angles_y);
+               WriteAngleVector2D(MSG_ENTITY, this.angles);
        }
 
        if(sf & TNSF_ANG)
@@ -426,11 +429,11 @@ void turret_projectile_explode(entity this)
        this.event_damage = func_null;
 #ifdef TURRET_DEBUG
        float d;
-       d = RadiusDamage (this, this.owner, this.owner.shot_dmg, 0, this.owner.shot_radius, this, NULL, this.owner.shot_force, this.totalfrags, DMG_NOWEP, NULL);
+       d = RadiusDamage (this, this.owner, this.owner.shot_dmg, 0, this.owner.shot_radius, this, NULL, this.owner.shot_force, this.projectiledeathtype, DMG_NOWEP, NULL);
        this.owner.tur_debug_dmg_t_h = this.owner.tur_debug_dmg_t_h + d;
        this.owner.tur_debug_dmg_t_f = this.owner.tur_debug_dmg_t_f + this.owner.shot_dmg;
 #else
-       RadiusDamage (this, this.realowner, this.owner.shot_dmg, 0, this.owner.shot_radius, this, NULL, this.owner.shot_force, this.totalfrags, DMG_NOWEP, NULL);
+       RadiusDamage (this, this.realowner, this.owner.shot_dmg, 0, this.owner.shot_radius, this, NULL, this.owner.shot_force, this.projectiledeathtype, DMG_NOWEP, NULL);
 #endif
        delete(this);
 }
@@ -472,7 +475,7 @@ entity turret_projectile(entity actor, Sound _snd, float _size, float _health, f
        IL_PUSH(g_projectiles, proj);
        IL_PUSH(g_bot_dodge, proj);
        proj.enemy                = actor.enemy;
-       proj.totalfrags  = _death;
+       proj.projectiledeathtype         = _death;
        PROJECTILE_MAKETRIGGER(proj);
        if(_health)
        {
index f7b14b0a65e5641295c962018bd6bd89ee70210f..5191940b1cc49e7244d312588bdfe42375124c58 100644 (file)
@@ -103,3 +103,6 @@ vector tvt_thadv; // turret head angle diff vector, updated by a successful call
 vector tvt_tadv; // turret angle diff vector, updated by a successful call to turret_validate_target
 float tvt_thadf; // turret head angle diff float, updated by a successful call to turret_validate_target
 float tvt_dist; // turret distance, updated by a successful call to turret_validate_target
+
+IntrusiveList g_turrets;
+STATIC_INIT(g_turrets) { g_turrets = IL_NEW(); }
index 64b5e20543f1639d0cf44c38f926262448a6fe71..ef7b60c8e83a2ed393112d1f0f513c7a81ec30af 100644 (file)
@@ -41,11 +41,11 @@ void turret_flac_projectile_think_explode(entity this)
         setorigin(this, this.enemy.origin + randomvec() * this.owner.shot_radius);
 
 #ifdef TURRET_DEBUG
-    float d = RadiusDamage (this, this.owner, this.owner.shot_dmg, this.owner.shot_dmg, this.owner.shot_radius, this, NULL, this.owner.shot_force, this.totalfrags, DMG_NOWEP, NULL);
+    float d = RadiusDamage (this, this.owner, this.owner.shot_dmg, this.owner.shot_dmg, this.owner.shot_radius, this, NULL, this.owner.shot_force, this.projectiledeathtype, DMG_NOWEP, NULL);
     this.owner.tur_debug_dmg_t_h = this.owner.tur_debug_dmg_t_h + d;
     this.owner.tur_debug_dmg_t_f = this.owner.tur_debug_dmg_t_f + this.owner.shot_dmg;
 #else
-    RadiusDamage (this, this.realowner, this.owner.shot_dmg, this.owner.shot_dmg, this.owner.shot_radius, this, NULL, this.owner.shot_force, this.totalfrags, DMG_NOWEP, NULL);
+    RadiusDamage (this, this.realowner, this.owner.shot_dmg, this.owner.shot_dmg, this.owner.shot_radius, this, NULL, this.owner.shot_force, this.projectiledeathtype, DMG_NOWEP, NULL);
 #endif
     delete(this);
 }
index 7273f5a642220820bd7007cd8720c7aad9f1c1ae..beff57489779392c07f7e1ccc876d56eb10bed4c 100644 (file)
@@ -1,5 +1,16 @@
 #include "sv_vehicles.qh"
 
+#include <server/bot/api.qh>
+#include <server/damage.qh>
+#include <server/world.qh>
+#include <server/items/items.qh>
+#include <common/items/_mod.qh>
+#include <common/mapobjects/defs.qh>
+#include <common/mapobjects/teleporters.qh>
+#include <common/mapobjects/triggers.qh>
+#include <server/main.qh>
+#include <server/weapons/common.qh>
+
 bool SendAuxiliaryXhair(entity this, entity to, int sf)
 {
        WriteHeader(MSG_ENTITY, ENT_CLIENT_AUXILIARYXHAIR);
@@ -230,7 +241,7 @@ void vehicles_projectile_explode(entity this, entity toucher)
        PROJECTILE_TOUCH(this, toucher);
 
        this.event_damage = func_null;
-       RadiusDamage (this, this.realowner, this.shot_dmg, 0, this.shot_radius, this, NULL, this.shot_force, this.totalfrags, DMG_NOWEP, toucher);
+       RadiusDamage (this, this.realowner, this.shot_dmg, 0, this.shot_radius, this, NULL, this.shot_force, this.projectiledeathtype, DMG_NOWEP, toucher);
 
        delete(this);
 }
@@ -262,7 +273,7 @@ entity vehicles_projectile(entity this, entity _mzlfx, Sound _mzlsound,
        proj.shot_dmg            = _dmg;
        proj.shot_radius          = _radi;
        proj.shot_force    = _force;
-       proj.totalfrags    = _deahtype;
+       proj.projectiledeathtype           = _deahtype;
        proj.solid                      = SOLID_BBOX;
        set_movetype(proj, MOVETYPE_FLYMISSILE);
        proj.flags = FL_PROJECTILE;
@@ -839,6 +850,7 @@ void vehicles_exit(entity vehic, bool eject)
                        WriteByte (MSG_ONE, SVC_SETVIEWPORT);
                        WriteEntity( MSG_ONE, player);
 
+                       // NOTE: engine networked
                        WriteByte (MSG_ONE, SVC_SETVIEWANGLES);
                        WriteAngle(MSG_ONE, 0);
                        WriteAngle(MSG_ONE, vehic.angles_y);
@@ -1026,7 +1038,7 @@ void vehicles_enter(entity pl, entity veh)
 
        veh.vehicle_hudmodel.viewmodelforclient = pl;
 
-       pl.crouch = false;
+       UNSET_DUCKED(pl);
        pl.view_ofs = STAT(PL_VIEW_OFS, pl);
        setsize(pl, STAT(PL_MIN, pl), STAT(PL_MAX, pl));
 
@@ -1081,6 +1093,7 @@ void vehicles_enter(entity pl, entity veh)
                WriteByte (MSG_ONE, SVC_SETVIEWPORT);
                WriteEntity(MSG_ONE, veh.vehicle_viewport);
 
+               // NOTE: engine networked
                WriteByte (MSG_ONE, SVC_SETVIEWANGLES);
                if(veh.tur_head)
                {
@@ -1205,10 +1218,7 @@ bool vehicle_initialize(entity this, Vehicle info, bool nodrop)
                return false;
 
        if(!this.tur_head)
-       {
                info.vr_precache(info);
-               IL_PUSH(g_vehicles, this);
-       }
 
        if(this.targetname && this.targetname != "")
        {
index 0d707b52fc15af238e7f156772b12a0d58f929fb..a92da29fb03b237f34ba4a4d8be5b0fbc8e90a84 100644 (file)
@@ -67,6 +67,8 @@ const float VHSF_FACTORY = 2;
 
 .float dmg_time;
 
+.float pain_frame;
+
 .float play_time;
 
 .int volly_counter;
index 224f96564e7a0fc7347decf2350fc268b8af92e6..0a8875b48df02cb9a74f7392883d9210d7d0fda5 100644 (file)
@@ -230,6 +230,7 @@ void bumblebee_gunner_exit(entity this, int _exitflag)
                WriteByte(MSG_ONE, SVC_SETVIEWPORT);
                WriteEntity(MSG_ONE, player);
 
+               // NOTE: engine networked
                WriteByte(MSG_ONE, SVC_SETVIEWANGLES);
                WriteAngle(MSG_ONE, 0);
                WriteAngle(MSG_ONE, vehic.angles.y);
@@ -340,6 +341,7 @@ bool bumblebee_gunner_enter(entity this, entity player)
                WriteByte(MSG_ONE,              SVC_SETVIEWPORT);
                WriteEntity(MSG_ONE,    gunner.vehicle_viewport);
 
+               // NOTE: engine networked
                WriteByte(MSG_ONE,              SVC_SETVIEWANGLES);
                WriteAngle(MSG_ONE,     gunner.angles_x + vehic.angles_x); // tilt
                WriteAngle(MSG_ONE,     gunner.angles_y + vehic.angles_y); // yaw
index a0e35e02ee37a9a7a44f948901c77ab3ba406032..423eefd1945bd78b5e1d0401fd19b698c6e06d70 100644 (file)
@@ -1,5 +1,9 @@
 #include "racer.qh"
 
+#if defined(SVQC)
+       #include <common/gamemodes/gamemode/ctf/sv_ctf.qh>
+#endif
+
 #ifdef GAMEQC
 
 #ifdef SVQC
@@ -78,6 +82,7 @@ float autocvar_g_vehicle_racer_bouncestop = 0;
 vector autocvar_g_vehicle_racer_bouncepain = '200 0.15 150';
 
 .float racer_watertime;
+.float racer_air_finished; // TODO: use a standard air meter for entities
 
 var .vector(entity this, string tag_name, float spring_length, float max_power) racer_force_from_tag;
 
@@ -111,7 +116,7 @@ void racer_align4point(entity this, entity player, float _delta)
        {
                uforce = autocvar_g_vehicle_racer_water_upforcedamper;
 
-               if(PHYS_INPUT_BUTTON_CROUCH(player) && time < this.air_finished)
+               if(PHYS_INPUT_BUTTON_CROUCH(player) && time < this.racer_air_finished)
                        this.velocity_z += 30;
                else
                        this.velocity_z += 200;
@@ -163,9 +168,9 @@ bool racer_frame(entity this, float dt)
 
        int cont = Mod_Q1BSP_SuperContentsFromNativeContents(pointcontents(vehic.origin));
        if(!(cont & DPCONTENTS_WATER))
-               vehic.air_finished = 0;
-       else if (!vehic.air_finished)
-               vehic.air_finished = time + autocvar_g_vehicle_racer_water_time;
+               vehic.racer_air_finished = 0;
+       else if (!vehic.racer_air_finished)
+               vehic.racer_air_finished = time + autocvar_g_vehicle_racer_water_time;
 
        if(IS_DEAD(vehic))
        {
index a868eb4aa1f65b9c56d098ceeb779d68ba55038b..6f6e85687069e8d9986db250c707e9678de526d0 100644 (file)
@@ -1,5 +1,9 @@
 #include "raptor.qh"
 
+#if defined(SVQC)
+       #include <common/gamemodes/gamemode/ctf/sv_ctf.qh>
+#endif
+
 #ifdef GAMEQC
 
 #ifdef SVQC
@@ -411,7 +415,7 @@ bool raptor_frame(entity this, float dt)
                bool incoming = false;
                IL_EACH(g_projectiles, it.enemy == vehic,
                {
-                       if(MISSILE_IS_TRACKING(it))
+                       if(it.missile_flags & MIF_GUIDED_TRACKING)
                        if(vdist(vehic.origin - it.origin, <, 2 * autocvar_g_vehicle_raptor_flare_range))
                        {
                                incoming = true;
index e031222714e7b758496115675dbf3ed23b2c6846..069696639f8f1b2bfc6f917ca8e1934ef0cabe68 100644 (file)
@@ -1,5 +1,9 @@
 #include "spiderbot.qh"
 
+#if defined(SVQC)
+       #include <common/gamemodes/gamemode/ctf/sv_ctf.qh>
+#endif
+
 #ifdef GAMEQC
 
 const int SBRM_FIRST = 1;
index c3d70fc509d2d992fae61b7be4d37d2af8df271b..b2d518bcc6134ae4e20018ccf93a412a527cbd63 100644 (file)
@@ -2,11 +2,12 @@
 #include "util.qh"
 
 #if defined(CSQC)
-    #include "../client/defs.qh"
+    #include <client/main.qh>
     #include "constants.qh"
 #elif defined(MENUQC)
 #elif defined(SVQC)
-       #include "../server/defs.qh"
+       #include <common/weapons/_all.qh>
+       #include <common/stats.qh>
 #endif
 
 // client movement
index 9feb5ffe4369ae217f1db46954bca4f70ef1264f..b5bf64a781c517db36bc15c2b8abeed5e868d5ce 100644 (file)
@@ -3,7 +3,6 @@
 #define WEAPONS_ALL_C
 
 #if defined(CSQC)
-       #include <client/defs.qh>
        #include "../constants.qh"
        #include "../stats.qh"
        #include <lib/warpzone/anglestransform.qh>
     #include <common/util.qh>
     #include "../monsters/_mod.qh"
     #include "config.qh"
+    #include <server/weapons/common.qh>
     #include <server/weapons/csqcprojectile.qh>
     #include <server/weapons/tracing.qh>
-    #include "../t_items.qh"
+    #include <server/items/spawning.qh>
     #include <server/autocvars.qh>
-    #include <server/constants.qh>
-    #include <server/defs.qh>
     #include "../notifications/all.qh"
     #include "../deathtypes/all.qh"
     #include <server/mutators/_mod.qh>
@@ -42,7 +40,7 @@
     #include <server/command/_mod.qh>
     #include <lib/csqcmodel/sv_model.qh>
     #include <server/portals.qh>
-    #include <server/g_hook.qh>
+    #include <server/hook.qh>
 #endif
 #ifdef GAMEQC
        #include "calculations.qc"
@@ -803,10 +801,8 @@ NET_HANDLE(w_muzzleflash, bool isNew)
 
        vector md = wepent.movedir_aligned;
        vector vecs = ((md.x > 0) ? md : '0 0 0');
-       vector dv = right * -vecs.y + up * vecs.z;
+       vector dv = forward * vecs.x + right * -vecs.y + up * vecs.z;
        vector org = rlplayer.origin + rlplayer.view_ofs + dv;
-       tracebox(org, '0 0 0', '0 0 0', org + forward * (vecs.x + 1), MOVE_NORMAL, rlplayer);
-       org = trace_endpos - forward * 1;
 
        pointparticles(thiswep.m_muzzleeffect, org, forward * 1000, 1);
 
index 387bb910fdbab55ac6c4e308bd789e47c36f9083..5f79c8ccfa58d622c4607dc5129e73783399b103 100644 (file)
@@ -40,9 +40,7 @@ bool W_Arc_Beam_Send(entity this, entity to, int sf)
        }
        if(sf & ARC_SF_BEAMDIR) // beam direction
        {
-               WriteAngle(MSG_ENTITY, this.beam_dir.x);
-               WriteAngle(MSG_ENTITY, this.beam_dir.y);
-               WriteAngle(MSG_ENTITY, this.beam_dir.z);
+               WriteAngleVector(MSG_ENTITY, this.beam_dir);
        }
        if(sf & ARC_SF_BEAMTYPE) // beam type
        {
@@ -1274,9 +1272,7 @@ NET_HANDLE(ENT_CLIENT_ARC_BEAM, bool isnew)
 
        if(sf & ARC_SF_BEAMDIR) // beam direction
        {
-               this.angles_x = ReadAngle();
-               this.angles_y = ReadAngle();
-               this.angles_z = ReadAngle();
+               this.angles = ReadAngleVector();
        }
 
        if(sf & ARC_SF_BEAMTYPE) // beam type
index da2660b89e2ece43a4001f518393fede8a0eaf43..3bc2258207990046fa27fc71cc8428e45b00c709 100644 (file)
@@ -27,7 +27,7 @@ void W_HLAC_Attack(Weapon thiswep, entity actor, .entity weaponentity)
 
     spread = WEP_CVAR_PRI(hlac, spread_min) + (WEP_CVAR_PRI(hlac, spread_add) * actor.(weaponentity).misc_bulletcounter);
     spread = min(spread,WEP_CVAR_PRI(hlac, spread_max));
-    if(actor.crouch)
+    if(IS_DUCKED(actor))
         spread = spread * WEP_CVAR_PRI(hlac, spread_crouchmod);
 
        W_SetupShot(actor, weaponentity, false, 3, SND_LASERGUN_FIRE, CH_WEAPON_A, WEP_CVAR_PRI(hlac, damage), thiswep.m_id);
@@ -77,7 +77,7 @@ void W_HLAC_Attack2(Weapon thiswep, entity actor, .entity weaponentity)
     spread = WEP_CVAR_SEC(hlac, spread);
 
 
-    if(actor.crouch)
+    if(IS_DUCKED(actor))
         spread = spread * WEP_CVAR_SEC(hlac, spread_crouchmod);
 
        W_SetupShot(actor, weaponentity, false, 3, SND_LASERGUN_FIRE, CH_WEAPON_A, WEP_CVAR_SEC(hlac, damage), thiswep.m_id | HITTYPE_SECONDARY);
index b822eee68a162a3f327003d4f02e3a3318ab31a6..dc79d74ac70ab380798bed7b2ab602a6aef3d248 100644 (file)
@@ -63,4 +63,7 @@ void W_MineLayer_Think(entity this);
 .float minelayer_detonate, mine_explodeanyway;
 .float mine_time;
 .vector mine_orientation;
+
+IntrusiveList g_mines;
+STATIC_INIT(g_mines) { g_mines = IL_NEW(); }
 #endif
index 29820ef06baba6f4cc88eefbee9db167cd5a6246..6c1a6e7f2957a9ba08e14539df9ff66e9225a5dc 100644 (file)
@@ -50,4 +50,5 @@ void Porto_Draw(entity this);
 .float porto_forbidden;
 
 void W_Porto_Fail(entity this, float failhard);
+void W_Porto_Remove (entity p);
 #endif
index f38c34b19791182d9127b58a6459d12d8cc332db..accb917f687e460c05108fd8fd91f71e756f3ecb 100644 (file)
@@ -479,7 +479,7 @@ void W_Shockwave_Attack(Weapon thiswep, entity actor, .entity weaponentity)
                        //  BLAST CONE CALCULATION
                        // ========================
 
-                       // if it's a player, use the view origin as reference (stolen from RadiusDamage functions in g_damage.qc)
+                       // if it's a player, use the view origin as reference (stolen from RadiusDamage functions in damage.qc)
                        center = CENTER_OR_VIEWOFS(head);
 
                        // find the closest point on the enemy to the center of the attack
index a2b0a4b1db0689513c614286f020264ecfc41b93..74bf35ce4337c9ab1bf31778c4892529a2e2183b 100644 (file)
@@ -68,6 +68,8 @@ SPAWNFUNC_WEAPON(weapon_vortex, WEP_VORTEX)
 SPAWNFUNC_WEAPON(weapon_nex, WEP_VORTEX)
 
 #ifdef SVQC
+.float vortex_charge_rottime;
+
 .float vortex_lasthit;
 
 void W_Vortex_Charge(entity actor, .entity weaponentity, float dt);
index 5e78207d4a7986ea754e0a0dc692e96d86b391c1..3d751035b029f4b186c5af77ca8f3582bf558933 100644 (file)
@@ -36,10 +36,10 @@ MACRO_END
     \
     PROP(false, porto_v_angle_held, WEPENT_SET_NORMAL, \
        { WriteByte(chan, this.porto_v_angle_held); if(this.porto_v_angle_held) { \
-                WriteAngle(chan, this.owner.porto_v_angle.x); WriteAngle(chan, this.owner.porto_v_angle.y); \
+                WriteAngleVector2D(chan, this.owner.porto_v_angle); \
                } }, \
        { (viewmodels[this.m_wepent_slot]).angles_held_status = ReadByte(); if((viewmodels[this.m_wepent_slot]).angles_held_status) { \
-               (viewmodels[this.m_wepent_slot]).angles_held = vec2(ReadAngle(), ReadAngle()); } \
+               (viewmodels[this.m_wepent_slot]).angles_held = ReadAngleVector2D(); } \
                else { (viewmodels[this.m_wepent_slot]).angles_held = '0 0 0'; } }) \
     \
     PROP(false, tuba_instrument, WEPENT_SET_NORMAL, \
index ef2ca0b9f26b43f35ab02a28030c064b2a8cabee..d8ea2a070c4cb26031d99965d3a6d018c39ff4a9 100644 (file)
@@ -219,7 +219,7 @@ vector CSQCPlayer_ApplySmoothing(entity this, vector v)
        float smoothtime = bound(0, time - smooth_prevtime, 0.1);
        smooth_prevtime = max(smooth_prevtime, drawtime); // drawtime is the previous frame's time at this point
 
-       if(this.csqcmodel_teleported || !(this.pmove_flags & PMF_ONGROUND) || autocvar_cl_stairsmoothspeed <= 0)
+       if(this.csqcmodel_teleported || !(this.pmove_flags & PMF_ONGROUND) || autocvar_cl_stairsmoothspeed <= 0 || this.ground_networkentity)
                stairsmoothz = v.z;
        else
        {
index 92948dc5a92d119b34485fe649823fa67f0960a6..af708da25170f30287fb59507dc3c17c75034dca 100644 (file)
@@ -35,8 +35,6 @@ const int PMF_JUMP_HELD = 1;
 //const int PMF_DUCKED = 4;
 //const int PMF_ONGROUND = 8;
 
-const int FL_DUCKED = BIT(19);
-
 void CSQCPlayer_SetCamera();
 float CSQCPlayer_PreUpdate(entity this);
 float CSQCPlayer_PostUpdate(entity this);
index dbac8b8b190f90a6923ee30239ba4a9b7429c185..82ae7c58dde6383faf684a1796d17a0a5f49215b 100644 (file)
@@ -5,7 +5,8 @@
        #include "i18n.qh"
        #include "vector.qh"
 
-       float vid_conwidth;
+       noref float vid_conwidth;
+       noref float vid_conheight;
 
        void Draw_CylindricLine(vector from, vector to, float thickness, string texture, float aspect, float shift, vector rgb, float theAlpha, float drawflag, vector vieworg)
        {
index 3cec9fd9ba8734a9ed1b9ff52014a05a5787e821..522b4ff2301f86b4e22f8c6d008e79a4f8103f83 100644 (file)
@@ -357,6 +357,8 @@ MACRO_END
                #define ReadFloat() ReadCoord()
                #define ReadVector() vec3(ReadFloat(), ReadFloat(), ReadFloat())
                #define ReadVector2D() vec2(ReadFloat(), ReadFloat())
+               #define ReadAngleVector() vec3(ReadAngle(), ReadAngle(), ReadAngle())
+               #define ReadAngleVector2D() vec2(ReadAngle(), ReadAngle())
 
                int Readbits(int num)
                {
@@ -397,6 +399,8 @@ MACRO_END
                #define WriteFloat(to, f) WriteCoord(to, f)
                #define WriteVector(to, v) MACRO_BEGIN WriteFloat(to, v.x); WriteFloat(to, v.y); WriteFloat(to, v.z); MACRO_END
                #define WriteVector2D(to, v) MACRO_BEGIN WriteFloat(to, v.x); WriteFloat(to, v.y); MACRO_END
+               #define WriteAngleVector(to, v) MACRO_BEGIN WriteAngle(to, v.x); WriteAngle(to, v.y); WriteAngle(to, v.z); MACRO_END
+               #define WriteAngleVector2D(to, v) MACRO_BEGIN WriteAngle(to, v.x); WriteAngle(to, v.y); MACRO_END
 
                void Writebits(float dst, float val, int num)
                {
index 120551b4e3595dccc9506f4fea2908639c4095cf..830c56de65f0cca4834131760898e93b9a148006 100644 (file)
@@ -1,7 +1,7 @@
 #include "common.qh"
 
 #if defined(CSQC)
-    #include <common/t_items.qh>
+    #include <client/items/items.qh>
 #elif defined(MENUQC)
 #elif defined(SVQC)
     #include <common/weapons/_all.qh>
index 66ee6b133c22b2ef98cc1e1e4aae614ed21ae79d..1036ab0c8d2e1177981f957d0044e37913da3f5e 100644 (file)
@@ -7,9 +7,10 @@
        #include <common/constants.qh>
        #include <common/net_linked.qh>
        #include <common/mapobjects/subs.qh>
+       #include <common/mapobjects/teleporters.qh>
        #include <common/util.qh>
-       #include <server/constants.qh>
-       #include <server/defs.qh>
+       #include <common/weapons/_all.qh>
+       #include <common/stats.qh>
        #include <server/utils.qh>
 #endif
 
index b57d7cae8a8f536a643b67d25c1c7275a61801b6..822e2c32dd85a6058b903c99a5b891da7129aa00 100644 (file)
@@ -55,6 +55,7 @@ void XonoticGameModelSettingsTab_fill(entity me)
                        e.addValue(e, _("Never"), "0");
                        e.addValue(e, _("In non teamplay modes only"), "1");
                        e.addValue(e, _("Always"), "2");
+                       e.addValue(e, _("Only in Duel"), "3");
                        e.configureXonoticTextSliderValues(e);
        me.TR(me);
                me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Body fading:")));
index 6c66dd95f015f374bd6376a66059f18054ceecd2..0da2e2be4cc5f09c8d3452f798ab10801619b675 100644 (file)
@@ -5,14 +5,14 @@
 #include <server/cheats.qc>
 #include <server/client.qc>
 #include <server/clientkill.qc>
-#include <server/g_damage.qc>
-#include <server/g_hook.qc>
-#include <server/g_world.qc>
+#include <server/damage.qc>
+#include <server/hook.qc>
+#include <server/world.qc>
 #include <server/gamelog.qc>
 #include <server/handicap.qc>
 #include <server/impulse.qc>
 #include <server/ipban.qc>
-#include <server/items.qc>
+#include <server/main.qc>
 #include <server/mapvoting.qc>
 #include <server/matrix.qc>
 #include <server/miscfunctions.qc>
 #include <server/scores_rules.qc>
 #include <server/spawnpoints.qc>
 #include <server/steerlib.qc>
-#ifdef SVQC
-    #include <server/sv_main.qc>
-#endif
 #include <server/teamplay.qc>
 #include <server/tests.qc>
 
 #include <server/bot/_mod.inc>
 #include <server/command/_mod.inc>
 #include <server/compat/_mod.inc>
+#include <server/items/_mod.inc>
 #include <server/mutators/_mod.inc>
 #include <server/pathlib/_mod.inc>
 #include <server/weapons/_mod.inc>
index 06bb03df306d21faa905473d127f9922156ed4c0..67080b3687838d623afcfe4e11e8eaa602730df8 100644 (file)
@@ -5,14 +5,14 @@
 #include <server/cheats.qh>
 #include <server/client.qh>
 #include <server/clientkill.qh>
-#include <server/g_damage.qh>
-#include <server/g_hook.qh>
-#include <server/g_world.qh>
+#include <server/damage.qh>
+#include <server/hook.qh>
+#include <server/world.qh>
 #include <server/gamelog.qh>
 #include <server/handicap.qh>
 #include <server/impulse.qh>
 #include <server/ipban.qh>
-#include <server/items.qh>
+#include <server/main.qh>
 #include <server/mapvoting.qh>
 #include <server/matrix.qh>
 #include <server/miscfunctions.qh>
 #include <server/scores_rules.qh>
 #include <server/spawnpoints.qh>
 #include <server/steerlib.qh>
-#ifdef SVQC
-    #include <server/sv_main.qh>
-#endif
 #include <server/teamplay.qh>
 #include <server/tests.qh>
 
 #include <server/bot/_mod.qh>
 #include <server/command/_mod.qh>
 #include <server/compat/_mod.qh>
+#include <server/items/_mod.qh>
 #include <server/mutators/_mod.qh>
 #include <server/pathlib/_mod.qh>
 #include <server/weapons/_mod.qh>
index fa4af040b5e367cc436e8171076e19f61cb9d2d1..7e8e5066020e19df88acccd737838c93184a6b63 100644 (file)
@@ -2,8 +2,11 @@
 
 #include "antilag.qh"
 #include "autocvars.qh"
-#include "defs.qh"
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
+#include <server/client.qh>
 #include <server/gamelog.qh>
+#include <server/main.qh>
 #include "miscfunctions.qh"
 
 #include "command/common.qh"
index 93ca6acf93eba5b7204c3dd0d4353a5b4a9901dd..d116bc10918b97fa480d665a1745bc23a765d2f8 100644 (file)
@@ -2,8 +2,11 @@
 #if defined(CSQC)
 #elif defined(MENUQC)
 #elif defined(SVQC)
-    #include <server/defs.qh>
+    #include <common/weapons/_all.qh>
+    #include <common/stats.qh>
+    #include <server/weapons/common.qh>
     #include <common/state.qh>
+    #include <common/monsters/sv_monsters.qh>
     #include <common/vehicles/all.qh>
        #include <lib/warpzone/common.qh>
     #include "antilag.qh"
index 81baa2c196dd5042c2610de8707282272527797e..5ee3963cbbe21d00d3d6ac546214da98a0d16a24 100644 (file)
@@ -1,9 +1,12 @@
 #pragma once
 
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 #include <common/weapons/_all.qh>
 #include <common/physics/player.qh>
 
+bool bot_waypoints_for_items;
+
 const int WAYPOINTFLAG_GENERATED = BIT(23);
 const int WAYPOINTFLAG_ITEM = BIT(22);
 const int WAYPOINTFLAG_TELEPORT = BIT(21); // teleports, warpzones and jumppads
@@ -95,6 +98,11 @@ float havocbot_symmetry_origin_order;
 .float ignoregoaltime;
 .entity ignoregoal;
 
+bool bots_would_leave;
+
+int player_count;
+int currentbots;
+
 .entity bot_basewaypoint;
 .bool navigation_dynamicgoal;
 void navigation_dynamicgoal_init(entity this, bool initially_static);
@@ -136,3 +144,13 @@ void waypoint_lock(entity pl);
 
 void waypoint_getSymmetricalOrigin_cmd(entity caller, bool save, int arg_idx);
 void waypoint_getSymmetricalAxis_cmd(entity caller, bool save, int arg_idx);
+
+IntrusiveList g_waypoints;
+IntrusiveList g_bot_targets;
+IntrusiveList g_bot_dodge;
+STATIC_INIT(botapi)
+{
+       g_waypoints = IL_NEW();
+       g_bot_targets = IL_NEW();
+       g_bot_dodge = IL_NEW();
+}
index 21506d07523e406f0a5591d84f4c302668321f15..fc6755fb040e2d31edeed6de13d19989677a8f8b 100644 (file)
@@ -1,6 +1,7 @@
 #include "aim.qh"
 
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 
 #include "cvars.qh"
 
index 57de9f05cefecc0376946dd8d5ec26ae0017f689..c42a053f45c8a421a8a0fff54fa1ade1023e172d 100644 (file)
 #include "../../autocvars.qh"
 #include "../../campaign.qh"
 #include "../../client.qh"
-#include "../../constants.qh"
-#include "../../defs.qh"
+#include <common/stats.qh>
+#include <server/world.qh>
+#include <server/damage.qh>
 #include "../../race.qh"
-#include <common/t_items.qh>
+#include <server/items/items.qh>
 
 #include <server/mutators/_mod.qh>
 
index 0ff47977762180e7eb5688d9215e3623ccd0fafe..40a07a44c43c1d23422b88edcfd438bf95ec00d5 100644 (file)
@@ -2,8 +2,15 @@
 
 #include "roles.qh"
 
-#include <server/defs.qh>
+#include <server/bot/api.qh>
+#include <server/client.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
+#include <server/damage.qh>
+#include <server/items/items.qh>
 #include <server/miscfunctions.qh>
+#include <server/weapons/selection.qh>
+#include <server/weapons/weaponsystem.qh>
 #include "../cvars.qh"
 
 #include "../aim.qh"
@@ -22,6 +29,7 @@
 
 #include <common/mapobjects/func/ladder.qh>
 #include <common/mapobjects/teleporters.qh>
+#include <common/mapobjects/trigger/hurt.qh>
 #include <common/mapobjects/trigger/jumppads.qh>
 
 #include <lib/warpzone/common.qh>
index d078cae8604903d461bf824bb3a8b4283f0b7755..9c95fb87ba8d955fa6a2af70115f465b5ec1ca2d 100644 (file)
@@ -1,8 +1,10 @@
 #include "roles.qh"
 
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 #include <server/miscfunctions.qh>
-#include <server/items.qh>
+#include <server/items/items.qh>
+#include <server/items/spawning.qh>
 #include <server/resources.qh>
 #include "havocbot.qh"
 
index fe608d1f55ac26de10917346710bff7de2e6ff68..cf7cd99c2199f6e49b1761d5c060404b51dde7ad 100644 (file)
@@ -1,19 +1,22 @@
 #include "navigation.qh"
 
-#include <server/defs.qh>
+#include <server/bot/api.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 #include <server/miscfunctions.qh>
 #include "cvars.qh"
 
 #include "bot.qh"
 #include "waypoints.qh"
 
-#include <common/t_items.qh>
+#include <server/items/items.qh>
 
 #include <common/items/_mod.qh>
 
 #include <common/constants.qh>
 #include <common/net_linked.qh>
 #include <common/mapobjects/func/ladder.qh>
+#include <common/mapobjects/trigger/hurt.qh>
 #include <common/mapobjects/trigger/jumppads.qh>
 
 .float speed;
index 20b29a86cc10ca9ffd6b7e318acaada0a037765c..94c849650f9bbc47b73cfdee073a1a668ae25366 100644 (file)
@@ -1,10 +1,14 @@
 #include "scripting.qh"
 
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 #include <server/miscfunctions.qh>
+#include <server/weapons/selection.qh>
+#include <server/weapons/weaponsystem.qh>
 #include "cvars.qh"
 
 #include <common/state.qh>
+#include <common/gamemodes/gamemode/ctf/sv_ctf.qh>
 #include <common/physics/player.qh>
 #include <common/wepent.qh>
 
index b4e6df09c60b50fd27e6ff540d810b19d53f6625..a9069a0b158ac58cdf394339c28ac171781bf285 100644 (file)
@@ -1,7 +1,10 @@
 #include "waypoints.qh"
 
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
+#include <server/items/items.qh>
 #include <server/miscfunctions.qh>
+#include <server/spawnpoints.qh>
 #include "cvars.qh"
 
 #include "bot.qh"
index 784288a6ee555b50dbf6637f238f0b4a4168bc92..de46e57d508f12fcdb37a95f38da8ebee27da7ac 100644 (file)
@@ -1,10 +1,11 @@
 #include "campaign.qh"
 
-#include "defs.qh"
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 
 #include "cheats.qh"
 #include "miscfunctions.qh"
-#include "g_world.qh"
+#include "world.qh"
 
 #include "../common/campaign_common.qh"
 
index eda0838fd24e61d6a9a34078a936edefba74f15f..9d5cc1d42e3a051760ad5c528382d6448b465a2a 100644 (file)
@@ -1,11 +1,13 @@
 #include "cheats.qh"
 
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 #include <server/miscfunctions.qh>
 #include <common/effects/all.qh>
 #include <server/resources.qh>
+#include <server/main.qh>
 
-#include "g_damage.qh"
+#include "damage.qh"
 #include "clientkill.qh"
 #include "player.qh"
 #include "race.qh"
@@ -23,6 +25,8 @@
 
 #include "../common/monsters/_mod.qh"
 
+#include <common/items/_mod.qh>
+
 #include <common/weapons/_all.qh>
 
 #include "../common/mapobjects/subs.qh"
index 962e017a19d6dad9e4919c86d53b20bb92efb84c..4a730d77f9196a3da6e0be888d2aa9b0ab96cb52 100644 (file)
@@ -14,6 +14,13 @@ float CheatFrame(entity this);
 
 const float CHRAME_DRAG = 8;
 
+// speedrun: when 1, player auto teleports back when capture timeout happens
+.bool speedrunning;
+
+.entity personal;
+
+.int grab; // 0 = can't grab, 1 = owner can grab, 2 = owner and team mates can grab, 3 = anyone can grab
+
 bool drag_undraggable(entity draggee, entity dragger);
 
 .bool(entity this, entity dragger) draggable;
index 1211e8988ea98b65c5fb90ac8f952a3c0e540067..0a9a38fafe3c6b68666345b36b46a000c08a5246 100644 (file)
@@ -1,6 +1,7 @@
 #include "client.qh"
 
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 #include <server/miscfunctions.qh>
 #include <common/effects/all.qh>
 #include "anticheat.qh"
 #include "teamplay.qh"
 #include "spawnpoints.qh"
 #include "resources.qh"
-#include "g_damage.qh"
+#include "damage.qh"
 #include "handicap.qh"
-#include "g_hook.qh"
+#include "hook.qh"
 #include "command/common.qh"
 #include "command/vote.qh"
 #include "clientkill.qh"
 #include "cheats.qh"
-#include "g_world.qh"
+#include "world.qh"
 #include <server/gamelog.qh>
 #include "race.qh"
+#include <server/main.qh>
 #include "antilag.qh"
 #include "campaign.qh"
 #include "command/common.qh"
@@ -48,6 +50,7 @@
 #include "../common/vehicles/all.qh"
 
 #include "weapons/hitplot.qh"
+#include "weapons/selection.qh"
 #include "weapons/weaponsystem.qh"
 
 #include "../common/net_notice.qh"
@@ -58,6 +61,8 @@
 
 #include "../common/items/_mod.qh"
 
+#include <common/gamemodes/gamemode/nexball/sv_nexball.qh>
+
 #include "../common/mutators/mutator/waypoints/all.qh"
 #include "../common/mutators/mutator/instagib/sv_instagib.qh"
 #include <common/gamemodes/_mod.qh>
@@ -76,6 +81,8 @@
 
 #include <common/mutators/mutator/overkill/oknex.qh>
 
+#include <common/weapons/weapon/vortex.qh>
+
 STATIC_METHOD(Client, Add, void(Client this, int _team))
 {
     ClientConnect(this);
@@ -114,9 +121,13 @@ void WriteSpectators(entity player, entity to)
 {
        if(!player) { return; } // not sure how, but best to be safe
 
+       int spec_count = 0;
        FOREACH_CLIENT(IS_REAL_CLIENT(it) && IS_SPEC(it) && it != to && it.enemy == player,
        {
+               if(spec_count >= MAX_SPECTATORS)
+                       break;
                WriteByte(MSG_ENTITY, num_for_edict(it));
+               ++spec_count;
        });
 }
 
@@ -334,12 +345,11 @@ void PutObserverInServer(entity this)
        this.alpha = 0;
        this.scale = 0;
        this.fade_time = 0;
-       this.pain_frame = 0;
        this.pain_finished = 0;
        STAT(STRENGTH_FINISHED, this) = 0;
        STAT(INVINCIBLE_FINISHED, this) = 0;
        STAT(SUPERWEAPONS_FINISHED, this) = 0;
-       this.air_finished = 0;
+       STAT(AIR_FINISHED, this) = 0;
        //this.dphitcontentsmask = 0;
        this.dphitcontentsmask = DPCONTENTS_SOLID;
        if (autocvar_g_playerclip_collisions)
@@ -349,7 +359,7 @@ void PutObserverInServer(entity this)
        setthink(this, func_null);
        this.nextthink = 0;
        this.deadflag = DEAD_NO;
-       this.crouch = false;
+       UNSET_DUCKED(this);
        STAT(REVIVE_PROGRESS, this) = 0;
        this.revival_time = 0;
        this.draggable = drag_undraggable;
@@ -617,7 +627,6 @@ void PutPlayerInServer(entity this)
        bool q3dfcompat = autocvar_sv_q3defragcompat && autocvar_sv_q3defragcompat_changehitbox;
        this.scale = ((q3dfcompat) ? 0.9 : autocvar_sv_player_scale);
        this.fade_time = 0;
-       this.pain_frame = 0;
        this.pain_finished = 0;
        this.pushltime = 0;
        setthink(this, func_null); // players have no think function
@@ -650,7 +659,7 @@ void PutPlayerInServer(entity this)
        STAT(BUFFS, this) = 0;
        STAT(BUFF_TIME, this) = 0;
 
-       this.air_finished = 0;
+       STAT(AIR_FINISHED, this) = 0;
        this.waterlevel = WATERLEVEL_NONE;
        this.watertype = CONTENT_EMPTY;
 
@@ -678,7 +687,7 @@ void PutPlayerInServer(entity this)
 
        this.spawnpoint_targ = NULL;
 
-       this.crouch = false;
+       UNSET_DUCKED(this);
        this.view_ofs = STAT(PL_VIEW_OFS, this);
        setsize(this, STAT(PL_MIN, this), STAT(PL_MAX, this));
        this.spawnorigin = spot.origin;
@@ -1309,6 +1318,91 @@ void UpdateChatBubble(entity this)
        }
 }
 
+void calculate_player_respawn_time(entity this)
+{
+       if(MUTATOR_CALLHOOK(CalculateRespawnTime, this))
+               return;
+
+       float gametype_setting_tmp;
+       float sdelay_max = GAMETYPE_DEFAULTED_SETTING(respawn_delay_max);
+       float sdelay_small = GAMETYPE_DEFAULTED_SETTING(respawn_delay_small);
+       float sdelay_large = GAMETYPE_DEFAULTED_SETTING(respawn_delay_large);
+       float sdelay_small_count = GAMETYPE_DEFAULTED_SETTING(respawn_delay_small_count);
+       float sdelay_large_count = GAMETYPE_DEFAULTED_SETTING(respawn_delay_large_count);
+       float waves = GAMETYPE_DEFAULTED_SETTING(respawn_waves);
+
+       float pcount = 1;  // Include myself whether or not team is already set right and I'm a "player".
+       if (teamplay)
+       {
+               FOREACH_CLIENT(IS_PLAYER(it) && it != this, {
+                       if(it.team == this.team)
+                               ++pcount;
+               });
+               if (sdelay_small_count == 0)
+                       sdelay_small_count = 1;
+               if (sdelay_large_count == 0)
+                       sdelay_large_count = 1;
+       }
+       else
+       {
+               FOREACH_CLIENT(IS_PLAYER(it) && it != this, {
+                       ++pcount;
+               });
+               if (sdelay_small_count == 0)
+               {
+                       if (IS_INDEPENDENT_PLAYER(this))
+                       {
+                               // Players play independently. No point in requiring enemies.
+                               sdelay_small_count = 1;
+                       }
+                       else
+                       {
+                               // Players play AGAINST each other. Enemies required.
+                               sdelay_small_count = 2;
+                       }
+               }
+               if (sdelay_large_count == 0)
+               {
+                       if (IS_INDEPENDENT_PLAYER(this))
+                       {
+                               // Players play independently. No point in requiring enemies.
+                               sdelay_large_count = 1;
+                       }
+                       else
+                       {
+                               // Players play AGAINST each other. Enemies required.
+                               sdelay_large_count = 2;
+                       }
+               }
+       }
+
+       float sdelay;
+
+       if (pcount <= sdelay_small_count)
+               sdelay = sdelay_small;
+       else if (pcount >= sdelay_large_count)
+               sdelay = sdelay_large;
+       else  // NOTE: this case implies sdelay_large_count > sdelay_small_count.
+               sdelay = sdelay_small + (sdelay_large - sdelay_small) * (pcount - sdelay_small_count) / (sdelay_large_count - sdelay_small_count);
+
+       if(waves)
+               this.respawn_time = ceil((time + sdelay) / waves) * waves;
+       else
+               this.respawn_time = time + sdelay;
+
+       if(sdelay < sdelay_max)
+               this.respawn_time_max = time + sdelay_max;
+       else
+               this.respawn_time_max = this.respawn_time;
+
+       if((sdelay + waves >= 5.0) && (this.respawn_time - time > 1.75))
+               this.respawn_countdown = 10; // first number to count down from is 10
+       else
+               this.respawn_countdown = -1; // do not count down
+
+       if(autocvar_g_forced_respawn)
+               this.respawn_flags = this.respawn_flags | RESPAWN_FORCE;
+}
 
 // LordHavoc: this hack will be removed when proper _pants/_shirt layers are
 // added to the model skins
@@ -1723,7 +1817,7 @@ void SpectateCopy(entity this, entity spectatee)
        STAT(STRENGTH_FINISHED, this) = STAT(STRENGTH_FINISHED, spectatee);
        STAT(INVINCIBLE_FINISHED, this) = STAT(INVINCIBLE_FINISHED, spectatee);
        STAT(SUPERWEAPONS_FINISHED, this) = STAT(SUPERWEAPONS_FINISHED, spectatee);
-       this.air_finished = spectatee.air_finished;
+       STAT(AIR_FINISHED, this) = STAT(AIR_FINISHED, spectatee);
        STAT(PRESSED_KEYS, this) = STAT(PRESSED_KEYS, spectatee);
        STAT(WEAPONS, this) = STAT(WEAPONS, spectatee);
        this.punchangle = spectatee.punchangle;
@@ -2267,7 +2361,6 @@ bool PlayerThink(entity this)
                this.dmg_team = max(0, this.dmg_team - autocvar_g_teamdamage_resetspeed * frametime);
        }
 
-       secrets_setstatus(this);
        monsters_setstatus(this);
 
        return true;
@@ -2612,21 +2705,21 @@ void DrownPlayer(entity this)
        if(IS_DEAD(this) || game_stopped || time < game_starttime || this.vehicle
                || STAT(FROZEN, this) || this.watertype != CONTENT_WATER)
        {
-               this.air_finished = 0;
+               STAT(AIR_FINISHED, this) = 0;
                return;
        }
 
        if (this.waterlevel != WATERLEVEL_SUBMERGED)
        {
-               if(this.air_finished && this.air_finished < time)
+               if(STAT(AIR_FINISHED, this) && STAT(AIR_FINISHED, this) < time)
                        PlayerSound(this, playersound_gasp, CH_PLAYER, VOL_BASE, VOICETYPE_PLAYERSOUND);
-               this.air_finished = 0;
+               STAT(AIR_FINISHED, this) = 0;
        }
        else
        {
-               if (!this.air_finished)
-                       this.air_finished = time + autocvar_g_balance_contents_drowndelay;
-               if (this.air_finished < time)
+               if (!STAT(AIR_FINISHED, this))
+                       STAT(AIR_FINISHED, this) = time + autocvar_g_balance_contents_drowndelay;
+               if (STAT(AIR_FINISHED, this) < time)
                {       // drown!
                        if (this.pain_finished < time)
                        {
index 2f380ae2fda49fdf68d9ba6cd6186a8f7f7fe146..e288bebfcb27ad10248c46fdd8ec2acbb22f1ecd 100644 (file)
@@ -1,8 +1,33 @@
 #pragma once
 
 #include "utils.qh"
+#include <common/replicate.qh>
 #include <common/sounds/all.qh>
 
+// WEAPONTODO
+.string weaponorder_byimpulse;
+
+.entity clientdata;
+
+.float jointime; // time of connecting
+.float startplaytime; // time of switching from spectator to player
+.float alivetime; // time of being alive
+.float motd_actived_time; // used for both motd and campaign_message
+
+.bool wasplayer;
+
+.int spectatee_status;
+.bool zoomstate;
+
+.bool just_joined;
+
+.int pressedkeys;
+
+.int playerid;
+
+.string playermodel;
+.string playerskin;
+
 void ClientState_attach(entity this);
 
 IntrusiveList g_players;
@@ -231,8 +256,86 @@ METHOD(Client, m_unwind, bool(Client this))
     return false;
 }
 
+int autocvar__independent_players;
+bool independent_players;
+#define INDEPENDENT_PLAYERS (autocvar__independent_players ? (autocvar__independent_players > 0) : independent_players)
+#define IS_INDEPENDENT_PLAYER(e) ((e).solid == SOLID_TRIGGER)
+#define MAKE_INDEPENDENT_PLAYER(e) (((e).solid = SOLID_TRIGGER), ((e).frags = FRAGS_PLAYER_OUT_OF_GAME))
+
+.int killcount;
+
+//flood fields
+.float nickspamtime; // time of last nick change
+.float nickspamcount;
+.float floodcontrol_chat;
+.float floodcontrol_chatteam;
+.float floodcontrol_chattell;
+.float floodcontrol_voice;
+.float floodcontrol_voiceteam;
+
+// respawning
+.int respawn_flags;
+.float respawn_time;
+.float respawn_time_max;
+
+.float respawn_countdown; // next number to count
+
+const int RESPAWN_FORCE = BIT(0);
+const int RESPAWN_SILENT = BIT(1);
+const int RESPAWN_DENY = BIT(2);
+
+float blockSpectators; // if set, new or existing spectators or observers will be removed unless they become a player within g_maxplayers_spectator_blocktime seconds
+.float spectatortime; // point in time since the client is spectating or observing
+
+.bool player_blocked;
+
+const int SVC_SETVIEW = 5; // TODO: move to dpdefs where this belongs!
+
+// TODO: standardise resource regeneration
+.float pauseregen_finished;
+.float pauserothealth_finished;
+.float pauserotarmor_finished;
+.float pauserotfuel_finished;
+
+// idle kicking
+float sv_maxidle;
+float sv_maxidle_spectatorsareidle;
+int sv_maxidle_slots;
+bool sv_maxidle_slots_countbots;
+
+// g_<gametype>_str:
+// If 0, default is used.
+// If <0, 0 is used.
+// Otherwise, g_str (default value) is used.
+// For consistency, negative values there are mapped to zero too.
+#define GAMETYPE_DEFAULTED_SETTING(str) \
+    ((gametype_setting_tmp = cvar(strcat("g_", GetGametype(), "_" #str))), \
+    (gametype_setting_tmp < 0) ? 0 \
+    : (gametype_setting_tmp == 0 || autocvar_g_respawn_delay_forced) ? max(0, autocvar_g_##str) \
+    : gametype_setting_tmp)
+
+void calculate_player_respawn_time(entity this);
+
 bool PlayerInList(entity player, string list);
 
+void ClientData_Touch(entity e);
+
+int nJoinAllowed(entity this, entity ignore);
+
+void FixIntermissionClient(entity e);
+
+void checkSpectatorBlock(entity this);
+
+void PlayerUseKey(entity this);
+
+void FixClientCvars(entity e);
+
+// called when a client connects, useful for updating sounds and such of static objects
+.void(entity this, entity player) init_for_player;
+
+IntrusiveList g_initforplayer;
+STATIC_INIT(g_initforplayer) { g_initforplayer = IL_NEW(); }
+
 /// \brief Print the string to the client's chat.
 /// \param[in] client Client to print to.
 /// \param[in] text Text to print.
@@ -291,3 +394,5 @@ void Join(entity this);
 #define SPECTATE_COPYFIELD(fld) SPECTATE_COPY() { this.(fld) = spectatee.(fld); }
 
 int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodcontrol);
+
+const int MAX_SPECTATORS = 7;
index 51b133636756d558d79cae3d7371d5617a99660d..73ccb383d40fe3f2c355b325c3eb3846f15e8541 100644 (file)
@@ -1,11 +1,15 @@
 #include "clientkill.qh"
 
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
+#include <server/client.qh>
+#include <server/player.qh>
 
-#include "g_damage.qh"
+#include "damage.qh"
 #include "teamplay.qh"
 
 #include <common/vehicles/sv_vehicles.qh>
+#include <common/mapobjects/triggers.qh>
 #include <common/notifications/all.qh>
 #include <common/stats.qh>
 
index 42de51882e81d8f6f39d2d1585875028604ea3db..962a8a1a8c203551e5af591a87f27ca6c3ec54f1 100644 (file)
@@ -1,6 +1,7 @@
 #include "banning.qh"
 
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 #include <server/miscfunctions.qh>
 #include <common/state.qh>
 #include <common/command/_mod.qh>
index 925a16012e735c58d3ae0c71d8ed6c995fa56e26..fe92d36673552852495602cd46b6d798450b752f 100644 (file)
@@ -1,6 +1,6 @@
 #include "cmd.qh"
 
-#include <server/defs.qh>
+#include <server/world.qh>
 #include <server/miscfunctions.qh>
 
 #include <common/command/_mod.qh>
index 32ccd883e97d28d0ebbce901bdd67cf8e2b4399d..0f59802dd5960e3bdfb72230a7d2d877584ee00a 100644 (file)
@@ -1,6 +1,9 @@
 #include "common.qh"
 
-#include <server/defs.qh>
+#include <server/client.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
+#include <server/world.qh>
 #include <server/miscfunctions.qh>
 
 #include <common/command/_mod.qh>
index ea3af546935bb3903ee290a3e2e504d62be058ef..c9aad4b7971c18634935bdb0d6b4659349c2f4d3 100644 (file)
@@ -54,7 +54,7 @@ float timeout_status;    // (values: 0, 1, 2) contains whether a timeout is not
 .float allowed_timeouts; // contains the number of allowed timeouts for each player
 .vector lastV_angle;     // used when pausing the game in order to force the player to keep his old view angle fixed
 
-// allow functions to be used in other code like g_world.qc and teamplay.qc
+// allow functions to be used in other code like world.qc and teamplay.qc
 void timeout_handler_think(entity this);
 
 // used by common/command/generic.qc:GenericCommand_dumpcommands to list all commands into a .txt file
index 3e75b5b6f140f9dc7df7176d959c5ed2b5af952d..3262974898a1a284858dcf3ef325c6eb393569ec 100644 (file)
@@ -1,6 +1,8 @@
 #include "getreplies.qh"
 
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
+#include <server/world.qh>
 #include <server/miscfunctions.qh>
 
 #include <common/command/_mod.qh>
@@ -20,7 +22,7 @@
 //  Last updated: December 30th, 2011
 // =========================================================
 
-// These strings are set usually during init in g_world.qc,
+// These strings are set usually during init in world.qc,
 // or also by some game modes or other functions manually,
 // and their purpose is to output information to clients
 // without using any extra processing time.
index 7b436079227f47c1d1621cb891b5bd87400122c0..3ababeec576028bb07b69722714e9ee16a2b2746 100644 (file)
@@ -13,7 +13,7 @@ const int LADDER_SIZE = 30; // ladder shows the top X players
 string top_uids[LADDER_SIZE];
 float top_scores[LADDER_SIZE];
 
-// allow functions to be used in other code like g_world.qc and race.qc
+// allow functions to be used in other code like world.qc and race.qc
 string getrecords(float page);
 string getrankings();
 string getladder();
index e3dbf795f60541f9482f4997c42b28b540552837..6e73777a0f0321e55bd02ae54749e6f13623d914 100644 (file)
@@ -2,8 +2,9 @@
 #ifdef RADARMAP
 
 #include <common/command/_mod.qh>
+#include <common/mapobjects/triggers.qh>
 
-#include "../g_world.qh"
+#include "../world.qh"
 
 #include <common/util.qh>
 
index 034bd6cb92cc37004d364ff67334f355855c287d..7de740bdde1049fc7b1f8c7c8e4d797ef91df4ae 100644 (file)
@@ -13,7 +13,7 @@
 #include "../campaign.qh"
 #include "../client.qh"
 #include "../player.qh"
-#include "../g_world.qh"
+#include "../world.qh"
 #include "../ipban.qh"
 #include "../teamplay.qh"
 
index f98242ad668166f3089c15ada94bc0b774ecfd58..ee8a8e8db9a1550ec56cd407d3d2d0e05d6ccede 100644 (file)
@@ -1,6 +1,8 @@
 #include "vote.qh"
 
-#include <server/defs.qh>
+#include <server/client.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 #include <server/gamelog.qh>
 #include <server/miscfunctions.qh>
 
@@ -9,8 +11,8 @@
 
 #include "common.qh"
 
-#include "../g_damage.qh"
-#include "../g_world.qh"
+#include "../damage.qh"
+#include "../world.qh"
 #include "../teamplay.qh"
 #include "../race.qh"
 #include "../round_handler.qh"
index 988e91bbce615648873186adf6fb5306d4641c54..7085ca0e1bc457d992e593e9485a7e516b1e0f77 100644 (file)
@@ -38,7 +38,7 @@ string vote_called_display; // visual string of command sent by client
 string vote_parsed_command; // command which is fixed after being parsed
 string vote_parsed_display; // visual string which is fixed after being parsed
 
-// allow functions to be used in other code like g_world.qc and teamplay.qc
+// allow functions to be used in other code like world.qc and teamplay.qc
 void VoteThink();
 void VoteReset();
 void VoteCommand(int request, entity caller, int argc, string vote_command);
@@ -50,8 +50,14 @@ float readycount;                  // amount of players who are ready
 float readyrestart_happened;       // keeps track of whether a restart has already happened
 float restart_mapalreadyrestarted; // bool, indicates whether reset_map() was already executed
 .float ready;                      // flag for if a player is ready
+.int team_saved;                   // team number to restore upon map reset
+.void(entity this) reset;             // if set, an entity is reset using this
+.void(entity this) reset2;         // if set, an entity is reset using this (after calling ALL the reset functions for other entities)
 void reset_map(float dorespawn);
 void ReadyCount();
 void ReadyRestart_force();
 void VoteCount(float first_count);
 void Nagger_Init();
+
+IntrusiveList g_saved_team;
+STATIC_INIT(g_saved_team) { g_saved_team = IL_NEW(); }
index c80da0af3772cf40ddd744cf1c471f0268702e23..d2eb785b584fec3a810ad6d6405aff25413bdd96 100644 (file)
@@ -1,6 +1,7 @@
 #include "quake.qh"
 
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 #include <server/miscfunctions.qh>
 #include <common/weapons/_all.qh>
 
index 134956e7d8fc528c328e1ee68f21a908139f6bac..de97cba569b0b7e0f0d86d7d87535a36267e37fc 100644 (file)
@@ -1,11 +1,13 @@
 #include "quake3.qh"
 
-#include <server/defs.qh>
+#include <server/client.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 #include <server/miscfunctions.qh>
-#include <server/items.qh>
+#include <server/items/items.qh>
+#include <server/items/spawning.qh>
 #include <server/resources.qh>
 #include <common/gamemodes/_mod.qh>
-#include <common/t_items.qh>
 #include <common/gamemodes/gamemode/ctf/sv_ctf.qh>
 #include <common/mapobjects/triggers.qh>
 #include <common/mapobjects/trigger/counter.qh>
@@ -249,9 +251,9 @@ spawnfunc(target_fragsFilter)
 //spawnfunc(item_doubler)        /* handled by buffs mutator */
 //spawnfunc(item_haste)        /* handled by buffs mutator */
 //spawnfunc(item_health)       /* handled in t_quake.qc */
-//spawnfunc(item_health_large) /* handled in t_items.qc */
-//spawnfunc(item_health_small) /* handled in t_items.qc */
-//spawnfunc(item_health_mega)  /* handled in t_items.qc */
+//spawnfunc(item_health_large) /* handled in items.qc */
+//spawnfunc(item_health_small) /* handled in items.qc */
+//spawnfunc(item_health_mega)  /* handled in items.qc */
 //spawnfunc(item_invis)        /* handled by buffs mutator */
 //spawnfunc(item_regen)        /* handled by buffs mutator */
 
index d2577b46afb356fef97917bf577493f0e483fbaf..4b7a6d31b30ee480b6f0a1054d729216b2730547 100644 (file)
@@ -1,8 +1,9 @@
 #include "wop.qh"
 
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 #include <server/miscfunctions.qh>
-#include <server/items.qh>
+#include <server/items/spawning.qh>
 #include <common/weapons/_all.qh>
 
 spawnfunc(item_haste);
diff --git a/qcsrc/server/constants.qh b/qcsrc/server/constants.qh
deleted file mode 100644 (file)
index 62a15f6..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#pragma once
-
-const int FL_WEAPON = BIT(13);
-const int FL_POWERUP = BIT(14);
-const int FL_PROJECTILE = BIT(15);
-const int FL_TOSSED = BIT(16);
-const int FL_NO_WEAPON_STAY = BIT(17);
-const int FL_SPAWNING = BIT(18);
-const int FL_PICKUPITEMS = BIT(19);
-
-const int SVC_SETVIEW = 5;
-
-const int RESPAWN_FORCE = BIT(0);
-const int RESPAWN_SILENT = BIT(1);
-const int RESPAWN_DENY = BIT(2);
-
-#define EFMASK_CHEAP (EF_ADDITIVE | EF_DOUBLESIDED | EF_FULLBRIGHT | EF_NODEPTHTEST | EF_NODRAW | EF_NOGUNBOB | EF_NOSHADOW | EF_LOWPRECISION | EF_SELECTABLE | EF_TELEPORT_BIT)
-
-const int NUM_PLAYERSKINS_TEAMPLAY = 3;
diff --git a/qcsrc/server/damage.qc b/qcsrc/server/damage.qc
new file mode 100644 (file)
index 0000000..f799e96
--- /dev/null
@@ -0,0 +1,1301 @@
+#include "damage.qh"
+
+#include <common/effects/all.qh>
+#include "bot/api.qh"
+#include "hook.qh"
+#include <server/client.qh>
+#include <server/gamelog.qh>
+#include <server/items/items.qh>
+#include <server/mutators/_mod.qh>
+#include <server/main.qh>
+#include "teamplay.qh"
+#include "scores.qh"
+#include "spawnpoints.qh"
+#include "../common/state.qh"
+#include "../common/physics/player.qh"
+#include "resources.qh"
+#include "../common/vehicles/all.qh"
+#include "../common/items/_mod.qh"
+#include "../common/mutators/mutator/waypoints/waypointsprites.qh"
+#include "../common/mutators/mutator/instagib/sv_instagib.qh"
+#include "../common/mutators/mutator/buffs/buffs.qh"
+#include "weapons/accuracy.qh"
+#include "weapons/csqcprojectile.qh"
+#include "weapons/selection.qh"
+#include "../common/constants.qh"
+#include "../common/deathtypes/all.qh"
+#include <common/mapobjects/defs.qh>
+#include <common/mapobjects/triggers.qh>
+#include "../common/notifications/all.qh"
+#include "../common/physics/movetypes/movetypes.qh"
+#include "../common/playerstats.qh"
+#include "../common/teams.qh"
+#include "../common/util.qh"
+#include <common/gamemodes/_mod.qh>
+#include <common/gamemodes/rules.qh>
+#include <common/weapons/_all.qh>
+#include "../lib/csqcmodel/sv_model.qh"
+#include "../lib/warpzone/common.qh"
+
+void UpdateFrags(entity player, int f)
+{
+       GameRules_scoring_add_team(player, SCORE, f);
+}
+
+void GiveFrags(entity attacker, entity targ, float f, int deathtype, .entity weaponentity)
+{
+       // TODO route through PlayerScores instead
+       if(game_stopped) return;
+
+       if(f < 0)
+       {
+               if(targ == attacker)
+               {
+                       // suicide
+                       GameRules_scoring_add(attacker, SUICIDES, 1);
+               }
+               else
+               {
+                       // teamkill
+                       GameRules_scoring_add(attacker, TEAMKILLS, 1);
+               }
+       }
+       else
+       {
+               // regular frag
+               GameRules_scoring_add(attacker, KILLS, 1);
+               if(!warmup_stage && targ.playerid)
+                       PlayerStats_GameReport_Event_Player(attacker, sprintf("kills-%d", targ.playerid), 1);
+       }
+
+       GameRules_scoring_add(targ, DEATHS, 1);
+
+       // FIXME fix the mess this is (we have REAL points now!)
+       if(MUTATOR_CALLHOOK(GiveFragsForKill, attacker, targ, f, deathtype, attacker.(weaponentity)))
+               f = M_ARGV(2, float);
+
+       attacker.totalfrags += f;
+
+       if(f)
+               UpdateFrags(attacker, f);
+}
+
+string AppendItemcodes(string s, entity player)
+{
+       for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+       {
+               .entity weaponentity = weaponentities[slot];
+               int w = player.(weaponentity).m_weapon.m_id;
+               if(w == 0)
+                       w = player.(weaponentity).cnt; // previous weapon
+               if(w != 0 || slot == 0)
+                       s = strcat(s, ftos(w));
+       }
+       if(time < STAT(STRENGTH_FINISHED, player))
+               s = strcat(s, "S");
+       if(time < STAT(INVINCIBLE_FINISHED, player))
+               s = strcat(s, "I");
+       if(PHYS_INPUT_BUTTON_CHAT(player))
+               s = strcat(s, "T");
+       // TODO: include these codes as a flag on the item itself
+       MUTATOR_CALLHOOK(LogDeath_AppendItemCodes, player, s);
+       s = M_ARGV(1, string);
+       return s;
+}
+
+void LogDeath(string mode, int deathtype, entity killer, entity killed)
+{
+       string s;
+       if(!autocvar_sv_eventlog)
+               return;
+       s = strcat(":kill:", mode);
+       s = strcat(s, ":", ftos(killer.playerid));
+       s = strcat(s, ":", ftos(killed.playerid));
+       s = strcat(s, ":type=", Deathtype_Name(deathtype));
+       s = strcat(s, ":items=");
+       s = AppendItemcodes(s, killer);
+       if(killed != killer)
+       {
+               s = strcat(s, ":victimitems=");
+               s = AppendItemcodes(s, killed);
+       }
+       GameLogEcho(s);
+}
+
+void Obituary_SpecialDeath(
+       entity notif_target,
+       float murder,
+       int deathtype,
+       string s1, string s2, string s3,
+       float f1, float f2, float f3)
+{
+       if(!DEATH_ISSPECIAL(deathtype))
+       {
+               backtrace("Obituary_SpecialDeath called without a special deathtype?\n");
+               return;
+       }
+
+       entity deathent = REGISTRY_GET(Deathtypes, deathtype - DT_FIRST);
+       if (!deathent)
+       {
+               backtrace("Obituary_SpecialDeath: Could not find deathtype entity!\n");
+               return;
+       }
+
+       if(g_cts && deathtype == DEATH_KILL.m_id)
+               return; // TODO: somehow put this in CTS gamemode file!
+
+       Notification death_message = (murder) ? deathent.death_msgmurder : deathent.death_msgself;
+       if(death_message)
+       {
+               Send_Notification_WOCOVA(
+                       NOTIF_ONE,
+                       notif_target,
+                       MSG_MULTI,
+                       death_message,
+                       s1, s2, s3, "",
+                       f1, f2, f3, 0
+               );
+               Send_Notification_WOCOVA(
+                       NOTIF_ALL_EXCEPT,
+                       notif_target,
+                       MSG_INFO,
+                       death_message.nent_msginfo,
+                       s1, s2, s3, "",
+                       f1, f2, f3, 0
+               );
+       }
+}
+
+float Obituary_WeaponDeath(
+       entity notif_target,
+       float murder,
+       int deathtype,
+       string s1, string s2, string s3,
+       float f1, float f2)
+{
+       Weapon death_weapon = DEATH_WEAPONOF(deathtype);
+       if (death_weapon == WEP_Null)
+               return false;
+
+       w_deathtype = deathtype;
+       Notification death_message = ((murder) ? death_weapon.wr_killmessage(death_weapon) : death_weapon.wr_suicidemessage(death_weapon));
+       w_deathtype = false;
+
+       if (death_message)
+       {
+               Send_Notification_WOCOVA(
+                       NOTIF_ONE,
+                       notif_target,
+                       MSG_MULTI,
+                       death_message,
+                       s1, s2, s3, "",
+                       f1, f2, 0, 0
+               );
+               // send the info part to everyone
+               Send_Notification_WOCOVA(
+                       NOTIF_ALL_EXCEPT,
+                       notif_target,
+                       MSG_INFO,
+                       death_message.nent_msginfo,
+                       s1, s2, s3, "",
+                       f1, f2, 0, 0
+               );
+       }
+       else
+       {
+               LOG_TRACEF(
+                       "Obituary_WeaponDeath(): ^1Deathtype ^7(%d)^1 has no notification for weapon %s!\n",
+                       deathtype,
+                       death_weapon.netname
+               );
+       }
+
+       return true;
+}
+
+bool frag_centermessage_override(entity attacker, entity targ, int deathtype, int kill_count_to_attacker, int kill_count_to_target, string attacker_name)
+{
+       if(deathtype == DEATH_FIRE.m_id)
+       {
+               Send_Notification(NOTIF_ONE, attacker, MSG_CHOICE, CHOICE_FRAG_FIRE, targ.netname, kill_count_to_attacker, (IS_BOT_CLIENT(targ) ? -1 : CS(targ).ping));
+               Send_Notification(NOTIF_ONE, targ, MSG_CHOICE, CHOICE_FRAGGED_FIRE, attacker_name, kill_count_to_target, GetResource(attacker, RES_HEALTH), GetResource(attacker, RES_ARMOR), (IS_BOT_CLIENT(attacker) ? -1 : CS(attacker).ping));
+               return true;
+       }
+
+       return MUTATOR_CALLHOOK(FragCenterMessage, attacker, targ, deathtype, kill_count_to_attacker, kill_count_to_target);
+}
+
+void Obituary(entity attacker, entity inflictor, entity targ, int deathtype, .entity weaponentity)
+{
+       // Sanity check
+       if (!IS_PLAYER(targ)) { backtrace("Obituary called on non-player?!\n"); return; }
+
+       // Declarations
+       float notif_firstblood = false;
+       float kill_count_to_attacker, kill_count_to_target;
+       bool notif_anonymous = false;
+       string attacker_name = attacker.netname;
+
+       // Set final information for the death
+       targ.death_origin = targ.origin;
+       string deathlocation = (autocvar_notification_server_allows_location ? NearestLocation(targ.death_origin) : "");
+
+       // Abort now if a mutator requests it
+       if (MUTATOR_CALLHOOK(ClientObituary, inflictor, attacker, targ, deathtype, attacker.(weaponentity))) { CS(targ).killcount = 0; return; }
+       notif_anonymous = M_ARGV(5, bool);
+
+       if(notif_anonymous)
+               attacker_name = "Anonymous player";
+
+       #ifdef NOTIFICATIONS_DEBUG
+       Debug_Notification(
+               sprintf(
+                       "Obituary(%s, %s, %s, %s = %d);\n",
+                       attacker_name,
+                       inflictor.netname,
+                       targ.netname,
+                       Deathtype_Name(deathtype),
+                       deathtype
+               )
+       );
+       #endif
+
+       // =======
+       // SUICIDE
+       // =======
+       if(targ == attacker)
+       {
+               if(DEATH_ISSPECIAL(deathtype))
+               {
+                       if(deathtype == DEATH_TEAMCHANGE.m_id || deathtype == DEATH_AUTOTEAMCHANGE.m_id)
+                       {
+                               Obituary_SpecialDeath(targ, false, deathtype, targ.netname, deathlocation, "", targ.team, 0, 0);
+                       }
+                       else
+                       {
+                               switch(DEATH_ENT(deathtype))
+                               {
+                                       case DEATH_MIRRORDAMAGE:
+                                       {
+                                               Obituary_SpecialDeath(targ, false, deathtype, targ.netname, deathlocation, "", CS(targ).killcount, 0, 0);
+                                               break;
+                                       }
+
+                                       default:
+                                       {
+                                               Obituary_SpecialDeath(targ, false, deathtype, targ.netname, deathlocation, "", CS(targ).killcount, 0, 0);
+                                               break;
+                                       }
+                               }
+                       }
+               }
+               else if (!Obituary_WeaponDeath(targ, false, deathtype, targ.netname, deathlocation, "", CS(targ).killcount, 0))
+               {
+                       backtrace("SUICIDE: what the hell happened here?\n");
+                       return;
+               }
+               LogDeath("suicide", deathtype, targ, targ);
+               if(deathtype != DEATH_AUTOTEAMCHANGE.m_id) // special case: don't negate frags if auto switched
+                       GiveFrags(attacker, targ, -1, deathtype, weaponentity);
+       }
+
+       // ======
+       // MURDER
+       // ======
+       else if(IS_PLAYER(attacker))
+       {
+               if(SAME_TEAM(attacker, targ))
+               {
+                       LogDeath("tk", deathtype, attacker, targ);
+                       GiveFrags(attacker, targ, -1, deathtype, weaponentity);
+
+                       CS(attacker).killcount = 0;
+
+                       Send_Notification(NOTIF_ONE, attacker, MSG_CENTER, CENTER_DEATH_TEAMKILL_FRAG, targ.netname);
+                       Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_DEATH_TEAMKILL_FRAGGED, attacker_name);
+                       Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(targ.team, INFO_DEATH_TEAMKILL), targ.netname, attacker_name, deathlocation, CS(targ).killcount);
+
+                       // In this case, the death message will ALWAYS be "foo was betrayed by bar"
+                       // No need for specific death/weapon messages...
+               }
+               else
+               {
+                       LogDeath("frag", deathtype, attacker, targ);
+                       GiveFrags(attacker, targ, 1, deathtype, weaponentity);
+
+                       CS(attacker).taunt_soundtime = time + 1;
+                       CS(attacker).killcount = CS(attacker).killcount + 1;
+
+                       attacker.killsound += 1;
+
+                       // TODO: improve SPREE_ITEM and KILL_SPREE_LIST
+                       // these 2 macros are spread over multiple files
+                       #define SPREE_ITEM(counta,countb,center,normal,gentle) \
+                               case counta: \
+                                       Send_Notification(NOTIF_ONE, attacker, MSG_ANNCE, ANNCE_KILLSTREAK_##countb); \
+                                       if (!warmup_stage) \
+                                               PlayerStats_GameReport_Event_Player(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_##counta, 1); \
+                                       break;
+
+                       switch(CS(attacker).killcount)
+                       {
+                               KILL_SPREE_LIST
+                               default: break;
+                       }
+                       #undef SPREE_ITEM
+
+                       if(!warmup_stage && !checkrules_firstblood)
+                       {
+                               checkrules_firstblood = true;
+                               notif_firstblood = true; // modify the current messages so that they too show firstblood information
+                               PlayerStats_GameReport_Event_Player(attacker, PLAYERSTATS_ACHIEVEMENT_FIRSTBLOOD, 1);
+                               PlayerStats_GameReport_Event_Player(targ, PLAYERSTATS_ACHIEVEMENT_FIRSTVICTIM, 1);
+
+                               // tell spree_inf and spree_cen that this is a first-blood and first-victim event
+                               kill_count_to_attacker = -1;
+                               kill_count_to_target = -2;
+                       }
+                       else
+                       {
+                               kill_count_to_attacker = CS(attacker).killcount;
+                               kill_count_to_target = 0;
+                       }
+
+                       if(targ.istypefrag)
+                       {
+                               Send_Notification(
+                                       NOTIF_ONE,
+                                       attacker,
+                                       MSG_CHOICE,
+                                       CHOICE_TYPEFRAG,
+                                       targ.netname,
+                                       kill_count_to_attacker,
+                                       (IS_BOT_CLIENT(targ) ? -1 : CS(targ).ping)
+                               );
+                               Send_Notification(
+                                       NOTIF_ONE,
+                                       targ,
+                                       MSG_CHOICE,
+                                       CHOICE_TYPEFRAGGED,
+                                       attacker_name,
+                                       kill_count_to_target,
+                                       GetResource(attacker, RES_HEALTH),
+                                       GetResource(attacker, RES_ARMOR),
+                                       (IS_BOT_CLIENT(attacker) ? -1 : CS(attacker).ping)
+                               );
+                       }
+                       else if(!frag_centermessage_override(attacker, targ, deathtype, kill_count_to_attacker, kill_count_to_target, attacker_name))
+                       {
+                               Send_Notification(
+                                       NOTIF_ONE,
+                                       attacker,
+                                       MSG_CHOICE,
+                                       CHOICE_FRAG,
+                                       targ.netname,
+                                       kill_count_to_attacker,
+                                       (IS_BOT_CLIENT(targ) ? -1 : CS(targ).ping)
+                               );
+                               Send_Notification(
+                                       NOTIF_ONE,
+                                       targ,
+                                       MSG_CHOICE,
+                                       CHOICE_FRAGGED,
+                                       attacker_name,
+                                       kill_count_to_target,
+                                       GetResource(attacker, RES_HEALTH),
+                                       GetResource(attacker, RES_ARMOR),
+                                       (IS_BOT_CLIENT(attacker) ? -1 : CS(attacker).ping)
+                               );
+                       }
+
+                       int f3 = 0;
+                       if(deathtype == DEATH_BUFF.m_id)
+                               f3 = buff_FirstFromFlags(STAT(BUFFS, attacker)).m_id;
+
+                       if (!Obituary_WeaponDeath(targ, true, deathtype, targ.netname, attacker_name, deathlocation, CS(targ).killcount, kill_count_to_attacker))
+                               Obituary_SpecialDeath(targ, true, deathtype, targ.netname, attacker_name, deathlocation, CS(targ).killcount, kill_count_to_attacker, f3);
+               }
+       }
+
+       // =============
+       // ACCIDENT/TRAP
+       // =============
+       else
+       {
+               switch(DEATH_ENT(deathtype))
+               {
+                       // For now, we're just forcing HURTTRIGGER to behave as "DEATH_VOID" and giving it no special options...
+                       // Later on you will only be able to make custom messages using DEATH_CUSTOM,
+                       // and there will be a REAL DEATH_VOID implementation which mappers will use.
+                       case DEATH_HURTTRIGGER:
+                       {
+                               Obituary_SpecialDeath(targ, false, deathtype,
+                                       targ.netname,
+                                       inflictor.message,
+                                       deathlocation,
+                                       CS(targ).killcount,
+                                       0,
+                                       0);
+                               break;
+                       }
+
+                       case DEATH_CUSTOM:
+                       {
+                               Obituary_SpecialDeath(targ, false, deathtype,
+                                       targ.netname,
+                                       ((strstrofs(deathmessage, "%", 0) < 0) ? strcat("%s ", deathmessage) : deathmessage),
+                                       deathlocation,
+                                       CS(targ).killcount,
+                                       0,
+                                       0);
+                               break;
+                       }
+
+                       default:
+                       {
+                               Obituary_SpecialDeath(targ, false, deathtype, targ.netname, deathlocation, "", CS(targ).killcount, 0, 0);
+                               break;
+                       }
+               }
+
+               LogDeath("accident", deathtype, targ, targ);
+               GiveFrags(targ, targ, -1, deathtype, weaponentity);
+
+               if(GameRules_scoring_add(targ, SCORE, 0) == -5)
+               {
+                       Send_Notification(NOTIF_ONE, targ, MSG_ANNCE, ANNCE_ACHIEVEMENT_BOTLIKE);
+                       if (!warmup_stage)
+                       {
+                               PlayerStats_GameReport_Event_Player(attacker, PLAYERSTATS_ACHIEVEMENT_BOTLIKE, 1);
+                       }
+               }
+       }
+
+       // reset target kill count
+       CS(targ).killcount = 0;
+}
+
+void Ice_Think(entity this)
+{
+       if(!STAT(FROZEN, this.owner) || this.owner.iceblock != this)
+       {
+               delete(this);
+               return;
+       }
+       vector ice_org = this.owner.origin - '0 0 16';
+       if (this.origin != ice_org)
+               setorigin(this, ice_org);
+       this.nextthink = time;
+}
+
+void Freeze(entity targ, float revivespeed, int frozen_type, bool show_waypoint)
+{
+       if(!IS_PLAYER(targ) && !IS_MONSTER(targ)) // TODO: only specified entities can be freezed
+               return;
+
+       if(STAT(FROZEN, targ))
+               return;
+
+       float targ_maxhealth = ((IS_MONSTER(targ)) ? targ.max_health : start_health);
+
+       STAT(FROZEN, targ) = frozen_type;
+       STAT(REVIVE_PROGRESS, targ) = ((frozen_type == FROZEN_TEMP_DYING) ? 1 : 0);
+       SetResource(targ, RES_HEALTH, ((frozen_type == FROZEN_TEMP_DYING) ? targ_maxhealth : 1));
+       targ.revive_speed = revivespeed;
+       if(targ.bot_attack)
+               IL_REMOVE(g_bot_targets, targ);
+       targ.bot_attack = false;
+       targ.freeze_time = time;
+
+       entity ice = new(ice);
+       ice.owner = targ;
+       ice.scale = targ.scale;
+       // set_movetype(ice, MOVETYPE_FOLLOW) would rotate the ice model with the player
+       setthink(ice, Ice_Think);
+       ice.nextthink = time;
+       ice.frame = floor(random() * 21); // ice model has 20 different looking frames
+       setmodel(ice, MDL_ICE);
+       ice.alpha = 1;
+       ice.colormod = Team_ColorRGB(targ.team);
+       ice.glowmod = ice.colormod;
+       targ.iceblock = ice;
+       targ.revival_time = 0;
+
+       Ice_Think(ice);
+
+       RemoveGrapplingHooks(targ);
+
+       FOREACH_CLIENT(IS_PLAYER(it),
+       {
+               for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+           {
+               .entity weaponentity = weaponentities[slot];
+               if(it.(weaponentity).hook.aiment == targ)
+                       RemoveHook(it.(weaponentity).hook);
+           }
+       });
+
+       // add waypoint
+       if(MUTATOR_CALLHOOK(Freeze, targ, revivespeed, frozen_type) || show_waypoint)
+               WaypointSprite_Spawn(WP_Frozen, 0, 0, targ, '0 0 64', NULL, targ.team, targ, waypointsprite_attached, true, RADARICON_WAYPOINT);
+}
+
+void Unfreeze(entity targ, bool reset_health)
+{
+       if(!STAT(FROZEN, targ))
+               return;
+
+       if (reset_health && STAT(FROZEN, targ) != FROZEN_TEMP_DYING)
+               SetResource(targ, RES_HEALTH, ((IS_PLAYER(targ)) ? start_health : targ.max_health));
+
+       targ.pauseregen_finished = time + autocvar_g_balance_pause_health_regen;
+
+       STAT(FROZEN, targ) = 0;
+       STAT(REVIVE_PROGRESS, targ) = 0;
+       targ.revival_time = time;
+       if(!targ.bot_attack)
+               IL_PUSH(g_bot_targets, targ);
+       targ.bot_attack = true;
+
+       WaypointSprite_Kill(targ.waypointsprite_attached);
+
+       FOREACH_CLIENT(IS_PLAYER(it),
+       {
+               for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+           {
+               .entity weaponentity = weaponentities[slot];
+               if(it.(weaponentity).hook.aiment == targ)
+                       RemoveHook(it.(weaponentity).hook);
+           }
+       });
+
+       // remove the ice block
+       if(targ.iceblock)
+               delete(targ.iceblock);
+       targ.iceblock = NULL;
+
+       MUTATOR_CALLHOOK(Unfreeze, targ);
+}
+
+void Damage(entity targ, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
+{
+       float complainteamdamage = 0;
+       float mirrordamage = 0;
+       float mirrorforce = 0;
+
+       if (game_stopped || (IS_CLIENT(targ) && CS(targ).killcount == FRAGS_SPECTATOR))
+               return;
+
+       entity attacker_save = attacker;
+
+       // special rule: gravity bombs and sound-based attacks do not affect team mates (other than for disconnecting the hook)
+       if(DEATH_ISWEAPON(deathtype, WEP_HOOK) || (deathtype & HITTYPE_SOUND))
+       {
+               if(IS_PLAYER(targ) && SAME_TEAM(targ, attacker))
+               {
+                       return;
+               }
+       }
+
+       if(deathtype == DEATH_KILL.m_id || deathtype == DEATH_TEAMCHANGE.m_id || deathtype == DEATH_AUTOTEAMCHANGE.m_id)
+       {
+               // exit the vehicle before killing (fixes a crash)
+               if(IS_PLAYER(targ) && targ.vehicle)
+                       vehicles_exit(targ.vehicle, VHEF_RELEASE);
+
+               // These are ALWAYS lethal
+               // No damage modification here
+               // Instead, prepare the victim for his death...
+               SetResourceExplicit(targ, RES_ARMOR, 0);
+               targ.spawnshieldtime = 0;
+               SetResourceExplicit(targ, RES_HEALTH, 0.9); // this is < 1
+               targ.flags -= targ.flags & FL_GODMODE;
+               damage = 100000;
+       }
+       else if(deathtype == DEATH_MIRRORDAMAGE.m_id || deathtype == DEATH_NOAMMO.m_id)
+       {
+               // no processing
+       }
+       else
+       {
+               // nullify damage if teamplay is on
+               if(deathtype != DEATH_TELEFRAG.m_id)
+               if(IS_PLAYER(attacker))
+               {
+                       if(IS_PLAYER(targ) && targ != attacker && (IS_INDEPENDENT_PLAYER(attacker) || IS_INDEPENDENT_PLAYER(targ)))
+                       {
+                               damage = 0;
+                               force = '0 0 0';
+                       }
+                       else if(SAME_TEAM(attacker, targ))
+                       {
+                               if(autocvar_teamplay_mode == 1)
+                                       damage = 0;
+                               else if(attacker != targ)
+                               {
+                                       if(autocvar_teamplay_mode == 2)
+                                       {
+                                               if(IS_PLAYER(targ) && !IS_DEAD(targ))
+                                               {
+                                                       attacker.dmg_team = attacker.dmg_team + damage;
+                                                       complainteamdamage = attacker.dmg_team - autocvar_g_teamdamage_threshold;
+                                               }
+                                       }
+                                       else if(autocvar_teamplay_mode == 3)
+                                               damage = 0;
+                                       else if(autocvar_teamplay_mode == 4)
+                                       {
+                                               if(IS_PLAYER(targ) && !IS_DEAD(targ))
+                                               {
+                                                       attacker.dmg_team = attacker.dmg_team + damage;
+                                                       complainteamdamage = attacker.dmg_team - autocvar_g_teamdamage_threshold;
+                                                       if(complainteamdamage > 0)
+                                                               mirrordamage = autocvar_g_mirrordamage * complainteamdamage;
+                                                       mirrorforce = autocvar_g_mirrordamage * vlen(force);
+                                                       damage = autocvar_g_friendlyfire * damage;
+                                                       // mirrordamage will be used LATER
+
+                                                       if(autocvar_g_mirrordamage_virtual)
+                                                       {
+                                                               vector v  = healtharmor_applydamage(GetResource(attacker, RES_ARMOR), autocvar_g_balance_armor_blockpercent, deathtype, mirrordamage);
+                                                               attacker.dmg_take += v.x;
+                                                               attacker.dmg_save += v.y;
+                                                               attacker.dmg_inflictor = inflictor;
+                                                               mirrordamage = v.z;
+                                                               mirrorforce = 0;
+                                                       }
+
+                                                       if(autocvar_g_friendlyfire_virtual)
+                                                       {
+                                                               vector v = healtharmor_applydamage(GetResource(targ, RES_ARMOR), autocvar_g_balance_armor_blockpercent, deathtype, damage);
+                                                               targ.dmg_take += v.x;
+                                                               targ.dmg_save += v.y;
+                                                               targ.dmg_inflictor = inflictor;
+                                                               damage = 0;
+                                                               if(!autocvar_g_friendlyfire_virtual_force)
+                                                                       force = '0 0 0';
+                                                       }
+                                               }
+                                               else if(!targ.canteamdamage)
+                                                       damage = 0;
+                                       }
+                               }
+                       }
+               }
+
+               if (!DEATH_ISSPECIAL(deathtype))
+               {
+                       damage *= g_weapondamagefactor;
+                       mirrordamage *= g_weapondamagefactor;
+                       complainteamdamage *= g_weapondamagefactor;
+                       force = force * g_weaponforcefactor;
+                       mirrorforce *= g_weaponforcefactor;
+               }
+
+               // should this be changed at all? If so, in what way?
+               MUTATOR_CALLHOOK(Damage_Calculate, inflictor, attacker, targ, deathtype, damage, mirrordamage, force, attacker.(weaponentity));
+               damage = M_ARGV(4, float);
+               mirrordamage = M_ARGV(5, float);
+               force = M_ARGV(6, vector);
+
+               if(IS_PLAYER(targ) && damage > 0 && attacker)
+               {
+                       for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+                   {
+                       .entity went = weaponentities[slot];
+                       if(targ.(went).hook && targ.(went).hook.aiment == attacker)
+                               RemoveHook(targ.(went).hook);
+                   }
+               }
+
+               if(STAT(FROZEN, targ) && !ITEM_DAMAGE_NEEDKILL(deathtype)
+                       && deathtype != DEATH_TEAMCHANGE.m_id && deathtype != DEATH_AUTOTEAMCHANGE.m_id)
+               {
+                       if(autocvar_g_frozen_revive_falldamage > 0 && deathtype == DEATH_FALL.m_id && damage >= autocvar_g_frozen_revive_falldamage)
+                       {
+                               Unfreeze(targ, false);
+                               SetResource(targ, RES_HEALTH, autocvar_g_frozen_revive_falldamage_health);
+                               Send_Effect(EFFECT_ICEORGLASS, targ.origin, '0 0 0', 3);
+                               Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_FREEZETAG_REVIVED_FALL, targ.netname);
+                               Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_FREEZETAG_REVIVE_SELF);
+                       }
+
+                       damage = 0;
+                       force *= autocvar_g_frozen_force;
+               }
+
+               if(IS_PLAYER(targ) && STAT(FROZEN, targ)
+                       && ITEM_DAMAGE_NEEDKILL(deathtype) && !autocvar_g_frozen_damage_trigger)
+               {
+                       Send_Effect(EFFECT_TELEPORT, targ.origin, '0 0 0', 1);
+
+                       entity spot = SelectSpawnPoint(targ, false);
+                       if(spot)
+                       {
+                               damage = 0;
+                               targ.deadflag = DEAD_NO;
+
+                               targ.angles = spot.angles;
+
+                               targ.effects = 0;
+                               targ.effects |= EF_TELEPORT_BIT;
+
+                               targ.angles_z = 0; // never spawn tilted even if the spot says to
+                               targ.fixangle = true; // turn this way immediately
+                               targ.velocity = '0 0 0';
+                               targ.avelocity = '0 0 0';
+                               targ.punchangle = '0 0 0';
+                               targ.punchvector = '0 0 0';
+                               targ.oldvelocity = targ.velocity;
+
+                               targ.spawnorigin = spot.origin;
+                               setorigin(targ, spot.origin + '0 0 1' * (1 - targ.mins.z - 24));
+                               // don't reset back to last position, even if new position is stuck in solid
+                               targ.oldorigin = targ.origin;
+
+                               Send_Effect(EFFECT_TELEPORT, targ.origin, '0 0 0', 1);
+                       }
+               }
+
+               if(!MUTATOR_IS_ENABLED(mutator_instagib))
+               {
+                       // apply strength multiplier
+                       if (attacker.items & ITEM_Strength.m_itemid)
+                       {
+                               if(targ == attacker)
+                               {
+                                       damage = damage * autocvar_g_balance_powerup_strength_selfdamage;
+                                       force = force * autocvar_g_balance_powerup_strength_selfforce;
+                               }
+                               else
+                               {
+                                       damage = damage * autocvar_g_balance_powerup_strength_damage;
+                                       force = force * autocvar_g_balance_powerup_strength_force;
+                               }
+                       }
+
+                       // apply invincibility multiplier
+                       if (targ.items & ITEM_Shield.m_itemid)
+                       {
+                               damage = damage * autocvar_g_balance_powerup_invincible_takedamage;
+                               if (targ != attacker)
+                               {
+                                       force = force * autocvar_g_balance_powerup_invincible_takeforce;
+                               }
+                       }
+               }
+
+               if (targ == attacker)
+                       damage = damage * autocvar_g_balance_selfdamagepercent; // Partial damage if the attacker hits himself
+
+               // count the damage
+               if(attacker)
+               if(!IS_DEAD(targ))
+               if(deathtype != DEATH_BUFF.m_id)
+               if(targ.takedamage == DAMAGE_AIM)
+               if(targ != attacker)
+               {
+                       entity victim;
+                       if(IS_VEHICLE(targ) && targ.owner)
+                               victim = targ.owner;
+                       else
+                               victim = targ;
+
+                       if(IS_PLAYER(victim) || (IS_TURRET(victim) && victim.active == ACTIVE_ACTIVE) || IS_MONSTER(victim) || MUTATOR_CALLHOOK(PlayHitsound, victim, attacker))
+                       {
+                               if(DIFF_TEAM(victim, attacker) && !STAT(FROZEN, victim))
+                               {
+                                       if(damage > 0)
+                                       {
+                                               if(deathtype != DEATH_FIRE.m_id)
+                                               {
+                                                       if(PHYS_INPUT_BUTTON_CHAT(victim))
+                                                               attacker.typehitsound += 1;
+                                                       else
+                                                               attacker.damage_dealt += damage;
+                                               }
+
+                                               damage_goodhits += 1;
+                                               damage_gooddamage += damage;
+
+                                               if (!DEATH_ISSPECIAL(deathtype))
+                                               {
+                                                       if(IS_PLAYER(targ)) // don't do this for vehicles
+                                                       if(IsFlying(victim))
+                                                               yoda = 1;
+                                               }
+                                       }
+                               }
+                               else if(IS_PLAYER(attacker))
+                               {
+                                       // if enemy gets frozen in this frame and receives other damage don't
+                                       // play the typehitsound e.g. when hit by multiple bullets of the shotgun
+                                       if (deathtype != DEATH_FIRE.m_id && (!STAT(FROZEN, victim) || time > victim.freeze_time))
+                                       {
+                                               attacker.typehitsound += 1;
+                                       }
+                                       if(complainteamdamage > 0)
+                                               if(time > CS(attacker).teamkill_complain)
+                                               {
+                                                       CS(attacker).teamkill_complain = time + 5;
+                                                       CS(attacker).teamkill_soundtime = time + 0.4;
+                                                       CS(attacker).teamkill_soundsource = targ;
+                                               }
+                               }
+                       }
+               }
+       }
+
+       // apply push
+       if (targ.damageforcescale)
+       if (force)
+       if (!IS_PLAYER(targ) || time >= targ.spawnshieldtime || targ == attacker)
+       {
+               vector farce = damage_explosion_calcpush(targ.damageforcescale * force, targ.velocity, autocvar_g_balance_damagepush_speedfactor);
+               if(targ.move_movetype == MOVETYPE_PHYSICS)
+               {
+                       entity farcent = new(farce);
+                       farcent.enemy = targ;
+                       farcent.movedir = farce * 10;
+                       if(targ.mass)
+                               farcent.movedir = farcent.movedir * targ.mass;
+                       farcent.origin = hitloc;
+                       farcent.forcetype = FORCETYPE_FORCEATPOS;
+                       farcent.nextthink = time + 0.1;
+                       setthink(farcent, SUB_Remove);
+               }
+               else if(targ.move_movetype != MOVETYPE_NOCLIP)
+               {
+                       targ.velocity = targ.velocity + farce;
+               }
+               UNSET_ONGROUND(targ);
+               UpdateCSQCProjectile(targ);
+       }
+       // apply damage
+       if (damage != 0 || (targ.damageforcescale && force))
+       if (targ.event_damage)
+               targ.event_damage (targ, inflictor, attacker, damage, deathtype, weaponentity, hitloc, force);
+
+       // apply mirror damage if any
+       if(!autocvar_g_mirrordamage_onlyweapons || DEATH_WEAPONOF(deathtype) != WEP_Null)
+       if(mirrordamage > 0 || mirrorforce > 0)
+       {
+               attacker = attacker_save;
+
+               force = normalize(attacker.origin + attacker.view_ofs - hitloc) * mirrorforce;
+               Damage(attacker, inflictor, attacker, mirrordamage, DEATH_MIRRORDAMAGE.m_id, weaponentity, attacker.origin, force);
+       }
+}
+
+float RadiusDamageForSource (entity inflictor, vector inflictororigin, vector inflictorvelocity, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe,
+                                                               float inflictorselfdamage, float forceintensity, float forcezscale, int deathtype, .entity weaponentity, entity directhitentity)
+       // Returns total damage applies to creatures
+{
+       entity  targ;
+       vector  force;
+       float   total_damage_to_creatures;
+       entity  next;
+       float   tfloordmg;
+       float   tfloorforce;
+
+       float stat_damagedone;
+
+       if(RadiusDamage_running)
+       {
+               backtrace("RadiusDamage called recursively! Expect stuff to go HORRIBLY wrong.");
+               return 0;
+       }
+
+       RadiusDamage_running = 1;
+
+       tfloordmg = autocvar_g_throughfloor_damage;
+       tfloorforce = autocvar_g_throughfloor_force;
+
+       total_damage_to_creatures = 0;
+
+       if(deathtype != (WEP_HOOK.m_id | HITTYPE_SECONDARY | HITTYPE_BOUNCE)) // only send gravity bomb damage once
+               if(!(deathtype & HITTYPE_SOUND)) // do not send radial sound damage (bandwidth hog)
+               {
+                       force = inflictorvelocity;
+                       if(force == '0 0 0')
+                               force = '0 0 -1';
+                       else
+                               force = normalize(force);
+                       if(forceintensity >= 0)
+                               Damage_DamageInfo(inflictororigin, coredamage, edgedamage, rad, forceintensity * force, deathtype, 0, attacker);
+                       else
+                               Damage_DamageInfo(inflictororigin, coredamage, edgedamage, -rad, (-forceintensity) * force, deathtype, 0, attacker);
+               }
+
+       stat_damagedone = 0;
+
+       targ = WarpZone_FindRadius (inflictororigin, rad + MAX_DAMAGEEXTRARADIUS, false);
+       while (targ)
+       {
+               next = targ.chain;
+               if ((targ != inflictor) || inflictorselfdamage)
+               if (((cantbe != targ) && !mustbe) || (mustbe == targ))
+               if (targ.takedamage)
+               {
+                       vector nearest;
+                       vector diff;
+                       float power;
+
+                       // LordHavoc: measure distance to nearest point on target (not origin)
+                       // (this guarentees 100% damage on a touch impact)
+                       nearest = targ.WarpZone_findradius_nearest;
+                       diff = targ.WarpZone_findradius_dist;
+                       // round up a little on the damage to ensure full damage on impacts
+                       // and turn the distance into a fraction of the radius
+                       power = 1 - ((vlen (diff) - bound(MIN_DAMAGEEXTRARADIUS, targ.damageextraradius, MAX_DAMAGEEXTRARADIUS)) / rad);
+                       //bprint(" ");
+                       //bprint(ftos(power));
+                       //if (targ == attacker)
+                       //      print(ftos(power), "\n");
+                       if (power > 0)
+                       {
+                               float finaldmg;
+                               if (power > 1)
+                                       power = 1;
+                               finaldmg = coredamage * power + edgedamage * (1 - power);
+                               if (finaldmg > 0)
+                               {
+                                       float a;
+                                       float c;
+                                       vector hitloc;
+                                       vector myblastorigin;
+                                       vector center;
+
+                                       myblastorigin = WarpZone_TransformOrigin(targ, inflictororigin);
+
+                                       // if it's a player, use the view origin as reference
+                                       center = CENTER_OR_VIEWOFS(targ);
+
+                                       force = normalize(center - myblastorigin);
+                                       force = force * (finaldmg / coredamage) * forceintensity;
+                                       hitloc = nearest;
+
+                                       // apply special scaling along the z axis if set
+                                       // NOTE: 0 value is not allowed for compatibility, in the case of weapon cvars not being set
+                                       if(forcezscale)
+                                               force.z *= forcezscale;
+
+                                       if(targ != directhitentity)
+                                       {
+                                               float hits;
+                                               float total;
+                                               float hitratio;
+                                               float mininv_f, mininv_d;
+
+                                               // test line of sight to multiple positions on box,
+                                               // and do damage if any of them hit
+                                               hits = 0;
+
+                                               // we know: max stddev of hitratio = 1 / (2 * sqrt(n))
+                                               // so for a given max stddev:
+                                               // n = (1 / (2 * max stddev of hitratio))^2
+
+                                               mininv_d = (finaldmg * (1-tfloordmg)) / autocvar_g_throughfloor_damage_max_stddev;
+                                               mininv_f = (vlen(force) * (1-tfloorforce)) / autocvar_g_throughfloor_force_max_stddev;
+
+                                               if(autocvar_g_throughfloor_debug)
+                                                       LOG_INFOF("THROUGHFLOOR: D=%f F=%f max(dD)=1/%f max(dF)=1/%f", finaldmg, vlen(force), mininv_d, mininv_f);
+
+
+                                               total = 0.25 * (max(mininv_f, mininv_d) ** 2);
+
+                                               if(autocvar_g_throughfloor_debug)
+                                                       LOG_INFOF(" steps=%f", total);
+
+
+                                               if (IS_PLAYER(targ))
+                                                       total = ceil(bound(autocvar_g_throughfloor_min_steps_player, total, autocvar_g_throughfloor_max_steps_player));
+                                               else
+                                                       total = ceil(bound(autocvar_g_throughfloor_min_steps_other, total, autocvar_g_throughfloor_max_steps_other));
+
+                                               if(autocvar_g_throughfloor_debug)
+                                                       LOG_INFOF(" steps=%f dD=%f dF=%f", total, finaldmg * (1-tfloordmg) / (2 * sqrt(total)), vlen(force) * (1-tfloorforce) / (2 * sqrt(total)));
+
+                                               for(c = 0; c < total; ++c)
+                                               {
+                                                       //traceline(targ.WarpZone_findradius_findorigin, nearest, MOVE_NOMONSTERS, inflictor);
+                                                       WarpZone_TraceLine(inflictororigin, WarpZone_UnTransformOrigin(targ, nearest), MOVE_NOMONSTERS, inflictor);
+                                                       if (trace_fraction == 1 || trace_ent == targ)
+                                                       {
+                                                               ++hits;
+                                                               if (hits > 1)
+                                                                       hitloc = hitloc + nearest;
+                                                               else
+                                                                       hitloc = nearest;
+                                                       }
+                                                       nearest.x = targ.origin.x + targ.mins.x + random() * targ.size.x;
+                                                       nearest.y = targ.origin.y + targ.mins.y + random() * targ.size.y;
+                                                       nearest.z = targ.origin.z + targ.mins.z + random() * targ.size.z;
+                                               }
+
+                                               nearest = hitloc * (1 / max(1, hits));
+                                               hitratio = (hits / total);
+                                               a = bound(0, tfloordmg + (1-tfloordmg) * hitratio, 1);
+                                               finaldmg = finaldmg * a;
+                                               a = bound(0, tfloorforce + (1-tfloorforce) * hitratio, 1);
+                                               force = force * a;
+
+                                               if(autocvar_g_throughfloor_debug)
+                                                       LOG_INFOF(" D=%f F=%f", finaldmg, vlen(force));
+                                       }
+
+                                       //if (targ == attacker)
+                                       //{
+                                       //      print("hits ", ftos(hits), " / ", ftos(total));
+                                       //      print(" finaldmg ", ftos(finaldmg), " force ", vtos(force));
+                                       //      print(" (", ftos(a), ")\n");
+                                       //}
+                                       if(finaldmg || force)
+                                       {
+                                               if(targ.iscreature)
+                                               {
+                                                       total_damage_to_creatures += finaldmg;
+
+                                                       if(accuracy_isgooddamage(attacker, targ))
+                                                               stat_damagedone += finaldmg;
+                                               }
+
+                                               if(targ == directhitentity || DEATH_ISSPECIAL(deathtype))
+                                                       Damage(targ, inflictor, attacker, finaldmg, deathtype, weaponentity, nearest, force);
+                                               else
+                                                       Damage(targ, inflictor, attacker, finaldmg, deathtype | HITTYPE_SPLASH, weaponentity, nearest, force);
+                                       }
+                               }
+                       }
+               }
+               targ = next;
+       }
+
+       RadiusDamage_running = 0;
+
+       if(!DEATH_ISSPECIAL(deathtype))
+               accuracy_add(attacker, DEATH_WEAPONOF(deathtype), 0, min(coredamage, stat_damagedone));
+
+       return total_damage_to_creatures;
+}
+
+float RadiusDamage(entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float forceintensity, int deathtype, .entity weaponentity, entity directhitentity)
+{
+       return RadiusDamageForSource(inflictor, (inflictor.origin + (inflictor.mins + inflictor.maxs) * 0.5), inflictor.velocity, attacker, coredamage, edgedamage, rad, 
+                                                                       cantbe, mustbe, false, forceintensity, 1, deathtype, weaponentity, directhitentity);
+}
+
+bool Heal(entity targ, entity inflictor, float amount, float limit)
+{
+       if(game_stopped || (IS_CLIENT(targ) && CS(targ).killcount == FRAGS_SPECTATOR) || STAT(FROZEN, targ) || IS_DEAD(targ))
+               return false;
+
+       bool healed = false;
+       if(targ.event_heal)
+               healed = targ.event_heal(targ, inflictor, amount, limit);
+       // TODO: additional handling? what if the healing kills them? should this abort if healing would do so etc
+       // TODO: healing fx!
+       // TODO: armor healing?
+       return healed;
+}
+
+float Fire_IsBurning(entity e)
+{
+       return (time < e.fire_endtime);
+}
+
+float Fire_AddDamage(entity e, entity o, float d, float t, float dt)
+{
+       float dps;
+       float maxtime, mintime, maxdamage, mindamage, maxdps, mindps, totaldamage, totaltime;
+
+       if(IS_PLAYER(e))
+       {
+               if(IS_DEAD(e))
+                       return -1;
+       }
+       else
+       {
+               if(!e.fire_burner)
+               {
+                       // print("adding a fire burner to ", e.classname, "\n");
+                       e.fire_burner = new(fireburner);
+                       setthink(e.fire_burner, fireburner_think);
+                       e.fire_burner.nextthink = time;
+                       e.fire_burner.owner = e;
+               }
+       }
+
+       t = max(t, 0.1);
+       dps = d / t;
+       if(Fire_IsBurning(e))
+       {
+               mintime = e.fire_endtime - time;
+               maxtime = max(mintime, t);
+
+               mindps = e.fire_damagepersec;
+               maxdps = max(mindps, dps);
+
+               if(maxtime > mintime || maxdps > mindps)
+               {
+                       // Constraints:
+
+                       // damage we have right now
+                       mindamage = mindps * mintime;
+
+                       // damage we want to get
+                       maxdamage = mindamage + d;
+
+                       // but we can't exceed maxtime * maxdps!
+                       totaldamage = min(maxdamage, maxtime * maxdps);
+
+                       // LEMMA:
+                       // Look at:
+                       // totaldamage = min(mindamage + d, maxtime * maxdps)
+                       // We see:
+                       // totaldamage <= maxtime * maxdps
+                       // ==> totaldamage / maxdps <= maxtime.
+                       // We also see:
+                       // totaldamage / mindps = min(mindamage / mindps + d, maxtime * maxdps / mindps)
+                       //                     >= min(mintime, maxtime)
+                       // ==> totaldamage / maxdps >= mintime.
+
+                       /*
+                       // how long do we damage then?
+                       // at least as long as before
+                       // but, never exceed maxdps
+                       totaltime = max(mintime, totaldamage / maxdps); // always <= maxtime due to lemma
+                       */
+
+                       // alternate:
+                       // at most as long as maximum allowed
+                       // but, never below mindps
+                       totaltime = min(maxtime, totaldamage / mindps); // always >= mintime due to lemma
+
+                       // assuming t > mintime, dps > mindps:
+                       // we get d = t * dps = maxtime * maxdps
+                       // totaldamage = min(maxdamage, maxtime * maxdps) = min(... + d, maxtime * maxdps) = maxtime * maxdps
+                       // totaldamage / maxdps = maxtime
+                       // totaldamage / mindps > totaldamage / maxdps = maxtime
+                       // FROM THIS:
+                       // a) totaltime = max(mintime, maxtime) = maxtime
+                       // b) totaltime = min(maxtime, totaldamage / maxdps) = maxtime
+
+                       // assuming t <= mintime:
+                       // we get maxtime = mintime
+                       // a) totaltime = max(mintime, ...) >= mintime, also totaltime <= maxtime by the lemma, therefore totaltime = mintime = maxtime
+                       // b) totaltime = min(maxtime, ...) <= maxtime, also totaltime >= mintime by the lemma, therefore totaltime = mintime = maxtime
+
+                       // assuming dps <= mindps:
+                       // we get mindps = maxdps.
+                       // With this, the lemma says that mintime <= totaldamage / mindps = totaldamage / maxdps <= maxtime.
+                       // a) totaltime = max(mintime, totaldamage / maxdps) = totaldamage / maxdps
+                       // b) totaltime = min(maxtime, totaldamage / mindps) = totaldamage / maxdps
+
+                       e.fire_damagepersec = totaldamage / totaltime;
+                       e.fire_endtime = time + totaltime;
+                       if(totaldamage > 1.2 * mindamage)
+                       {
+                               e.fire_deathtype = dt;
+                               if(e.fire_owner != o)
+                               {
+                                       e.fire_owner = o;
+                                       e.fire_hitsound = false;
+                               }
+                       }
+                       if(accuracy_isgooddamage(o, e))
+                               accuracy_add(o, DEATH_WEAPONOF(dt), 0, max(0, totaldamage - mindamage));
+                       return max(0, totaldamage - mindamage); // can never be negative, but to make sure
+               }
+               else
+                       return 0;
+       }
+       else
+       {
+               e.fire_damagepersec = dps;
+               e.fire_endtime = time + t;
+               e.fire_deathtype = dt;
+               e.fire_owner = o;
+               e.fire_hitsound = false;
+               if(accuracy_isgooddamage(o, e))
+                       accuracy_add(o, DEATH_WEAPONOF(dt), 0, d);
+               return d;
+       }
+}
+
+void Fire_ApplyDamage(entity e)
+{
+       float t, d, hi, ty;
+       entity o;
+
+       if (!Fire_IsBurning(e))
+               return;
+
+       for(t = 0, o = e.owner; o.owner && t < 16; o = o.owner, ++t);
+       if(IS_NOT_A_CLIENT(o))
+               o = e.fire_owner;
+
+       // water and slime stop fire
+       if(e.waterlevel)
+       if(e.watertype != CONTENT_LAVA)
+               e.fire_endtime = 0;
+
+       // ice stops fire
+       if(STAT(FROZEN, e))
+               e.fire_endtime = 0;
+
+       t = min(frametime, e.fire_endtime - time);
+       d = e.fire_damagepersec * t;
+
+       hi = e.fire_owner.damage_dealt;
+       ty = e.fire_owner.typehitsound;
+       Damage(e, e, e.fire_owner, d, e.fire_deathtype, DMG_NOWEP, e.origin, '0 0 0');
+       if(e.fire_hitsound && e.fire_owner)
+       {
+               e.fire_owner.damage_dealt = hi;
+               e.fire_owner.typehitsound = ty;
+       }
+       e.fire_hitsound = true;
+
+       if(!IS_INDEPENDENT_PLAYER(e) && !STAT(FROZEN, e))
+       {
+               IL_EACH(g_damagedbycontents, it.damagedbycontents && it != e,
+               {
+                       if(!IS_DEAD(it) && it.takedamage && !IS_INDEPENDENT_PLAYER(it))
+                       if(boxesoverlap(e.absmin, e.absmax, it.absmin, it.absmax))
+                       {
+                               t = autocvar_g_balance_firetransfer_time * (e.fire_endtime - time);
+                               d = autocvar_g_balance_firetransfer_damage * e.fire_damagepersec * t;
+                               Fire_AddDamage(it, o, d, t, DEATH_FIRE.m_id);
+                       }
+               });
+       }
+}
+
+void Fire_ApplyEffect(entity e)
+{
+       if(Fire_IsBurning(e))
+               e.effects |= EF_FLAME;
+       else
+               e.effects &= ~EF_FLAME;
+}
+
+void fireburner_think(entity this)
+{
+       // for players, this is done in the regular loop
+       if(wasfreed(this.owner))
+       {
+               delete(this);
+               return;
+       }
+       Fire_ApplyEffect(this.owner);
+       if(!Fire_IsBurning(this.owner))
+       {
+               this.owner.fire_burner = NULL;
+               delete(this);
+               return;
+       }
+       Fire_ApplyDamage(this.owner);
+       this.nextthink = time;
+}
diff --git a/qcsrc/server/damage.qh b/qcsrc/server/damage.qh
new file mode 100644 (file)
index 0000000..02a637c
--- /dev/null
@@ -0,0 +1,162 @@
+#pragma once
+
+#if defined(CSQC)
+#elif defined(MENUQC)
+#elif defined(SVQC)
+    #include <common/weapons/_all.qh>
+    #include <common/stats.qh>
+    #include <server/items/items.qh>
+    #include <server/miscfunctions.qh>
+    #include <lib/warpzone/common.qh>
+    #include <common/constants.qh>
+    #include <common/teams.qh>
+    #include <common/util.qh>
+    #include <common/weapons/_all.qh>
+    #include "weapons/accuracy.qh"
+    #include "weapons/csqcprojectile.qh"
+    #include "weapons/selection.qh"
+    #include "autocvars.qh"
+    #include <common/notifications/all.qh>
+    #include <common/deathtypes/all.qh>
+    #include <server/mutators/_mod.qh>
+    #include <common/turrets/sv_turrets.qh>
+    #include <common/vehicles/all.qh>
+    #include <lib/csqcmodel/sv_model.qh>
+    #include <common/playerstats.qh>
+    #include "hook.qh"
+    #include "scores.qh"
+    #include "spawnpoints.qh"
+#endif
+
+.void(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force) event_damage;
+
+.bool(entity targ, entity inflictor, float amount, float limit) event_heal;
+
+.float dmg;
+.float dmg_edge;
+.float dmg_force;
+.float dmg_radius;
+
+bool Damage_DamageInfo_SendEntity(entity this, entity to, int sf);
+
+void Damage_DamageInfo(vector org, float coredamage, float edgedamage, float rad, vector force, int deathtype, float bloodtype, entity dmgowner);
+
+float checkrules_firstblood;
+
+.float damagedbycontents;
+.float damagedbytriggers;
+
+float yoda;
+float damage_goodhits;
+float damage_gooddamage;
+
+.float pain_finished; // Added by Supajoe
+
+.float dmg_team;
+.float teamkill_complain;
+.float teamkill_soundtime;
+.entity teamkill_soundsource;
+.entity pusher;
+.bool istypefrag;
+.float taunt_soundtime;
+
+.float spawnshieldtime;
+
+.int totalfrags;
+
+.bool canteamdamage;
+
+.vector death_origin;
+
+.float damage_dealt, typehitsound, killsound;
+
+// used for custom deathtype
+string deathmessage;
+
+float IsFlying(entity a);
+
+void UpdateFrags(entity player, int f);
+
+// NOTE: f=0 means still count as a (positive) kill, but count no frags for it
+void W_SwitchWeapon_Force(Player this, Weapon w, .entity weaponentity);
+void GiveFrags (entity attacker, entity targ, float f, int deathtype, .entity weaponentity);
+
+string AppendItemcodes(string s, entity player);
+
+void LogDeath(string mode, int deathtype, entity killer, entity killed);
+
+void Obituary_SpecialDeath(
+       entity notif_target,
+       float murder,
+       int deathtype,
+       string s1, string s2, string s3,
+       float f1, float f2, float f3);
+
+float w_deathtype;
+float Obituary_WeaponDeath(
+       entity notif_target,
+       float murder,
+       int deathtype,
+       string s1, string s2, string s3,
+       float f1, float f2);
+
+void Obituary(entity attacker, entity inflictor, entity targ, int deathtype, .entity weaponentity);
+
+// Frozen status effect
+//const int FROZEN_NOT              = 0;
+const int FROZEN_NORMAL             = 1;
+const int FROZEN_TEMP_REVIVING      = 2;
+const int FROZEN_TEMP_DYING         = 3;
+
+.float revival_time; // time at which player was last revived
+.float revive_speed; // NOTE: multiplier (anything above 1 is instaheal)
+.float freeze_time;
+.entity iceblock;
+.entity frozen_by; // for ice fields
+
+void Ice_Think(entity this);
+
+void Freeze(entity targ, float revivespeed, int frozen_type, bool show_waypoint);
+
+void Unfreeze(entity targ, bool reset_health);
+
+// WEAPONTODO
+#define DMG_NOWEP (weaponentities[0])
+
+// NOTE: the .weaponentity parameter can be set to DMG_NOWEP if the attack wasn't caused by a weapon or player
+void Damage (entity targ, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force);
+
+float RadiusDamage_running;
+float RadiusDamageForSource (entity inflictor, vector inflictororigin, vector inflictorvelocity, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float inflictorselfdamage, float forceintensity, float forcezscale, int deathtype, .entity weaponentity, entity directhitentity);
+       // Returns total damage applies to creatures
+
+float RadiusDamage (entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float forceintensity, int deathtype, .entity weaponentity, entity directhitentity);
+
+.float damageforcescale;
+const float MIN_DAMAGEEXTRARADIUS = 2;
+const float MAX_DAMAGEEXTRARADIUS = 16;
+.float damageextraradius;
+
+// Calls .event_heal on the target so that they can handle healing themselves
+// a limit of RES_LIMIT_NONE should be handled by the entity as its max health (if applicable)
+bool Heal(entity targ, entity inflictor, float amount, float limit);
+
+.float fire_damagepersec;
+.float fire_endtime;
+.float fire_deathtype;
+.entity fire_owner;
+.float fire_hitsound;
+.entity fire_burner;
+
+void fireburner_think(entity this);
+
+float Fire_IsBurning(entity e);
+
+float Fire_AddDamage(entity e, entity o, float d, float t, float dt);
+
+void Fire_ApplyDamage(entity e);
+
+void Fire_ApplyEffect(entity e);
+
+IntrusiveList g_damagedbycontents;
+STATIC_INIT(g_damagedbycontents) { g_damagedbycontents = IL_NEW(); }
diff --git a/qcsrc/server/defs.qh b/qcsrc/server/defs.qh
deleted file mode 100644 (file)
index 1e50f3e..0000000
+++ /dev/null
@@ -1,436 +0,0 @@
-#pragma once
-
-#include <common/weapons/_all.qh>
-#include <common/stats.qh>
-
-#define INDEPENDENT_ATTACK_FINISHED 1
-
-// Globals
-
-float g_footsteps, g_grappling_hook;
-float g_warmup_allguns;
-float g_warmup_allow_timeout;
-float warmup_stage;
-float g_jetpack;
-
-bool sv_ready_restart;
-bool sv_ready_restart_after_countdown;
-bool sv_ready_restart_repeatable;
-
-float sv_clones;
-float sv_foginterval;
-
-float player_count;
-float currentbots;
-float bots_would_leave;
-
-void UpdateFrags(entity player, int f);
-.int totalfrags;
-
-// flag set on worldspawn so that the code knows if it is dedicated or not
-float server_is_dedicated;
-
-// Fields
-
-.void(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force) event_damage;
-
-.bool(entity targ, entity inflictor, float amount, float limit) event_heal;
-
-//.string      wad;
-//.string      map;
-
-//.float       worldtype;
-// Needed for dynamic clientwalls
-.bool inactive; // Clientwall disappears when inactive
-.float alpha_max, alpha_min;
-.float fade_start, fade_end, fade_vertical_offset;
-.float default_solid; // Variable to store default .solid for clientwalls
-
-.float pain_finished;                  //Added by Supajoe
-.float pain_frame;                     //"
-.float  crouch;        // Crouching or not?
-
-.float superweapons_finished; // NOTE: this field is used only by map entities, it does not directly apply the superweapons stat
-const .float air_finished = _STAT(AIR_FINISHED);
-
-.float cnt; // used in too many places
-.float count;
-//.float cnt2;
-
-.int respawn_flags;
-.float respawn_time;
-.float respawn_time_max;
-.float death_time;
-.float fade_time;
-.float fade_rate;
-
-void player_setupanimsformodel(entity this);
-
-.string mdl;
-
-.string playermodel;
-.string playerskin;
-
-.float species;
-
-.float scheduledrespawntime;
-.float respawntime;
-.float respawntimejitter;
-.float respawntimestart;
-//.float       chasecam;
-
-.float damageforcescale;
-const float MIN_DAMAGEEXTRARADIUS = 2;
-const float MAX_DAMAGEEXTRARADIUS = 16;
-.float damageextraradius;
-
-//.float          gravity;
-
-.float         dmg;
-
-// for railgun damage (hitting multiple enemies)
-.bool railgunhit;
-.float railgunhitsolidbackup;
-.vector railgunhitloc;
-
-.float         dmgtime;
-
-.float         killcount;
-.float damage_dealt, typehitsound, killsound;
-
-.float watersound_finished;
-.float iscreature;
-.float damagedbycontents;
-.float damagedbytriggers;
-.float teleportable;
-.vector oldvelocity;
-
-.float pauseregen_finished;
-.float pauserothealth_finished;
-.float pauserotarmor_finished;
-.float pauserotfuel_finished;
-// string overrides entity
-.string item_pickupsound;
-.entity item_pickupsound_ent;
-.entity item_model_ent;
-
-// WEAPONTODO
-.float autoswitch;
-bool client_hasweapon(entity this, Weapon wpn, .entity weaponentity, float andammo, bool complain);
-void w_clear(Weapon thiswep, entity actor, .entity weaponentity, int fire);
-void w_ready(Weapon thiswep, entity actor, .entity weaponentity, int fire);
-// VorteX: standalone think for weapons, so normal think on weaponentity can be reserved by weaponflashes (which needs update even player dies)
-.float weapon_nextthink;
-.void(Weapon thiswep, entity actor, .entity weaponentity, int fire) weapon_think;
-
-
-// there is 2 weapon tics that can run in one server frame
-const int W_TICSPERFRAME = 2;
-
-void weapon_defaultspawnfunc(entity this, Weapon e);
-
-float intermission_running;
-float intermission_exittime;
-float alreadychangedlevel;
-
-// footstep interval
-.float nextstep;
-
-float blockSpectators; //if set, new or existing spectators or observers will be removed unless they become a player within g_maxplayers_spectator_blocktime seconds
-.float spectatortime; //point in time since the client is spectating or observing
-void checkSpectatorBlock(entity this);
-
-.float winning;
-.float jointime; // time of connecting
-.float startplaytime; // time of switching from spectator to player
-.float alivetime; // time of being alive
-.float motd_actived_time; // used for both motd and campaign_message
-
-int nJoinAllowed(entity this, entity ignore);
-
-.float spawnshieldtime;
-.float item_spawnshieldtime;
-
-.entity flagcarried;
-
-.int playerid;
-.float noalign;                // if set to 1, the item or spawnpoint won't be dropped to the floor
-
-.vector death_origin;
-
-float default_player_alpha;
-float default_weapon_alpha;
-
-.float cvar_cl_handicap;
-.int cvar_cl_gunalign;
-.float cvar_cl_clippedspectating;
-.float cvar_cl_autoscreenshot;
-.float cvar_cl_jetpack_jump;
-.float cvar_cl_movement_track_canjump;
-.float cvar_cl_newusekeysupported;
-.float cvar_cl_cts_noautoswitch;
-.bool cvar_cl_weapon_switch_reload;
-.bool cvar_cl_weapon_switch_fallback_to_impulse;
-
-.string cvar_g_xonoticversion;
-.string cvar_cl_weaponpriority;
-.string cvar_cl_weaponpriorities[10];
-.float cvar_cl_noantilag;
-
-.string weaponorder_byimpulse;
-
-.float cvar_cl_allow_uid2name;
-.float cvar_cl_allow_uidtracking;
-.bool cvar_cl_allow_uidranking;
-.string stored_netname;
-
-string gamemode_name;
-
-string W_Apply_Weaponreplace(string in);
-
-void FixIntermissionClient(entity e);
-void FixClientCvars(entity e);
-
-.float respawn_countdown; // next number to count
-
-float bot_waypoints_for_items;
-
-.float attack_finished_for[REGISTRY_MAX(Weapons) * MAX_WEAPONSLOTS];
-.float attack_finished_single[MAX_WEAPONSLOTS];
-#if INDEPENDENT_ATTACK_FINISHED
-#define ATTACK_FINISHED_FOR(ent, w, slot) ((ent).(attack_finished_for[((w) - WEP_FIRST) * MAX_WEAPONSLOTS + (slot)]))
-#else
-#define ATTACK_FINISHED_FOR(ent, w, slot) ((ent).attack_finished_single[slot])
-#endif
-#define ATTACK_FINISHED(ent, w) ATTACK_FINISHED_FOR(ent, ent.(w).m_weapon.m_id, weaponslot(w))
-
-// speedrun: when 1, player auto teleports back when capture timeout happens
-.float speedrunning;
-
-// database
-float ServerProgsDB;
-float TemporaryDB;
-
-.int team_saved;
-
-bool some_spawn_has_been_used;
-int have_team_spawns; // 0 = no team spawns requested, -1 = team spawns requested but none found, 1 = team spawns requested and found
-int have_team_spawns_forteams; // if Xth bit is 1 then team X has spawns else it has no spawns; team 0 is the "no-team"
-
-.bool canteamdamage;
-
-void Damage (entity targ, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force);
-
-// WEAPONTODO
-#define DMG_NOWEP (weaponentities[0])
-
-float sv_maxidle;
-float sv_maxidle_spectatorsareidle;
-int sv_maxidle_slots;
-bool sv_maxidle_slots_countbots;
-
-float tracebox_hits_trigger_hurt(vector start, vector mi, vector ma, vector end);
-
-float next_pingtime;
-
-// autotaunt system
-.float cvar_cl_autotaunt;
-.float cvar_cl_voice_directional;
-.float cvar_cl_voice_directional_taunt_attenuation;
-
-int autocvar__independent_players;
-bool independent_players;
-#define INDEPENDENT_PLAYERS (autocvar__independent_players ? (autocvar__independent_players > 0) : independent_players)
-#define IS_INDEPENDENT_PLAYER(e) ((e).solid == SOLID_TRIGGER)
-#define MAKE_INDEPENDENT_PLAYER(e) (((e).solid = SOLID_TRIGGER), ((e).frags = FRAGS_PLAYER_OUT_OF_GAME))
-
-string clientstuff;
-.float phase;
-.int pressedkeys;
-
-.string fog;
-
-string cvar_changes;
-string cvar_purechanges;
-float cvar_purechanges_count;
-
-//float game_starttime; //point in time when the countdown to game start is over
-//float round_starttime; //point in time when the countdown to round start is over
-
-void W_Porto_Remove (entity p);
-
-.int projectiledeathtype;
-
-.string message2;
-
-// reset to 0 on weapon switch
-// may be useful to all weapons
-.float bulletcounter;
-
-// Nexball
-float g_nexball_meter_period;
-
-.void(entity this) reset; // if set, an entity is reset using this
-.void(entity this) reset2; // if set, an entity is reset using this (after calling ALL the reset functions for other entities)
-
-void ClientData_Touch(entity e);
-
-//vector debug_shotorg; // if non-zero, overrides the shot origin of all weapons
-
-.bool wasplayer;
-
-float servertime, serverprevtime, serverframetime;
-
-.float ammo_fuel;
-
-//flood fields
-.float nickspamtime; // time of last nick change
-.float nickspamcount;
-.float floodcontrol_chat;
-.float floodcontrol_chatteam;
-.float floodcontrol_chattell;
-.float floodcontrol_voice;
-.float floodcontrol_voiceteam;
-
-string matchid;
-
-bool radar_showennemies;
-
-.float weapon_load[REGISTRY_MAX(Weapons)];
-.int ammo_none; // used by the reloading system, must always be 0
-.int clip_load;
-.int old_clip_load;
-.int clip_size;
-
-.int minelayer_mines;
-.float vortex_charge;
-.float vortex_charge_rottime;
-.float vortex_chargepool_ammo;
-.float oknex_charge;
-.float oknex_charge_rottime;
-.float oknex_chargepool_ammo;
-.int hagar_load;
-
-.int grab; // 0 = can't grab, 1 = owner can grab, 2 = owner and team mates can grab, 3 = anyone can grab
-
-#define PROJECTILE_MAKETRIGGER(e) (e).solid = SOLID_CORPSE; (e).dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE
-// when doing this, hagar can go through clones
-// #define PROJECTILE_MAKETRIGGER(e) (e).solid = SOLID_BBOX
-
-.int spectatee_status;
-.bool zoomstate;
-.int restriction;
-
-.entity clientdata;
-.entity personal;
-
-string deathmessage;
-
-.bool just_joined;
-
-.float cvar_cl_weaponimpulsemode;
-.int selectweapon; // last selected weapon of the player
-
-.float ballistics_density;
-
-//const int FROZEN_NOT                         = 0;
-const int FROZEN_NORMAL                                = 1;
-const int FROZEN_TEMP_REVIVING         = 2;
-const int FROZEN_TEMP_DYING                    = 3;
-
-const int ACTIVE_NOT           = 0;
-const int ACTIVE_ACTIVE        = 1;
-const int ACTIVE_IDLE          = 2;
-const int ACTIVE_BUSY          = 2;
-const int ACTIVE_TOGGLE        = 3;
-.int active;
-.void (entity this, int act_state) setactive;
-.entity realowner;
-
-//float serverflags;
-
-.bool player_blocked;
-
-.float revival_time; // time at which player was last revived
-.float revive_speed; // NOTE: multiplier (anything above 1 is instaheal)
-.float freeze_time;
-.entity iceblock;
-.entity frozen_by; // for ice fields
-
-.float misc_bulletcounter;     // replaces uzi & hlac bullet counter.
-
-void PlayerUseKey(entity this);
-
-USING(spawn_evalfunc_t, vector(entity this, entity player, entity spot, vector current));
-.spawn_evalfunc_t spawn_evalfunc;
-
-string modname;
-
-.int missile_flags;
-const int MIF_SPLASH = BIT(1);
-const int MIF_ARC = BIT(2);
-const int MIF_PROXY = BIT(3);
-const int MIF_GUIDED_MANUAL = BIT(4);
-const int MIF_GUIDED_HEAT = BIT(5);
-const int MIF_GUIDED_LASER = BIT(6);
-const int MIF_GUIDED_AI = BIT(7);
-const int MIF_GUIDED_TAG = BIT(7);
-const int MIF_GUIDED_ALL = MIF_GUIDED_MANUAL | MIF_GUIDED_HEAT | MIF_GUIDED_LASER | MIF_GUIDED_AI | MIF_GUIDED_TAG;
-const int MIF_GUIDED_TRACKING = MIF_GUIDED_HEAT | MIF_GUIDED_LASER | MIF_GUIDED_AI | MIF_GUIDED_TAG;
-const int MIF_GUIDED_CONFUSABLE = MIF_GUIDED_HEAT | MIF_GUIDED_AI;
-
-#define MISSILE_IS_CONFUSABLE(m) ((m.missile_flags & MIF_GUIDED_CONFUSABLE) ? true : false)
-#define MISSILE_IS_GUIDED(m) ((m.missile_flags & MIF_GUIDED_ALL) ? true : false)
-#define MISSILE_IS_TRACKING(m) ((m.missile_flags & MIF_GUIDED_TRACKING) ? true : false)
-
-////
-
-.string cvar_cl_physics;
-
-.void(entity this, entity player) init_for_player;
-
-.WepSet dual_weapons;
-
-IntrusiveList g_monsters;
-IntrusiveList g_waypoints;
-IntrusiveList g_vehicles;
-IntrusiveList g_turrets;
-IntrusiveList g_mines;
-IntrusiveList g_projectiles;
-IntrusiveList g_items;
-IntrusiveList g_initforplayer;
-IntrusiveList g_clones;
-IntrusiveList g_spawnpoints;
-IntrusiveList g_bot_targets;
-IntrusiveList g_bot_dodge;
-IntrusiveList g_damagedbycontents;
-IntrusiveList g_railgunhit;
-IntrusiveList g_ladders;
-IntrusiveList g_locations;
-IntrusiveList g_saved_team;
-IntrusiveList g_monster_targets;
-IntrusiveList g_pathlib_nodes;
-IntrusiveList g_moveables;
-STATIC_INIT(defs)
-{
-       g_monsters = IL_NEW();
-       g_waypoints = IL_NEW();
-       g_vehicles = IL_NEW();
-       g_turrets = IL_NEW();
-       g_mines = IL_NEW();
-       g_projectiles = IL_NEW();
-       g_items = IL_NEW();
-       g_initforplayer = IL_NEW();
-       g_clones = IL_NEW();
-       g_spawnpoints = IL_NEW();
-       g_bot_targets = IL_NEW();
-       g_bot_dodge = IL_NEW();
-       g_damagedbycontents = IL_NEW();
-       g_railgunhit = IL_NEW();
-       g_ladders = IL_NEW();
-       g_locations = IL_NEW();
-       g_saved_team = IL_NEW();
-       g_monster_targets = IL_NEW();
-       g_pathlib_nodes = IL_NEW();
-       g_moveables = IL_NEW();
-}
diff --git a/qcsrc/server/g_damage.qc b/qcsrc/server/g_damage.qc
deleted file mode 100644 (file)
index 626b3e5..0000000
+++ /dev/null
@@ -1,1297 +0,0 @@
-#include "g_damage.qh"
-
-#include <common/effects/all.qh>
-#include "bot/api.qh"
-#include "g_hook.qh"
-#include <server/gamelog.qh>
-#include <server/mutators/_mod.qh>
-#include "teamplay.qh"
-#include "scores.qh"
-#include "spawnpoints.qh"
-#include "../common/state.qh"
-#include "../common/physics/player.qh"
-#include "../common/t_items.qh"
-#include "resources.qh"
-#include "../common/vehicles/all.qh"
-#include "../common/items/_mod.qh"
-#include "../common/mutators/mutator/waypoints/waypointsprites.qh"
-#include "../common/mutators/mutator/instagib/sv_instagib.qh"
-#include "../common/mutators/mutator/buffs/buffs.qh"
-#include "weapons/accuracy.qh"
-#include "weapons/csqcprojectile.qh"
-#include "weapons/selection.qh"
-#include "../common/constants.qh"
-#include "../common/deathtypes/all.qh"
-#include "../common/notifications/all.qh"
-#include "../common/physics/movetypes/movetypes.qh"
-#include "../common/playerstats.qh"
-#include "../common/teams.qh"
-#include "../common/util.qh"
-#include <common/gamemodes/_mod.qh>
-#include <common/gamemodes/rules.qh>
-#include <common/weapons/_all.qh>
-#include "../lib/csqcmodel/sv_model.qh"
-#include "../lib/warpzone/common.qh"
-
-void UpdateFrags(entity player, int f)
-{
-       GameRules_scoring_add_team(player, SCORE, f);
-}
-
-void GiveFrags(entity attacker, entity targ, float f, int deathtype, .entity weaponentity)
-{
-       // TODO route through PlayerScores instead
-       if(game_stopped) return;
-
-       if(f < 0)
-       {
-               if(targ == attacker)
-               {
-                       // suicide
-                       GameRules_scoring_add(attacker, SUICIDES, 1);
-               }
-               else
-               {
-                       // teamkill
-                       GameRules_scoring_add(attacker, TEAMKILLS, 1);
-               }
-       }
-       else
-       {
-               // regular frag
-               GameRules_scoring_add(attacker, KILLS, 1);
-               if(!warmup_stage && targ.playerid)
-                       PlayerStats_GameReport_Event_Player(attacker, sprintf("kills-%d", targ.playerid), 1);
-       }
-
-       GameRules_scoring_add(targ, DEATHS, 1);
-
-       // FIXME fix the mess this is (we have REAL points now!)
-       if(MUTATOR_CALLHOOK(GiveFragsForKill, attacker, targ, f, deathtype, attacker.(weaponentity)))
-               f = M_ARGV(2, float);
-
-       attacker.totalfrags += f;
-
-       if(f)
-               UpdateFrags(attacker, f);
-}
-
-string AppendItemcodes(string s, entity player)
-{
-       for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
-       {
-               .entity weaponentity = weaponentities[slot];
-               int w = player.(weaponentity).m_weapon.m_id;
-               if(w == 0)
-                       w = player.(weaponentity).cnt; // previous weapon
-               if(w != 0 || slot == 0)
-                       s = strcat(s, ftos(w));
-       }
-       if(time < STAT(STRENGTH_FINISHED, player))
-               s = strcat(s, "S");
-       if(time < STAT(INVINCIBLE_FINISHED, player))
-               s = strcat(s, "I");
-       if(PHYS_INPUT_BUTTON_CHAT(player))
-               s = strcat(s, "T");
-       // TODO: include these codes as a flag on the item itself
-       MUTATOR_CALLHOOK(LogDeath_AppendItemCodes, player, s);
-       s = M_ARGV(1, string);
-       return s;
-}
-
-void LogDeath(string mode, int deathtype, entity killer, entity killed)
-{
-       string s;
-       if(!autocvar_sv_eventlog)
-               return;
-       s = strcat(":kill:", mode);
-       s = strcat(s, ":", ftos(killer.playerid));
-       s = strcat(s, ":", ftos(killed.playerid));
-       s = strcat(s, ":type=", Deathtype_Name(deathtype));
-       s = strcat(s, ":items=");
-       s = AppendItemcodes(s, killer);
-       if(killed != killer)
-       {
-               s = strcat(s, ":victimitems=");
-               s = AppendItemcodes(s, killed);
-       }
-       GameLogEcho(s);
-}
-
-void Obituary_SpecialDeath(
-       entity notif_target,
-       float murder,
-       int deathtype,
-       string s1, string s2, string s3,
-       float f1, float f2, float f3)
-{
-       if(!DEATH_ISSPECIAL(deathtype))
-       {
-               backtrace("Obituary_SpecialDeath called without a special deathtype?\n");
-               return;
-       }
-
-       entity deathent = REGISTRY_GET(Deathtypes, deathtype - DT_FIRST);
-       if (!deathent)
-       {
-               backtrace("Obituary_SpecialDeath: Could not find deathtype entity!\n");
-               return;
-       }
-
-       if(g_cts && deathtype == DEATH_KILL.m_id)
-               return; // TODO: somehow put this in CTS gamemode file!
-
-       Notification death_message = (murder) ? deathent.death_msgmurder : deathent.death_msgself;
-       if(death_message)
-       {
-               Send_Notification_WOCOVA(
-                       NOTIF_ONE,
-                       notif_target,
-                       MSG_MULTI,
-                       death_message,
-                       s1, s2, s3, "",
-                       f1, f2, f3, 0
-               );
-               Send_Notification_WOCOVA(
-                       NOTIF_ALL_EXCEPT,
-                       notif_target,
-                       MSG_INFO,
-                       death_message.nent_msginfo,
-                       s1, s2, s3, "",
-                       f1, f2, f3, 0
-               );
-       }
-}
-
-float Obituary_WeaponDeath(
-       entity notif_target,
-       float murder,
-       int deathtype,
-       string s1, string s2, string s3,
-       float f1, float f2)
-{
-       Weapon death_weapon = DEATH_WEAPONOF(deathtype);
-       if (death_weapon == WEP_Null)
-               return false;
-
-       w_deathtype = deathtype;
-       Notification death_message = ((murder) ? death_weapon.wr_killmessage(death_weapon) : death_weapon.wr_suicidemessage(death_weapon));
-       w_deathtype = false;
-
-       if (death_message)
-       {
-               Send_Notification_WOCOVA(
-                       NOTIF_ONE,
-                       notif_target,
-                       MSG_MULTI,
-                       death_message,
-                       s1, s2, s3, "",
-                       f1, f2, 0, 0
-               );
-               // send the info part to everyone
-               Send_Notification_WOCOVA(
-                       NOTIF_ALL_EXCEPT,
-                       notif_target,
-                       MSG_INFO,
-                       death_message.nent_msginfo,
-                       s1, s2, s3, "",
-                       f1, f2, 0, 0
-               );
-       }
-       else
-       {
-               LOG_TRACEF(
-                       "Obituary_WeaponDeath(): ^1Deathtype ^7(%d)^1 has no notification for weapon %s!\n",
-                       deathtype,
-                       death_weapon.netname
-               );
-       }
-
-       return true;
-}
-
-bool frag_centermessage_override(entity attacker, entity targ, int deathtype, int kill_count_to_attacker, int kill_count_to_target, string attacker_name)
-{
-       if(deathtype == DEATH_FIRE.m_id)
-       {
-               Send_Notification(NOTIF_ONE, attacker, MSG_CHOICE, CHOICE_FRAG_FIRE, targ.netname, kill_count_to_attacker, (IS_BOT_CLIENT(targ) ? -1 : CS(targ).ping));
-               Send_Notification(NOTIF_ONE, targ, MSG_CHOICE, CHOICE_FRAGGED_FIRE, attacker_name, kill_count_to_target, GetResource(attacker, RES_HEALTH), GetResource(attacker, RES_ARMOR), (IS_BOT_CLIENT(attacker) ? -1 : CS(attacker).ping));
-               return true;
-       }
-
-       return MUTATOR_CALLHOOK(FragCenterMessage, attacker, targ, deathtype, kill_count_to_attacker, kill_count_to_target);
-}
-
-void Obituary(entity attacker, entity inflictor, entity targ, int deathtype, .entity weaponentity)
-{
-       // Sanity check
-       if (!IS_PLAYER(targ)) { backtrace("Obituary called on non-player?!\n"); return; }
-
-       // Declarations
-       float notif_firstblood = false;
-       float kill_count_to_attacker, kill_count_to_target;
-       bool notif_anonymous = false;
-       string attacker_name = attacker.netname;
-
-       // Set final information for the death
-       targ.death_origin = targ.origin;
-       string deathlocation = (autocvar_notification_server_allows_location ? NearestLocation(targ.death_origin) : "");
-
-       // Abort now if a mutator requests it
-       if (MUTATOR_CALLHOOK(ClientObituary, inflictor, attacker, targ, deathtype, attacker.(weaponentity))) { CS(targ).killcount = 0; return; }
-       notif_anonymous = M_ARGV(5, bool);
-
-       if(notif_anonymous)
-               attacker_name = "Anonymous player";
-
-       #ifdef NOTIFICATIONS_DEBUG
-       Debug_Notification(
-               sprintf(
-                       "Obituary(%s, %s, %s, %s = %d);\n",
-                       attacker_name,
-                       inflictor.netname,
-                       targ.netname,
-                       Deathtype_Name(deathtype),
-                       deathtype
-               )
-       );
-       #endif
-
-       // =======
-       // SUICIDE
-       // =======
-       if(targ == attacker)
-       {
-               if(DEATH_ISSPECIAL(deathtype))
-               {
-                       if(deathtype == DEATH_TEAMCHANGE.m_id || deathtype == DEATH_AUTOTEAMCHANGE.m_id)
-                       {
-                               Obituary_SpecialDeath(targ, false, deathtype, targ.netname, deathlocation, "", targ.team, 0, 0);
-                       }
-                       else
-                       {
-                               switch(DEATH_ENT(deathtype))
-                               {
-                                       case DEATH_MIRRORDAMAGE:
-                                       {
-                                               Obituary_SpecialDeath(targ, false, deathtype, targ.netname, deathlocation, "", CS(targ).killcount, 0, 0);
-                                               break;
-                                       }
-
-                                       default:
-                                       {
-                                               Obituary_SpecialDeath(targ, false, deathtype, targ.netname, deathlocation, "", CS(targ).killcount, 0, 0);
-                                               break;
-                                       }
-                               }
-                       }
-               }
-               else if (!Obituary_WeaponDeath(targ, false, deathtype, targ.netname, deathlocation, "", CS(targ).killcount, 0))
-               {
-                       backtrace("SUICIDE: what the hell happened here?\n");
-                       return;
-               }
-               LogDeath("suicide", deathtype, targ, targ);
-               if(deathtype != DEATH_AUTOTEAMCHANGE.m_id) // special case: don't negate frags if auto switched
-                       GiveFrags(attacker, targ, -1, deathtype, weaponentity);
-       }
-
-       // ======
-       // MURDER
-       // ======
-       else if(IS_PLAYER(attacker))
-       {
-               if(SAME_TEAM(attacker, targ))
-               {
-                       LogDeath("tk", deathtype, attacker, targ);
-                       GiveFrags(attacker, targ, -1, deathtype, weaponentity);
-
-                       CS(attacker).killcount = 0;
-
-                       Send_Notification(NOTIF_ONE, attacker, MSG_CENTER, CENTER_DEATH_TEAMKILL_FRAG, targ.netname);
-                       Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_DEATH_TEAMKILL_FRAGGED, attacker_name);
-                       Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(targ.team, INFO_DEATH_TEAMKILL), targ.netname, attacker_name, deathlocation, CS(targ).killcount);
-
-                       // In this case, the death message will ALWAYS be "foo was betrayed by bar"
-                       // No need for specific death/weapon messages...
-               }
-               else
-               {
-                       LogDeath("frag", deathtype, attacker, targ);
-                       GiveFrags(attacker, targ, 1, deathtype, weaponentity);
-
-                       CS(attacker).taunt_soundtime = time + 1;
-                       CS(attacker).killcount = CS(attacker).killcount + 1;
-
-                       attacker.killsound += 1;
-
-                       // TODO: improve SPREE_ITEM and KILL_SPREE_LIST
-                       // these 2 macros are spread over multiple files
-                       #define SPREE_ITEM(counta,countb,center,normal,gentle) \
-                               case counta: \
-                                       Send_Notification(NOTIF_ONE, attacker, MSG_ANNCE, ANNCE_KILLSTREAK_##countb); \
-                                       if (!warmup_stage) \
-                                               PlayerStats_GameReport_Event_Player(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_##counta, 1); \
-                                       break;
-
-                       switch(CS(attacker).killcount)
-                       {
-                               KILL_SPREE_LIST
-                               default: break;
-                       }
-                       #undef SPREE_ITEM
-
-                       if(!warmup_stage && !checkrules_firstblood)
-                       {
-                               checkrules_firstblood = true;
-                               notif_firstblood = true; // modify the current messages so that they too show firstblood information
-                               PlayerStats_GameReport_Event_Player(attacker, PLAYERSTATS_ACHIEVEMENT_FIRSTBLOOD, 1);
-                               PlayerStats_GameReport_Event_Player(targ, PLAYERSTATS_ACHIEVEMENT_FIRSTVICTIM, 1);
-
-                               // tell spree_inf and spree_cen that this is a first-blood and first-victim event
-                               kill_count_to_attacker = -1;
-                               kill_count_to_target = -2;
-                       }
-                       else
-                       {
-                               kill_count_to_attacker = CS(attacker).killcount;
-                               kill_count_to_target = 0;
-                       }
-
-                       if(targ.istypefrag)
-                       {
-                               Send_Notification(
-                                       NOTIF_ONE,
-                                       attacker,
-                                       MSG_CHOICE,
-                                       CHOICE_TYPEFRAG,
-                                       targ.netname,
-                                       kill_count_to_attacker,
-                                       (IS_BOT_CLIENT(targ) ? -1 : CS(targ).ping)
-                               );
-                               Send_Notification(
-                                       NOTIF_ONE,
-                                       targ,
-                                       MSG_CHOICE,
-                                       CHOICE_TYPEFRAGGED,
-                                       attacker_name,
-                                       kill_count_to_target,
-                                       GetResource(attacker, RES_HEALTH),
-                                       GetResource(attacker, RES_ARMOR),
-                                       (IS_BOT_CLIENT(attacker) ? -1 : CS(attacker).ping)
-                               );
-                       }
-                       else if(!frag_centermessage_override(attacker, targ, deathtype, kill_count_to_attacker, kill_count_to_target, attacker_name))
-                       {
-                               Send_Notification(
-                                       NOTIF_ONE,
-                                       attacker,
-                                       MSG_CHOICE,
-                                       CHOICE_FRAG,
-                                       targ.netname,
-                                       kill_count_to_attacker,
-                                       (IS_BOT_CLIENT(targ) ? -1 : CS(targ).ping)
-                               );
-                               Send_Notification(
-                                       NOTIF_ONE,
-                                       targ,
-                                       MSG_CHOICE,
-                                       CHOICE_FRAGGED,
-                                       attacker_name,
-                                       kill_count_to_target,
-                                       GetResource(attacker, RES_HEALTH),
-                                       GetResource(attacker, RES_ARMOR),
-                                       (IS_BOT_CLIENT(attacker) ? -1 : CS(attacker).ping)
-                               );
-                       }
-
-                       int f3 = 0;
-                       if(deathtype == DEATH_BUFF.m_id)
-                               f3 = buff_FirstFromFlags(STAT(BUFFS, attacker)).m_id;
-
-                       if (!Obituary_WeaponDeath(targ, true, deathtype, targ.netname, attacker_name, deathlocation, CS(targ).killcount, kill_count_to_attacker))
-                               Obituary_SpecialDeath(targ, true, deathtype, targ.netname, attacker_name, deathlocation, CS(targ).killcount, kill_count_to_attacker, f3);
-               }
-       }
-
-       // =============
-       // ACCIDENT/TRAP
-       // =============
-       else
-       {
-               switch(DEATH_ENT(deathtype))
-               {
-                       // For now, we're just forcing HURTTRIGGER to behave as "DEATH_VOID" and giving it no special options...
-                       // Later on you will only be able to make custom messages using DEATH_CUSTOM,
-                       // and there will be a REAL DEATH_VOID implementation which mappers will use.
-                       case DEATH_HURTTRIGGER:
-                       {
-                               Obituary_SpecialDeath(targ, false, deathtype,
-                                       targ.netname,
-                                       inflictor.message,
-                                       deathlocation,
-                                       CS(targ).killcount,
-                                       0,
-                                       0);
-                               break;
-                       }
-
-                       case DEATH_CUSTOM:
-                       {
-                               Obituary_SpecialDeath(targ, false, deathtype,
-                                       targ.netname,
-                                       ((strstrofs(deathmessage, "%", 0) < 0) ? strcat("%s ", deathmessage) : deathmessage),
-                                       deathlocation,
-                                       CS(targ).killcount,
-                                       0,
-                                       0);
-                               break;
-                       }
-
-                       default:
-                       {
-                               Obituary_SpecialDeath(targ, false, deathtype, targ.netname, deathlocation, "", CS(targ).killcount, 0, 0);
-                               break;
-                       }
-               }
-
-               LogDeath("accident", deathtype, targ, targ);
-               GiveFrags(targ, targ, -1, deathtype, weaponentity);
-
-               if(GameRules_scoring_add(targ, SCORE, 0) == -5)
-               {
-                       Send_Notification(NOTIF_ONE, targ, MSG_ANNCE, ANNCE_ACHIEVEMENT_BOTLIKE);
-                       if (!warmup_stage)
-                       {
-                               PlayerStats_GameReport_Event_Player(attacker, PLAYERSTATS_ACHIEVEMENT_BOTLIKE, 1);
-                       }
-               }
-       }
-
-       // reset target kill count
-       CS(targ).killcount = 0;
-}
-
-void Ice_Think(entity this)
-{
-       if(!STAT(FROZEN, this.owner) || this.owner.iceblock != this)
-       {
-               delete(this);
-               return;
-       }
-       vector ice_org = this.owner.origin - '0 0 16';
-       if (this.origin != ice_org)
-               setorigin(this, ice_org);
-       this.nextthink = time;
-}
-
-void Freeze(entity targ, float revivespeed, int frozen_type, bool show_waypoint)
-{
-       if(!IS_PLAYER(targ) && !IS_MONSTER(targ)) // TODO: only specified entities can be freezed
-               return;
-
-       if(STAT(FROZEN, targ))
-               return;
-
-       float targ_maxhealth = ((IS_MONSTER(targ)) ? targ.max_health : start_health);
-
-       STAT(FROZEN, targ) = frozen_type;
-       STAT(REVIVE_PROGRESS, targ) = ((frozen_type == FROZEN_TEMP_DYING) ? 1 : 0);
-       SetResource(targ, RES_HEALTH, ((frozen_type == FROZEN_TEMP_DYING) ? targ_maxhealth : 1));
-       targ.revive_speed = revivespeed;
-       if(targ.bot_attack)
-               IL_REMOVE(g_bot_targets, targ);
-       targ.bot_attack = false;
-       targ.freeze_time = time;
-
-       entity ice = new(ice);
-       ice.owner = targ;
-       ice.scale = targ.scale;
-       // set_movetype(ice, MOVETYPE_FOLLOW) would rotate the ice model with the player
-       setthink(ice, Ice_Think);
-       ice.nextthink = time;
-       ice.frame = floor(random() * 21); // ice model has 20 different looking frames
-       setmodel(ice, MDL_ICE);
-       ice.alpha = 1;
-       ice.colormod = Team_ColorRGB(targ.team);
-       ice.glowmod = ice.colormod;
-       targ.iceblock = ice;
-       targ.revival_time = 0;
-
-       Ice_Think(ice);
-
-       RemoveGrapplingHooks(targ);
-
-       FOREACH_CLIENT(IS_PLAYER(it),
-       {
-               for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
-           {
-               .entity weaponentity = weaponentities[slot];
-               if(it.(weaponentity).hook.aiment == targ)
-                       RemoveHook(it.(weaponentity).hook);
-           }
-       });
-
-       // add waypoint
-       if(MUTATOR_CALLHOOK(Freeze, targ, revivespeed, frozen_type) || show_waypoint)
-               WaypointSprite_Spawn(WP_Frozen, 0, 0, targ, '0 0 64', NULL, targ.team, targ, waypointsprite_attached, true, RADARICON_WAYPOINT);
-}
-
-void Unfreeze(entity targ, bool reset_health)
-{
-       if(!STAT(FROZEN, targ))
-               return;
-
-       if (reset_health && STAT(FROZEN, targ) != FROZEN_TEMP_DYING)
-               SetResource(targ, RES_HEALTH, ((IS_PLAYER(targ)) ? start_health : targ.max_health));
-
-       targ.pauseregen_finished = time + autocvar_g_balance_pause_health_regen;
-
-       STAT(FROZEN, targ) = 0;
-       STAT(REVIVE_PROGRESS, targ) = 0;
-       targ.revival_time = time;
-       if(!targ.bot_attack)
-               IL_PUSH(g_bot_targets, targ);
-       targ.bot_attack = true;
-
-       WaypointSprite_Kill(targ.waypointsprite_attached);
-
-       FOREACH_CLIENT(IS_PLAYER(it),
-       {
-               for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
-           {
-               .entity weaponentity = weaponentities[slot];
-               if(it.(weaponentity).hook.aiment == targ)
-                       RemoveHook(it.(weaponentity).hook);
-           }
-       });
-
-       // remove the ice block
-       if(targ.iceblock)
-               delete(targ.iceblock);
-       targ.iceblock = NULL;
-
-       MUTATOR_CALLHOOK(Unfreeze, targ);
-}
-
-void Damage(entity targ, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
-{
-       float complainteamdamage = 0;
-       float mirrordamage = 0;
-       float mirrorforce = 0;
-
-       if (game_stopped || (IS_CLIENT(targ) && CS(targ).killcount == FRAGS_SPECTATOR))
-               return;
-
-       entity attacker_save = attacker;
-
-       // special rule: gravity bombs and sound-based attacks do not affect team mates (other than for disconnecting the hook)
-       if(DEATH_ISWEAPON(deathtype, WEP_HOOK) || (deathtype & HITTYPE_SOUND))
-       {
-               if(IS_PLAYER(targ) && SAME_TEAM(targ, attacker))
-               {
-                       return;
-               }
-       }
-
-       if(deathtype == DEATH_KILL.m_id || deathtype == DEATH_TEAMCHANGE.m_id || deathtype == DEATH_AUTOTEAMCHANGE.m_id)
-       {
-               // exit the vehicle before killing (fixes a crash)
-               if(IS_PLAYER(targ) && targ.vehicle)
-                       vehicles_exit(targ.vehicle, VHEF_RELEASE);
-
-               // These are ALWAYS lethal
-               // No damage modification here
-               // Instead, prepare the victim for his death...
-               SetResourceExplicit(targ, RES_ARMOR, 0);
-               targ.spawnshieldtime = 0;
-               SetResourceExplicit(targ, RES_HEALTH, 0.9); // this is < 1
-               targ.flags -= targ.flags & FL_GODMODE;
-               damage = 100000;
-       }
-       else if(deathtype == DEATH_MIRRORDAMAGE.m_id || deathtype == DEATH_NOAMMO.m_id)
-       {
-               // no processing
-       }
-       else
-       {
-               // nullify damage if teamplay is on
-               if(deathtype != DEATH_TELEFRAG.m_id)
-               if(IS_PLAYER(attacker))
-               {
-                       if(IS_PLAYER(targ) && targ != attacker && (IS_INDEPENDENT_PLAYER(attacker) || IS_INDEPENDENT_PLAYER(targ)))
-                       {
-                               damage = 0;
-                               force = '0 0 0';
-                       }
-                       else if(SAME_TEAM(attacker, targ))
-                       {
-                               if(autocvar_teamplay_mode == 1)
-                                       damage = 0;
-                               else if(attacker != targ)
-                               {
-                                       if(autocvar_teamplay_mode == 2)
-                                       {
-                                               if(IS_PLAYER(targ) && !IS_DEAD(targ))
-                                               {
-                                                       attacker.dmg_team = attacker.dmg_team + damage;
-                                                       complainteamdamage = attacker.dmg_team - autocvar_g_teamdamage_threshold;
-                                               }
-                                       }
-                                       else if(autocvar_teamplay_mode == 3)
-                                               damage = 0;
-                                       else if(autocvar_teamplay_mode == 4)
-                                       {
-                                               if(IS_PLAYER(targ) && !IS_DEAD(targ))
-                                               {
-                                                       attacker.dmg_team = attacker.dmg_team + damage;
-                                                       complainteamdamage = attacker.dmg_team - autocvar_g_teamdamage_threshold;
-                                                       if(complainteamdamage > 0)
-                                                               mirrordamage = autocvar_g_mirrordamage * complainteamdamage;
-                                                       mirrorforce = autocvar_g_mirrordamage * vlen(force);
-                                                       damage = autocvar_g_friendlyfire * damage;
-                                                       // mirrordamage will be used LATER
-
-                                                       if(autocvar_g_mirrordamage_virtual)
-                                                       {
-                                                               vector v  = healtharmor_applydamage(GetResource(attacker, RES_ARMOR), autocvar_g_balance_armor_blockpercent, deathtype, mirrordamage);
-                                                               attacker.dmg_take += v.x;
-                                                               attacker.dmg_save += v.y;
-                                                               attacker.dmg_inflictor = inflictor;
-                                                               mirrordamage = v.z;
-                                                               mirrorforce = 0;
-                                                       }
-
-                                                       if(autocvar_g_friendlyfire_virtual)
-                                                       {
-                                                               vector v = healtharmor_applydamage(GetResource(targ, RES_ARMOR), autocvar_g_balance_armor_blockpercent, deathtype, damage);
-                                                               targ.dmg_take += v.x;
-                                                               targ.dmg_save += v.y;
-                                                               targ.dmg_inflictor = inflictor;
-                                                               damage = 0;
-                                                               if(!autocvar_g_friendlyfire_virtual_force)
-                                                                       force = '0 0 0';
-                                                       }
-                                               }
-                                               else if(!targ.canteamdamage)
-                                                       damage = 0;
-                                       }
-                               }
-                       }
-               }
-
-               if (!DEATH_ISSPECIAL(deathtype))
-               {
-                       damage *= g_weapondamagefactor;
-                       mirrordamage *= g_weapondamagefactor;
-                       complainteamdamage *= g_weapondamagefactor;
-                       force = force * g_weaponforcefactor;
-                       mirrorforce *= g_weaponforcefactor;
-               }
-
-               // should this be changed at all? If so, in what way?
-               MUTATOR_CALLHOOK(Damage_Calculate, inflictor, attacker, targ, deathtype, damage, mirrordamage, force, attacker.(weaponentity));
-               damage = M_ARGV(4, float);
-               mirrordamage = M_ARGV(5, float);
-               force = M_ARGV(6, vector);
-
-               if(IS_PLAYER(targ) && damage > 0 && attacker)
-               {
-                       for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
-                   {
-                       .entity went = weaponentities[slot];
-                       if(targ.(went).hook && targ.(went).hook.aiment == attacker)
-                               RemoveHook(targ.(went).hook);
-                   }
-               }
-
-               if(STAT(FROZEN, targ) && !ITEM_DAMAGE_NEEDKILL(deathtype)
-                       && deathtype != DEATH_TEAMCHANGE.m_id && deathtype != DEATH_AUTOTEAMCHANGE.m_id)
-               {
-                       if(autocvar_g_frozen_revive_falldamage > 0 && deathtype == DEATH_FALL.m_id && damage >= autocvar_g_frozen_revive_falldamage)
-                       {
-                               Unfreeze(targ, false);
-                               SetResource(targ, RES_HEALTH, autocvar_g_frozen_revive_falldamage_health);
-                               Send_Effect(EFFECT_ICEORGLASS, targ.origin, '0 0 0', 3);
-                               Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_FREEZETAG_REVIVED_FALL, targ.netname);
-                               Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_FREEZETAG_REVIVE_SELF);
-                       }
-
-                       damage = 0;
-                       force *= autocvar_g_frozen_force;
-               }
-
-               if(IS_PLAYER(targ) && STAT(FROZEN, targ)
-                       && ITEM_DAMAGE_NEEDKILL(deathtype) && !autocvar_g_frozen_damage_trigger)
-               {
-                       Send_Effect(EFFECT_TELEPORT, targ.origin, '0 0 0', 1);
-
-                       entity spot = SelectSpawnPoint(targ, false);
-                       if(spot)
-                       {
-                               damage = 0;
-                               targ.deadflag = DEAD_NO;
-
-                               targ.angles = spot.angles;
-
-                               targ.effects = 0;
-                               targ.effects |= EF_TELEPORT_BIT;
-
-                               targ.angles_z = 0; // never spawn tilted even if the spot says to
-                               targ.fixangle = true; // turn this way immediately
-                               targ.velocity = '0 0 0';
-                               targ.avelocity = '0 0 0';
-                               targ.punchangle = '0 0 0';
-                               targ.punchvector = '0 0 0';
-                               targ.oldvelocity = targ.velocity;
-
-                               targ.spawnorigin = spot.origin;
-                               setorigin(targ, spot.origin + '0 0 1' * (1 - targ.mins.z - 24));
-                               // don't reset back to last position, even if new position is stuck in solid
-                               targ.oldorigin = targ.origin;
-
-                               Send_Effect(EFFECT_TELEPORT, targ.origin, '0 0 0', 1);
-                       }
-               }
-
-               if(!MUTATOR_IS_ENABLED(mutator_instagib))
-               {
-                       // apply strength multiplier
-                       if (attacker.items & ITEM_Strength.m_itemid)
-                       {
-                               if(targ == attacker)
-                               {
-                                       damage = damage * autocvar_g_balance_powerup_strength_selfdamage;
-                                       force = force * autocvar_g_balance_powerup_strength_selfforce;
-                               }
-                               else
-                               {
-                                       damage = damage * autocvar_g_balance_powerup_strength_damage;
-                                       force = force * autocvar_g_balance_powerup_strength_force;
-                               }
-                       }
-
-                       // apply invincibility multiplier
-                       if (targ.items & ITEM_Shield.m_itemid)
-                       {
-                               damage = damage * autocvar_g_balance_powerup_invincible_takedamage;
-                               if (targ != attacker)
-                               {
-                                       force = force * autocvar_g_balance_powerup_invincible_takeforce;
-                               }
-                       }
-               }
-
-               if (targ == attacker)
-                       damage = damage * autocvar_g_balance_selfdamagepercent; // Partial damage if the attacker hits himself
-
-               // count the damage
-               if(attacker)
-               if(!IS_DEAD(targ))
-               if(deathtype != DEATH_BUFF.m_id)
-               if(targ.takedamage == DAMAGE_AIM)
-               if(targ != attacker)
-               {
-                       entity victim;
-                       if(IS_VEHICLE(targ) && targ.owner)
-                               victim = targ.owner;
-                       else
-                               victim = targ;
-
-                       if(IS_PLAYER(victim) || (IS_TURRET(victim) && victim.active == ACTIVE_ACTIVE) || IS_MONSTER(victim) || MUTATOR_CALLHOOK(PlayHitsound, victim, attacker))
-                       {
-                               if(DIFF_TEAM(victim, attacker) && !STAT(FROZEN, victim))
-                               {
-                                       if(damage > 0)
-                                       {
-                                               if(deathtype != DEATH_FIRE.m_id)
-                                               {
-                                                       if(PHYS_INPUT_BUTTON_CHAT(victim))
-                                                               attacker.typehitsound += 1;
-                                                       else
-                                                               attacker.damage_dealt += damage;
-                                               }
-
-                                               damage_goodhits += 1;
-                                               damage_gooddamage += damage;
-
-                                               if (!DEATH_ISSPECIAL(deathtype))
-                                               {
-                                                       if(IS_PLAYER(targ)) // don't do this for vehicles
-                                                       if(IsFlying(victim))
-                                                               yoda = 1;
-                                               }
-                                       }
-                               }
-                               else if(IS_PLAYER(attacker))
-                               {
-                                       // if enemy gets frozen in this frame and receives other damage don't
-                                       // play the typehitsound e.g. when hit by multiple bullets of the shotgun
-                                       if (deathtype != DEATH_FIRE.m_id && (!STAT(FROZEN, victim) || time > victim.freeze_time))
-                                       {
-                                               attacker.typehitsound += 1;
-                                       }
-                                       if(complainteamdamage > 0)
-                                               if(time > CS(attacker).teamkill_complain)
-                                               {
-                                                       CS(attacker).teamkill_complain = time + 5;
-                                                       CS(attacker).teamkill_soundtime = time + 0.4;
-                                                       CS(attacker).teamkill_soundsource = targ;
-                                               }
-                               }
-                       }
-               }
-       }
-
-       // apply push
-       if (targ.damageforcescale)
-       if (force)
-       if (!IS_PLAYER(targ) || time >= targ.spawnshieldtime || targ == attacker)
-       {
-               vector farce = damage_explosion_calcpush(targ.damageforcescale * force, targ.velocity, autocvar_g_balance_damagepush_speedfactor);
-               if(targ.move_movetype == MOVETYPE_PHYSICS)
-               {
-                       entity farcent = new(farce);
-                       farcent.enemy = targ;
-                       farcent.movedir = farce * 10;
-                       if(targ.mass)
-                               farcent.movedir = farcent.movedir * targ.mass;
-                       farcent.origin = hitloc;
-                       farcent.forcetype = FORCETYPE_FORCEATPOS;
-                       farcent.nextthink = time + 0.1;
-                       setthink(farcent, SUB_Remove);
-               }
-               else if(targ.move_movetype != MOVETYPE_NOCLIP)
-               {
-                       targ.velocity = targ.velocity + farce;
-               }
-               UNSET_ONGROUND(targ);
-               UpdateCSQCProjectile(targ);
-       }
-       // apply damage
-       if (damage != 0 || (targ.damageforcescale && force))
-       if (targ.event_damage)
-               targ.event_damage (targ, inflictor, attacker, damage, deathtype, weaponentity, hitloc, force);
-
-       // apply mirror damage if any
-       if(!autocvar_g_mirrordamage_onlyweapons || DEATH_WEAPONOF(deathtype) != WEP_Null)
-       if(mirrordamage > 0 || mirrorforce > 0)
-       {
-               attacker = attacker_save;
-
-               force = normalize(attacker.origin + attacker.view_ofs - hitloc) * mirrorforce;
-               Damage(attacker, inflictor, attacker, mirrordamage, DEATH_MIRRORDAMAGE.m_id, weaponentity, attacker.origin, force);
-       }
-}
-
-float RadiusDamageForSource (entity inflictor, vector inflictororigin, vector inflictorvelocity, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe,
-                                                               float inflictorselfdamage, float forceintensity, float forcezscale, int deathtype, .entity weaponentity, entity directhitentity)
-       // Returns total damage applies to creatures
-{
-       entity  targ;
-       vector  force;
-       float   total_damage_to_creatures;
-       entity  next;
-       float   tfloordmg;
-       float   tfloorforce;
-
-       float stat_damagedone;
-
-       if(RadiusDamage_running)
-       {
-               backtrace("RadiusDamage called recursively! Expect stuff to go HORRIBLY wrong.");
-               return 0;
-       }
-
-       RadiusDamage_running = 1;
-
-       tfloordmg = autocvar_g_throughfloor_damage;
-       tfloorforce = autocvar_g_throughfloor_force;
-
-       total_damage_to_creatures = 0;
-
-       if(deathtype != (WEP_HOOK.m_id | HITTYPE_SECONDARY | HITTYPE_BOUNCE)) // only send gravity bomb damage once
-               if(!(deathtype & HITTYPE_SOUND)) // do not send radial sound damage (bandwidth hog)
-               {
-                       force = inflictorvelocity;
-                       if(force == '0 0 0')
-                               force = '0 0 -1';
-                       else
-                               force = normalize(force);
-                       if(forceintensity >= 0)
-                               Damage_DamageInfo(inflictororigin, coredamage, edgedamage, rad, forceintensity * force, deathtype, 0, attacker);
-                       else
-                               Damage_DamageInfo(inflictororigin, coredamage, edgedamage, -rad, (-forceintensity) * force, deathtype, 0, attacker);
-               }
-
-       stat_damagedone = 0;
-
-       targ = WarpZone_FindRadius (inflictororigin, rad + MAX_DAMAGEEXTRARADIUS, false);
-       while (targ)
-       {
-               next = targ.chain;
-               if ((targ != inflictor) || inflictorselfdamage)
-               if (((cantbe != targ) && !mustbe) || (mustbe == targ))
-               if (targ.takedamage)
-               {
-                       vector nearest;
-                       vector diff;
-                       float power;
-
-                       // LordHavoc: measure distance to nearest point on target (not origin)
-                       // (this guarentees 100% damage on a touch impact)
-                       nearest = targ.WarpZone_findradius_nearest;
-                       diff = targ.WarpZone_findradius_dist;
-                       // round up a little on the damage to ensure full damage on impacts
-                       // and turn the distance into a fraction of the radius
-                       power = 1 - ((vlen (diff) - bound(MIN_DAMAGEEXTRARADIUS, targ.damageextraradius, MAX_DAMAGEEXTRARADIUS)) / rad);
-                       //bprint(" ");
-                       //bprint(ftos(power));
-                       //if (targ == attacker)
-                       //      print(ftos(power), "\n");
-                       if (power > 0)
-                       {
-                               float finaldmg;
-                               if (power > 1)
-                                       power = 1;
-                               finaldmg = coredamage * power + edgedamage * (1 - power);
-                               if (finaldmg > 0)
-                               {
-                                       float a;
-                                       float c;
-                                       vector hitloc;
-                                       vector myblastorigin;
-                                       vector center;
-
-                                       myblastorigin = WarpZone_TransformOrigin(targ, inflictororigin);
-
-                                       // if it's a player, use the view origin as reference
-                                       center = CENTER_OR_VIEWOFS(targ);
-
-                                       force = normalize(center - myblastorigin);
-                                       force = force * (finaldmg / coredamage) * forceintensity;
-                                       hitloc = nearest;
-
-                                       // apply special scaling along the z axis if set
-                                       // NOTE: 0 value is not allowed for compatibility, in the case of weapon cvars not being set
-                                       if(forcezscale)
-                                               force.z *= forcezscale;
-
-                                       if(targ != directhitentity)
-                                       {
-                                               float hits;
-                                               float total;
-                                               float hitratio;
-                                               float mininv_f, mininv_d;
-
-                                               // test line of sight to multiple positions on box,
-                                               // and do damage if any of them hit
-                                               hits = 0;
-
-                                               // we know: max stddev of hitratio = 1 / (2 * sqrt(n))
-                                               // so for a given max stddev:
-                                               // n = (1 / (2 * max stddev of hitratio))^2
-
-                                               mininv_d = (finaldmg * (1-tfloordmg)) / autocvar_g_throughfloor_damage_max_stddev;
-                                               mininv_f = (vlen(force) * (1-tfloorforce)) / autocvar_g_throughfloor_force_max_stddev;
-
-                                               if(autocvar_g_throughfloor_debug)
-                                                       LOG_INFOF("THROUGHFLOOR: D=%f F=%f max(dD)=1/%f max(dF)=1/%f", finaldmg, vlen(force), mininv_d, mininv_f);
-
-
-                                               total = 0.25 * (max(mininv_f, mininv_d) ** 2);
-
-                                               if(autocvar_g_throughfloor_debug)
-                                                       LOG_INFOF(" steps=%f", total);
-
-
-                                               if (IS_PLAYER(targ))
-                                                       total = ceil(bound(autocvar_g_throughfloor_min_steps_player, total, autocvar_g_throughfloor_max_steps_player));
-                                               else
-                                                       total = ceil(bound(autocvar_g_throughfloor_min_steps_other, total, autocvar_g_throughfloor_max_steps_other));
-
-                                               if(autocvar_g_throughfloor_debug)
-                                                       LOG_INFOF(" steps=%f dD=%f dF=%f", total, finaldmg * (1-tfloordmg) / (2 * sqrt(total)), vlen(force) * (1-tfloorforce) / (2 * sqrt(total)));
-
-                                               for(c = 0; c < total; ++c)
-                                               {
-                                                       //traceline(targ.WarpZone_findradius_findorigin, nearest, MOVE_NOMONSTERS, inflictor);
-                                                       WarpZone_TraceLine(inflictororigin, WarpZone_UnTransformOrigin(targ, nearest), MOVE_NOMONSTERS, inflictor);
-                                                       if (trace_fraction == 1 || trace_ent == targ)
-                                                       {
-                                                               ++hits;
-                                                               if (hits > 1)
-                                                                       hitloc = hitloc + nearest;
-                                                               else
-                                                                       hitloc = nearest;
-                                                       }
-                                                       nearest.x = targ.origin.x + targ.mins.x + random() * targ.size.x;
-                                                       nearest.y = targ.origin.y + targ.mins.y + random() * targ.size.y;
-                                                       nearest.z = targ.origin.z + targ.mins.z + random() * targ.size.z;
-                                               }
-
-                                               nearest = hitloc * (1 / max(1, hits));
-                                               hitratio = (hits / total);
-                                               a = bound(0, tfloordmg + (1-tfloordmg) * hitratio, 1);
-                                               finaldmg = finaldmg * a;
-                                               a = bound(0, tfloorforce + (1-tfloorforce) * hitratio, 1);
-                                               force = force * a;
-
-                                               if(autocvar_g_throughfloor_debug)
-                                                       LOG_INFOF(" D=%f F=%f", finaldmg, vlen(force));
-                                       }
-
-                                       //if (targ == attacker)
-                                       //{
-                                       //      print("hits ", ftos(hits), " / ", ftos(total));
-                                       //      print(" finaldmg ", ftos(finaldmg), " force ", vtos(force));
-                                       //      print(" (", ftos(a), ")\n");
-                                       //}
-                                       if(finaldmg || force)
-                                       {
-                                               if(targ.iscreature)
-                                               {
-                                                       total_damage_to_creatures += finaldmg;
-
-                                                       if(accuracy_isgooddamage(attacker, targ))
-                                                               stat_damagedone += finaldmg;
-                                               }
-
-                                               if(targ == directhitentity || DEATH_ISSPECIAL(deathtype))
-                                                       Damage(targ, inflictor, attacker, finaldmg, deathtype, weaponentity, nearest, force);
-                                               else
-                                                       Damage(targ, inflictor, attacker, finaldmg, deathtype | HITTYPE_SPLASH, weaponentity, nearest, force);
-                                       }
-                               }
-                       }
-               }
-               targ = next;
-       }
-
-       RadiusDamage_running = 0;
-
-       if(!DEATH_ISSPECIAL(deathtype))
-               accuracy_add(attacker, DEATH_WEAPONOF(deathtype), 0, min(coredamage, stat_damagedone));
-
-       return total_damage_to_creatures;
-}
-
-float RadiusDamage(entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float forceintensity, int deathtype, .entity weaponentity, entity directhitentity)
-{
-       return RadiusDamageForSource(inflictor, (inflictor.origin + (inflictor.mins + inflictor.maxs) * 0.5), inflictor.velocity, attacker, coredamage, edgedamage, rad, 
-                                                                       cantbe, mustbe, false, forceintensity, 1, deathtype, weaponentity, directhitentity);
-}
-
-bool Heal(entity targ, entity inflictor, float amount, float limit)
-{
-       if(game_stopped || (IS_CLIENT(targ) && CS(targ).killcount == FRAGS_SPECTATOR) || STAT(FROZEN, targ) || IS_DEAD(targ))
-               return false;
-
-       bool healed = false;
-       if(targ.event_heal)
-               healed = targ.event_heal(targ, inflictor, amount, limit);
-       // TODO: additional handling? what if the healing kills them? should this abort if healing would do so etc
-       // TODO: healing fx!
-       // TODO: armor healing?
-       return healed;
-}
-
-float Fire_IsBurning(entity e)
-{
-       return (time < e.fire_endtime);
-}
-
-float Fire_AddDamage(entity e, entity o, float d, float t, float dt)
-{
-       float dps;
-       float maxtime, mintime, maxdamage, mindamage, maxdps, mindps, totaldamage, totaltime;
-
-       if(IS_PLAYER(e))
-       {
-               if(IS_DEAD(e))
-                       return -1;
-       }
-       else
-       {
-               if(!e.fire_burner)
-               {
-                       // print("adding a fire burner to ", e.classname, "\n");
-                       e.fire_burner = new(fireburner);
-                       setthink(e.fire_burner, fireburner_think);
-                       e.fire_burner.nextthink = time;
-                       e.fire_burner.owner = e;
-               }
-       }
-
-       t = max(t, 0.1);
-       dps = d / t;
-       if(Fire_IsBurning(e))
-       {
-               mintime = e.fire_endtime - time;
-               maxtime = max(mintime, t);
-
-               mindps = e.fire_damagepersec;
-               maxdps = max(mindps, dps);
-
-               if(maxtime > mintime || maxdps > mindps)
-               {
-                       // Constraints:
-
-                       // damage we have right now
-                       mindamage = mindps * mintime;
-
-                       // damage we want to get
-                       maxdamage = mindamage + d;
-
-                       // but we can't exceed maxtime * maxdps!
-                       totaldamage = min(maxdamage, maxtime * maxdps);
-
-                       // LEMMA:
-                       // Look at:
-                       // totaldamage = min(mindamage + d, maxtime * maxdps)
-                       // We see:
-                       // totaldamage <= maxtime * maxdps
-                       // ==> totaldamage / maxdps <= maxtime.
-                       // We also see:
-                       // totaldamage / mindps = min(mindamage / mindps + d, maxtime * maxdps / mindps)
-                       //                     >= min(mintime, maxtime)
-                       // ==> totaldamage / maxdps >= mintime.
-
-                       /*
-                       // how long do we damage then?
-                       // at least as long as before
-                       // but, never exceed maxdps
-                       totaltime = max(mintime, totaldamage / maxdps); // always <= maxtime due to lemma
-                       */
-
-                       // alternate:
-                       // at most as long as maximum allowed
-                       // but, never below mindps
-                       totaltime = min(maxtime, totaldamage / mindps); // always >= mintime due to lemma
-
-                       // assuming t > mintime, dps > mindps:
-                       // we get d = t * dps = maxtime * maxdps
-                       // totaldamage = min(maxdamage, maxtime * maxdps) = min(... + d, maxtime * maxdps) = maxtime * maxdps
-                       // totaldamage / maxdps = maxtime
-                       // totaldamage / mindps > totaldamage / maxdps = maxtime
-                       // FROM THIS:
-                       // a) totaltime = max(mintime, maxtime) = maxtime
-                       // b) totaltime = min(maxtime, totaldamage / maxdps) = maxtime
-
-                       // assuming t <= mintime:
-                       // we get maxtime = mintime
-                       // a) totaltime = max(mintime, ...) >= mintime, also totaltime <= maxtime by the lemma, therefore totaltime = mintime = maxtime
-                       // b) totaltime = min(maxtime, ...) <= maxtime, also totaltime >= mintime by the lemma, therefore totaltime = mintime = maxtime
-
-                       // assuming dps <= mindps:
-                       // we get mindps = maxdps.
-                       // With this, the lemma says that mintime <= totaldamage / mindps = totaldamage / maxdps <= maxtime.
-                       // a) totaltime = max(mintime, totaldamage / maxdps) = totaldamage / maxdps
-                       // b) totaltime = min(maxtime, totaldamage / mindps) = totaldamage / maxdps
-
-                       e.fire_damagepersec = totaldamage / totaltime;
-                       e.fire_endtime = time + totaltime;
-                       if(totaldamage > 1.2 * mindamage)
-                       {
-                               e.fire_deathtype = dt;
-                               if(e.fire_owner != o)
-                               {
-                                       e.fire_owner = o;
-                                       e.fire_hitsound = false;
-                               }
-                       }
-                       if(accuracy_isgooddamage(o, e))
-                               accuracy_add(o, DEATH_WEAPONOF(dt), 0, max(0, totaldamage - mindamage));
-                       return max(0, totaldamage - mindamage); // can never be negative, but to make sure
-               }
-               else
-                       return 0;
-       }
-       else
-       {
-               e.fire_damagepersec = dps;
-               e.fire_endtime = time + t;
-               e.fire_deathtype = dt;
-               e.fire_owner = o;
-               e.fire_hitsound = false;
-               if(accuracy_isgooddamage(o, e))
-                       accuracy_add(o, DEATH_WEAPONOF(dt), 0, d);
-               return d;
-       }
-}
-
-void Fire_ApplyDamage(entity e)
-{
-       float t, d, hi, ty;
-       entity o;
-
-       if (!Fire_IsBurning(e))
-               return;
-
-       for(t = 0, o = e.owner; o.owner && t < 16; o = o.owner, ++t);
-       if(IS_NOT_A_CLIENT(o))
-               o = e.fire_owner;
-
-       // water and slime stop fire
-       if(e.waterlevel)
-       if(e.watertype != CONTENT_LAVA)
-               e.fire_endtime = 0;
-
-       // ice stops fire
-       if(STAT(FROZEN, e))
-               e.fire_endtime = 0;
-
-       t = min(frametime, e.fire_endtime - time);
-       d = e.fire_damagepersec * t;
-
-       hi = e.fire_owner.damage_dealt;
-       ty = e.fire_owner.typehitsound;
-       Damage(e, e, e.fire_owner, d, e.fire_deathtype, DMG_NOWEP, e.origin, '0 0 0');
-       if(e.fire_hitsound && e.fire_owner)
-       {
-               e.fire_owner.damage_dealt = hi;
-               e.fire_owner.typehitsound = ty;
-       }
-       e.fire_hitsound = true;
-
-       if(!IS_INDEPENDENT_PLAYER(e) && !STAT(FROZEN, e))
-       {
-               IL_EACH(g_damagedbycontents, it.damagedbycontents && it != e,
-               {
-                       if(!IS_DEAD(it) && it.takedamage && !IS_INDEPENDENT_PLAYER(it))
-                       if(boxesoverlap(e.absmin, e.absmax, it.absmin, it.absmax))
-                       {
-                               t = autocvar_g_balance_firetransfer_time * (e.fire_endtime - time);
-                               d = autocvar_g_balance_firetransfer_damage * e.fire_damagepersec * t;
-                               Fire_AddDamage(it, o, d, t, DEATH_FIRE.m_id);
-                       }
-               });
-       }
-}
-
-void Fire_ApplyEffect(entity e)
-{
-       if(Fire_IsBurning(e))
-               e.effects |= EF_FLAME;
-       else
-               e.effects &= ~EF_FLAME;
-}
-
-void fireburner_think(entity this)
-{
-       // for players, this is done in the regular loop
-       if(wasfreed(this.owner))
-       {
-               delete(this);
-               return;
-       }
-       Fire_ApplyEffect(this.owner);
-       if(!Fire_IsBurning(this.owner))
-       {
-               this.owner.fire_burner = NULL;
-               delete(this);
-               return;
-       }
-       Fire_ApplyDamage(this.owner);
-       this.nextthink = time;
-}
diff --git a/qcsrc/server/g_damage.qh b/qcsrc/server/g_damage.qh
deleted file mode 100644 (file)
index a99846c..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-#pragma once
-
-#if defined(CSQC)
-#elif defined(MENUQC)
-#elif defined(SVQC)
-    #include <server/defs.qh>
-    #include <server/miscfunctions.qh>
-    #include <lib/warpzone/common.qh>
-    #include <common/constants.qh>
-    #include <common/teams.qh>
-    #include <common/util.qh>
-    #include <common/weapons/_all.qh>
-    #include "weapons/accuracy.qh"
-    #include "weapons/csqcprojectile.qh"
-    #include "weapons/selection.qh"
-    #include <common/t_items.qh>
-    #include "autocvars.qh"
-    #include "constants.qh"
-    #include "defs.qh"
-    #include <common/notifications/all.qh>
-    #include <common/deathtypes/all.qh>
-    #include <server/mutators/_mod.qh>
-    #include <common/turrets/sv_turrets.qh>
-    #include <common/vehicles/all.qh>
-    #include <lib/csqcmodel/sv_model.qh>
-    #include <common/playerstats.qh>
-    #include "g_hook.qh"
-    #include "scores.qh"
-    #include "spawnpoints.qh"
-#endif
-
-.float dmg;
-.float dmg_edge;
-.float dmg_force;
-.float dmg_radius;
-
-bool Damage_DamageInfo_SendEntity(entity this, entity to, int sf);
-
-void Damage_DamageInfo(vector org, float coredamage, float edgedamage, float rad, vector force, int deathtype, float bloodtype, entity dmgowner);
-
-float checkrules_firstblood;
-
-float yoda;
-float damage_goodhits;
-float damage_gooddamage;
-
-.float dmg_team;
-.float teamkill_complain;
-.float teamkill_soundtime;
-.entity teamkill_soundsource;
-.entity pusher;
-.bool istypefrag;
-.float taunt_soundtime;
-
-float IsFlying(entity a);
-
-void UpdateFrags(entity player, int f);
-
-// NOTE: f=0 means still count as a (positive) kill, but count no frags for it
-void W_SwitchWeapon_Force(Player this, Weapon w, .entity weaponentity);
-void GiveFrags (entity attacker, entity targ, float f, int deathtype, .entity weaponentity);
-
-string AppendItemcodes(string s, entity player);
-
-void LogDeath(string mode, int deathtype, entity killer, entity killed);
-
-void Obituary_SpecialDeath(
-       entity notif_target,
-       float murder,
-       int deathtype,
-       string s1, string s2, string s3,
-       float f1, float f2, float f3);
-
-float w_deathtype;
-float Obituary_WeaponDeath(
-       entity notif_target,
-       float murder,
-       int deathtype,
-       string s1, string s2, string s3,
-       float f1, float f2);
-
-void Obituary(entity attacker, entity inflictor, entity targ, int deathtype, .entity weaponentity);
-
-void Ice_Think(entity this);
-
-void Freeze(entity targ, float freeze_time, int frozen_type, bool show_waypoint);
-
-void Unfreeze(entity targ, bool reset_health);
-
-// NOTE: the .weaponentity parameter can be set to DMG_NOWEP if the attack wasn't caused by a weapon or player
-void Damage (entity targ, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force);
-
-float RadiusDamage_running;
-float RadiusDamageForSource (entity inflictor, vector inflictororigin, vector inflictorvelocity, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float inflictorselfdamage, float forceintensity, float forcezscale, int deathtype, .entity weaponentity, entity directhitentity);
-       // Returns total damage applies to creatures
-
-float RadiusDamage (entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float forceintensity, int deathtype, .entity weaponentity, entity directhitentity);
-
-// Calls .event_heal on the target so that they can handle healing themselves
-// a limit of RES_LIMIT_NONE should be handled by the entity as its max health (if applicable)
-bool Heal(entity targ, entity inflictor, float amount, float limit);
-
-.float fire_damagepersec;
-.float fire_endtime;
-.float fire_deathtype;
-.entity fire_owner;
-.float fire_hitsound;
-.entity fire_burner;
-
-void fireburner_think(entity this);
-
-float Fire_IsBurning(entity e);
-
-float Fire_AddDamage(entity e, entity o, float d, float t, float dt);
-
-void Fire_ApplyDamage(entity e);
-
-void Fire_ApplyEffect(entity e);
diff --git a/qcsrc/server/g_hook.qc b/qcsrc/server/g_hook.qc
deleted file mode 100644 (file)
index 4894b27..0000000
+++ /dev/null
@@ -1,431 +0,0 @@
-#include "g_hook.qh"
-
-#include <server/defs.qh>
-#include <server/miscfunctions.qh>
-#include <common/effects/all.qh>
-#include "weapons/common.qh"
-#include "weapons/csqcprojectile.qh"
-#include "weapons/weaponsystem.qh"
-#include "weapons/selection.qh"
-#include "weapons/tracing.qh"
-#include "player.qh"
-#include "command/common.qh"
-#include "round_handler.qh"
-#include "../common/state.qh"
-#include "../common/physics/player.qh"
-#include "../common/vehicles/all.qh"
-#include "../common/constants.qh"
-#include "../common/util.qh"
-#include <common/net_linked.qh>
-#include <common/weapons/_all.qh>
-#include "../lib/warpzone/common.qh"
-#include "../lib/warpzone/server.qh"
-
-/*============================================
-
-      Wazat's Xonotic Grappling Hook
-
-        Contact: Wazat1@gmail.com
-
-
-Installation instructions:
---------------------------
-
-1. Place hook.c in your gamec source directory with the other source files.
-
-2. Add this line to the bottom of progs.src:
-
-gamec/hook.c
-
-3. Open defs.h and add these lines to the very bottom:
-
-// Wazat's grappling hook
-.entity                hook;
-void GrapplingHookFrame();
-void RemoveGrapplingHook(entity pl);
-void SetGrappleHookBindings();
-// hook impulses
-const float GRAPHOOK_FIRE              = 20;
-const float GRAPHOOK_RELEASE           = 21;
-// (note: you can change the hook impulse #'s to whatever you please)
-
-4. Open client.c and add this to the top of PutClientInServer():
-
-       RemoveGrapplingHook(this); // Wazat's Grappling Hook
-
-5. Find ClientConnect() (in client.c) and add these lines to the bottom:
-
-       // Wazat's grappling hook
-       SetGrappleHookBindings();
-
-6. Still in client.c, find PlayerPreThink and add this line just above the call to W_WeaponFrame:
-
-       GrapplingHookFrame();
-
-7. Build and test the mod.  You'll want to bind a key to "+hook" like this:
-bind ctrl "+hook"
-
-And you should be done!
-
-
-============================================*/
-
-void RemoveGrapplingHooks(entity pl)
-{
-       if(pl.move_movetype == MOVETYPE_FLY)
-               set_movetype(pl, MOVETYPE_WALK);
-
-       for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
-    {
-       .entity weaponentity = weaponentities[slot];
-       if(!pl.(weaponentity))
-               continue; // continue incase other slots exist?
-       if(pl.(weaponentity).hook)
-               delete(pl.(weaponentity).hook);
-       pl.(weaponentity).hook = NULL;
-    }
-
-       //pl.disableclientprediction = false;
-}
-
-void RemoveHook(entity this)
-{
-       entity player = this.realowner;
-    .entity weaponentity = this.weaponentity_fld;
-
-    if(player.(weaponentity).hook == this)
-       player.(weaponentity).hook = NULL;
-
-    if(player.move_movetype == MOVETYPE_FLY)
-       set_movetype(player, MOVETYPE_WALK);
-    delete(this);
-}
-
-void GrapplingHookReset(entity this)
-{
-       RemoveHook(this);
-}
-
-void GrapplingHook_Stop(entity this)
-{
-       Send_Effect(EFFECT_HOOK_IMPACT, this.origin, '0 0 0', 1);
-       sound (this, CH_SHOTS, SND_HOOK_IMPACT, VOL_BASE, ATTEN_NORM);
-
-       this.state = 1;
-       setthink(this, GrapplingHookThink);
-       this.nextthink = time;
-       settouch(this, func_null);
-       this.velocity = '0 0 0';
-       set_movetype(this, MOVETYPE_NONE);
-       this.hook_length = -1;
-}
-
-.vector hook_start, hook_end;
-bool GrapplingHookSend(entity this, entity to, int sf)
-{
-       WriteHeader(MSG_ENTITY, ENT_CLIENT_HOOK);
-       sf = sf & 0x7F;
-       if(sound_allowed(MSG_BROADCAST, this.realowner))
-               sf |= 0x80;
-       WriteByte(MSG_ENTITY, sf);
-       if(sf & 1)
-       {
-               WriteByte(MSG_ENTITY, etof(this.realowner));
-               WriteByte(MSG_ENTITY, weaponslot(this.weaponentity_fld));
-       }
-       if(sf & 2)
-       {
-               WriteVector(MSG_ENTITY, this.hook_start);
-       }
-       if(sf & 4)
-       {
-               WriteVector(MSG_ENTITY, this.hook_end);
-       }
-       return true;
-}
-
-int autocvar_g_grappling_hook_tarzan;
-
-void GrapplingHookThink(entity this)
-{
-       float spd, dist, minlength, pullspeed, ropestretch, ropeairfriction, rubberforce, newlength, rubberforce_overstretch;
-       vector dir, org, end, v0, dv, v, myorg, vs;
-       .entity weaponentity = this.weaponentity_fld;
-       if(this.realowner.(weaponentity).hook != this)  // how did that happen?
-       {
-               error("Owner lost the hook!\n");
-               return;
-       }
-       if(LostMovetypeFollow(this) || game_stopped || (round_handler_IsActive() && !round_handler_IsRoundStarted()) || ((this.aiment.flags & FL_PROJECTILE) && this.aiment.classname != "nade"))
-       {
-               RemoveHook(this);
-               return;
-       }
-       if(this.aiment)
-               WarpZone_RefSys_AddIncrementally(this, this.aiment);
-
-       this.nextthink = time;
-
-       int s = W_GunAlign(this.realowner.(weaponentity), STAT(GUNALIGN, this.realowner)) - 1;
-       vs = hook_shotorigin[s];
-
-       makevectors(this.realowner.v_angle);
-       org = this.realowner.origin + this.realowner.view_ofs + v_forward * vs.x + v_right * -vs.y + v_up * vs.z;
-       myorg = WarpZone_RefSys_TransformOrigin(this.realowner, this, org);
-
-       if(this.hook_length < 0)
-               this.hook_length = vlen(myorg - this.origin);
-
-       int tarzan = autocvar_g_grappling_hook_tarzan;
-       entity pull_entity = this.realowner;
-       float velocity_multiplier = 1;
-       MUTATOR_CALLHOOK(GrappleHookThink, this, tarzan, pull_entity, velocity_multiplier);
-       tarzan = M_ARGV(1, int);
-       pull_entity = M_ARGV(2, entity);
-       velocity_multiplier = M_ARGV(3, float);
-
-       if(this.state == 1)
-       {
-               pullspeed = autocvar_g_balance_grapplehook_speed_pull;//2000;
-               // speed the rope is pulled with
-
-               rubberforce = autocvar_g_balance_grapplehook_force_rubber;//2000;
-               // force the rope will use if it is stretched
-
-               rubberforce_overstretch = autocvar_g_balance_grapplehook_force_rubber_overstretch;//1000;
-               // force the rope will use if it is stretched
-
-               minlength = autocvar_g_balance_grapplehook_length_min;//100;
-               // minimal rope length
-               // if the rope goes below this length, it isn't pulled any more
-
-               ropestretch = autocvar_g_balance_grapplehook_stretch;//400;
-               // if the rope is stretched by more than this amount, more rope is
-               // given to you again
-
-               ropeairfriction = autocvar_g_balance_grapplehook_airfriction;//0.2
-               // while hanging on the rope, this friction component will help you a
-               // bit to control the rope
-
-               bool frozen_pulling = (autocvar_g_grappling_hook_tarzan >= 2 && autocvar_g_balance_grapplehook_pull_frozen);
-
-               dir = this.origin - myorg;
-               dist = vlen(dir);
-               dir = normalize(dir);
-
-               if(tarzan)
-               {
-                       v = v0 = WarpZone_RefSys_TransformVelocity(pull_entity, this, pull_entity.velocity);
-
-                       // first pull the rope...
-                       if(this.realowner.(weaponentity).hook_state & HOOK_PULLING)
-                       {
-                               newlength = this.hook_length;
-                               newlength = max(newlength - pullspeed * frametime, minlength);
-
-                               if(newlength < dist - ropestretch) // overstretched?
-                               {
-                                       newlength = dist - ropestretch;
-                                       if(v * dir < 0) // only if not already moving in hook direction
-                                               v = v + frametime * dir * rubberforce_overstretch;
-                               }
-
-                               this.hook_length = newlength;
-                       }
-
-                       if(pull_entity.move_movetype == MOVETYPE_FLY)
-                               set_movetype(pull_entity, MOVETYPE_WALK);
-
-                       if(this.realowner.(weaponentity).hook_state & HOOK_RELEASING)
-                       {
-                               newlength = dist;
-                               this.hook_length = newlength;
-                       }
-                       else
-                       {
-                               // then pull the player
-                               spd = bound(0, (dist - this.hook_length) / ropestretch, 1);
-                               v = v * (1 - frametime * ropeairfriction);
-                               v = v + frametime * dir * spd * rubberforce;
-
-                               dv = ((v - v0) * dir) * dir;
-                               if(tarzan >= 2)
-                               {
-                                       if(this.aiment.move_movetype == MOVETYPE_WALK || this.aiment.classname == "nade")
-                                       {
-                                               entity aim_ent = ((IS_VEHICLE(this.aiment) && this.aiment.owner) ? this.aiment.owner : this.aiment);
-                                               v = v - dv * 0.5;
-                                               if((frozen_pulling && STAT(FROZEN, this.aiment)) || !frozen_pulling)
-                                               {
-                                                       this.aiment.velocity = this.aiment.velocity - dv * 0.5;
-                                                       UNSET_ONGROUND(this.aiment);
-                                                       if(this.aiment.flags & FL_PROJECTILE)
-                                                               UpdateCSQCProjectile(this.aiment);
-                                               }
-                                               if(this.aiment.classname == "nade")
-                                                       this.aiment.nextthink = time + autocvar_g_balance_grapplehook_nade_time; // set time after letting go?
-                                               aim_ent.pusher = this.realowner;
-                                               aim_ent.pushltime = time + autocvar_g_maxpushtime;
-                                               aim_ent.istypefrag = PHYS_INPUT_BUTTON_CHAT(aim_ent);
-                                       }
-                               }
-
-                               UNSET_ONGROUND(pull_entity);
-                       }
-
-                       if(!frozen_pulling && !(this.aiment.flags & FL_PROJECTILE))
-                               pull_entity.velocity = WarpZone_RefSys_TransformVelocity(this, pull_entity, v * velocity_multiplier);
-
-                       if(frozen_pulling && autocvar_g_balance_grapplehook_pull_frozen == 2 && !STAT(FROZEN, this.aiment))
-                       {
-                               RemoveHook(this);
-                               return;
-                       }
-               }
-               else
-               {
-                       end = this.origin - dir*50;
-                       dist = vlen(end - myorg);
-                       if(dist < 200)
-                               spd = dist * (pullspeed / 200);
-                       else
-                               spd = pullspeed;
-                       if(spd < 50)
-                               spd = 0;
-                       this.realowner.velocity = dir*spd;
-                       set_movetype(this.realowner, MOVETYPE_FLY);
-
-                       UNSET_ONGROUND(this.realowner);
-               }
-       }
-
-       makevectors(this.angles.x * '-1 0 0' + this.angles.y * '0 1 0');
-       myorg = WarpZone_RefSys_TransformOrigin(this, this.realowner, this.origin); // + v_forward * (-9);
-
-       if(myorg != this.hook_start)
-       {
-               this.SendFlags |= 2;
-               this.hook_start = myorg;
-       }
-       if(org != this.hook_end)
-       {
-               this.SendFlags |= 4;
-               this.hook_end = org;
-       }
-}
-
-void GrapplingHookTouch(entity this, entity toucher)
-{
-       if(toucher.move_movetype == MOVETYPE_FOLLOW)
-               return;
-       PROJECTILE_TOUCH(this, toucher);
-
-       GrapplingHook_Stop(this);
-
-       if(toucher)
-               //if(toucher.move_movetype != MOVETYPE_NONE)
-               {
-                       SetMovetypeFollow(this, toucher);
-                       WarpZone_RefSys_BeginAddingIncrementally(this, this.aiment);
-               }
-
-       //this.realowner.disableclientprediction = true;
-}
-
-void GrapplingHook_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
-{
-       if(GetResource(this, RES_HEALTH) <= 0)
-               return;
-
-       if (!W_CheckProjectileDamage(inflictor.realowner, this.realowner, deathtype, -1)) // no exceptions
-               return; // g_balance_projectiledamage says to halt
-
-       TakeResource(this, RES_HEALTH, damage);
-
-       if (GetResource(this, RES_HEALTH) <= 0)
-       {
-               if(attacker != this.realowner)
-               {
-                       this.realowner.pusher = attacker;
-                       this.realowner.pushltime = time + autocvar_g_maxpushtime;
-                       this.realowner.istypefrag = PHYS_INPUT_BUTTON_CHAT(this.realowner);
-               }
-               RemoveHook(this);
-       }
-}
-
-void FireGrapplingHook(entity actor, .entity weaponentity)
-{
-       if(weaponLocked(actor)) return;
-       if(actor.vehicle) return;
-
-       int s = W_GunAlign(actor.(weaponentity), STAT(GUNALIGN, actor)) - 1;
-       vector vs = hook_shotorigin[s];
-       vector oldmovedir = actor.(weaponentity).movedir;
-       actor.(weaponentity).movedir = vs;
-       W_SetupShot_ProjectileSize(actor, weaponentity, '-3 -3 -3', '3 3 3', true, 0, SND_HOOK_FIRE, CH_WEAPON_B, 0, WEP_HOOK.m_id);
-       W_MuzzleFlash(WEP_HOOK, actor, weaponentity, w_shotorg, '0 0 0');
-       actor.(weaponentity).movedir = oldmovedir;
-
-       entity missile = WarpZone_RefSys_SpawnSameRefSys(actor);
-       missile.owner = missile.realowner = actor;
-       actor.(weaponentity).hook = missile;
-       missile.weaponentity_fld = weaponentity;
-       missile.reset = GrapplingHookReset;
-       missile.classname = "grapplinghook";
-       missile.flags = FL_PROJECTILE;
-       IL_PUSH(g_projectiles, missile);
-       IL_PUSH(g_bot_dodge, missile);
-
-       set_movetype(missile, ((autocvar_g_balance_grapplehook_gravity) ? MOVETYPE_TOSS : MOVETYPE_FLY));
-       PROJECTILE_MAKETRIGGER(missile);
-
-       //setmodel (missile, MDL_HOOK); // precision set below
-       setsize (missile, '-3 -3 -3', '3 3 3');
-       setorigin(missile, w_shotorg);
-
-       missile.state = 0; // not latched onto anything
-
-       W_SetupProjVelocity_Explicit(missile, w_shotdir, v_up, autocvar_g_balance_grapplehook_speed_fly, 0, 0, 0, false);
-
-       missile.angles = vectoangles (missile.velocity);
-       //missile.glow_color = 250; // 244, 250
-       //missile.glow_size = 120;
-       settouch(missile, GrapplingHookTouch);
-       setthink(missile, GrapplingHookThink);
-       missile.nextthink = time;
-
-       missile.effects = /*EF_FULLBRIGHT | EF_ADDITIVE |*/ EF_LOWPRECISION;
-
-       SetResourceExplicit(missile, RES_HEALTH, autocvar_g_balance_grapplehook_health);
-       missile.event_damage = GrapplingHook_Damage;
-       missile.takedamage = DAMAGE_AIM;
-       missile.damageforcescale = 0;
-       missile.damagedbycontents = (autocvar_g_balance_grapplehook_damagedbycontents);
-       if(missile.damagedbycontents)
-               IL_PUSH(g_damagedbycontents, missile);
-
-       missile.hook_start = missile.hook_end = missile.origin;
-
-       Net_LinkEntity(missile, false, 0, GrapplingHookSend);
-}
-
-void GrappleHookInit()
-{
-       if(g_grappling_hook)
-       {
-               hook_shotorigin[0] = '8 8 -12';
-               hook_shotorigin[1] = '8 8 -12';
-               hook_shotorigin[2] = '8 8 -12';
-               hook_shotorigin[3] = '8 8 -12';
-       }
-       else
-       {
-               Weapon w = WEP_HOOK;
-               w.wr_init(w);
-               hook_shotorigin[0] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_HOOK.m_id), false, false, 1);
-               hook_shotorigin[1] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_HOOK.m_id), false, false, 2);
-               hook_shotorigin[2] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_HOOK.m_id), false, false, 3);
-               hook_shotorigin[3] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_HOOK.m_id), false, false, 4);
-       }
-}
diff --git a/qcsrc/server/g_hook.qh b/qcsrc/server/g_hook.qh
deleted file mode 100644 (file)
index 1ed78e2..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-#pragma once
-
-// Wazat's grappling hook
-.entity                hook;
-void GrapplingHookThink(entity this);
-void RemoveGrapplingHooks(entity pl);
-void RemoveHook(entity this);
-// (note: you can change the hook impulse #'s to whatever you please)
-.float hook_time;
-
-.float hook_length;
-
-const float HOOK_FIRING = BIT(0);
-const float HOOK_REMOVING = BIT(1);
-const float HOOK_PULLING = BIT(2);
-const float HOOK_RELEASING = BIT(3);
-const float HOOK_WAITING_FOR_RELEASE = BIT(4);
-.float hook_state;
-.int state;
-
-void GrappleHookInit();
-vector hook_shotorigin[4];
-
diff --git a/qcsrc/server/g_world.qc b/qcsrc/server/g_world.qc
deleted file mode 100644 (file)
index b66bcda..0000000
+++ /dev/null
@@ -1,2286 +0,0 @@
-#include "g_world.qh"
-
-#include "anticheat.qh"
-#include "antilag.qh"
-#include "bot/api.qh"
-#include "campaign.qh"
-#include "cheats.qh"
-#include "client.qh"
-#include "command/common.qh"
-#include "command/getreplies.qh"
-#include "command/sv_cmd.qh"
-#include "command/vote.qh"
-#include "g_hook.qh"
-#include <server/gamelog.qh>
-#include "ipban.qh"
-#include "mapvoting.qh"
-#include <server/mutators/_mod.qh>
-#include "race.qh"
-#include "scores.qh"
-#include "scores_rules.qh"
-#include "teamplay.qh"
-#include "weapons/weaponstats.qh"
-#include "../common/constants.qh"
-#include <common/net_linked.qh>
-#include "../common/deathtypes/all.qh"
-#include <common/gamemodes/_mod.qh>
-#include "../common/gamemodes/sv_rules.qh"
-#include "../common/mapinfo.qh"
-#include "../common/monsters/_mod.qh"
-#include "../common/monsters/sv_monsters.qh"
-#include "../common/vehicles/all.qh"
-#include "../common/notifications/all.qh"
-#include "../common/physics/player.qh"
-#include "../common/playerstats.qh"
-#include "../common/stats.qh"
-#include "../common/teams.qh"
-#include "../common/mapobjects/trigger/secret.qh"
-#include "../common/mapobjects/target/music.qh"
-#include "../common/util.qh"
-#include "../common/items/_mod.qh"
-#include <common/weapons/_all.qh>
-#include "../common/state.qh"
-
-const float LATENCY_THINKRATE = 10;
-.float latency_sum;
-.float latency_cnt;
-.float latency_time;
-entity pingplreport;
-void PingPLReport_Think(entity this)
-{
-       float delta;
-       entity e;
-
-       delta = 3 / maxclients;
-       if(delta < sys_frametime)
-               delta = 0;
-       this.nextthink = time + delta;
-
-       e = edict_num(this.cnt + 1);
-       if(IS_CLIENT(e) && IS_REAL_CLIENT(e))
-       {
-               WriteHeader(MSG_BROADCAST, TE_CSQC_PINGPLREPORT);
-               WriteByte(MSG_BROADCAST, this.cnt);
-               WriteShort(MSG_BROADCAST, bound(1, CS(e).ping, 65535));
-               WriteByte(MSG_BROADCAST, min(ceil(CS(e).ping_packetloss * 255), 255));
-               WriteByte(MSG_BROADCAST, min(ceil(CS(e).ping_movementloss * 255), 255));
-
-               // record latency times for clients throughout the match so we can report it to playerstats
-               if(time > (CS(e).latency_time + LATENCY_THINKRATE))
-               {
-                       CS(e).latency_sum += CS(e).ping;
-                       CS(e).latency_cnt += 1;
-                       CS(e).latency_time = time;
-                       //print("sum: ", ftos(CS(e).latency_sum), ", cnt: ", ftos(CS(e).latency_cnt), ", avg: ", ftos(CS(e).latency_sum / CS(e).latency_cnt), ".\n");
-               }
-       }
-       else
-       {
-               WriteHeader(MSG_BROADCAST, TE_CSQC_PINGPLREPORT);
-               WriteByte(MSG_BROADCAST, this.cnt);
-               WriteShort(MSG_BROADCAST, 0);
-               WriteByte(MSG_BROADCAST, 0);
-               WriteByte(MSG_BROADCAST, 0);
-       }
-       this.cnt = (this.cnt + 1) % maxclients;
-}
-void PingPLReport_Spawn()
-{
-       pingplreport = new_pure(pingplreport);
-       setthink(pingplreport, PingPLReport_Think);
-       pingplreport.nextthink = time;
-}
-
-const float SPAWNFLAG_NO_WAYPOINTS_FOR_ITEMS = 1;
-string redirection_target;
-float world_initialized;
-
-void SetDefaultAlpha()
-{
-       if (!MUTATOR_CALLHOOK(SetDefaultAlpha))
-       {
-               default_player_alpha = autocvar_g_player_alpha;
-               if(default_player_alpha == 0)
-                       default_player_alpha = 1;
-               default_weapon_alpha = default_player_alpha;
-       }
-}
-
-void GotoFirstMap(entity this)
-{
-       float n;
-       if(autocvar__sv_init)
-       {
-               // cvar_set("_sv_init", "0");
-               // we do NOT set this to 0 any more, so someone "accidentally" changing
-               // to this "init" map on a dedicated server will cause no permanent
-               // harm
-               if(autocvar_g_maplist_shuffle)
-                       ShuffleMaplist();
-               n = tokenizebyseparator(autocvar_g_maplist, " ");
-               cvar_set("g_maplist_index", ftos(n - 1)); // jump to map 0 in GotoNextMap
-
-               MapInfo_Enumerate();
-               MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
-
-               if(!DoNextMapOverride(1))
-                       GotoNextMap(1);
-
-               return;
-       }
-
-       if(time < 5)
-       {
-               this.nextthink = time;
-       }
-       else
-       {
-               this.nextthink = time + 1;
-               LOG_INFO("Waiting for _sv_init being set to 1 by initialization scripts...");
-       }
-}
-
-void cvar_changes_init()
-{
-       float h;
-       string k, v, d;
-       float n, i, adding, pureadding;
-
-       strfree(cvar_changes);
-       strfree(cvar_purechanges);
-       cvar_purechanges_count = 0;
-
-       h = buf_create();
-       buf_cvarlist(h, "", "_"); // exclude all _ cvars as they are temporary
-       n = buf_getsize(h);
-
-       adding = true;
-       pureadding = true;
-
-       for(i = 0; i < n; ++i)
-       {
-               k = bufstr_get(h, i);
-
-#define BADPREFIX(p) if(substring(k, 0, strlen(p)) == p) continue
-#define BADPRESUFFIX(p,s) if(substring(k, 0, strlen(p)) == p && substring(k, -strlen(s), -1) == s) continue
-#define BADCVAR(p) if(k == p) continue
-
-               // general excludes and namespaces for server admin used cvars
-               BADPREFIX("help_"); // PN's server has this listed as changed, let's not rat him out for THAT
-
-               // internal
-               BADPREFIX("csqc_");
-               BADPREFIX("cvar_check_");
-               BADCVAR("gamecfg");
-               BADCVAR("g_configversion");
-               BADCVAR("halflifebsp");
-               BADCVAR("sv_mapformat_is_quake2");
-               BADCVAR("sv_mapformat_is_quake3");
-               BADPREFIX("sv_world");
-
-               // client
-               BADPREFIX("chase_");
-               BADPREFIX("cl_");
-               BADPREFIX("con_");
-               BADPREFIX("scoreboard_");
-               BADPREFIX("g_campaign");
-               BADPREFIX("g_waypointsprite_");
-               BADPREFIX("gl_");
-               BADPREFIX("joy");
-               BADPREFIX("hud_");
-               BADPREFIX("m_");
-               BADPREFIX("menu_");
-               BADPREFIX("net_slist_");
-               BADPREFIX("r_");
-               BADPREFIX("sbar_");
-               BADPREFIX("scr_");
-               BADPREFIX("snd_");
-               BADPREFIX("show");
-               BADPREFIX("sensitivity");
-               BADPREFIX("userbind");
-               BADPREFIX("v_");
-               BADPREFIX("vid_");
-               BADPREFIX("crosshair");
-               BADCVAR("mod_q3bsp_lightmapmergepower");
-               BADCVAR("mod_q3bsp_nolightmaps");
-               BADCVAR("fov");
-               BADCVAR("mastervolume");
-               BADCVAR("volume");
-               BADCVAR("bgmvolume");
-               BADCVAR("in_pitch_min");
-               BADCVAR("in_pitch_max");
-
-               // private
-               BADCVAR("developer");
-               BADCVAR("log_dest_udp");
-               BADCVAR("net_address");
-               BADCVAR("net_address_ipv6");
-               BADCVAR("port");
-               BADCVAR("savedgamecfg");
-               BADCVAR("serverconfig");
-               BADCVAR("sv_autoscreenshot");
-               BADCVAR("sv_heartbeatperiod");
-               BADCVAR("sv_vote_master_password");
-               BADCVAR("sys_colortranslation");
-               BADCVAR("sys_specialcharactertranslation");
-               BADCVAR("timeformat");
-               BADCVAR("timestamps");
-               BADCVAR("g_require_stats");
-               BADPREFIX("developer_");
-               BADPREFIX("g_ban_");
-               BADPREFIX("g_banned_list");
-               BADPREFIX("g_require_stats_");
-               BADPREFIX("g_chat_flood_");
-               BADPREFIX("g_ghost_items");
-               BADPREFIX("g_playerstats_");
-               BADPREFIX("g_voice_flood_");
-               BADPREFIX("log_file");
-               BADPREFIX("quit_");
-               BADPREFIX("rcon_");
-               BADPREFIX("sv_allowdownloads");
-               BADPREFIX("sv_autodemo");
-               BADPREFIX("sv_curl_");
-               BADPREFIX("sv_eventlog");
-               BADPREFIX("sv_logscores_");
-               BADPREFIX("sv_master");
-               BADPREFIX("sv_weaponstats_");
-               BADPREFIX("sv_waypointsprite_");
-               BADCVAR("rescan_pending");
-
-               // these can contain player IDs, so better hide
-               BADPREFIX("g_forced_team_");
-               BADCVAR("sv_muteban_list");
-               BADCVAR("sv_voteban_list");
-               BADCVAR("sv_allow_customplayermodels_idlist");
-               BADCVAR("sv_allow_customplayermodels_speciallist");
-
-               // mapinfo
-               BADCVAR("fraglimit");
-               BADCVAR("g_arena");
-               BADCVAR("g_assault");
-               BADCVAR("g_ca");
-               BADCVAR("g_ca_teams");
-               BADCVAR("g_conquest");
-               BADCVAR("g_conquest_teams");
-               BADCVAR("g_ctf");
-               BADCVAR("g_cts");
-               BADCVAR("g_dotc");
-               BADCVAR("g_dm");
-               BADCVAR("g_domination");
-               BADCVAR("g_domination_default_teams");
-               BADCVAR("g_duel");
-               BADCVAR("g_duel_not_dm_maps");
-               BADCVAR("g_freezetag");
-               BADCVAR("g_freezetag_teams");
-               BADCVAR("g_invasion_teams");
-               BADCVAR("g_invasion_type");
-               BADCVAR("g_jailbreak");
-               BADCVAR("g_jailbreak_teams");
-               BADCVAR("g_keepaway");
-               BADCVAR("g_keyhunt");
-               BADCVAR("g_keyhunt_teams");
-               BADCVAR("g_lms");
-               BADCVAR("g_nexball");
-               BADCVAR("g_onslaught");
-               BADCVAR("g_race");
-               BADCVAR("g_race_laps_limit");
-               BADCVAR("g_race_qualifying_timelimit");
-               BADCVAR("g_race_qualifying_timelimit_override");
-               BADCVAR("g_runematch");
-               BADCVAR("g_shootfromeye");
-               BADCVAR("g_snafu");
-               BADCVAR("g_survival");
-               BADCVAR("g_survival_not_dm_maps");
-               BADCVAR("g_tdm");
-               BADCVAR("g_tdm_on_dm_maps");
-               BADCVAR("g_tdm_teams");
-               BADCVAR("g_vip");
-               BADCVAR("leadlimit");
-               BADCVAR("nextmap");
-               BADCVAR("teamplay");
-               BADCVAR("timelimit");
-               BADCVAR("g_mapinfo_settemp_acl");
-               BADCVAR("g_mapinfo_ignore_warnings");
-               BADCVAR("g_maplist_ignore_sizes");
-               BADCVAR("g_maplist_sizes_count_bots");
-
-               // long
-               BADCVAR("hostname");
-               BADCVAR("g_maplist");
-               BADCVAR("g_maplist_mostrecent");
-               BADCVAR("sv_motd");
-
-               v = cvar_string(k);
-               d = cvar_defstring(k);
-               if(v == d)
-                       continue;
-
-               if(adding)
-               {
-                       cvar_changes = strcat(cvar_changes, k, " \"", v, "\" // \"", d, "\"\n");
-                       if(strlen(cvar_changes) > 16384)
-                       {
-                               cvar_changes = "// too many settings have been changed to show them here\n";
-                               adding = 0;
-                       }
-               }
-
-               // now check if the changes are actually gameplay relevant
-
-               // does nothing gameplay relevant
-               BADCVAR("captureleadlimit_override");
-               BADCVAR("condump_stripcolors");
-               BADCVAR("gameversion");
-               BADCVAR("fs_gamedir");
-               BADCVAR("g_allow_oldvortexbeam");
-               BADCVAR("g_balance_kill_delay");
-               BADCVAR("g_buffs_pickup_anyway");
-               BADCVAR("g_buffs_randomize");
-               BADCVAR("g_buffs_randomize_teamplay");
-               BADCVAR("g_campcheck_distance");
-               BADCVAR("g_chatsounds");
-               BADCVAR("g_ca_point_leadlimit");
-               BADCVAR("g_ca_point_limit");
-               BADCVAR("g_ctf_captimerecord_always");
-               BADCVAR("g_ctf_flag_glowtrails");
-               BADCVAR("g_ctf_dynamiclights");
-               BADCVAR("g_ctf_flag_pickup_verbosename");
-               BADPRESUFFIX("g_ctf_flag_", "_model");
-               BADPRESUFFIX("g_ctf_flag_", "_skin");
-               BADCVAR("g_domination_point_leadlimit");
-               BADCVAR("g_forced_respawn");
-               BADCVAR("g_freezetag_point_leadlimit");
-               BADCVAR("g_freezetag_point_limit");
-               BADCVAR("g_glowtrails");
-               BADCVAR("g_hats");
-               BADCVAR("g_casings");
-               BADCVAR("g_invasion_point_limit");
-               BADCVAR("g_jump_grunt");
-               BADCVAR("g_keepaway_ballcarrier_effects");
-               BADCVAR("g_keepawayball_effects");
-               BADCVAR("g_keyhunt_point_leadlimit");
-               BADCVAR("g_nexball_goalleadlimit");
-               BADCVAR("g_new_toys_autoreplace");
-               BADCVAR("g_new_toys_use_pickupsound");
-               BADCVAR("g_physics_predictall");
-               BADCVAR("g_piggyback");
-               BADCVAR("g_playerclip_collisions");
-               BADCVAR("g_spawn_alloweffects");
-               BADCVAR("g_tdm_point_leadlimit");
-               BADCVAR("g_tdm_point_limit");
-               BADCVAR("leadlimit_and_fraglimit");
-               BADCVAR("leadlimit_override");
-               BADCVAR("pausable");
-               BADCVAR("sv_announcer");
-               BADCVAR("sv_checkforpacketsduringsleep");
-               BADCVAR("sv_damagetext");
-               BADCVAR("sv_db_saveasdump");
-               BADCVAR("sv_intermission_cdtrack");
-               BADCVAR("sv_mapchange_delay");
-               BADCVAR("sv_minigames");
-               BADCVAR("sv_namechangetimer");
-               BADCVAR("sv_precacheplayermodels");
-               BADCVAR("sv_radio");
-               BADCVAR("sv_stepheight");
-               BADCVAR("sv_timeout");
-               BADCVAR("sv_weapons_modeloverride");
-               BADCVAR("w_prop_interval");
-               BADPREFIX("chat_");
-               BADPREFIX("crypto_");
-               BADPREFIX("gameversion_");
-               BADPREFIX("g_chat_");
-               BADPREFIX("g_ctf_captimerecord_");
-               BADPREFIX("g_hats_");
-               BADPREFIX("g_maplist_");
-               BADPREFIX("g_mod_");
-               BADPREFIX("g_respawn_");
-               BADPREFIX("net_");
-               BADPREFIX("notification_");
-               BADPREFIX("prvm_");
-               BADPREFIX("skill_");
-               BADPREFIX("sv_allow_");
-               BADPREFIX("sv_cullentities_");
-               BADPREFIX("sv_maxidle_");
-               BADPREFIX("sv_minigames_");
-               BADPREFIX("sv_radio_");
-               BADPREFIX("sv_timeout_");
-               BADPREFIX("sv_vote_");
-               BADPREFIX("timelimit_");
-
-               // allowed changes to server admins (please sync this to server.cfg)
-               // vi commands:
-               //   :/"impure"/,$d
-               //   :g!,^\/\/[^ /],d
-               //   :%s,//\([^ ]*\).*,BADCVAR("\1");,
-               //   :%!sort
-               // yes, this does contain some redundant stuff, don't really care
-               BADPREFIX("bot_ai_");
-               BADCVAR("bot_config_file");
-               BADCVAR("bot_number");
-               BADCVAR("bot_prefix");
-               BADCVAR("bot_suffix");
-               BADCVAR("capturelimit_override");
-               BADCVAR("fraglimit_override");
-               BADCVAR("gametype");
-               BADCVAR("g_antilag");
-               BADCVAR("g_balance_teams");
-               BADCVAR("g_balance_teams_prevent_imbalance");
-               BADCVAR("g_balance_teams_scorefactor");
-               BADCVAR("g_ban_sync_trusted_servers");
-               BADCVAR("g_ban_sync_uri");
-               BADCVAR("g_buffs");
-               BADCVAR("g_ca_teams_override");
-               BADCVAR("g_ctf_fullbrightflags");
-               BADCVAR("g_ctf_ignore_frags");
-               BADCVAR("g_ctf_leaderboard");
-               BADCVAR("g_domination_point_limit");
-               BADCVAR("g_domination_teams_override");
-               BADCVAR("g_freezetag_teams_override");
-               BADCVAR("g_friendlyfire");
-               BADCVAR("g_fullbrightitems");
-               BADCVAR("g_fullbrightplayers");
-               BADCVAR("g_keyhunt_point_limit");
-               BADCVAR("g_keyhunt_teams_override");
-               BADCVAR("g_lms_lives_override");
-               BADCVAR("g_maplist");
-               BADCVAR("g_maxplayers");
-               BADCVAR("g_mirrordamage");
-               BADCVAR("g_nexball_goallimit");
-               BADCVAR("g_norecoil");
-               BADCVAR("g_physics_clientselect");
-               BADCVAR("g_pinata");
-               BADCVAR("g_powerups");
-               BADCVAR("g_player_brightness");
-               BADCVAR("g_rocket_flying");
-               BADCVAR("g_rocket_flying_disabledelays");
-               BADCVAR("g_spawnshieldtime");
-               BADCVAR("g_start_delay");
-               BADCVAR("g_superspectate");
-               BADCVAR("g_tdm_teams_override");
-               BADCVAR("g_warmup");
-               BADCVAR("g_weapon_stay"); BADPRESUFFIX("g_", "_weapon_stay");
-               BADCVAR("hostname");
-               BADCVAR("log_file");
-               BADCVAR("maxplayers");
-               BADCVAR("minplayers");
-               BADCVAR("minplayers_per_team");
-               BADCVAR("net_address");
-               BADCVAR("port");
-               BADCVAR("rcon_password");
-               BADCVAR("rcon_restricted_commands");
-               BADCVAR("rcon_restricted_password");
-               BADCVAR("skill");
-               BADCVAR("sv_adminnick");
-               BADCVAR("sv_autoscreenshot");
-               BADCVAR("sv_autotaunt");
-               BADCVAR("sv_curl_defaulturl");
-               BADCVAR("sv_defaultcharacter");
-               BADCVAR("sv_defaultcharacterskin");
-               BADCVAR("sv_defaultplayercolors");
-               BADCVAR("sv_defaultplayermodel");
-               BADCVAR("sv_defaultplayerskin");
-               BADCVAR("sv_maxidle");
-               BADCVAR("sv_maxrate");
-               BADCVAR("sv_motd");
-               BADCVAR("sv_public");
-               BADCVAR("sv_ready_restart");
-               BADCVAR("sv_status_privacy");
-               BADCVAR("sv_taunt");
-               BADCVAR("sv_vote_call");
-               BADCVAR("sv_vote_commands");
-               BADCVAR("sv_vote_majority_factor");
-               BADCVAR("sv_vote_master");
-               BADCVAR("sv_vote_master_commands");
-               BADCVAR("sv_vote_master_password");
-               BADCVAR("sv_vote_simple_majority_factor");
-               BADCVAR("teamplay_mode");
-               BADCVAR("timelimit_override");
-               BADPREFIX("g_warmup_");
-               BADPREFIX("sv_info_");
-               BADPREFIX("sv_ready_restart_");
-
-               // mutators that announce themselves properly to the server browser
-               BADCVAR("g_instagib");
-               BADCVAR("g_new_toys");
-               BADCVAR("g_nix");
-               BADCVAR("g_grappling_hook");
-               BADCVAR("g_jetpack");
-
-               // temporary for testing
-               // TODO remove before 0.8.3 release
-               BADCVAR("g_ca_weaponarena");
-               BADCVAR("g_freezetag_weaponarena");
-               BADCVAR("g_lms_weaponarena");
-               BADCVAR("g_ctf_stalemate_time");
-
-               if(cvar_string("g_mod_balance") == "Testing")
-               {
-                       // (temporary) while using the Testing balance, any weapon balance cvars are allowed to be changed
-                       BADPREFIX("g_balance_");
-               }
-
-#undef BADPRESUFFIX
-#undef BADPREFIX
-#undef BADCVAR
-
-               if(pureadding)
-               {
-                       cvar_purechanges = strcat(cvar_purechanges, k, " \"", v, "\" // \"", d, "\"\n");
-                       if(strlen(cvar_purechanges) > 16384)
-                       {
-                               cvar_purechanges = "// too many settings have been changed to show them here\n";
-                               pureadding = 0;
-                       }
-               }
-               ++cvar_purechanges_count;
-               // WARNING: this variable is used for the server list
-               // NEVER dare to skip this code!
-               // Hacks to intentionally appearing as "pure server" even though you DO have
-               // modified settings may be punished by removal from the server list.
-               // You can do to the variables cvar_changes and cvar_purechanges all you want,
-               // though.
-       }
-       buf_del(h);
-       if(cvar_changes == "")
-               cvar_changes = "// this server runs at default server settings\n";
-       else
-               cvar_changes = strcat("// this server runs at modified server settings:\n", cvar_changes);
-       cvar_changes = strzone(cvar_changes);
-       if(cvar_purechanges == "")
-               cvar_purechanges = "// this server runs at default gameplay settings\n";
-       else
-               cvar_purechanges = strcat("// this server runs at modified gameplay settings:\n", cvar_purechanges);
-       cvar_purechanges = strzone(cvar_purechanges);
-}
-
-entity randomseed;
-bool RandomSeed_Send(entity this, entity to, int sf)
-{
-       WriteHeader(MSG_ENTITY, ENT_CLIENT_RANDOMSEED);
-       WriteShort(MSG_ENTITY, this.cnt);
-       return true;
-}
-void RandomSeed_Think(entity this)
-{
-       this.cnt = bound(0, floor(random() * 65536), 65535);
-       this.nextthink = time + 5;
-
-       this.SendFlags |= 1;
-}
-void RandomSeed_Spawn()
-{
-       randomseed = new_pure(randomseed);
-       setthink(randomseed, RandomSeed_Think);
-       Net_LinkEntity(randomseed, false, 0, RandomSeed_Send);
-
-       getthink(randomseed)(randomseed); // sets random seed and nextthink
-}
-
-spawnfunc(__init_dedicated_server)
-{
-       // handler for _init/_init map (only for dedicated server initialization)
-
-       world_initialized = -1; // don't complain
-
-       delete_fn = remove_unsafely;
-
-       entity e = spawn();
-       setthink(e, GotoFirstMap);
-       e.nextthink = time; // this is usually 1 at this point
-
-       e = new(info_player_deathmatch);  // safeguard against player joining
-
-    // assign reflectively to avoid "assignment to world" warning
-    for (int i = 0, n = numentityfields(); i < n; ++i) {
-        string k = entityfieldname(i);
-        if (k == "classname") {
-            // safeguard against various stuff ;)
-            putentityfieldstring(i, this, "worldspawn");
-            break;
-        }
-    }
-
-       // needs to be done so early because of the constants they create
-       static_init();
-       static_init_late();
-       static_init_precache();
-
-       IL_PUSH(g_spawnpoints, e); // just incase
-
-       MapInfo_Enumerate();
-       MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
-}
-
-void __init_dedicated_server_shutdown() {
-       MapInfo_Shutdown();
-}
-
-STATIC_INIT_EARLY(maxclients)
-{
-       maxclients = 0;
-       for (entity head = nextent(NULL); head; head = nextent(head)) {
-               ++maxclients;
-       }
-}
-
-void default_delayedinit(entity this)
-{
-       if(!scores_initialized)
-               ScoreRules_generic();
-}
-
-void InitGameplayMode()
-{
-       VoteReset();
-
-       // find out good world mins/maxs bounds, either the static bounds found by looking for solid, or the mapinfo specified bounds
-       get_mi_min_max(1);
-       // assign reflectively to avoid "assignment to world" warning
-       int done = 0; for (int i = 0, n = numentityfields(); i < n; ++i) {
-           string k = entityfieldname(i); vector v = (k == "mins") ? mi_min : (k == "maxs") ? mi_max : '0 0 0';
-           if (v) {
-            putentityfieldstring(i, world, sprintf("%v", v));
-            if (++done == 2) break;
-        }
-       }
-       // currently, NetRadiant's limit is 131072 qu for each side
-       // distance from one corner of a 131072qu cube to the opposite corner is approx. 227023 qu
-       // set the distance according to map size but don't go over the limit to avoid issues with float precision
-       // in case somebody makes extremely large maps
-       max_shot_distance = min(230000, vlen(world.maxs - world.mins));
-
-       MapInfo_LoadMapSettings(mapname);
-       GameRules_teams(false);
-
-       if (!cvar_value_issafe(world.fog))
-       {
-               LOG_INFO("The current map contains a potentially harmful fog setting, ignored");
-               world.fog = string_null;
-       }
-       if(MapInfo_Map_fog != "")
-       {
-               if(MapInfo_Map_fog == "none")
-                       world.fog = string_null;
-               else
-                       world.fog = strzone(MapInfo_Map_fog);
-       }
-       clientstuff = strzone(MapInfo_Map_clientstuff);
-
-       MapInfo_ClearTemps();
-
-       gamemode_name = MapInfo_Type_ToText(MapInfo_LoadedGametype);
-
-       cache_mutatormsg = strzone("");
-       cache_lastmutatormsg = strzone("");
-
-       InitializeEntity(NULL, default_delayedinit, INITPRIO_GAMETYPE_FALLBACK);
-}
-
-void Map_MarkAsRecent(string m);
-float world_already_spawned;
-spawnfunc(worldspawn)
-{
-       server_is_dedicated = boolean(stof(cvar_defstring("is_dedicated")));
-
-       bool wantrestart = false;
-       {
-               if (!server_is_dedicated)
-               {
-                       // force unloading of server pk3 files when starting a listen server
-                       // localcmd("\nfs_rescan\n"); // FIXME: does more harm than good, has unintended side effects. What we really want is to unload temporary pk3s only
-                       // restore csqc_progname too
-                       string expect = "csprogs.dat";
-                       wantrestart = cvar_string("csqc_progname") != expect;
-                       cvar_set("csqc_progname", expect);
-               }
-               else
-               {
-                       // Try to use versioned csprogs from pk3
-                       // Only ever use versioned csprogs.dat files on dedicated servers;
-                       // we need to reset csqc_progname on clients ourselves, and it's easier if the client's release name is constant
-                       string pk3csprogs = "csprogs-" WATERMARK ".dat";
-                       // This always works; fall back to it if a versioned csprogs.dat is suddenly missing
-                       string select = "csprogs.dat";
-                       if (fexists(pk3csprogs)) select = pk3csprogs;
-                       if (cvar_string("csqc_progname") != select)
-                       {
-                               cvar_set("csqc_progname", select);
-                               wantrestart = true;
-                       }
-                       // Check for updates on startup
-                       // We do it this way for atomicity so that connecting clients still match the server progs and don't disconnect
-                       int sentinel = fopen("progs.txt", FILE_READ);
-                       if (sentinel >= 0)
-                       {
-                               string switchversion = fgets(sentinel);
-                               fclose(sentinel);
-                               if (switchversion != "" && switchversion != WATERMARK)
-                               {
-                                       LOG_INFOF("Switching progs: " WATERMARK " -> %s", switchversion);
-                                       // if it doesn't exist, assume either:
-                                       //   a) the current program was overwritten
-                                       //   b) this is a client only update
-                                       string newprogs = sprintf("progs-%s.dat", switchversion);
-                                       if (fexists(newprogs))
-                                       {
-                                               cvar_set("sv_progs", newprogs);
-                                               wantrestart = true;
-                                       }
-                                       string newcsprogs = sprintf("csprogs-%s.dat", switchversion);
-                                       if (fexists(newcsprogs))
-                                       {
-                                               cvar_set("csqc_progname", newcsprogs);
-                                               wantrestart = true;
-                                       }
-                               }
-                       }
-               }
-               if (wantrestart)
-               {
-                       LOG_INFO("Restart requested");
-                       changelevel(mapname);
-                       // let initialization continue, shutdown depends on it
-               }
-       }
-
-       if(world_already_spawned)
-               error("world already spawned - you may have EXACTLY ONE worldspawn!");
-       world_already_spawned = true;
-
-       delete_fn = remove_safely; // during spawning, watch what you remove!
-
-       cvar_changes_init(); // do this very early now so it REALLY matches the server config
-
-       // needs to be done so early because of the constants they create
-       static_init();
-
-       ServerProgsDB = db_load(strcat("server.db", autocvar_sessionid));
-
-       TemporaryDB = db_create();
-
-       // 0 normal
-       lightstyle(0, "m");
-
-       // 1 FLICKER (first variety)
-       lightstyle(1, "mmnmmommommnonmmonqnmmo");
-
-       // 2 SLOW STRONG PULSE
-       lightstyle(2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba");
-
-       // 3 CANDLE (first variety)
-       lightstyle(3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg");
-
-       // 4 FAST STROBE
-       lightstyle(4, "mamamamamama");
-
-       // 5 GENTLE PULSE 1
-       lightstyle(5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj");
-
-       // 6 FLICKER (second variety)
-       lightstyle(6, "nmonqnmomnmomomno");
-
-       // 7 CANDLE (second variety)
-       lightstyle(7, "mmmaaaabcdefgmmmmaaaammmaamm");
-
-       // 8 CANDLE (third variety)
-       lightstyle(8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa");
-
-       // 9 SLOW STROBE (fourth variety)
-       lightstyle(9, "aaaaaaaazzzzzzzz");
-
-       // 10 FLUORESCENT FLICKER
-       lightstyle(10, "mmamammmmammamamaaamammma");
-
-       // 11 SLOW PULSE NOT FADE TO BLACK
-       lightstyle(11, "abcdefghijklmnopqrrqponmlkjihgfedcba");
-
-       // styles 32-62 are assigned by the spawnfunc_light program for switchable lights
-
-       // 63 testing
-       lightstyle(63, "a");
-
-       if(autocvar_g_campaign)
-               CampaignPreInit();
-
-       Map_MarkAsRecent(mapname);
-
-       PlayerStats_GameReport_Init(); // we need this to be initiated before InitGameplayMode
-
-       InitGameplayMode();
-       static_init_late();
-       static_init_precache();
-       readlevelcvars();
-       GrappleHookInit();
-
-       GameRules_limit_fallbacks();
-
-       if(warmup_limit == 0)
-               warmup_limit = (autocvar_timelimit > 0) ? autocvar_timelimit * 60 : autocvar_timelimit;
-
-       player_count = 0;
-       bot_waypoints_for_items = autocvar_g_waypoints_for_items;
-       if(bot_waypoints_for_items == 1)
-               if(this.spawnflags & SPAWNFLAG_NO_WAYPOINTS_FOR_ITEMS)
-                       bot_waypoints_for_items = 0;
-
-       WaypointSprite_Init();
-
-       GameLogInit(); // prepare everything
-       // NOTE for matchid:
-       // changing the logic generating it is okay. But:
-       // it HAS to stay <= 64 chars
-       // character set: ASCII 33-126 without the following characters: : ; ' " \ $
-       if(autocvar_sv_eventlog)
-       {
-               string s = sprintf("%s.%s.%06d", itos(autocvar_sv_eventlog_files_counter), strftime(false, "%s"), floor(random() * 1000000));
-               matchid = strzone(s);
-
-               GameLogEcho(strcat(":gamestart:", GetGametype(), "_", GetMapname(), ":", s));
-               s = ":gameinfo:mutators:LIST";
-
-               MUTATOR_CALLHOOK(BuildMutatorsString, s);
-               s = M_ARGV(0, string);
-
-               // initialiation stuff, not good in the mutator system
-               if(!autocvar_g_use_ammunition)
-                       s = strcat(s, ":no_use_ammunition");
-
-               // initialiation stuff, not good in the mutator system
-               if(autocvar_g_pickup_items == 0)
-                       s = strcat(s, ":no_pickup_items");
-               if(autocvar_g_pickup_items > 0)
-                       s = strcat(s, ":pickup_items");
-
-               // initialiation stuff, not good in the mutator system
-               if(autocvar_g_weaponarena != "0")
-                       s = strcat(s, ":", autocvar_g_weaponarena, " arena");
-
-               // TODO to mutator system
-               if(autocvar_g_norecoil)
-                       s = strcat(s, ":norecoil");
-
-               // TODO to mutator system
-               if(autocvar_g_powerups == 0)
-                       s = strcat(s, ":no_powerups");
-               if(autocvar_g_powerups > 0)
-                       s = strcat(s, ":powerups");
-
-               GameLogEcho(s);
-               GameLogEcho(":gameinfo:end");
-       }
-       else
-               matchid = strzone(ftos(random()));
-
-       cvar_set("nextmap", "");
-
-       SetDefaultAlpha();
-
-       if(autocvar_g_campaign)
-               CampaignPostInit();
-
-       Ban_LoadBans();
-
-       MapInfo_Enumerate();
-       MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 1);
-
-       if(fexists(_MapInfo_FindArenaFile(mapname, ".arena")))
-               cvar_settemp("sv_q3acompat_machineshotgunswap", "1");
-
-       if(fexists(_MapInfo_FindArenaFile(mapname, ".defi")))
-               cvar_settemp("sv_q3defragcompat", "1");
-
-       // quake 3 music support
-       if(world.music || world.noise)
-       {
-               // prefer .music over .noise
-               string chosen_music;
-               string oldstuff;
-               if(world.music)
-                       chosen_music = world.music;
-               else
-                       chosen_music = world.noise;
-               if(
-                       substring(chosen_music, strlen(chosen_music) - 4, 4) == ".wav"
-                       ||
-                       substring(chosen_music, strlen(chosen_music) - 4, 4) == ".ogg"
-               )
-                       oldstuff = strcat(clientstuff, "cd loop \"", chosen_music, "\"\n");
-               else
-                       oldstuff = strcat(clientstuff, "cd loop \"", chosen_music, "\"\n");
-
-               strcpy(clientstuff, oldstuff);
-       }
-
-       if(whichpack(strcat("maps/", mapname, ".cfg")) != "")
-       {
-               int fd = fopen(strcat("maps/", mapname, ".cfg"), FILE_READ);
-               if(fd != -1)
-               {
-                       string s;
-                       while((s = fgets(fd)))
-                       {
-                               int l = tokenize_console(s);
-                               if(l < 2)
-                                       continue;
-                               if(argv(0) == "cd")
-                               {
-                                       string trackname = argv(2);
-                                       LOG_INFO("Found ^1UNSUPPORTED^7 cd loop command in .cfg file; put this line in mapinfo instead:");
-                                       LOG_INFO("  cdtrack ", trackname);
-                                       if (cvar_value_issafe(trackname))
-                                       {
-                                               string newstuff = strcat(clientstuff, "cd loop \"", trackname, "\"\n");
-                                               strcpy(clientstuff, newstuff);
-                                       }
-                               }
-                               else if(argv(0) == "fog")
-                               {
-                                       LOG_INFO("Found ^1UNSUPPORTED^7 fog command in .cfg file; put this line in worldspawn in the .map/.bsp/.ent file instead:");
-                                       LOG_INFO("  \"fog\" \"", s, "\"");
-                               }
-                               else if(argv(0) == "set")
-                               {
-                                       LOG_INFO("Found ^1UNSUPPORTED^7 set command in .cfg file; put this line in mapinfo instead:");
-                                       LOG_INFO("  clientsettemp_for_type all ", argv(1), " ", argv(2));
-                               }
-                               else if(argv(0) != "//")
-                               {
-                                       LOG_INFO("Found ^1UNSUPPORTED^7 set command in .cfg file; put this line in mapinfo instead:");
-                                       LOG_INFO("  clientsettemp_for_type all ", argv(0), " ", argv(1));
-                               }
-                       }
-                       fclose(fd);
-               }
-       }
-
-       WeaponStats_Init();
-
-       Nagger_Init();
-
-       next_pingtime = time + 5;
-
-       // set up information replies for clients and server to use
-       maplist_reply = strzone(getmaplist());
-       lsmaps_reply = strzone(getlsmaps());
-       monsterlist_reply = strzone(getmonsterlist());
-       for(int i = 0; i < 10; ++i)
-       {
-               string s = getrecords(i);
-               if (s)
-                       records_reply[i] = strzone(s);
-       }
-       ladder_reply = strzone(getladder());
-       rankings_reply = strzone(getrankings());
-
-       // begin other init
-       ClientInit_Spawn();
-       RandomSeed_Spawn();
-       PingPLReport_Spawn();
-
-       CheatInit();
-
-       if (!wantrestart) localcmd("\n_sv_hook_gamestart ", GetGametype(), "\n");
-
-       // fill sv_curl_serverpackages from .serverpackage files
-       if (autocvar_sv_curl_serverpackages_auto)
-       {
-               string s = "csprogs-" WATERMARK ".txt";
-               // remove automatically managed files from the list to prevent duplicates
-               for (int i = 0, n = tokenize_console(cvar_string("sv_curl_serverpackages")); i < n; ++i)
-               {
-                       string pkg = argv(i);
-                       if (startsWith(pkg, "csprogs-")) continue;
-                       if (endsWith(pkg, "-serverpackage.txt")) continue;
-                       if (endsWith(pkg, ".serverpackage")) continue;  // OLD legacy
-                       s = cons(s, pkg);
-               }
-               // add automatically managed files to the list
-               #define X(match) MACRO_BEGIN \
-                       int fd = search_begin(match, true, false); \
-                       if (fd >= 0) \
-                       { \
-                               for (int i = 0, j = search_getsize(fd); i < j; ++i) \
-                               { \
-                                       s = cons(s, search_getfilename(fd, i)); \
-                               } \
-                               search_end(fd); \
-                       } \
-               MACRO_END
-               X("*-serverpackage.txt");
-               X("*.serverpackage");
-               #undef X
-               cvar_set("sv_curl_serverpackages", s);
-       }
-
-       // MOD AUTHORS: change this, and possibly remove a few of the blocks below to ignore certain changes
-       modname = "Xonotic";
-       // physics/balance/config changes that count as mod
-       if(cvar_string("g_mod_physics") != cvar_defstring("g_mod_physics"))
-               modname = cvar_string("g_mod_physics");
-       if(cvar_string("g_mod_balance") != cvar_defstring("g_mod_balance") && cvar_string("g_mod_balance") != "Testing")
-               modname = cvar_string("g_mod_balance");
-       if(cvar_string("g_mod_config") != cvar_defstring("g_mod_config"))
-               modname = cvar_string("g_mod_config");
-       // extra mutators that deserve to count as mod
-       MUTATOR_CALLHOOK(SetModname, modname);
-       modname = M_ARGV(0, string);
-
-       // save it for later
-       modname = strzone(modname);
-
-       WinningConditionHelper(this); // set worldstatus
-
-       world_initialized = 1;
-       __spawnfunc_spawn_all();
-}
-
-spawnfunc(light)
-{
-       //makestatic (this); // Who the f___ did that?
-       delete(this);
-}
-
-string GetGametype()
-{
-       return MapInfo_Type_ToString(MapInfo_LoadedGametype);
-}
-
-string GetMapname()
-{
-       return mapname;
-}
-
-float Map_Count, Map_Current;
-string Map_Current_Name;
-
-// NOTE: this now expects the map list to be already tokenized and the count in Map_Count
-int GetMaplistPosition()
-{
-       string map = GetMapname();
-       int idx = autocvar_g_maplist_index;
-
-       if(idx >= 0)
-       {
-               if(idx < Map_Count)
-               {
-                       if(map == argv(idx))
-                       {
-                               return idx;
-                       }
-               }
-       }
-
-       for(int pos = 0; pos < Map_Count; ++pos)
-       {
-               if(map == argv(pos))
-                       return pos;
-       }
-
-       // resume normal maplist rotation if current map is not in g_maplist
-       return idx;
-}
-
-bool MapHasRightSize(string map)
-{
-       int minplayers = max(0, floor(autocvar_minplayers));
-       if (teamplay)
-               minplayers = max(0, floor(autocvar_minplayers_per_team) * AvailableTeams());
-       if (autocvar_g_maplist_check_waypoints
-               && (currentbots || autocvar_bot_number || player_count < minplayers))
-       {
-               string checkwp_msg = strcat("checkwp ", map);
-               if(!fexists(strcat("maps/", map, ".waypoints")))
-               {
-                       LOG_TRACE(checkwp_msg, ": no waypoints");
-                       return false;
-               }
-               LOG_TRACE(checkwp_msg, ": has waypoints");
-       }
-
-       if(autocvar_g_maplist_ignore_sizes)
-               return true;
-
-       // open map size restriction file
-       string opensize_msg = strcat("opensize ", map);
-       float fh = fopen(strcat("maps/", map, ".sizes"), FILE_READ);
-       int player_limit = ((autocvar_g_maplist_sizes_count_maxplayers) ? GetPlayerLimit() : 0);
-       int pcount = ((player_limit > 0) ? min(player_count, player_limit) : player_count); // bind it to the player limit so that forced spectators don't influence the limits
-       if(!autocvar_g_maplist_sizes_count_bots)
-               pcount -= currentbots;
-       if(fh >= 0)
-       {
-               opensize_msg = strcat(opensize_msg, ": ok, ");
-               int mapmin = stoi(fgets(fh));
-               int mapmax = stoi(fgets(fh));
-               fclose(fh);
-               if(pcount < mapmin)
-               {
-                       LOG_TRACE(opensize_msg, "not enough");
-                       return false;
-               }
-               if(mapmax && pcount > mapmax)
-               {
-                       LOG_TRACE(opensize_msg, "too many");
-                       return false;
-               }
-               LOG_TRACE(opensize_msg, "right size");
-               return true;
-       }
-       LOG_TRACE(opensize_msg, ": not found");
-       return true;
-}
-
-string Map_Filename(float position)
-{
-       return strcat("maps/", argv(position), ".bsp");
-}
-
-void Map_MarkAsRecent(string m)
-{
-       cvar_set("g_maplist_mostrecent", strwords(cons(m, autocvar_g_maplist_mostrecent), max(0, autocvar_g_maplist_mostrecent_count)));
-}
-
-float Map_IsRecent(string m)
-{
-       return strhasword(autocvar_g_maplist_mostrecent, m);
-}
-
-float Map_Check(float position, float pass)
-{
-       string filename;
-       string map_next;
-       map_next = argv(position);
-       if(pass <= 1)
-       {
-               if(Map_IsRecent(map_next))
-                       return 0;
-       }
-       filename = Map_Filename(position);
-       if(MapInfo_CheckMap(map_next))
-       {
-               if(pass == 2)
-                       return 1;
-               if(MapHasRightSize(map_next))
-                       return 1;
-               return 0;
-       }
-       else
-               LOG_DEBUG( "Couldn't select '", filename, "'..." );
-
-       return 0;
-}
-
-void Map_Goto_SetStr(string nextmapname)
-{
-       if(getmapname_stored != "")
-               strunzone(getmapname_stored);
-       if(nextmapname == "")
-               getmapname_stored = "";
-       else
-               getmapname_stored = strzone(nextmapname);
-}
-
-void Map_Goto_SetFloat(float position)
-{
-       cvar_set("g_maplist_index", ftos(position));
-       Map_Goto_SetStr(argv(position));
-}
-
-void Map_Goto(float reinit)
-{
-       MapInfo_LoadMap(getmapname_stored, reinit);
-}
-
-// return codes of map selectors:
-//   -1 = temporary failure (that is, try some method that is guaranteed to succeed)
-//   -2 = permanent failure
-float MaplistMethod_Iterate() // usual method
-{
-       float pass, i;
-
-       LOG_TRACE("Trying MaplistMethod_Iterate");
-
-       for(pass = 1; pass <= 2; ++pass)
-       {
-               for(i = 1; i < Map_Count; ++i)
-               {
-                       float mapindex;
-                       mapindex = (i + Map_Current) % Map_Count;
-                       if(Map_Check(mapindex, pass))
-                               return mapindex;
-               }
-       }
-       return -1;
-}
-
-float MaplistMethod_Repeat() // fallback method
-{
-       LOG_TRACE("Trying MaplistMethod_Repeat");
-
-       if(Map_Check(Map_Current, 2))
-               return Map_Current;
-       return -2;
-}
-
-float MaplistMethod_Random() // random map selection
-{
-       float i, imax;
-
-       LOG_TRACE("Trying MaplistMethod_Random");
-
-       imax = 42;
-
-       for(i = 0; i <= imax; ++i)
-       {
-               float mapindex;
-               mapindex = (Map_Current + floor(random() * (Map_Count - 1) + 1)) % Map_Count; // any OTHER map
-               if(Map_Check(mapindex, 1))
-                       return mapindex;
-       }
-       return -1;
-}
-
-float MaplistMethod_Shuffle(float exponent) // more clever shuffling
-// the exponent sets a bias on the map selection:
-// the higher the exponent, the less likely "shortly repeated" same maps are
-{
-       float i, j, imax, insertpos;
-
-       LOG_TRACE("Trying MaplistMethod_Shuffle");
-
-       imax = 42;
-
-       for(i = 0; i <= imax; ++i)
-       {
-               string newlist;
-
-               // now reinsert this at another position
-               insertpos = (random() ** (1 / exponent));       // ]0, 1]
-               insertpos = insertpos * (Map_Count - 1);       // ]0, Map_Count - 1]
-               insertpos = ceil(insertpos) + 1;               // {2, 3, 4, ..., Map_Count}
-               LOG_TRACE("SHUFFLE: insert pos = ", ftos(insertpos));
-
-               // insert the current map there
-               newlist = "";
-               for(j = 1; j < insertpos; ++j)                 // i == 1: no loop, will be inserted as first; however, i == 1 has been excluded above
-                       newlist = strcat(newlist, " ", argv(j));
-               newlist = strcat(newlist, " ", argv(0));       // now insert the just selected map
-               for(j = insertpos; j < Map_Count; ++j)         // i == Map_Count: no loop, has just been inserted as last
-                       newlist = strcat(newlist, " ", argv(j));
-               newlist = substring(newlist, 1, strlen(newlist) - 1);
-               cvar_set("g_maplist", newlist);
-               Map_Count = tokenizebyseparator(autocvar_g_maplist, " ");
-
-               // NOTE: the selected map has just been inserted at (insertpos-1)th position
-               Map_Current = insertpos - 1; // this is not really valid, but this way the fallback has a chance of working
-               if(Map_Check(Map_Current, 1))
-                       return Map_Current;
-       }
-       return -1;
-}
-
-void Maplist_Init()
-{
-       float i = Map_Count = 0;
-       if(autocvar_g_maplist != "")
-       {
-               Map_Count = tokenizebyseparator(autocvar_g_maplist, " ");
-               for (i = 0; i < Map_Count; ++i)
-               {
-                       if (Map_Check(i, 2))
-                               break;
-               }
-       }
-
-       if (i == Map_Count)
-       {
-               bprint( "Maplist contains no usable maps!  Resetting it to default map list.\n" );
-               cvar_set("g_maplist", MapInfo_ListAllAllowedMaps(MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags() | MAPINFO_FLAG_NOAUTOMAPLIST));
-               if(autocvar_g_maplist_shuffle)
-                       ShuffleMaplist();
-               if(!server_is_dedicated)
-                       localcmd("\nmenu_cmd sync\n");
-               Map_Count = tokenizebyseparator(autocvar_g_maplist, " ");
-       }
-       if(Map_Count == 0)
-               error("empty maplist, cannot select a new map");
-       Map_Current = bound(0, GetMaplistPosition(), Map_Count - 1);
-
-       strcpy(Map_Current_Name, argv(Map_Current)); // will be automatically freed on exit thanks to DP
-       // this may or may not be correct, but who cares, in the worst case a map
-       // isn't chosen in the first pass that should have been
-}
-
-string GetNextMap()
-{
-       Maplist_Init();
-       float nextMap = -1;
-
-       if(nextMap == -1)
-               if(autocvar_g_maplist_shuffle > 0)
-                       nextMap = MaplistMethod_Shuffle(autocvar_g_maplist_shuffle + 1);
-
-       if(nextMap == -1)
-               if(autocvar_g_maplist_selectrandom)
-                       nextMap = MaplistMethod_Random();
-
-       if(nextMap == -1)
-               nextMap = MaplistMethod_Iterate();
-
-       if(nextMap == -1)
-               nextMap = MaplistMethod_Repeat();
-
-       if(nextMap >= 0)
-       {
-               Map_Goto_SetFloat(nextMap);
-               return getmapname_stored;
-       }
-
-       return "";
-}
-
-float DoNextMapOverride(float reinit)
-{
-       if(autocvar_g_campaign)
-       {
-               CampaignPostIntermission();
-               alreadychangedlevel = true;
-               return true;
-       }
-       if(autocvar_quit_when_empty)
-       {
-               if(player_count <= currentbots)
-               {
-                       localcmd("quit\n");
-                       alreadychangedlevel = true;
-                       return true;
-               }
-       }
-       if(autocvar_quit_and_redirect != "")
-       {
-               redirection_target = strzone(autocvar_quit_and_redirect);
-               alreadychangedlevel = true;
-               return true;
-       }
-       if (!reinit && autocvar_samelevel) // if samelevel is set, stay on same level
-       {
-               localcmd("restart\n");
-               alreadychangedlevel = true;
-               return true;
-       }
-       if(autocvar_nextmap != "")
-       {
-               string m;
-               m = GameTypeVote_MapInfo_FixName(autocvar_nextmap);
-               cvar_set("nextmap",m);
-
-               if(!m || gametypevote)
-                       return false;
-               if(autocvar_sv_vote_gametype)
-               {
-                       Map_Goto_SetStr(m);
-                       return false;
-               }
-
-               if(MapInfo_CheckMap(m))
-               {
-                       Map_Goto_SetStr(m);
-                       Map_Goto(reinit);
-                       alreadychangedlevel = true;
-                       return true;
-               }
-       }
-       if(!reinit && autocvar_lastlevel)
-       {
-               cvar_settemp_restore();
-               localcmd("set lastlevel 0\ntogglemenu 1\n");
-               alreadychangedlevel = true;
-               return true;
-       }
-       return false;
-}
-
-void GotoNextMap(float reinit)
-{
-       //string nextmap;
-       //float n, nummaps;
-       //string s;
-       if (alreadychangedlevel)
-               return;
-       alreadychangedlevel = true;
-
-       string nextMap = GetNextMap();
-       if(nextMap == "")
-               error("Everything is broken - cannot find a next map. Please report this to the developers.");
-       Map_Goto(reinit);
-}
-
-
-/*
-============
-IntermissionThink
-
-When the player presses attack or jump, change to the next level
-============
-*/
-.float autoscreenshot;
-void IntermissionThink(entity this)
-{
-       FixIntermissionClient(this);
-
-       float server_screenshot = (autocvar_sv_autoscreenshot && CS(this).cvar_cl_autoscreenshot);
-       float client_screenshot = (CS(this).cvar_cl_autoscreenshot == 2);
-
-       if( (server_screenshot || client_screenshot)
-               && ((this.autoscreenshot > 0) && (time > this.autoscreenshot)) )
-       {
-               this.autoscreenshot = -1;
-               if(IS_REAL_CLIENT(this)) { stuffcmd(this, sprintf("\nscreenshot screenshots/autoscreenshot/%s-%s.jpg; echo \"^5A screenshot has been taken at request of the server.\"\n", GetMapname(), strftime(false, "%s"))); }
-               return;
-       }
-
-       if (time < intermission_exittime)
-               return;
-
-       if(!mapvote_initialized)
-               if (time < intermission_exittime + 10 && !(PHYS_INPUT_BUTTON_ATCK(this) || PHYS_INPUT_BUTTON_JUMP(this) || PHYS_INPUT_BUTTON_ATCK2(this) || PHYS_INPUT_BUTTON_HOOK(this) || PHYS_INPUT_BUTTON_USE(this)))
-                       return;
-
-       MapVote_Start();
-}
-
-/*
-===============================================================================
-
-RULES
-
-===============================================================================
-*/
-
-void DumpStats(float final)
-{
-       float file;
-       string s;
-       float to_console;
-       float to_eventlog;
-       float to_file;
-       float i;
-
-       to_console = autocvar_sv_logscores_console;
-       to_eventlog = autocvar_sv_eventlog;
-       to_file = autocvar_sv_logscores_file;
-
-       if(!final)
-       {
-               to_console = true; // always print printstats replies
-               to_eventlog = false; // but never print them to the event log
-       }
-
-       if(to_eventlog)
-               if(autocvar_sv_eventlog_console)
-                       to_console = false; // otherwise we get the output twice
-
-       if(final)
-               s = ":scores:";
-       else
-               s = ":status:";
-       s = strcat(s, GetGametype(), "_", GetMapname(), ":", ftos(rint(time)));
-
-       if(to_console)
-               LOG_INFO(s);
-       if(to_eventlog)
-               GameLogEcho(s);
-
-       file = -1;
-       if(to_file)
-       {
-               file = fopen(autocvar_sv_logscores_filename, FILE_APPEND);
-               if(file == -1)
-                       to_file = false;
-               else
-                       fputs(file, strcat(s, "\n"));
-       }
-
-       s = strcat(":labels:player:", GetPlayerScoreString(NULL, 0));
-       if(to_console)
-               LOG_INFO(s);
-       if(to_eventlog)
-               GameLogEcho(s);
-       if(to_file)
-               fputs(file, strcat(s, "\n"));
-
-       FOREACH_CLIENT(IS_REAL_CLIENT(it) || (IS_BOT_CLIENT(it) && autocvar_sv_logscores_bots), {
-               s = strcat(":player:see-labels:", GetPlayerScoreString(it, 0), ":");
-               s = strcat(s, ftos(rint(time - CS(it).jointime)), ":");
-               if(IS_PLAYER(it) || MUTATOR_CALLHOOK(GetPlayerStatus, it))
-                       s = strcat(s, ftos(it.team), ":");
-               else
-                       s = strcat(s, "spectator:");
-
-               if(to_console)
-                       LOG_INFO(s, playername(it, false));
-               if(to_eventlog)
-                       GameLogEcho(strcat(s, ftos(it.playerid), ":", playername(it, false)));
-               if(to_file)
-                       fputs(file, strcat(s, playername(it, false), "\n"));
-       });
-
-       if(teamplay)
-       {
-               s = strcat(":labels:teamscores:", GetTeamScoreString(0, 0));
-               if(to_console)
-                       LOG_INFO(s);
-               if(to_eventlog)
-                       GameLogEcho(s);
-               if(to_file)
-                       fputs(file, strcat(s, "\n"));
-
-               for(i = 1; i < 16; ++i)
-               {
-                       s = strcat(":teamscores:see-labels:", GetTeamScoreString(i, 0));
-                       s = strcat(s, ":", ftos(i));
-                       if(to_console)
-                               LOG_INFO(s);
-                       if(to_eventlog)
-                               GameLogEcho(s);
-                       if(to_file)
-                               fputs(file, strcat(s, "\n"));
-               }
-       }
-
-       if(to_console)
-               LOG_INFO(":end");
-       if(to_eventlog)
-               GameLogEcho(":end");
-       if(to_file)
-       {
-               fputs(file, ":end\n");
-               fclose(file);
-       }
-}
-
-void FixIntermissionClient(entity e)
-{
-       if(!e.autoscreenshot) // initial call
-       {
-               e.autoscreenshot = time + 0.8;  // used for autoscreenshot
-               SetResourceExplicit(e, RES_HEALTH, -2342);
-               // first intermission phase; voting phase has positive health (used to decide whether to send SVC_FINALE or not)
-               for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
-               {
-                   .entity weaponentity = weaponentities[slot];
-                       if(e.(weaponentity))
-                       {
-                               e.(weaponentity).effects = EF_NODRAW;
-                               if (e.(weaponentity).weaponchild)
-                                       e.(weaponentity).weaponchild.effects = EF_NODRAW;
-                       }
-               }
-               if(IS_REAL_CLIENT(e))
-               {
-                       stuffcmd(e, "\nscr_printspeed 1000000\n");
-                       RandomSelection_Init();
-                       FOREACH_WORD(autocvar_sv_intermission_cdtrack, true, {
-                               RandomSelection_AddString(it, 1, 1);
-                       });
-                       if (RandomSelection_chosen_string != "")
-                       {
-                               stuffcmd(e, sprintf("\ncd loop %s\n", RandomSelection_chosen_string));
-                       }
-                       msg_entity = e;
-                       WriteByte(MSG_ONE, SVC_INTERMISSION);
-               }
-       }
-}
-
-/*
-go to the next level for deathmatch
-only called if a time or frag limit has expired
-*/
-void NextLevel()
-{
-       game_stopped = true;
-       intermission_running = 1; // game over
-
-       // enforce a wait time before allowing changelevel
-       if(player_count > 0)
-               intermission_exittime = time + autocvar_sv_mapchange_delay;
-       else
-               intermission_exittime = -1;
-
-       /*
-       WriteByte (MSG_ALL, SVC_CDTRACK);
-       WriteByte (MSG_ALL, 3);
-       WriteByte (MSG_ALL, 3);
-       // done in FixIntermission
-       */
-
-       //pos = FindIntermission ();
-
-       VoteReset();
-
-       DumpStats(true);
-
-       // send statistics
-       PlayerStats_GameReport(true);
-       WeaponStats_Shutdown();
-
-       Kill_Notification(NOTIF_ALL, NULL, MSG_CENTER, CPID_Null); // kill all centerprints now
-
-       if(autocvar_sv_eventlog)
-               GameLogEcho(":gameover");
-
-       GameLogClose();
-
-       FOREACH_CLIENT(IS_PLAYER(it), {
-               FixIntermissionClient(it);
-               if(it.winning)
-                       bprint(playername(it, false), " ^7wins.\n");
-       });
-
-       target_music_kill();
-
-       if(autocvar_g_campaign)
-               CampaignPreIntermission();
-
-       MUTATOR_CALLHOOK(MatchEnd);
-
-       localcmd("\nsv_hook_gameend\n");
-}
-
-
-float InitiateSuddenDeath()
-{
-       // Check first whether normal overtimes could be added before initiating suddendeath mode
-       // - for this timelimit_overtime needs to be >0 of course
-       // - also check the winning condition calculated in the previous frame and only add normal overtime
-       //   again, if at the point at which timelimit would be extended again, still no winner was found
-       if (!autocvar_g_campaign && checkrules_overtimesadded >= 0
-               && (checkrules_overtimesadded < autocvar_timelimit_overtimes || autocvar_timelimit_overtimes < 0)
-               && autocvar_timelimit_overtime && !(g_race && !g_race_qualifying))
-       {
-               return 1; // need to call InitiateOvertime later
-       }
-       else
-       {
-               if(!checkrules_suddendeathend)
-               {
-                       if(autocvar_g_campaign)
-                               checkrules_suddendeathend = time; // no suddendeath in campaign
-                       else
-                               checkrules_suddendeathend = time + 60 * autocvar_timelimit_suddendeath;
-                       if(g_race && !g_race_qualifying)
-                               race_StartCompleting();
-               }
-               return 0;
-       }
-}
-
-void InitiateOvertime() // ONLY call this if InitiateSuddenDeath returned true
-{
-       ++checkrules_overtimesadded;
-       //add one more overtime by simply extending the timelimit
-       cvar_set("timelimit", ftos(autocvar_timelimit + autocvar_timelimit_overtime));
-       Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_OVERTIME_TIME, autocvar_timelimit_overtime * 60);
-}
-
-float GetWinningCode(float fraglimitreached, float equality)
-{
-       if(autocvar_g_campaign == 1)
-       {
-               if(fraglimitreached)
-                       return WINNING_YES;
-               else
-                       return WINNING_NO;
-       }
-       else
-       {
-               if(equality)
-               {
-                       if(fraglimitreached)
-                               return WINNING_STARTSUDDENDEATHOVERTIME;
-                       else
-                               return WINNING_NEVER;
-               }
-               else
-               {
-                       if(fraglimitreached)
-                               return WINNING_YES;
-                       else
-                               return WINNING_NO;
-               }
-       }
-}
-
-// set the .winning flag for exactly those players with a given field value
-void SetWinners(.float field, float value)
-{
-       FOREACH_CLIENT(IS_PLAYER(it), { it.winning = (it.(field) == value); });
-}
-
-// set the .winning flag for those players with a given field value
-void AddWinners(.float field, float value)
-{
-       FOREACH_CLIENT(IS_PLAYER(it), {
-               if(it.(field) == value)
-                       it.winning = 1;
-       });
-}
-
-// clear the .winning flags
-void ClearWinners()
-{
-       FOREACH_CLIENT(IS_PLAYER(it), { it.winning = 0; });
-}
-
-void ShuffleMaplist()
-{
-       cvar_set("g_maplist", shufflewords(autocvar_g_maplist));
-}
-
-int fragsleft_last;
-float WinningCondition_Scores(float limit, float leadlimit)
-{
-       // TODO make everything use THIS winning condition (except LMS)
-       WinningConditionHelper(NULL);
-
-       if(teamplay)
-       {
-               for (int i = 1; i < 5; ++i)
-               {
-                       Team_SetTeamScore(Team_GetTeamFromIndex(i),
-                               TeamScore_GetCompareValue(Team_IndexToTeam(i)));
-               }
-       }
-
-       ClearWinners();
-       if(WinningConditionHelper_winner)
-               WinningConditionHelper_winner.winning = 1;
-       if(WinningConditionHelper_winnerteam >= 0)
-               SetWinners(team, WinningConditionHelper_winnerteam);
-
-       if(WinningConditionHelper_lowerisbetter)
-       {
-               WinningConditionHelper_topscore = -WinningConditionHelper_topscore;
-               WinningConditionHelper_secondscore = -WinningConditionHelper_secondscore;
-               limit = -limit;
-       }
-
-       if(WinningConditionHelper_zeroisworst)
-               leadlimit = 0; // not supported in this mode
-
-       if(MUTATOR_CALLHOOK(Scores_CountFragsRemaining))
-       {
-               float fragsleft;
-               if (checkrules_suddendeathend && time >= checkrules_suddendeathend)
-               {
-                       fragsleft = 1;
-               }
-               else
-               {
-                       fragsleft = FLOAT_MAX;
-                       float leadingfragsleft = FLOAT_MAX;
-                       if (limit)
-                               fragsleft = limit - WinningConditionHelper_topscore;
-                       if (leadlimit)
-                               leadingfragsleft = WinningConditionHelper_secondscore + leadlimit - WinningConditionHelper_topscore;
-
-                       if (limit && leadlimit && autocvar_leadlimit_and_fraglimit)
-                               fragsleft = max(fragsleft, leadingfragsleft);
-                       else
-                               fragsleft = min(fragsleft, leadingfragsleft);
-               }
-
-               if (fragsleft_last != fragsleft) // do not announce same remaining frags multiple times
-               {
-                       if (fragsleft == 1)
-                               Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_REMAINING_FRAG_1);
-                       else if (fragsleft == 2)
-                               Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_REMAINING_FRAG_2);
-                       else if (fragsleft == 3)
-                               Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_REMAINING_FRAG_3);
-
-                       fragsleft_last = fragsleft;
-               }
-       }
-
-       bool fraglimit_reached = (limit && WinningConditionHelper_topscore >= limit);
-       bool leadlimit_reached = (leadlimit && WinningConditionHelper_topscore - WinningConditionHelper_secondscore >= leadlimit);
-
-       bool limit_reached;
-       // only respect leadlimit_and_fraglimit when both limits are set or the game will never end
-       if (limit && leadlimit && autocvar_leadlimit_and_fraglimit)
-               limit_reached = (fraglimit_reached && leadlimit_reached);
-       else
-               limit_reached = (fraglimit_reached || leadlimit_reached);
-
-       return GetWinningCode(
-               WinningConditionHelper_topscore && limit_reached,
-               WinningConditionHelper_equality
-       );
-}
-
-float WinningCondition_RanOutOfSpawns()
-{
-       if(have_team_spawns <= 0)
-               return WINNING_NO;
-
-       if(!autocvar_g_spawn_useallspawns)
-               return WINNING_NO;
-
-       if(!some_spawn_has_been_used)
-               return WINNING_NO;
-
-       for (int i = 1; i < 5; ++i)
-       {
-               Team_SetTeamScore(Team_GetTeamFromIndex(i), 0);
-       }
-
-       FOREACH_CLIENT(IS_PLAYER(it) && !IS_DEAD(it),
-       {
-               if (Team_IsValidTeam(it.team))
-               {
-                       Team_SetTeamScore(Team_GetTeam(it.team), 1);
-               }
-       });
-
-       IL_EACH(g_spawnpoints, true,
-       {
-               if (Team_IsValidTeam(it.team))
-               {
-                       Team_SetTeamScore(Team_GetTeam(it.team), 1);
-               }
-       });
-
-       ClearWinners();
-       float team1_score = Team_GetTeamScore(Team_GetTeamFromIndex(1));
-       float team2_score = Team_GetTeamScore(Team_GetTeamFromIndex(2));
-       float team3_score = Team_GetTeamScore(Team_GetTeamFromIndex(3));
-       float team4_score = Team_GetTeamScore(Team_GetTeamFromIndex(4));
-       if(team1_score + team2_score + team3_score + team4_score == 0)
-       {
-               checkrules_equality = true;
-               return WINNING_YES;
-       }
-       else if(team1_score + team2_score + team3_score + team4_score == 1)
-       {
-               float t, i;
-               if(team1_score)
-                       t = 1;
-               else if(team2_score)
-                       t = 2;
-               else if(team3_score)
-                       t = 3;
-               else // if(team4_score)
-                       t = 4;
-               entity balance = TeamBalance_CheckAllowedTeams(NULL);
-               for(i = 0; i < MAX_TEAMSCORE; ++i)
-               {
-                       for (int j = 1; j <= NUM_TEAMS; ++j)
-                       {
-                               if (t == j)
-                               {
-                                       continue;
-                               }
-                               if (!TeamBalance_IsTeamAllowed(balance, j))
-                               {
-                                       continue;
-                               }
-                               TeamScore_AddToTeam(Team_IndexToTeam(j), i, -1000);
-                       }
-               }
-
-               AddWinners(team, t);
-               return WINNING_YES;
-       }
-       else
-               return WINNING_NO;
-}
-
-/*
-============
-CheckRules_World
-
-Exit deathmatch games upon conditions
-============
-*/
-void CheckRules_World()
-{
-       VoteThink();
-       MapVote_Think();
-
-       SetDefaultAlpha();
-
-       if (intermission_running) // someone else quit the game already
-       {
-               if(player_count == 0) // Nobody there? Then let's go to the next map
-                       MapVote_Start();
-                       // this will actually check the player count in the next frame
-                       // again, but this shouldn't hurt
-               return;
-       }
-
-       float timelimit = autocvar_timelimit * 60;
-       float fraglimit = autocvar_fraglimit;
-       float leadlimit = autocvar_leadlimit;
-       if (leadlimit < 0) leadlimit = 0;
-
-       if(warmup_stage || time <= game_starttime) // NOTE: this is <= to prevent problems in the very tic where the game starts
-       {
-               if(timelimit > 0)
-                       timelimit = 0; // timelimit is not made for warmup
-               if(fraglimit > 0)
-                       fraglimit = 0; // no fraglimit for now
-               leadlimit = 0; // no leadlimit for now
-       }
-
-       if(timelimit > 0)
-       {
-               timelimit += game_starttime;
-       }
-       else if (timelimit < 0)
-       {
-               // endmatch
-               NextLevel();
-               return;
-       }
-
-       float wantovertime;
-       wantovertime = 0;
-
-       if(checkrules_suddendeathend)
-       {
-               if(!checkrules_suddendeathwarning)
-               {
-                       checkrules_suddendeathwarning = true;
-                       if(g_race && !g_race_qualifying)
-                               Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_RACE_FINISHLAP);
-                       else
-                               Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_OVERTIME_FRAG);
-               }
-       }
-       else
-       {
-               if (timelimit && time >= timelimit)
-               {
-                       if(g_race && (g_race_qualifying == 2) && timelimit > 0)
-                       {
-                               float totalplayers;
-                               float playerswithlaps;
-                               float readyplayers;
-                               totalplayers = playerswithlaps = readyplayers = 0;
-                               FOREACH_CLIENT(IS_PLAYER(it), {
-                                       ++totalplayers;
-                                       if(GameRules_scoring_add(it, RACE_FASTEST, 0))
-                                               ++playerswithlaps;
-                                       if(it.ready)
-                                               ++readyplayers;
-                               });
-
-                               // at least 2 of the players have completed a lap: start the RACE
-                               // otherwise, the players should end the qualifying on their own
-                               if(readyplayers || playerswithlaps >= 2)
-                               {
-                                       checkrules_suddendeathend = 0;
-                                       ReadyRestart(); // go to race
-                                       return;
-                               }
-                               else
-                                       wantovertime |= InitiateSuddenDeath();
-                       }
-                       else
-                               wantovertime |= InitiateSuddenDeath();
-               }
-       }
-
-       if (checkrules_suddendeathend && time >= checkrules_suddendeathend)
-       {
-               NextLevel();
-               return;
-       }
-
-       int checkrules_status = WinningCondition_RanOutOfSpawns();
-       if(checkrules_status == WINNING_YES)
-               bprint("Hey! Someone ran out of spawns!\n");
-       else if(MUTATOR_CALLHOOK(CheckRules_World, checkrules_status, timelimit, fraglimit))
-               checkrules_status = M_ARGV(0, float);
-       else
-               checkrules_status = WinningCondition_Scores(fraglimit, leadlimit);
-
-       if(checkrules_status == WINNING_STARTSUDDENDEATHOVERTIME)
-       {
-               checkrules_status = WINNING_NEVER;
-               checkrules_overtimesadded = -1;
-               wantovertime |= InitiateSuddenDeath();
-       }
-
-       if(checkrules_status == WINNING_NEVER)
-               // equality cases! Nobody wins if the overtime ends in a draw.
-               ClearWinners();
-
-       if(wantovertime)
-       {
-               if(checkrules_status == WINNING_NEVER)
-                       InitiateOvertime();
-               else
-                       checkrules_status = WINNING_YES;
-       }
-
-       if(checkrules_suddendeathend)
-               if(checkrules_status != WINNING_NEVER || time >= checkrules_suddendeathend)
-                       checkrules_status = WINNING_YES;
-
-       if(checkrules_status == WINNING_YES)
-       {
-               //print("WINNING\n");
-               NextLevel();
-       }
-}
-
-string GotoMap(string m)
-{
-       m = GameTypeVote_MapInfo_FixName(m);
-       if (!m)
-               return "The map you suggested is not available on this server.";
-       if (!autocvar_sv_vote_gametype)
-       if(!MapInfo_CheckMap(m))
-               return "The map you suggested does not support the current game mode.";
-       cvar_set("nextmap", m);
-       cvar_set("timelimit", "-1");
-       if(mapvote_initialized || alreadychangedlevel)
-       {
-               if(DoNextMapOverride(0))
-                       return "Map switch initiated.";
-               else
-                       return "Hm... no. For some reason I like THIS map more.";
-       }
-       else
-               return "Map switch will happen after scoreboard.";
-}
-
-bool autocvar_sv_gameplayfix_multiplethinksperframe = true;
-void RunThink(entity this)
-{
-       // don't let things stay in the past.
-       // it is possible to start that way by a trigger with a local time.
-       if(this.nextthink <= 0 || this.nextthink > time + frametime)
-               return;
-
-       float oldtime = time; // do we need to save this?
-
-       for (int iterations = 0; iterations < 128 && !wasfreed(this); iterations++)
-       {
-               time = max(oldtime, this.nextthink);
-               this.nextthink = 0;
-
-               if(getthink(this))
-                       getthink(this)(this);
-               // mods often set nextthink to time to cause a think every frame,
-               // we don't want to loop in that case, so exit if the new nextthink is
-               // <= the time the qc was told, also exit if it is past the end of the
-               // frame
-               if(this.nextthink <= time || this.nextthink > oldtime + frametime || !autocvar_sv_gameplayfix_multiplethinksperframe)
-                       break;
-       }
-
-       time = oldtime;
-}
-
-bool autocvar_sv_freezenonclients;
-bool autocvar_sv_gameplayfix_delayprojectiles = false;
-void Physics_Frame()
-{
-       if(autocvar_sv_freezenonclients)
-               return;
-
-       IL_EACH(g_moveables, true,
-       {
-               if(IS_CLIENT(it) || it.classname == "" || it.move_movetype == MOVETYPE_PHYSICS)
-                       continue;
-
-               //set_movetype(it, it.move_movetype);
-               // inline the set_movetype function, since this is called a lot
-               it.movetype = (it.move_qcphysics) ? MOVETYPE_QCENTITY : it.move_movetype;
-
-               if(it.move_qcphysics && it.move_movetype != MOVETYPE_NONE)
-                       Movetype_Physics_NoMatchTicrate(it, PHYS_INPUT_TIMELENGTH, false);
-
-               if(it.movetype >= MOVETYPE_USER_FIRST && it.movetype <= MOVETYPE_USER_LAST) // these cases have no think handling
-               {
-                       if(it.move_movetype == MOVETYPE_PUSH || it.move_movetype == MOVETYPE_FAKEPUSH)
-                               continue; // these movetypes have no regular think function
-                       // handle thinking here
-                       if (getthink(it) && it.nextthink > 0 && it.nextthink <= time + frametime)
-                               RunThink(it);
-               }
-       });
-
-       if(autocvar_sv_gameplayfix_delayprojectiles >= 0)
-               return;
-
-       IL_EACH(g_moveables, it.move_qcphysics,
-       {
-               if(IS_CLIENT(it) || it.classname == "" || it.move_movetype == MOVETYPE_NONE)
-                       continue;
-               Movetype_Physics_NoMatchTicrate(it, PHYS_INPUT_TIMELENGTH, false);
-       });
-}
-
-void systems_update();
-void EndFrame()
-{
-       anticheat_endframe();
-
-       Physics_Frame();
-
-       FOREACH_CLIENT(IS_REAL_CLIENT(it), {
-               entity e = IS_SPEC(it) ? it.enemy : it;
-               if (e.typehitsound) {
-                       STAT(TYPEHIT_TIME, it) = time;
-               } else if (e.killsound) {
-                       STAT(KILL_TIME, it) = time;
-               } else if (e.damage_dealt) {
-                       STAT(HIT_TIME, it) = time;
-                       STAT(DAMAGE_DEALT_TOTAL, it) += ceil(e.damage_dealt);
-               }
-       });
-       // add 1 frametime because after this, engine SV_Physics
-       // increases time by a frametime and then networks the frame
-       // add another frametime because client shows everything with
-       // 1 frame of lag (cl_nolerp 0). The last +1 however should not be
-       // needed!
-       float altime = time + frametime * (1 + autocvar_g_antilag_nudge);
-       FOREACH_CLIENT(true, {
-               it.typehitsound = false;
-               it.damage_dealt = 0;
-               it.killsound = false;
-               antilag_record(it, CS(it), altime);
-       });
-       IL_EACH(g_monsters, true,
-       {
-               antilag_record(it, it, altime);
-       });
-       IL_EACH(g_projectiles, it.classname == "nade",
-       {
-               antilag_record(it, it, altime);
-       });
-       systems_update();
-       IL_ENDFRAME();
-}
-
-
-/*
- * RedirectionThink:
- * returns true if redirecting
- */
-float redirection_timeout;
-float redirection_nextthink;
-float RedirectionThink()
-{
-       float clients_found;
-
-       if(redirection_target == "")
-               return false;
-
-       if(!redirection_timeout)
-       {
-               cvar_set("sv_public", "-2");
-               redirection_timeout = time + 0.6; // this will only try twice... should be able to keep more clients
-               if(redirection_target == "self")
-                       bprint("^3SERVER NOTICE:^7 restarting the server\n");
-               else
-                       bprint("^3SERVER NOTICE:^7 redirecting everyone to ", redirection_target, "\n");
-       }
-
-       if(time < redirection_nextthink)
-               return true;
-
-       redirection_nextthink = time + 1;
-
-       clients_found = 0;
-       FOREACH_CLIENT(IS_REAL_CLIENT(it), {
-               // TODO add timer
-               LOG_INFO("Redirecting: sending connect command to ", it.netname);
-               if(redirection_target == "self")
-                       stuffcmd(it, "\ndisconnect; defer ", ftos(autocvar_quit_and_redirect_timer), " reconnect\n");
-               else
-                       stuffcmd(it, strcat("\ndisconnect; defer ", ftos(autocvar_quit_and_redirect_timer), " \"connect ", redirection_target, "\"\n"));
-               ++clients_found;
-       });
-
-       LOG_INFO("Redirecting: ", ftos(clients_found), " clients left.");
-
-       if(time > redirection_timeout || clients_found == 0)
-               localcmd("\nwait; wait; wait; quit\n");
-
-       return true;
-}
-
-void RestoreGame()
-{
-       // Loaded from a save game
-       // some things then break, so let's work around them...
-
-       // Progs DB (capture records)
-       ServerProgsDB = db_load(strcat("server.db", autocvar_sessionid));
-
-       // Mapinfo
-       MapInfo_Shutdown();
-       MapInfo_Enumerate();
-       MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 1);
-       WeaponStats_Init();
-
-       TargetMusic_RestoreGame();
-}
-
-void Shutdown()
-{
-       game_stopped = 2;
-
-       if(world_initialized > 0)
-       {
-               world_initialized = 0;
-
-               // if a timeout is active, reset the slowmo value to normal
-               if(timeout_status == TIMEOUT_ACTIVE)
-                       cvar_set("slowmo", ftos(orig_slowmo));
-
-               LOG_TRACE("Saving persistent data...");
-               Ban_SaveBans();
-
-               // playerstats with unfinished match
-               PlayerStats_GameReport(false);
-
-               if(!cheatcount_total)
-               {
-                       if(autocvar_sv_db_saveasdump)
-                               db_dump(ServerProgsDB, strcat("server.db", autocvar_sessionid));
-                       else
-                               db_save(ServerProgsDB, strcat("server.db", autocvar_sessionid));
-               }
-               if(autocvar_developer > 0)
-               {
-                       if(autocvar_sv_db_saveasdump)
-                               db_dump(TemporaryDB, "server-temp.db");
-                       else
-                               db_save(TemporaryDB, "server-temp.db");
-               }
-               CheatShutdown(); // must be after cheatcount check
-               db_close(ServerProgsDB);
-               db_close(TemporaryDB);
-               LOG_TRACE("Saving persistent data... done!");
-               // tell the bot system the game is ending now
-               bot_endgame();
-
-               WeaponStats_Shutdown();
-               MapInfo_Shutdown();
-       }
-       else if(world_initialized == 0)
-       {
-               LOG_INFO("NOTE: crashed before even initializing the world, not saving persistent data");
-       }
-       else
-       {
-               __init_dedicated_server_shutdown();
-       }
-}
diff --git a/qcsrc/server/g_world.qh b/qcsrc/server/g_world.qh
deleted file mode 100644 (file)
index 35808f2..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#pragma once
-
-float checkrules_equality;
-float checkrules_suddendeathwarning;
-float checkrules_suddendeathend;
-float checkrules_overtimesadded; //how many overtimes have been already added
-
-string cache_mutatormsg;
-string cache_lastmutatormsg;
-
-const int WINNING_NO = 0; // no winner, but time limits may terminate the game
-const int WINNING_YES = 1; // winner found
-const int WINNING_NEVER = 2; // no winner, enter overtime if time limit is reached
-const int WINNING_STARTSUDDENDEATHOVERTIME = 3; // no winner, enter suddendeath overtime NOW
-
-float WinningCondition_Scores(float limit, float leadlimit);
-void SetWinners(.float field, float value);
-void IntermissionThink(entity this);
-void GotoNextMap(float reinit);
-void ReadyRestart();
-
-string GetGametype();
-
-void DumpStats(float final);
-float Map_IsRecent(string m);
-string GetNextMap();
-void ShuffleMaplist();
-void Map_Goto_SetStr(string nextmapname);
-void Map_Goto(float reinit);
-void Map_MarkAsRecent(string m);
-float DoNextMapOverride(float reinit);
-void CheckRules_World();
-float RedirectionThink();
-
-// quake 3 music compatibility
-.string music;
-.string noise;
diff --git a/qcsrc/server/hook.qc b/qcsrc/server/hook.qc
new file mode 100644 (file)
index 0000000..6042a48
--- /dev/null
@@ -0,0 +1,435 @@
+#include "hook.qh"
+
+#include <server/bot/api.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
+#include <server/damage.qh>
+#include <server/miscfunctions.qh>
+#include <common/effects/all.qh>
+#include "weapons/common.qh"
+#include "weapons/csqcprojectile.qh"
+#include "weapons/weaponsystem.qh"
+#include "weapons/selection.qh"
+#include "weapons/tracing.qh"
+#include "player.qh"
+#include "command/common.qh"
+#include "command/vote.qh"
+#include "round_handler.qh"
+#include "../common/state.qh"
+#include "../common/physics/player.qh"
+#include "../common/vehicles/all.qh"
+#include "../common/constants.qh"
+#include "../common/util.qh"
+#include <common/net_linked.qh>
+#include <common/weapons/_all.qh>
+#include "../lib/warpzone/common.qh"
+#include "../lib/warpzone/server.qh"
+
+/*============================================
+
+      Wazat's Xonotic Grappling Hook
+
+        Contact: Wazat1@gmail.com
+
+
+Installation instructions:
+--------------------------
+
+1. Place hook.c in your gamec source directory with the other source files.
+
+2. Add this line to the bottom of progs.src:
+
+gamec/hook.c
+
+3. Open defs.h and add these lines to the very bottom:
+
+// Wazat's grappling hook
+.entity                hook;
+void GrapplingHookFrame();
+void RemoveGrapplingHook(entity pl);
+void SetGrappleHookBindings();
+// hook impulses
+const float GRAPHOOK_FIRE              = 20;
+const float GRAPHOOK_RELEASE           = 21;
+// (note: you can change the hook impulse #'s to whatever you please)
+
+4. Open client.c and add this to the top of PutClientInServer():
+
+       RemoveGrapplingHook(this); // Wazat's Grappling Hook
+
+5. Find ClientConnect() (in client.c) and add these lines to the bottom:
+
+       // Wazat's grappling hook
+       SetGrappleHookBindings();
+
+6. Still in client.c, find PlayerPreThink and add this line just above the call to W_WeaponFrame:
+
+       GrapplingHookFrame();
+
+7. Build and test the mod.  You'll want to bind a key to "+hook" like this:
+bind ctrl "+hook"
+
+And you should be done!
+
+
+============================================*/
+
+void RemoveGrapplingHooks(entity pl)
+{
+       if(pl.move_movetype == MOVETYPE_FLY)
+               set_movetype(pl, MOVETYPE_WALK);
+
+       for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+    {
+       .entity weaponentity = weaponentities[slot];
+       if(!pl.(weaponentity))
+               continue; // continue incase other slots exist?
+       if(pl.(weaponentity).hook)
+               delete(pl.(weaponentity).hook);
+       pl.(weaponentity).hook = NULL;
+    }
+
+       //pl.disableclientprediction = false;
+}
+
+void RemoveHook(entity this)
+{
+       entity player = this.realowner;
+    .entity weaponentity = this.weaponentity_fld;
+
+    if(player.(weaponentity).hook == this)
+       player.(weaponentity).hook = NULL;
+
+    if(player.move_movetype == MOVETYPE_FLY)
+       set_movetype(player, MOVETYPE_WALK);
+    delete(this);
+}
+
+void GrapplingHookReset(entity this)
+{
+       RemoveHook(this);
+}
+
+void GrapplingHook_Stop(entity this)
+{
+       Send_Effect(EFFECT_HOOK_IMPACT, this.origin, '0 0 0', 1);
+       sound (this, CH_SHOTS, SND_HOOK_IMPACT, VOL_BASE, ATTEN_NORM);
+
+       this.state = 1;
+       setthink(this, GrapplingHookThink);
+       this.nextthink = time;
+       settouch(this, func_null);
+       this.velocity = '0 0 0';
+       set_movetype(this, MOVETYPE_NONE);
+       this.hook_length = -1;
+}
+
+.vector hook_start, hook_end;
+bool GrapplingHookSend(entity this, entity to, int sf)
+{
+       WriteHeader(MSG_ENTITY, ENT_CLIENT_HOOK);
+       sf = sf & 0x7F;
+       if(sound_allowed(MSG_BROADCAST, this.realowner))
+               sf |= 0x80;
+       WriteByte(MSG_ENTITY, sf);
+       if(sf & 1)
+       {
+               WriteByte(MSG_ENTITY, etof(this.realowner));
+               WriteByte(MSG_ENTITY, weaponslot(this.weaponentity_fld));
+       }
+       if(sf & 2)
+       {
+               WriteVector(MSG_ENTITY, this.hook_start);
+       }
+       if(sf & 4)
+       {
+               WriteVector(MSG_ENTITY, this.hook_end);
+       }
+       return true;
+}
+
+int autocvar_g_grappling_hook_tarzan;
+
+void GrapplingHookThink(entity this)
+{
+       float spd, dist, minlength, pullspeed, ropestretch, ropeairfriction, rubberforce, newlength, rubberforce_overstretch;
+       vector dir, org, end, v0, dv, v, myorg, vs;
+       .entity weaponentity = this.weaponentity_fld;
+       if(this.realowner.(weaponentity).hook != this)  // how did that happen?
+       {
+               error("Owner lost the hook!\n");
+               return;
+       }
+       if(LostMovetypeFollow(this) || game_stopped || (round_handler_IsActive() && !round_handler_IsRoundStarted()) || ((this.aiment.flags & FL_PROJECTILE) && this.aiment.classname != "nade"))
+       {
+               RemoveHook(this);
+               return;
+       }
+       if(this.aiment)
+               WarpZone_RefSys_AddIncrementally(this, this.aiment);
+
+       this.nextthink = time;
+
+       int s = W_GunAlign(this.realowner.(weaponentity), STAT(GUNALIGN, this.realowner)) - 1;
+       vs = hook_shotorigin[s];
+
+       makevectors(this.realowner.v_angle);
+       org = this.realowner.origin + this.realowner.view_ofs + v_forward * vs.x + v_right * -vs.y + v_up * vs.z;
+       myorg = WarpZone_RefSys_TransformOrigin(this.realowner, this, org);
+
+       if(this.hook_length < 0)
+               this.hook_length = vlen(myorg - this.origin);
+
+       int tarzan = autocvar_g_grappling_hook_tarzan;
+       entity pull_entity = this.realowner;
+       float velocity_multiplier = 1;
+       MUTATOR_CALLHOOK(GrappleHookThink, this, tarzan, pull_entity, velocity_multiplier);
+       tarzan = M_ARGV(1, int);
+       pull_entity = M_ARGV(2, entity);
+       velocity_multiplier = M_ARGV(3, float);
+
+       if(this.state == 1)
+       {
+               pullspeed = autocvar_g_balance_grapplehook_speed_pull;//2000;
+               // speed the rope is pulled with
+
+               rubberforce = autocvar_g_balance_grapplehook_force_rubber;//2000;
+               // force the rope will use if it is stretched
+
+               rubberforce_overstretch = autocvar_g_balance_grapplehook_force_rubber_overstretch;//1000;
+               // force the rope will use if it is stretched
+
+               minlength = autocvar_g_balance_grapplehook_length_min;//100;
+               // minimal rope length
+               // if the rope goes below this length, it isn't pulled any more
+
+               ropestretch = autocvar_g_balance_grapplehook_stretch;//400;
+               // if the rope is stretched by more than this amount, more rope is
+               // given to you again
+
+               ropeairfriction = autocvar_g_balance_grapplehook_airfriction;//0.2
+               // while hanging on the rope, this friction component will help you a
+               // bit to control the rope
+
+               bool frozen_pulling = (autocvar_g_grappling_hook_tarzan >= 2 && autocvar_g_balance_grapplehook_pull_frozen);
+
+               dir = this.origin - myorg;
+               dist = vlen(dir);
+               dir = normalize(dir);
+
+               if(tarzan)
+               {
+                       v = v0 = WarpZone_RefSys_TransformVelocity(pull_entity, this, pull_entity.velocity);
+
+                       // first pull the rope...
+                       if(this.realowner.(weaponentity).hook_state & HOOK_PULLING)
+                       {
+                               newlength = this.hook_length;
+                               newlength = max(newlength - pullspeed * frametime, minlength);
+
+                               if(newlength < dist - ropestretch) // overstretched?
+                               {
+                                       newlength = dist - ropestretch;
+                                       if(v * dir < 0) // only if not already moving in hook direction
+                                               v = v + frametime * dir * rubberforce_overstretch;
+                               }
+
+                               this.hook_length = newlength;
+                       }
+
+                       if(pull_entity.move_movetype == MOVETYPE_FLY)
+                               set_movetype(pull_entity, MOVETYPE_WALK);
+
+                       if(this.realowner.(weaponentity).hook_state & HOOK_RELEASING)
+                       {
+                               newlength = dist;
+                               this.hook_length = newlength;
+                       }
+                       else
+                       {
+                               // then pull the player
+                               spd = bound(0, (dist - this.hook_length) / ropestretch, 1);
+                               v = v * (1 - frametime * ropeairfriction);
+                               v = v + frametime * dir * spd * rubberforce;
+
+                               dv = ((v - v0) * dir) * dir;
+                               if(tarzan >= 2)
+                               {
+                                       if(this.aiment.move_movetype == MOVETYPE_WALK || this.aiment.classname == "nade")
+                                       {
+                                               entity aim_ent = ((IS_VEHICLE(this.aiment) && this.aiment.owner) ? this.aiment.owner : this.aiment);
+                                               v = v - dv * 0.5;
+                                               if((frozen_pulling && STAT(FROZEN, this.aiment)) || !frozen_pulling)
+                                               {
+                                                       this.aiment.velocity = this.aiment.velocity - dv * 0.5;
+                                                       UNSET_ONGROUND(this.aiment);
+                                                       if(this.aiment.flags & FL_PROJECTILE)
+                                                               UpdateCSQCProjectile(this.aiment);
+                                               }
+                                               if(this.aiment.classname == "nade")
+                                                       this.aiment.nextthink = time + autocvar_g_balance_grapplehook_nade_time; // set time after letting go?
+                                               aim_ent.pusher = this.realowner;
+                                               aim_ent.pushltime = time + autocvar_g_maxpushtime;
+                                               aim_ent.istypefrag = PHYS_INPUT_BUTTON_CHAT(aim_ent);
+                                       }
+                               }
+
+                               UNSET_ONGROUND(pull_entity);
+                       }
+
+                       if(!frozen_pulling && !(this.aiment.flags & FL_PROJECTILE))
+                               pull_entity.velocity = WarpZone_RefSys_TransformVelocity(this, pull_entity, v * velocity_multiplier);
+
+                       if(frozen_pulling && autocvar_g_balance_grapplehook_pull_frozen == 2 && !STAT(FROZEN, this.aiment))
+                       {
+                               RemoveHook(this);
+                               return;
+                       }
+               }
+               else
+               {
+                       end = this.origin - dir*50;
+                       dist = vlen(end - myorg);
+                       if(dist < 200)
+                               spd = dist * (pullspeed / 200);
+                       else
+                               spd = pullspeed;
+                       if(spd < 50)
+                               spd = 0;
+                       this.realowner.velocity = dir*spd;
+                       set_movetype(this.realowner, MOVETYPE_FLY);
+
+                       UNSET_ONGROUND(this.realowner);
+               }
+       }
+
+       makevectors(this.angles.x * '-1 0 0' + this.angles.y * '0 1 0');
+       myorg = WarpZone_RefSys_TransformOrigin(this, this.realowner, this.origin); // + v_forward * (-9);
+
+       if(myorg != this.hook_start)
+       {
+               this.SendFlags |= 2;
+               this.hook_start = myorg;
+       }
+       if(org != this.hook_end)
+       {
+               this.SendFlags |= 4;
+               this.hook_end = org;
+       }
+}
+
+void GrapplingHookTouch(entity this, entity toucher)
+{
+       if(toucher.move_movetype == MOVETYPE_FOLLOW)
+               return;
+       PROJECTILE_TOUCH(this, toucher);
+
+       GrapplingHook_Stop(this);
+
+       if(toucher)
+               //if(toucher.move_movetype != MOVETYPE_NONE)
+               {
+                       SetMovetypeFollow(this, toucher);
+                       WarpZone_RefSys_BeginAddingIncrementally(this, this.aiment);
+               }
+
+       //this.realowner.disableclientprediction = true;
+}
+
+void GrapplingHook_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
+{
+       if(GetResource(this, RES_HEALTH) <= 0)
+               return;
+
+       if (!W_CheckProjectileDamage(inflictor.realowner, this.realowner, deathtype, -1)) // no exceptions
+               return; // g_balance_projectiledamage says to halt
+
+       TakeResource(this, RES_HEALTH, damage);
+
+       if (GetResource(this, RES_HEALTH) <= 0)
+       {
+               if(attacker != this.realowner)
+               {
+                       this.realowner.pusher = attacker;
+                       this.realowner.pushltime = time + autocvar_g_maxpushtime;
+                       this.realowner.istypefrag = PHYS_INPUT_BUTTON_CHAT(this.realowner);
+               }
+               RemoveHook(this);
+       }
+}
+
+void FireGrapplingHook(entity actor, .entity weaponentity)
+{
+       if(weaponLocked(actor)) return;
+       if(actor.vehicle) return;
+
+       int s = W_GunAlign(actor.(weaponentity), STAT(GUNALIGN, actor)) - 1;
+       vector vs = hook_shotorigin[s];
+       vector oldmovedir = actor.(weaponentity).movedir;
+       actor.(weaponentity).movedir = vs;
+       W_SetupShot_ProjectileSize(actor, weaponentity, '-3 -3 -3', '3 3 3', true, 0, SND_HOOK_FIRE, CH_WEAPON_B, 0, WEP_HOOK.m_id);
+       W_MuzzleFlash(WEP_HOOK, actor, weaponentity, w_shotorg, '0 0 0');
+       actor.(weaponentity).movedir = oldmovedir;
+
+       entity missile = WarpZone_RefSys_SpawnSameRefSys(actor);
+       missile.owner = missile.realowner = actor;
+       actor.(weaponentity).hook = missile;
+       missile.weaponentity_fld = weaponentity;
+       missile.reset = GrapplingHookReset;
+       missile.classname = "grapplinghook";
+       missile.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, missile);
+       IL_PUSH(g_bot_dodge, missile);
+
+       set_movetype(missile, ((autocvar_g_balance_grapplehook_gravity) ? MOVETYPE_TOSS : MOVETYPE_FLY));
+       PROJECTILE_MAKETRIGGER(missile);
+
+       //setmodel (missile, MDL_HOOK); // precision set below
+       setsize (missile, '-3 -3 -3', '3 3 3');
+       setorigin(missile, w_shotorg);
+
+       missile.state = 0; // not latched onto anything
+
+       W_SetupProjVelocity_Explicit(missile, w_shotdir, v_up, autocvar_g_balance_grapplehook_speed_fly, 0, 0, 0, false);
+
+       missile.angles = vectoangles (missile.velocity);
+       //missile.glow_color = 250; // 244, 250
+       //missile.glow_size = 120;
+       settouch(missile, GrapplingHookTouch);
+       setthink(missile, GrapplingHookThink);
+       missile.nextthink = time;
+
+       missile.effects = /*EF_FULLBRIGHT | EF_ADDITIVE |*/ EF_LOWPRECISION;
+
+       SetResourceExplicit(missile, RES_HEALTH, autocvar_g_balance_grapplehook_health);
+       missile.event_damage = GrapplingHook_Damage;
+       missile.takedamage = DAMAGE_AIM;
+       missile.damageforcescale = 0;
+       missile.damagedbycontents = (autocvar_g_balance_grapplehook_damagedbycontents);
+       if(missile.damagedbycontents)
+               IL_PUSH(g_damagedbycontents, missile);
+
+       missile.hook_start = missile.hook_end = missile.origin;
+
+       Net_LinkEntity(missile, false, 0, GrapplingHookSend);
+}
+
+void GrappleHookInit()
+{
+       if(g_grappling_hook)
+       {
+               hook_shotorigin[0] = '8 8 -12';
+               hook_shotorigin[1] = '8 8 -12';
+               hook_shotorigin[2] = '8 8 -12';
+               hook_shotorigin[3] = '8 8 -12';
+       }
+       else
+       {
+               Weapon w = WEP_HOOK;
+               w.wr_init(w);
+               hook_shotorigin[0] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_HOOK.m_id), false, false, 1);
+               hook_shotorigin[1] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_HOOK.m_id), false, false, 2);
+               hook_shotorigin[2] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_HOOK.m_id), false, false, 3);
+               hook_shotorigin[3] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_HOOK.m_id), false, false, 4);
+       }
+}
diff --git a/qcsrc/server/hook.qh b/qcsrc/server/hook.qh
new file mode 100644 (file)
index 0000000..1ed78e2
--- /dev/null
@@ -0,0 +1,23 @@
+#pragma once
+
+// Wazat's grappling hook
+.entity                hook;
+void GrapplingHookThink(entity this);
+void RemoveGrapplingHooks(entity pl);
+void RemoveHook(entity this);
+// (note: you can change the hook impulse #'s to whatever you please)
+.float hook_time;
+
+.float hook_length;
+
+const float HOOK_FIRING = BIT(0);
+const float HOOK_REMOVING = BIT(1);
+const float HOOK_PULLING = BIT(2);
+const float HOOK_RELEASING = BIT(3);
+const float HOOK_WAITING_FOR_RELEASE = BIT(4);
+.float hook_state;
+.int state;
+
+void GrappleHookInit();
+vector hook_shotorigin[4];
+
index 090b239cc8c839ddddc8034d9f44ada102eac031..779384d70c08747fe6e29c13fa6c4ccec2644721 100644 (file)
@@ -4,7 +4,9 @@
 #include "weapons/throwing.qh"
 #include "command/common.qh"
 #include "cheats.qh"
+#include "client.qh"
 #include "clientkill.qh"
+#include "damage.qh"
 #include "weapons/selection.qh"
 #include "weapons/tracing.qh"
 #include "weapons/weaponsystem.qh"
@@ -322,13 +324,19 @@ IMPULSE(weapon_drop)
 {
        if (this.vehicle) return;
        if (IS_DEAD(this)) return;
+       bool is_dualwielding = W_DualWielding(this);
        for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
        {
                .entity weaponentity = weaponentities[slot];
-               W_ThrowWeapon(this, weaponentity, W_CalculateProjectileVelocity(this, this.velocity, v_forward * 750, false), '0 0 0', true);
-
-               if(autocvar_g_weaponswitch_debug != 1)
-                       break;
+               vector md = this.(weaponentity).movedir;
+               vector vecs = ((md.x > 0) ? md : '0 0 0');
+               vector dv = v_right * -vecs.y;
+               if(!is_dualwielding)
+                       dv = '0 0 0'; // don't override!
+               W_ThrowWeapon(this, weaponentity, W_CalculateProjectileVelocity(this, this.velocity, v_forward * 750, false), dv, true);
+
+               if(autocvar_g_weaponswitch_debug == 2)
+                       break; // in this mode, the off-hand weapon is selected based on the primary weapon, don't drop it twice!
        }
 }
 
index a7786f6b660eac467b1d7ea689dfb0f4dac98f92..bb19b0c701bca4273b1a7cf5f70fd4035761a3eb 100644 (file)
@@ -1,10 +1,10 @@
 #include "ipban.qh"
 
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 #include <server/miscfunctions.qh>
 #include "autocvars.qh"
 #include "command/banning.qh"
-#include "defs.qh"
 #include "../common/constants.qh"
 #include "../common/util.qh"
 
diff --git a/qcsrc/server/items.qc b/qcsrc/server/items.qc
deleted file mode 100644 (file)
index ab53a10..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-#include "items.qh"
-
-/// \file
-/// \brief Source file that contains implementation of the functions related to
-/// game items.
-/// \copyright GNU GPLv2 or any later version.
-
-#include <server/mutators/_mod.qh>
-#include <common/weapons/all.qh>
-#include <common/mapobjects/subs.qh>
-
-.bool m_isloot; ///< Holds whether item is loot.
-/// \brief Holds whether strength, shield or superweapon timers expire while
-/// this item is on the ground.
-.bool m_isexpiring;
-
-entity Item_FindDefinition(string class_name)
-{
-       FOREACH(Items, it.m_canonical_spawnfunc == class_name,
-       {
-               return it;
-       });
-       FOREACH(Weapons, it.m_canonical_spawnfunc == class_name,
-       {
-               return it.m_pickup;
-       });
-       return NULL;
-}
-
-bool Item_IsAllowed(string class_name)
-{
-       entity definition = Item_FindDefinition(class_name);
-       if (definition == NULL)
-       {
-               return false;
-       }
-       return Item_IsDefinitionAllowed(definition);
-}
-
-bool Item_IsDefinitionAllowed(entity definition)
-{
-       return !MUTATOR_CALLHOOK(FilterItemDefinition, definition);
-}
-
-entity Item_Create(string class_name, vector position, bool no_align)
-{
-       entity item = spawn();
-       item.classname = class_name;
-       item.spawnfunc_checked = true;
-       setorigin(item, position);
-       item.noalign = no_align;
-       Item_Initialize(item, class_name);
-       if (wasfreed(item))
-       {
-               return NULL;
-       }
-       return item;
-}
-
-void Item_Initialize(entity item, string class_name)
-{
-       FOREACH(Weapons, it.m_canonical_spawnfunc == class_name,
-       {
-               weapon_defaultspawnfunc(item, it);
-               return;
-       });
-       FOREACH(Items, it.m_canonical_spawnfunc == class_name,
-       {
-               StartItem(item, it);
-               return;
-       });
-       LOG_FATALF("Item_Initialize: Invalid classname: %s", class_name);
-}
-
-entity Item_CreateLoot(string class_name, vector position, vector vel,
-       float time_to_live)
-{
-       entity item = spawn();
-       if (!Item_InitializeLoot(item, class_name, position, vel, time_to_live))
-       {
-               return NULL;
-       }
-       return item;
-}
-
-bool Item_InitializeLoot(entity item, string class_name, vector position,
-       vector vel, float time_to_live)
-{
-       item.classname = class_name;
-       Item_SetLoot(item, true);
-       item.noalign = true;
-       setorigin(item, position);
-       item.pickup_anyway = true;
-       item.spawnfunc_checked = true;
-       Item_Initialize(item, class_name);
-       if (wasfreed(item))
-       {
-               return false;
-       }
-       item.gravity = 1;
-       item.velocity = vel;
-       SUB_SetFade(item, time + time_to_live, 1);
-       return true;
-}
-
-bool Item_IsLoot(entity item)
-{
-       return item.m_isloot || item.classname == "droppedweapon";
-}
-
-void Item_SetLoot(entity item, bool loot)
-{
-       item.m_isloot = loot;
-}
-
-bool Item_ShouldKeepPosition(entity item)
-{
-       return item.noalign || (item.spawnflags & 1);
-}
-
-bool Item_IsExpiring(entity item)
-{
-       return item.m_isexpiring;
-}
-
-void Item_SetExpiring(entity item, bool expiring)
-{
-       item.m_isexpiring = expiring;
-}
-
-// Compatibility spawn functions
-
-// FIXME: in Quake this is green armor, in Xonotic maps it is an armor shard
-SPAWNFUNC_ITEM(item_armor1, ITEM_ArmorSmall)
-
-SPAWNFUNC_ITEM(item_armor25, ITEM_ArmorMega)
-
-SPAWNFUNC_ITEM(item_armor_large, ITEM_ArmorMega)
-
-SPAWNFUNC_ITEM(item_health1, ITEM_HealthSmall)
-
-SPAWNFUNC_ITEM(item_health25, ITEM_HealthMedium)
-
-SPAWNFUNC_ITEM(item_health_large, ITEM_HealthBig)
-
-SPAWNFUNC_ITEM(item_health100, ITEM_HealthMega)
-
-SPAWNFUNC_ITEM(item_quad, ITEM_Strength)
diff --git a/qcsrc/server/items.qh b/qcsrc/server/items.qh
deleted file mode 100644 (file)
index b52449e..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-#pragma once
-
-/// \file
-/// \brief Header file that describes the functions related to game items.
-/// \copyright GNU GPLv2 or any later version.
-
-bool startitem_failed;
-
-/// \brief Returns the item definition corresponding to the given class name.
-/// \param[in] class_name Class name to search for.
-/// \return Item definition corresponding to the given class name or NULL is not
-/// found.
-entity Item_FindDefinition(string class_name);
-
-/// \brief Checks whether the items with the specified class name are allowed to
-/// spawn.
-/// \param[in] class_name Item class name to check.
-/// \return True items with the specified class name are allowed to spawn, false
-/// otherwise.
-bool Item_IsAllowed(string class_name);
-
-/// \brief Checks whether the items with the specified definition are allowed to
-/// spawn.
-/// \param[in] definition Item definition to check.
-/// \return True items with the specified definition are allowed to spawn, false
-/// otherwise.
-bool Item_IsDefinitionAllowed(entity definition);
-
-/// \brief Creates a new item.
-/// \param[in] class_name Class name of the item.
-/// \param[in] position Position of the item.
-/// \param[in] no_align True if item should be placed directly at specified
-/// position, false to let it drop to the ground.
-/// \return Item on success, NULL otherwise.
-entity Item_Create(string class_name, vector position, bool no_align);
-
-/// \brief Initializes the item according to class name.
-/// \param[in,out] item Item to initialize.
-/// \param[in] class_name Class name to use.
-/// \return No return.
-/// \nore This function is useful if you want to set some item properties before
-/// initialization.
-void Item_Initialize(entity item, string class_name);
-
-/// \brief Creates a loot item.
-/// \param[in] class_name Class name of the item.
-/// \param[in] position Position of the item.
-/// \param[in] velocity of the item.
-/// \param[in] time_to_live Amount of time after which the item will disappear.
-/// \return Item on success, NULL otherwise.
-entity Item_CreateLoot(string class_name, vector position, vector vel,
-       float time_to_live);
-
-/// \brief Initializes the loot item.
-/// \param[in] class_name Class name of the item.
-/// \param[in] position Position of the item.
-/// \param[in] velocity of the item.
-/// \param[in] time_to_live Amount of time after which the item will disappear.
-/// \return True on success, false otherwise.
-/// \nore This function is useful if you want to set some item properties before
-/// initialization.
-bool Item_InitializeLoot(entity item, string class_name, vector position,
-       vector vel, float time_to_live);
-
-/// \brief Returns whether the item is loot.
-/// \param[in] item Item to check.
-/// \return True if the item is loot, false otherwise.
-bool Item_IsLoot(entity item);
-
-/// \brief Sets the item loot status.
-/// \param[in,out] item Item to adjust.
-/// \param[in] loot Whether item is loot.
-/// \return No return.
-void Item_SetLoot(entity item, bool loot);
-
-/// \brief Returns whether item should keep its position or be dropped to the
-/// ground.
-/// \param[in] item Item to check.
-/// \return True if item should keep its position or false if it should be
-/// dropped to the ground.
-bool Item_ShouldKeepPosition(entity item);
-
-/// \brief Returns whether the item is expiring (i.e. its strength, shield and
-/// superweapon timers expire while it is on the ground).
-/// \param[in] item Item to check.
-/// \return True if the item is expiring, false otherwise.
-bool Item_IsExpiring(entity item);
-
-/// \brief Sets the item expiring status (i.e. whether its strength, shield
-/// and superweapon timers expire while it is on the ground).
-/// \param[in,out] item Item to adjust.
-/// \param[in] expiring Whether item is expiring.
-/// \return No return.
-void Item_SetExpiring(entity item, bool expiring);
diff --git a/qcsrc/server/items/_mod.inc b/qcsrc/server/items/_mod.inc
new file mode 100644 (file)
index 0000000..33936e2
--- /dev/null
@@ -0,0 +1,3 @@
+// generated file; do not modify
+#include <server/items/items.qc>
+#include <server/items/spawning.qc>
diff --git a/qcsrc/server/items/_mod.qh b/qcsrc/server/items/_mod.qh
new file mode 100644 (file)
index 0000000..d64b2c0
--- /dev/null
@@ -0,0 +1,3 @@
+// generated file; do not modify
+#include <server/items/items.qh>
+#include <server/items/spawning.qh>
diff --git a/qcsrc/server/items/items.qc b/qcsrc/server/items/items.qc
new file mode 100644 (file)
index 0000000..861b21e
--- /dev/null
@@ -0,0 +1,1651 @@
+#include "items.qh"
+
+#include <common/items/_mod.qh>
+
+#include <server/bot/api.qh>
+
+#include <server/command/vote.qh>
+
+#include <server/damage.qh>
+
+#include <server/mutators/_mod.qh>
+
+#include <server/teamplay.qh>
+
+#include <server/weapons/common.qh>
+#include <server/weapons/selection.qh>
+#include <server/weapons/weaponsystem.qh>
+
+#include <common/constants.qh>
+#include <common/deathtypes/all.qh>
+#include <common/notifications/all.qh>
+#include <common/mapobjects/subs.qh>
+#include <common/mapobjects/triggers.qh>
+#include <common/util.qh>
+
+#include <common/monsters/_mod.qh>
+
+#include <common/wepent.qh>
+#include <common/weapons/_all.qh>
+
+#include <common/mutators/mutator/buffs/buffs.qh>
+#include <common/mutators/mutator/buffs/sv_buffs.qh>
+
+#include <lib/warpzone/util_server.qh>
+
+bool ItemSend(entity this, entity to, int sf)
+{
+       if(this.gravity)
+               sf |= ISF_DROP;
+       else
+               sf &= ~ISF_DROP;
+
+       WriteHeader(MSG_ENTITY, ENT_CLIENT_ITEM);
+       WriteByte(MSG_ENTITY, sf);
+
+       //WriteByte(MSG_ENTITY, this.cnt);
+       if(sf & ISF_LOCATION)
+       {
+               WriteVector(MSG_ENTITY, this.origin);
+       }
+
+       if(sf & ISF_ANGLES)
+       {
+               WriteAngleVector(MSG_ENTITY, this.angles);
+       }
+
+       // sets size on the client, unused on server
+       //if(sf & ISF_SIZE)
+
+       if(sf & ISF_STATUS)
+               WriteByte(MSG_ENTITY, this.ItemStatus);
+
+       if(sf & ISF_MODEL)
+       {
+               WriteShort(MSG_ENTITY, this.fade_end);
+               WriteShort(MSG_ENTITY, this.fade_start);
+
+               if(this.mdl == "")
+                       LOG_TRACE("^1WARNING!^7 this.mdl is unset for item ", this.classname, "expect a crash just about now");
+
+               WriteString(MSG_ENTITY, this.mdl);
+       }
+
+
+       if(sf & ISF_COLORMAP)
+       {
+               WriteShort(MSG_ENTITY, this.colormap);
+               WriteByte(MSG_ENTITY, this.glowmod.x * 255.0);
+               WriteByte(MSG_ENTITY, this.glowmod.y * 255.0);
+               WriteByte(MSG_ENTITY, this.glowmod.z * 255.0);
+       }
+
+       if(sf & ISF_DROP)
+       {
+               WriteVector(MSG_ENTITY, this.velocity);
+       }
+
+       return true;
+}
+
+void ItemUpdate(entity this)
+{
+       this.oldorigin = this.origin;
+       this.SendFlags |= ISF_LOCATION;
+}
+
+void UpdateItemAfterTeleport(entity this)
+{
+       if(getSendEntity(this) == ItemSend)
+               ItemUpdate(this);
+}
+
+bool have_pickup_item(entity this)
+{
+       if(this.itemdef.instanceOfPowerup)
+       {
+               if(autocvar_g_powerups > 0)
+                       return true;
+               if(autocvar_g_powerups == 0)
+                       return false;
+       }
+       else
+       {
+               if(autocvar_g_pickup_items > 0)
+                       return true;
+               if(autocvar_g_pickup_items == 0)
+                       return false;
+               if(g_weaponarena)
+                       if(STAT(WEAPONS, this) || this.itemdef.instanceOfAmmo) // no item or ammo pickups in weaponarena
+                               return false;
+       }
+       return true;
+}
+
+void Item_Show(entity e, int mode)
+{
+       e.effects &= ~(EF_ADDITIVE | EF_STARDUST | EF_FULLBRIGHT | EF_NODEPTHTEST);
+       e.ItemStatus &= ~ITS_STAYWEP;
+       entity def = e.itemdef;
+       if (mode > 0)
+       {
+               // make the item look normal, and be touchable
+               e.model = e.mdl;
+               e.solid = SOLID_TRIGGER;
+               e.spawnshieldtime = 1;
+               e.ItemStatus |= ITS_AVAILABLE;
+       }
+       else if (mode < 0)
+       {
+               // hide the item completely
+               e.model = string_null;
+               e.solid = SOLID_NOT;
+               e.spawnshieldtime = 1;
+               e.ItemStatus &= ~ITS_AVAILABLE;
+       }
+       else
+       {
+               bool nostay = def.instanceOfWeaponPickup ? !!(def.m_weapon.m_wepset & WEPSET_SUPERWEAPONS) : false // no weapon-stay on superweapons
+                       || e.team // weapon stay isn't supported for teamed weapons
+                       ;
+               if(def.instanceOfWeaponPickup && !nostay && g_weapon_stay)
+               {
+                       // make the item translucent and not touchable
+                       e.model = e.mdl;
+                       e.solid = SOLID_TRIGGER; // can STILL be picked up!
+                       e.effects |= EF_STARDUST;
+                       e.spawnshieldtime = 0; // field indicates whether picking it up may give you anything other than the weapon
+                       e.ItemStatus |= (ITS_AVAILABLE | ITS_STAYWEP);
+               }
+               else
+               {
+                       //setmodel(e, "null");
+                       e.solid = SOLID_NOT;
+                       e.colormod = '0 0 0';
+                       //e.glowmod = e.colormod;
+                       e.spawnshieldtime = 1;
+                       e.ItemStatus &= ~ITS_AVAILABLE;
+               }
+       }
+
+       if (def.m_glow)
+               e.ItemStatus |= ITS_GLOW;
+
+       if (autocvar_g_nodepthtestitems)
+               e.effects |= EF_NODEPTHTEST;
+
+       if (autocvar_g_fullbrightitems)
+               e.ItemStatus |= ITS_ALLOWFB;
+       else
+               e.ItemStatus &= ~ITS_ALLOWFB;
+
+       if (autocvar_sv_simple_items)
+               e.ItemStatus |= ITS_ALLOWSI;
+
+       // relink entity (because solid may have changed)
+       setorigin(e, e.origin);
+       e.SendFlags |= ISF_STATUS;
+}
+
+void Item_Think(entity this)
+{
+       this.nextthink = time;
+       if(this.origin != this.oldorigin)
+               ItemUpdate(this);
+}
+
+bool Item_ItemsTime_SpectatorOnly(GameItem it);
+bool Item_ItemsTime_Allow(GameItem it);
+float Item_ItemsTime_UpdateTime(entity e, float t);
+void Item_ItemsTime_SetTime(entity e, float t);
+void Item_ItemsTime_SetTimesForAllPlayers();
+
+void Item_Respawn(entity this)
+{
+       Item_Show(this, 1);
+       sound(this, CH_TRIGGER, this.itemdef.m_respawnsound, VOL_BASE, ATTEN_NORM);     // play respawn sound
+       setorigin(this, this.origin);
+
+       if (Item_ItemsTime_Allow(this.itemdef) || (STAT(WEAPONS, this) & WEPSET_SUPERWEAPONS))
+       {
+               float t = Item_ItemsTime_UpdateTime(this, 0);
+               Item_ItemsTime_SetTime(this, t);
+               Item_ItemsTime_SetTimesForAllPlayers();
+       }
+
+       setthink(this, Item_Think);
+       this.nextthink = time;
+
+       //Send_Effect(EFFECT_ITEM_RESPAWN, this.origin + this.mins_z * '0 0 1' + '0 0 48', '0 0 0', 1);
+       Send_Effect(EFFECT_ITEM_RESPAWN, CENTER_OR_VIEWOFS(this), '0 0 0', 1);
+}
+
+void Item_RespawnCountdown(entity this)
+{
+       if(this.item_respawncounter >= ITEM_RESPAWN_TICKS)
+       {
+               if(this.waypointsprite_attached)
+                       WaypointSprite_Kill(this.waypointsprite_attached);
+               Item_Respawn(this);
+       }
+       else
+       {
+               this.nextthink = time + 1;
+               this.item_respawncounter += 1;
+               if(this.item_respawncounter == 1)
+               {
+                       do {
+                               {
+                                       entity wi = REGISTRY_GET(Weapons, this.weapon);
+                                       if (wi != WEP_Null) {
+                                               entity wp = WaypointSprite_Spawn(WP_Weapon, 0, 0, this, '0 0 64', NULL, 0, this, waypointsprite_attached, true, RADARICON_Weapon);
+                                               wp.wp_extra = wi.m_id;
+                                               break;
+                                       }
+                               }
+                               {
+                                       entity ii = this.itemdef;
+                                       if (ii != NULL) {
+                                               entity wp = WaypointSprite_Spawn(WP_Item, 0, 0, this, '0 0 64', NULL, 0, this, waypointsprite_attached, true, RADARICON_Item);
+                                               wp.wp_extra = ii.m_id;
+                                               break;
+                                       }
+                               }
+                       } while (0);
+                       bool mutator_returnvalue = MUTATOR_CALLHOOK(Item_RespawnCountdown, this);
+            if(this.waypointsprite_attached)
+            {
+                GameItem def = this.itemdef;
+                if (Item_ItemsTime_SpectatorOnly(def) && !mutator_returnvalue)
+                    WaypointSprite_UpdateRule(this.waypointsprite_attached, 0, SPRITERULE_SPECTATOR);
+                WaypointSprite_UpdateBuildFinished(this.waypointsprite_attached, time + ITEM_RESPAWN_TICKS);
+            }
+               }
+
+               if(this.waypointsprite_attached)
+               {
+                       FOREACH_CLIENT(IS_REAL_CLIENT(it), {
+                               if(this.waypointsprite_attached.waypointsprite_visible_for_player(this.waypointsprite_attached, it, it))
+                               {
+                                       msg_entity = it;
+                                       soundto(MSG_ONE, this, CH_TRIGGER, SND(ITEMRESPAWNCOUNTDOWN), VOL_BASE, ATTEN_NORM, 0); // play respawn sound
+                               }
+                       });
+
+                       WaypointSprite_Ping(this.waypointsprite_attached);
+                       //WaypointSprite_UpdateHealth(this.waypointsprite_attached, this.item_respawncounter);
+               }
+       }
+}
+
+void Item_RespawnThink(entity this)
+{
+       this.nextthink = time;
+       if(this.origin != this.oldorigin)
+               ItemUpdate(this);
+
+       if(time >= this.wait)
+               Item_Respawn(this);
+}
+
+void Item_ScheduleRespawnIn(entity e, float t)
+{
+       // if the respawn time is longer than 10 seconds, show a waypoint, otherwise, just respawn normally
+       if ((Item_ItemsTime_Allow(e.itemdef) || (STAT(WEAPONS, e) & WEPSET_SUPERWEAPONS) || MUTATOR_CALLHOOK(Item_ScheduleRespawn, e, t)) && (t - ITEM_RESPAWN_TICKS) > 0)
+       {
+               setthink(e, Item_RespawnCountdown);
+               e.nextthink = time + max(0, t - ITEM_RESPAWN_TICKS);
+               e.scheduledrespawntime = e.nextthink + ITEM_RESPAWN_TICKS;
+               e.item_respawncounter = 0;
+               if(Item_ItemsTime_Allow(e.itemdef) || (STAT(WEAPONS, e) & WEPSET_SUPERWEAPONS))
+               {
+                       t = Item_ItemsTime_UpdateTime(e, e.scheduledrespawntime);
+                       Item_ItemsTime_SetTime(e, t);
+                       Item_ItemsTime_SetTimesForAllPlayers();
+               }
+       }
+       else
+       {
+               setthink(e, Item_RespawnThink);
+               e.nextthink = time;
+               e.scheduledrespawntime = time + t;
+               e.wait = time + t;
+
+               if(Item_ItemsTime_Allow(e.itemdef) || (STAT(WEAPONS, e) & WEPSET_SUPERWEAPONS))
+               {
+                       t = Item_ItemsTime_UpdateTime(e, e.scheduledrespawntime);
+                       Item_ItemsTime_SetTime(e, t);
+                       Item_ItemsTime_SetTimesForAllPlayers();
+               }
+       }
+}
+
+AUTOCVAR(g_pickup_respawntime_scaling_reciprocal, float, 0.0, "Multiply respawn time by `reciprocal / (p + offset) + linear` where `p` is the current number of players, takes effect with 2 or more players present, `reciprocal` (with `offset` and `linear` set to 0) can be used to achieve a constant number of items spawned *per player*");
+AUTOCVAR(g_pickup_respawntime_scaling_offset, float, 0.0, "Multiply respawn time by `reciprocal / (p + offset) + linear` where `p` is the current number of players, takes effect with 2 or more players present, `offset` offsets the curve left or right - the results are not intuitive and I recommend plotting the respawn time and the number of items per player to see what's happening");
+AUTOCVAR(g_pickup_respawntime_scaling_linear, float, 1.0, "Multiply respawn time by `reciprocal / (p + offset) + linear` where `p` is the current number of players, takes effect with 2 or more players present, `linear` can be used to simply scale the respawn time linearly");
+
+/// Adjust respawn time according to the number of players.
+float adjust_respawntime(float normal_respawntime) {
+       float r = autocvar_g_pickup_respawntime_scaling_reciprocal;
+       float o = autocvar_g_pickup_respawntime_scaling_offset;
+       float l = autocvar_g_pickup_respawntime_scaling_linear;
+
+       if (r == 0 && l == 1) {
+               return normal_respawntime;
+       }
+
+       entity balance = TeamBalance_CheckAllowedTeams(NULL);
+       TeamBalance_GetTeamCounts(balance, NULL);
+       int players = 0;
+       for (int i = 1; i <= NUM_TEAMS; ++i)
+       {
+               if (TeamBalance_IsTeamAllowed(balance, i))
+               {
+                       players += TeamBalance_GetNumberOfPlayers(balance, i);
+               }
+       }
+       TeamBalance_Destroy(balance);
+
+       if (players >= 2) {
+               return normal_respawntime * (r / (players + o) + l);
+       } else {
+               return normal_respawntime;
+       }
+}
+
+void Item_ScheduleRespawn(entity e)
+{
+       if(e.respawntime > 0)
+       {
+               Item_Show(e, 0);
+
+               float adjusted_respawntime = adjust_respawntime(e.respawntime);
+               //LOG_INFOF("item %s will respawn in %f", e.classname, adjusted_respawntime);
+
+               // range: adjusted_respawntime - respawntimejitter .. adjusted_respawntime + respawntimejitter
+               float respawn_in = adjusted_respawntime + crandom() * e.respawntimejitter;
+               Item_ScheduleRespawnIn(e, respawn_in);
+       }
+       else // if respawntime is -1, this item does not respawn
+               Item_Show(e, -1);
+}
+
+AUTOCVAR(g_pickup_respawntime_initial_random, int, 1,
+       "For items that don't start spawned: 0: spawn after their normal respawntime; 1: spawn after `random * respawntime` with the *same* random; 2: same as 1 but each item has separate random");
+
+void Item_ScheduleInitialRespawn(entity e)
+{
+       Item_Show(e, 0);
+
+       float spawn_in;
+       if (autocvar_g_pickup_respawntime_initial_random == 0)
+       {
+               // range: respawntime .. respawntime + respawntimejitter
+               spawn_in = e.respawntime + random() * e.respawntimejitter;
+       }
+       else
+       {
+               float rnd;
+               if (autocvar_g_pickup_respawntime_initial_random == 1)
+               {
+                       static float shared_random = 0;
+                       // NOTE this code works only if items are scheduled at the same time (normal case)
+                       // NOTE2 random() can't return exactly 1 so this check always work as intended
+                       if (!shared_random || floor(time) > shared_random)
+                               shared_random = floor(time) + random();
+                       rnd = shared_random - floor(time);
+               }
+               else
+                       rnd = random();
+
+               // range:
+               // if respawntime >= ITEM_RESPAWN_TICKS: ITEM_RESPAWN_TICKS .. respawntime + respawntimejitter
+               // else: 0 .. ITEM_RESPAWN_TICKS
+               // this is to prevent powerups spawning unexpectedly without waypoints
+               spawn_in = ITEM_RESPAWN_TICKS + rnd * (e.respawntime + e.respawntimejitter - ITEM_RESPAWN_TICKS);
+       }
+
+       Item_ScheduleRespawnIn(e, max(0, game_starttime - time) + ((e.respawntimestart) ? e.respawntimestart : spawn_in));
+}
+
+void GiveRandomWeapons(entity receiver, int num_weapons, string weapon_names,
+       entity ammo_entity)
+{
+       if (num_weapons == 0)
+       {
+               return;
+       }
+       int num_potential_weapons = tokenize_console(weapon_names);
+       for (int give_attempt = 0; give_attempt < num_weapons; ++give_attempt)
+       {
+               RandomSelection_Init();
+               for (int weapon_index = 0; weapon_index < num_potential_weapons;
+                       ++weapon_index)
+               {
+                       string weapon = argv(weapon_index);
+                       FOREACH(Weapons, it != WEP_Null,
+                       {
+                               // Finding a weapon which player doesn't have.
+                               if (!(STAT(WEAPONS, receiver) & it.m_wepset) && (it.netname == weapon))
+                               {
+                                       RandomSelection_AddEnt(it, 1, 1);
+                                       break;
+                               }
+                       });
+               }
+               if (RandomSelection_chosen_ent == NULL)
+               {
+                       return;
+               }
+               STAT(WEAPONS, receiver) |= RandomSelection_chosen_ent.m_wepset;
+               if (RandomSelection_chosen_ent.ammo_type == RES_NONE)
+               {
+                       continue;
+               }
+               if (GetResource(receiver,
+                       RandomSelection_chosen_ent.ammo_type) != 0)
+               {
+                       continue;
+               }
+               GiveResource(receiver, RandomSelection_chosen_ent.ammo_type,
+                       GetResource(ammo_entity,
+                       RandomSelection_chosen_ent.ammo_type));
+       }
+}
+
+bool Item_GiveAmmoTo(entity item, entity player, int res_type, float ammomax)
+{
+       float amount = GetResource(item, res_type);
+       if (amount == 0)
+       {
+               return false;
+       }
+       float player_amount = GetResource(player, res_type);
+       if (item.spawnshieldtime)
+       {
+               if ((player_amount >= ammomax) && (item.pickup_anyway <= 0))
+                       return false;
+       }
+       else if (g_weapon_stay == 2)
+       {
+               ammomax = min(amount, ammomax);
+               if(player_amount >= ammomax)
+                       return false;
+       }
+       else
+               return false;
+       if (amount < 0)
+               TakeResourceWithLimit(player, res_type, -amount, ammomax);
+       else
+               GiveResourceWithLimit(player, res_type, amount, ammomax);
+       return true;
+}
+
+bool Item_GiveTo(entity item, entity player)
+{
+       // if nothing happens to player, just return without taking the item
+       int _switchweapon = 0;
+       // in case the player has autoswitch enabled do the following:
+       // if the player is using their best weapon before items are given, they
+       // probably want to switch to an even better weapon after items are given
+
+       if(CS(player).autoswitch)
+       {
+               for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+               {
+                       .entity weaponentity = weaponentities[slot];
+                       if(player.(weaponentity).m_weapon != WEP_Null || slot == 0)
+                       {
+                               if(player.(weaponentity).m_switchweapon == w_getbestweapon(player, weaponentity))
+                                       _switchweapon |= BIT(slot);
+
+                               if(!(STAT(WEAPONS, player) & WepSet_FromWeapon(player.(weaponentity).m_switchweapon)))
+                                       _switchweapon |= BIT(slot);
+                       }
+               }
+       }
+       bool pickedup = false;
+       pickedup |= Item_GiveAmmoTo(item, player, RES_HEALTH, item.max_health);
+       pickedup |= Item_GiveAmmoTo(item, player, RES_ARMOR, item.max_armorvalue);
+       pickedup |= Item_GiveAmmoTo(item, player, RES_SHELLS, g_pickup_shells_max);
+       pickedup |= Item_GiveAmmoTo(item, player, RES_BULLETS, g_pickup_nails_max);
+       pickedup |= Item_GiveAmmoTo(item, player, RES_ROCKETS, g_pickup_rockets_max);
+       pickedup |= Item_GiveAmmoTo(item, player, RES_CELLS, g_pickup_cells_max);
+       pickedup |= Item_GiveAmmoTo(item, player, RES_PLASMA, g_pickup_plasma_max);
+       pickedup |= Item_GiveAmmoTo(item, player, RES_FUEL, g_pickup_fuel_max);
+       if (item.itemdef.instanceOfWeaponPickup)
+       {
+               WepSet w;
+               w = STAT(WEAPONS, item);
+               w &= ~STAT(WEAPONS, player);
+
+               if (w || (item.spawnshieldtime && item.pickup_anyway > 0))
+               {
+                       pickedup = true;
+                       FOREACH(Weapons, it != WEP_Null, {
+                               if(w & (it.m_wepset))
+                               {
+                                       for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+                                       {
+                                               .entity weaponentity = weaponentities[slot];
+                                               if(player.(weaponentity).m_weapon != WEP_Null || slot == 0)
+                                                       W_DropEvent(wr_pickup, player, it.m_id, item, weaponentity);
+                                       }
+                                       W_GiveWeapon(player, it.m_id);
+                               }
+                       });
+               }
+       }
+
+       if (item.itemdef.instanceOfPowerup)
+       {
+               if ((item.itemdef == ITEM_JetpackRegen) && !(player.items & IT_FUEL_REGEN))
+                       Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_ITEM_FUELREGEN_GOT);
+               else if ((item.itemdef == ITEM_Jetpack) && !(player.items & IT_JETPACK))
+                       Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_ITEM_JETPACK_GOT);
+       }
+
+       int its;
+       if((its = (item.items - (item.items & player.items)) & IT_PICKUPMASK))
+       {
+               pickedup = true;
+               player.items |= its;
+               // TODO: we probably want to show a message in the console, but not this one!
+               //Send_Notification(NOTIF_ONE, player, MSG_INFO, INFO_ITEM_WEAPON_GOT, item.netname);
+       }
+
+       if (item.strength_finished)
+       {
+               pickedup = true;
+               STAT(STRENGTH_FINISHED, player) = max(STAT(STRENGTH_FINISHED, player), time) + item.strength_finished;
+       }
+       if (item.invincible_finished)
+       {
+               pickedup = true;
+               STAT(INVINCIBLE_FINISHED, player) = max(STAT(INVINCIBLE_FINISHED, player), time) + item.invincible_finished;
+       }
+       if (item.superweapons_finished)
+       {
+               pickedup = true;
+               STAT(SUPERWEAPONS_FINISHED, player) = max(STAT(SUPERWEAPONS_FINISHED, player), time) + item.superweapons_finished;
+       }
+
+       // always eat teamed entities
+       if(item.team)
+               pickedup = true;
+
+       if (!pickedup)
+               return false;
+
+       // crude hack to enforce switching weapons
+       if(g_cts && item.itemdef.instanceOfWeaponPickup && !CS(player).cvar_cl_cts_noautoswitch)
+       {
+               for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+               {
+                       .entity weaponentity = weaponentities[slot];
+                       if(player.(weaponentity).m_weapon != WEP_Null || slot == 0)
+                               W_SwitchWeapon_Force(player, REGISTRY_GET(Weapons, item.weapon), weaponentity);
+               }
+               return true;
+       }
+
+       if(_switchweapon)
+       {
+               for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+               {
+                       .entity weaponentity = weaponentities[slot];
+                       if(_switchweapon & BIT(slot))
+                       if(player.(weaponentity).m_switchweapon != w_getbestweapon(player, weaponentity))
+                               W_SwitchWeapon_Force(player, w_getbestweapon(player, weaponentity), weaponentity);
+               }
+       }
+
+       return true;
+}
+
+void Item_Touch(entity this, entity toucher)
+{
+       // remove the item if it's currnetly in a NODROP brush or hits a NOIMPACT surface (such as sky)
+       if (Item_IsLoot(this))
+       {
+               if (ITEM_TOUCH_NEEDKILL())
+               {
+                       delete(this);
+                       return;
+               }
+       }
+
+       if(!(toucher.flags & FL_PICKUPITEMS)
+       || STAT(FROZEN, toucher)
+       || IS_DEAD(toucher)
+       || (this.solid != SOLID_TRIGGER)
+       || (this.owner == toucher)
+       || (time < this.item_spawnshieldtime)
+       ) { return; }
+
+       switch (MUTATOR_CALLHOOK(ItemTouch, this, toucher))
+       {
+               case MUT_ITEMTOUCH_RETURN: { return; }
+               case MUT_ITEMTOUCH_PICKUP: { toucher = M_ARGV(1, entity); goto pickup; }
+       }
+
+       toucher = M_ARGV(1, entity);
+
+       if (Item_IsExpiring(this))
+       {
+               this.strength_finished = max(0, this.strength_finished - time);
+               this.invincible_finished = max(0, this.invincible_finished - time);
+               this.superweapons_finished = max(0, this.superweapons_finished - time);
+       }
+       bool gave = ITEM_HANDLE(Pickup, this.itemdef, this, toucher);
+       if (!gave)
+       {
+               if (Item_IsExpiring(this))
+               {
+                       // undo what we did above
+                       this.strength_finished += time;
+                       this.invincible_finished += time;
+                       this.superweapons_finished += time;
+               }
+               return;
+       }
+
+LABEL(pickup)
+
+       if(this.target && this.target != "" && this.target != "###item###") // defrag support
+               SUB_UseTargets(this, toucher, NULL);
+
+       STAT(LAST_PICKUP, toucher) = time;
+
+       Send_Effect(EFFECT_ITEM_PICKUP, CENTER_OR_VIEWOFS(this), '0 0 0', 1);
+       _sound (toucher, (this.itemdef.instanceOfPowerup ? CH_TRIGGER_SINGLE : CH_TRIGGER), (this.item_pickupsound ? this.item_pickupsound : Sound_fixpath(this.item_pickupsound_ent)), VOL_BASE, ATTEN_NORM);
+
+       MUTATOR_CALLHOOK(ItemTouched, this, toucher);
+       if (wasfreed(this))
+       {
+               return;
+       }
+
+       if (Item_IsLoot(this))
+       {
+               delete(this);
+               return;
+       }
+       if (!this.spawnshieldtime)
+       {
+               return;
+       }
+       entity e;
+       if (this.team)
+       {
+               RandomSelection_Init();
+               IL_EACH(g_items, it.team == this.team,
+               {
+                       if (it.itemdef) // is a registered item
+                       {
+                               Item_Show(it, -1);
+                               it.scheduledrespawntime = 0;
+                               RandomSelection_AddEnt(it, it.cnt, 0);
+                       }
+               });
+               e = RandomSelection_chosen_ent;
+               Item_Show(e, 1); // reset its state so it is visible (extra sendflags doesn't matter, this happens anyway)
+       }
+       else
+               e = this;
+       Item_ScheduleRespawn(e);
+}
+
+void Item_Reset(entity this)
+{
+       Item_Show(this, !this.state);
+       setorigin(this, this.origin);
+
+       if (Item_IsLoot(this))
+       {
+               return;
+       }
+       setthink(this, Item_Think);
+       this.nextthink = time;
+       if (this.waypointsprite_attached)
+       {
+               WaypointSprite_Kill(this.waypointsprite_attached);
+       }
+       if (this.itemdef.instanceOfPowerup || (STAT(WEAPONS, this) & WEPSET_SUPERWEAPONS)) // do not spawn powerups initially!
+       {
+               Item_ScheduleInitialRespawn(this);
+       }
+}
+
+void Item_FindTeam(entity this)
+{
+       entity e;
+
+       if(this.effects & EF_NODRAW)
+       {
+               // marker for item team search
+               LOG_TRACE("Initializing item team ", ftos(this.team));
+               RandomSelection_Init();
+               IL_EACH(g_items, it.team == this.team,
+               {
+                       if(it.itemdef) // is a registered item
+                               RandomSelection_AddEnt(it, it.cnt, 0);
+               });
+
+               e = RandomSelection_chosen_ent;
+               if (!e)
+                       return;
+
+               IL_EACH(g_items, it.team == this.team,
+               {
+                       if(it.itemdef) // is a registered item
+                       {
+                               if(it != e)
+                               {
+                                       // make it non-spawned
+                                       Item_Show(it, -1);
+                                       it.state = 1; // state 1 = initially hidden item, apparently
+                               }
+                               else
+                                       Item_Reset(it);
+                               it.effects &= ~EF_NODRAW;
+                       }
+               });
+       }
+}
+
+// Savage: used for item garbage-collection
+void RemoveItem(entity this)
+{
+       if(wasfreed(this) || !this) { return; }
+       Send_Effect(EFFECT_ITEM_PICKUP, CENTER_OR_VIEWOFS(this), '0 0 0', 1);
+       delete(this);
+}
+
+// pickup evaluation functions
+// these functions decide how desirable an item is to the bots
+
+float generic_pickupevalfunc(entity player, entity item) {return item.bot_pickupbasevalue;}
+
+float weapon_pickupevalfunc(entity player, entity item)
+{
+       // See if I have it already
+       if(STAT(WEAPONS, player) & STAT(WEAPONS, item))
+       {
+               // If I can pick it up
+               if(!item.spawnshieldtime)
+                       return 0;
+               return ammo_pickupevalfunc(player, item);
+       }
+
+       // reduce weapon value if bot already got a good arsenal
+       float c = 1;
+       int weapons_value = 0;
+       FOREACH(Weapons, it != WEP_Null && (STAT(WEAPONS, player) & it.m_wepset), {
+               weapons_value += it.bot_pickupbasevalue;
+       });
+       c -= bound(0, weapons_value / 20000, 1) * 0.5;
+
+       return item.bot_pickupbasevalue * c;
+}
+
+float ammo_pickupevalfunc(entity player, entity item)
+{
+       bool need_shells = false, need_nails = false, need_rockets = false, need_cells = false, need_plasma = false, need_fuel = false;
+       entity wpn = NULL;
+       float c = 0;
+       float rating = 0;
+
+       // Detect needed ammo
+       if(item.itemdef.instanceOfWeaponPickup)
+       {
+               entity ammo = NULL;
+               if(GetResource(item, RES_SHELLS))       { need_shells  = true; ammo = ITEM_Shells;      }
+               else if(GetResource(item, RES_BULLETS))   { need_nails   = true; ammo = ITEM_Bullets;     }
+               else if(GetResource(item, RES_ROCKETS)) { need_rockets = true; ammo = ITEM_Rockets;     }
+               else if(GetResource(item, RES_CELLS))   { need_cells   = true; ammo = ITEM_Cells;       }
+               else if(GetResource(item, RES_PLASMA))  { need_plasma  = true; ammo = ITEM_Plasma;      }
+               else if(GetResource(item, RES_FUEL))    { need_fuel    = true; ammo = ITEM_JetpackFuel; }
+
+               if(!ammo)
+                       return 0;
+               wpn = item;
+               rating = ammo.m_botvalue;
+       }
+       else
+       {
+               FOREACH(Weapons, it != WEP_Null, {
+                       if(!(STAT(WEAPONS, player) & (it.m_wepset)))
+                               continue;
+
+                       switch(it.ammo_type)
+                       {
+                               case RES_SHELLS:  need_shells  = true; break;
+                               case RES_BULLETS: need_nails   = true; break;
+                               case RES_ROCKETS: need_rockets = true; break;
+                               case RES_CELLS:   need_cells   = true; break;
+                               case RES_PLASMA:  need_plasma  = true; break;
+                               case RES_FUEL:    need_fuel    = true; break;
+                       }
+               });
+               rating = item.bot_pickupbasevalue;
+       }
+
+       float noammorating = 0.5;
+
+       if ((need_shells) && GetResource(item, RES_SHELLS) && (GetResource(player, RES_SHELLS) < g_pickup_shells_max))
+               c = GetResource(item, RES_SHELLS) / max(noammorating, GetResource(player, RES_SHELLS));
+
+       if ((need_nails) && GetResource(item, RES_BULLETS) && (GetResource(player, RES_BULLETS) < g_pickup_nails_max))
+               c = GetResource(item, RES_BULLETS) / max(noammorating, GetResource(player, RES_BULLETS));
+
+       if ((need_rockets) && GetResource(item, RES_ROCKETS) && (GetResource(player, RES_ROCKETS) < g_pickup_rockets_max))
+               c = GetResource(item, RES_ROCKETS) / max(noammorating, GetResource(player, RES_ROCKETS));
+
+       if ((need_cells) && GetResource(item, RES_CELLS) && (GetResource(player, RES_CELLS) < g_pickup_cells_max))
+               c = GetResource(item, RES_CELLS) / max(noammorating, GetResource(player, RES_CELLS));
+
+       if ((need_plasma) && GetResource(item, RES_PLASMA) && (GetResource(player, RES_PLASMA) < g_pickup_plasma_max))
+               c = GetResource(item, RES_PLASMA) / max(noammorating, GetResource(player, RES_PLASMA));
+
+       if ((need_fuel) && GetResource(item, RES_FUEL) && (GetResource(player, RES_FUEL) < g_pickup_fuel_max))
+               c = GetResource(item, RES_FUEL) / max(noammorating, GetResource(player, RES_FUEL));
+
+       rating *= min(c, 2);
+       if(wpn)
+               rating += wpn.bot_pickupbasevalue * 0.1;
+       return rating;
+}
+
+float healtharmor_pickupevalfunc(entity player, entity item)
+{
+       float c = 0;
+       float rating = item.bot_pickupbasevalue;
+
+       float itemarmor = GetResource(item, RES_ARMOR);
+       float itemhealth = GetResource(item, RES_HEALTH);
+
+       if(item.item_group)
+       {
+               itemarmor *= min(4, item.item_group_count);
+               itemhealth *= min(4, item.item_group_count);
+       }
+
+       if (itemarmor && (GetResource(player, RES_ARMOR) < item.max_armorvalue))
+               c = itemarmor / max(1, GetResource(player, RES_ARMOR) * 2/3 + GetResource(player, RES_HEALTH) * 1/3);
+
+       if (itemhealth && (GetResource(player, RES_HEALTH) < item.max_health))
+               c = itemhealth / max(1, GetResource(player, RES_HEALTH));
+
+       rating *= min(2, c);
+       return rating;
+}
+
+void Item_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
+{
+       if(ITEM_DAMAGE_NEEDKILL(deathtype))
+               RemoveItem(this);
+}
+
+void item_use(entity this, entity actor, entity trigger)
+{
+       // use the touch function to handle collection
+       gettouch(this)(this, actor);
+}
+
+void _StartItem(entity this, entity def, float defaultrespawntime, float defaultrespawntimejitter)
+{
+       string itemname = def.m_name;
+       Model itemmodel = def.m_model;
+       Sound pickupsound = def.m_sound;
+       float(entity player, entity item) pickupevalfunc = def.m_pickupevalfunc;
+       float pickupbasevalue = def.m_botvalue;
+       int itemflags = def.m_itemflags;
+
+       startitem_failed = false;
+
+       this.item_model_ent = itemmodel;
+       this.item_pickupsound_ent = pickupsound;
+
+       if(def.m_iteminit)
+               def.m_iteminit(def, this);
+
+       if(!this.respawntime) // both need to be set
+       {
+               this.respawntime = defaultrespawntime;
+               this.respawntimejitter = defaultrespawntimejitter;
+       }
+
+       if(!this.pickup_anyway && def.m_pickupanyway)
+               this.pickup_anyway = def.m_pickupanyway();
+
+       int itemid = def.m_itemid;
+       this.items = itemid;
+       int weaponid = def.instanceOfWeaponPickup ? def.m_weapon.m_id : 0;
+       this.weapon = weaponid;
+
+       if(!this.fade_end)
+       {
+               this.fade_start = autocvar_g_items_mindist;
+               this.fade_end = autocvar_g_items_maxdist;
+       }
+
+       if(weaponid)
+               STAT(WEAPONS, this) = WepSet_FromWeapon(REGISTRY_GET(Weapons, weaponid));
+
+       this.flags = FL_ITEM | itemflags;
+       IL_PUSH(g_items, this);
+
+       if(MUTATOR_CALLHOOK(FilterItem, this)) // error means we do not want the item
+       {
+               startitem_failed = true;
+               delete(this);
+               return;
+       }
+
+       precache_model(this.model);
+       precache_sound(this.item_pickupsound);
+
+       if (Item_IsLoot(this))
+       {
+               this.reset = SUB_Remove;
+               set_movetype(this, MOVETYPE_TOSS);
+
+               // Savage: remove thrown items after a certain period of time ("garbage collection")
+               setthink(this, RemoveItem);
+               this.nextthink = time + 20;
+
+               this.takedamage = DAMAGE_YES;
+               this.event_damage = Item_Damage;
+
+               if (Item_IsExpiring(this))
+               {
+                       // if item is worthless after a timer, have it expire then
+                       this.nextthink = max(this.strength_finished, this.invincible_finished, this.superweapons_finished);
+               }
+
+               // don't drop if in a NODROP zone (such as lava)
+               traceline(this.origin, this.origin, MOVE_NORMAL, this);
+               if (trace_dpstartcontents & DPCONTENTS_NODROP)
+               {
+                       startitem_failed = true;
+                       delete(this);
+                       return;
+               }
+       }
+       else
+       {
+               if(!have_pickup_item(this))
+               {
+                       startitem_failed = true;
+                       delete(this);
+                       return;
+               }
+
+               if(this.angles != '0 0 0')
+                       this.SendFlags |= ISF_ANGLES;
+
+               this.reset = Item_Reset;
+               // it's a level item
+               if(this.spawnflags & 1)
+                       this.noalign = 1;
+               if (this.noalign > 0)
+                       set_movetype(this, MOVETYPE_NONE);
+               else
+                       set_movetype(this, MOVETYPE_TOSS);
+               // do item filtering according to game mode and other things
+               if (this.noalign <= 0)
+               {
+                       // first nudge it off the floor a little bit to avoid math errors
+                       setorigin(this, this.origin + '0 0 1');
+                       // set item size before we spawn a spawnfunc_waypoint
+                       setsize(this, def.m_mins, def.m_maxs);
+                       this.SendFlags |= ISF_SIZE;
+                       // note droptofloor returns false if stuck/or would fall too far
+                       if (!this.noalign)
+                               droptofloor(this);
+                       waypoint_spawnforitem(this);
+               }
+
+               /*
+                * can't do it that way, as it would break maps
+                * TODO make a target_give like entity another way, that perhaps has
+                * the weapon name in a key
+               if(this.targetname)
+               {
+                       // target_give not yet supported; maybe later
+                       print("removed targeted ", this.classname, "\n");
+                       startitem_failed = true;
+                       delete(this);
+                       return;
+               }
+               */
+
+               if(this.targetname != "" && (this.spawnflags & 16))
+                       this.use = item_use;
+
+               if(autocvar_spawn_debug >= 2)
+               {
+            // why not flags & fl_item?
+                   FOREACH_ENTITY_RADIUS(this.origin, 3, it.is_item, {
+                LOG_TRACE("XXX Found duplicated item: ", itemname, vtos(this.origin));
+                LOG_TRACE(" vs ", it.netname, vtos(it.origin));
+                error("Mapper sucks.");
+            });
+                       this.is_item = true;
+               }
+
+               weaponsInMap |= WepSet_FromWeapon(REGISTRY_GET(Weapons, weaponid));
+
+               if (   def.instanceOfPowerup
+                       || def.instanceOfWeaponPickup
+                       || (def.instanceOfHealth && def != ITEM_HealthSmall)
+                       || (def.instanceOfArmor && def != ITEM_ArmorSmall)
+                       || (itemid & (IT_KEY1 | IT_KEY2))
+               )
+               {
+                       if(!this.target || this.target == "")
+                               this.target = "###item###"; // for finding the nearest item using findnearest
+               }
+
+               Item_ItemsTime_SetTime(this, 0);
+       }
+
+       this.bot_pickup = true;
+       this.bot_pickupevalfunc = pickupevalfunc;
+       this.bot_pickupbasevalue = pickupbasevalue;
+       this.mdl = this.model ? this.model : strzone(this.item_model_ent.model_str());
+       this.netname = itemname;
+       settouch(this, Item_Touch);
+       setmodel(this, MDL_Null); // precision set below
+       //this.effects |= EF_LOWPRECISION;
+
+       setsize (this, this.pos1 =  def.m_mins, this.pos2 = def.m_maxs);
+
+       this.SendFlags |= ISF_SIZE;
+
+       if (!(this.spawnflags & 1024)) {
+               if(def.instanceOfPowerup)
+                       this.ItemStatus |= ITS_ANIMATE1;
+
+               if(GetResource(this, RES_ARMOR) || GetResource(this, RES_HEALTH))
+                       this.ItemStatus |= ITS_ANIMATE2;
+       }
+
+       if(Item_IsLoot(this))
+               this.gravity = 1;
+
+       if(def.instanceOfWeaponPickup)
+       {
+               if (!Item_IsLoot(this)) // if dropped, colormap is already set up nicely
+                       this.colormap = 1024; // color shirt=0 pants=0 grey
+               if (!(this.spawnflags & 1024))
+                       this.ItemStatus |= ITS_ANIMATE1;
+               this.SendFlags |= ISF_COLORMAP;
+       }
+
+       this.state = 0;
+       if(this.team)
+       {
+               if(!this.cnt)
+                       this.cnt = 1; // item probability weight
+
+               this.effects |= EF_NODRAW; // marker for item team search
+               InitializeEntity(this, Item_FindTeam, INITPRIO_FINDTARGET);
+       }
+       else
+               Item_Reset(this);
+
+       Net_LinkEntity(this, !(def.instanceOfPowerup || def.instanceOfHealth || def.instanceOfArmor), 0, ItemSend);
+
+       // call this hook after everything else has been done
+       if (MUTATOR_CALLHOOK(Item_Spawn, this))
+       {
+               startitem_failed = true;
+               delete(this);
+               return;
+       }
+
+       setItemGroup(this);
+}
+
+void StartItem(entity this, GameItem def)
+{
+    def = def.m_spawnfunc_hookreplace(def, this);
+    if (def.spawnflags & ITEM_FLAG_MUTATORBLOCKED)
+    {
+        delete(this);
+        return;
+    }
+    this.classname = def.m_canonical_spawnfunc;
+    _StartItem(
+       this,
+       this.itemdef = def,
+       def.m_respawntime(), // defaultrespawntime
+       def.m_respawntimejitter() // defaultrespawntimejitter
+       );
+}
+
+#define IS_SMALL(def) ((def.instanceOfHealth && def == ITEM_HealthSmall) || (def.instanceOfArmor && def == ITEM_ArmorSmall))
+int group_count = 1;
+
+void setItemGroup(entity this)
+{
+       if(!IS_SMALL(this.itemdef) || Item_IsLoot(this))
+               return;
+
+       FOREACH_ENTITY_RADIUS(this.origin, 120, (it != this) && IS_SMALL(it.itemdef),
+       {
+               if(!this.item_group)
+               {
+                       if(!it.item_group)
+                       {
+                               it.item_group = group_count;
+                               group_count++;
+                       }
+                       this.item_group = it.item_group;
+               }
+               else // spawning item is already part of a item_group X
+               {
+                       if(!it.item_group)
+                               it.item_group = this.item_group;
+                       else if(it.item_group != this.item_group) // found an item near the spawning item that is part of a different item_group Y
+                       {
+                               int grY = it.item_group;
+                               // move all items of item_group Y to item_group X
+                               IL_EACH(g_items, IS_SMALL(it.itemdef),
+                               {
+                                       if(it.item_group == grY)
+                                               it.item_group = this.item_group;
+                               });
+                       }
+               }
+       });
+}
+
+void setItemGroupCount()
+{
+       for (int k = 1; k <= group_count; k++)
+       {
+               int count = 0;
+               IL_EACH(g_items, IS_SMALL(it.itemdef) && it.item_group == k, { count++; });
+               if (count)
+                       IL_EACH(g_items, IS_SMALL(it.itemdef) && it.item_group == k, { it.item_group_count = count; });
+       }
+}
+
+void target_items_use(entity this, entity actor, entity trigger)
+{
+       if(Item_IsLoot(actor))
+       {
+               EXACTTRIGGER_TOUCH(this, trigger);
+               delete(actor);
+               return;
+       }
+
+       if (!IS_PLAYER(actor) || IS_DEAD(actor))
+               return;
+
+       if(trigger.solid == SOLID_TRIGGER)
+       {
+               EXACTTRIGGER_TOUCH(this, trigger);
+       }
+
+       IL_EACH(g_items, it.enemy == actor && Item_IsLoot(it),
+       {
+               delete(it);
+       });
+
+       if(GiveItems(actor, 0, tokenize_console(this.netname)))
+               centerprint(actor, this.message);
+}
+
+spawnfunc(target_items)
+{
+       this.use = target_items_use;
+       if(!this.strength_finished)
+               this.strength_finished = autocvar_g_balance_powerup_strength_time;
+       if(!this.invincible_finished)
+               this.invincible_finished = autocvar_g_balance_powerup_invincible_time;
+       if(!this.superweapons_finished)
+               this.superweapons_finished = autocvar_g_balance_superweapons_time;
+
+       string str;
+       int n = tokenize_console(this.netname);
+       if(argv(0) == "give")
+       {
+               str = substring(this.netname, argv_start_index(1), argv_end_index(-1) - argv_start_index(1));
+       }
+       else
+       {
+               for(int j = 0; j < n; ++j)
+               {
+                       // this is from a time when unlimited superweapons were handled together with ammo in some parts of the code
+                       if     (argv(j) == "unlimited_ammo")         this.items |= IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPERWEAPONS;
+                       else if(argv(j) == "unlimited_weapon_ammo")  this.items |= IT_UNLIMITED_AMMO;
+                       else if(argv(j) == "unlimited_superweapons") this.items |= IT_UNLIMITED_SUPERWEAPONS;
+                       else if(argv(j) == "strength")               this.items |= ITEM_Strength.m_itemid;
+                       else if(argv(j) == "invincible")             this.items |= ITEM_Shield.m_itemid;
+                       else if(argv(j) == "superweapons")           this.items |= IT_SUPERWEAPON;
+                       else if(argv(j) == "jetpack")                this.items |= ITEM_Jetpack.m_itemid;
+                       else if(argv(j) == "fuel_regen")             this.items |= ITEM_JetpackRegen.m_itemid;
+                       else
+                       {
+                               FOREACH(Buffs, it != BUFF_Null,
+                               {
+                                       string s = Buff_UndeprecateName(argv(j));
+                                       if(s == it.netname)
+                                       {
+                                               STAT(BUFFS, this) |= (it.m_itemid);
+                                               if(!STAT(BUFF_TIME, this))
+                                                       STAT(BUFF_TIME, this) = it.m_time(it);
+                                               break;
+                                       }
+                               });
+                               FOREACH(Weapons, it != WEP_Null, {
+                                       string s = W_UndeprecateName(argv(j));
+                                       if(s == it.netname)
+                                       {
+                                               STAT(WEAPONS, this) |= (it.m_wepset);
+                                               if(this.spawnflags == 0 || this.spawnflags == 2)
+                                                       it.wr_init(it);
+                                               break;
+                                       }
+                               });
+                       }
+               }
+
+               string itemprefix, valueprefix;
+               if(this.spawnflags == 0)
+               {
+                       itemprefix = "";
+                       valueprefix = "";
+               }
+               else if(this.spawnflags == 1)
+               {
+                       itemprefix = "max ";
+                       valueprefix = "max ";
+               }
+               else if(this.spawnflags == 2)
+               {
+                       itemprefix = "min ";
+                       valueprefix = "min ";
+               }
+               else if(this.spawnflags == 4)
+               {
+                       itemprefix = "minus ";
+                       valueprefix = "max ";
+               }
+               else
+               {
+                       error("invalid spawnflags");
+                       itemprefix = valueprefix = string_null;
+               }
+
+               str = "";
+               str = sprintf("%s %s%d %s", str, itemprefix, boolean(this.items & IT_UNLIMITED_AMMO), "unlimited_weapon_ammo");
+               str = sprintf("%s %s%d %s", str, itemprefix, boolean(this.items & IT_UNLIMITED_SUPERWEAPONS), "unlimited_superweapons");
+               str = sprintf("%s %s%d %s", str, valueprefix, this.strength_finished * boolean(this.items & ITEM_Strength.m_itemid), "strength");
+               str = sprintf("%s %s%d %s", str, valueprefix, this.invincible_finished * boolean(this.items & ITEM_Shield.m_itemid), "invincible");
+               str = sprintf("%s %s%d %s", str, valueprefix, this.superweapons_finished * boolean(this.items & IT_SUPERWEAPON), "superweapons");
+               str = sprintf("%s %s%d %s", str, itemprefix, boolean(this.items & ITEM_Jetpack.m_itemid), "jetpack");
+               str = sprintf("%s %s%d %s", str, itemprefix, boolean(this.items & ITEM_JetpackRegen.m_itemid), "fuel_regen");
+               float res;
+               res = GetResource(this, RES_SHELLS);  if(res != 0) str = sprintf("%s %s%d %s", str, valueprefix, max(0, res), "shells");
+               res = GetResource(this, RES_BULLETS); if(res != 0) str = sprintf("%s %s%d %s", str, valueprefix, max(0, res), "nails");
+               res = GetResource(this, RES_ROCKETS); if(res != 0) str = sprintf("%s %s%d %s", str, valueprefix, max(0, res), "rockets");
+               res = GetResource(this, RES_CELLS);   if(res != 0) str = sprintf("%s %s%d %s", str, valueprefix, max(0, res), "cells");
+               res = GetResource(this, RES_PLASMA);  if(res != 0) str = sprintf("%s %s%d %s", str, valueprefix, max(0, res), "plasma");
+               res = GetResource(this, RES_FUEL);    if(res != 0) str = sprintf("%s %s%d %s", str, valueprefix, max(0, res), "fuel");
+               res = GetResource(this, RES_HEALTH);  if(res != 0) str = sprintf("%s %s%d %s", str, valueprefix, max(0, res), "health");
+               res = GetResource(this, RES_ARMOR);   if(res != 0) str = sprintf("%s %s%d %s", str, valueprefix, max(0, res), "armor");
+               // HACK: buffs share a single timer, so we need to include enabled buffs AFTER disabled ones to avoid loss
+               FOREACH(Buffs, it != BUFF_Null && !(STAT(BUFFS, this) & it.m_itemid), str = sprintf("%s %s%d %s", str, valueprefix, max(0, STAT(BUFF_TIME, this)), it.netname));
+               FOREACH(Buffs, it != BUFF_Null && (STAT(BUFFS, this) & it.m_itemid), str = sprintf("%s %s%d %s", str, valueprefix, max(0, STAT(BUFF_TIME, this)), it.netname));
+               FOREACH(Weapons, it != WEP_Null, str = sprintf("%s %s%d %s", str, itemprefix, !!(STAT(WEAPONS, this) & (it.m_wepset)), it.netname));
+       }
+       this.netname = strzone(str);
+
+       n = tokenize_console(this.netname);
+       for(int j = 0; j < n; ++j)
+       {
+               FOREACH(Weapons, it != WEP_Null && W_UndeprecateName(argv(j)) == it.netname, {
+                       it.wr_init(it);
+                       break;
+               });
+       }
+}
+
+float GiveWeapon(entity e, float wpn, float op, float val)
+{
+       WepSet v0, v1;
+       WepSet s = WepSet_FromWeapon(REGISTRY_GET(Weapons, wpn));
+       v0 = (STAT(WEAPONS, e) & s);
+       switch(op)
+       {
+               case OP_SET:
+                       if(val > 0)
+                               STAT(WEAPONS, e) |= s;
+                       else
+                               STAT(WEAPONS, e) &= ~s;
+                       break;
+               case OP_MIN:
+               case OP_PLUS:
+                       if(val > 0)
+                               STAT(WEAPONS, e) |= s;
+                       break;
+               case OP_MAX:
+                       if(val <= 0)
+                               STAT(WEAPONS, e) &= ~s;
+                       break;
+               case OP_MINUS:
+                       if(val > 0)
+                               STAT(WEAPONS, e) &= ~s;
+                       break;
+       }
+       v1 = (STAT(WEAPONS, e) & s);
+       return (v0 != v1);
+}
+
+bool GiveBuff(entity e, Buff thebuff, int op, int val)
+{
+       bool had_buff = (STAT(BUFFS, e) & thebuff.m_itemid);
+       float new_buff_time = ((had_buff) ? STAT(BUFF_TIME, e) : 0);
+       switch (op)
+       {
+               case OP_SET:
+                       new_buff_time = val;
+                       break;
+               case OP_MIN:
+                       new_buff_time = max(new_buff_time, val);
+                       break;
+               case OP_MAX:
+                       new_buff_time = min(new_buff_time, val);
+                       break;
+               case OP_PLUS:
+                       new_buff_time += val;
+                       break;
+               case OP_MINUS:
+                       new_buff_time -= val;
+                       break;
+       }
+       if(new_buff_time <= 0)
+       {
+               if(had_buff)
+                       STAT(BUFF_TIME, e) = new_buff_time;
+               STAT(BUFFS, e) &= ~thebuff.m_itemid;
+       }
+       else
+       {
+               STAT(BUFF_TIME, e) = new_buff_time;
+               STAT(BUFFS, e) = thebuff.m_itemid; // NOTE: replaces any existing buffs on the player!
+       }
+       bool have_buff = (STAT(BUFFS, e) & thebuff.m_itemid);
+       return (had_buff != have_buff);
+}
+
+void GiveSound(entity e, float v0, float v1, float t, Sound snd_incr, Sound snd_decr)
+{
+       if(v1 == v0)
+               return;
+       if(v1 <= v0 - t)
+       {
+               if(snd_decr != NULL)
+                       sound (e, CH_TRIGGER, snd_decr, VOL_BASE, ATTEN_NORM);
+       }
+       else if(v0 >= v0 + t)
+       {
+               if(snd_incr != NULL)
+                       sound (e, CH_TRIGGER, snd_incr, VOL_BASE, ATTEN_NORM);
+       }
+}
+
+void GiveRot(entity e, float v0, float v1, .float rotfield, float rottime, .float regenfield, float regentime)
+{
+       if(v0 < v1)
+               e.(rotfield) = max(e.(rotfield), time + rottime);
+       else if(v0 > v1)
+               e.(regenfield) = max(e.(regenfield), time + regentime);
+}
+bool GiveResourceValue(entity e, int res_type, int op, int val)
+{
+       int v0 = GetResource(e, res_type);
+       float new_val = 0;
+       switch (op)
+       {
+               // min 100 cells = at least 100 cells
+               case OP_SET: new_val = val; break;
+               case OP_MIN: new_val = max(v0, val); break;
+               case OP_MAX: new_val = min(v0, val); break;
+               case OP_PLUS: new_val = v0 + val; break;
+               case OP_MINUS: new_val = v0 - val; break;
+               default: return false;
+       }
+
+       return SetResourceExplicit(e, res_type, new_val);
+}
+
+float GiveItems(entity e, float beginarg, float endarg)
+{
+       float got, i, val, op;
+       string cmd;
+
+       val = 999;
+       op = OP_SET;
+
+       got = 0;
+
+       int _switchweapon = 0;
+
+       if(CS(e).autoswitch)
+       {
+               for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+               {
+                       .entity weaponentity = weaponentities[slot];
+                       if(e.(weaponentity).m_weapon != WEP_Null || slot == 0)
+                       if(e.(weaponentity).m_switchweapon == w_getbestweapon(e, weaponentity))
+                               _switchweapon |= BIT(slot);
+               }
+       }
+
+       STAT(STRENGTH_FINISHED, e) = max(0, STAT(STRENGTH_FINISHED, e) - time);
+       STAT(INVINCIBLE_FINISHED, e) = max(0, STAT(INVINCIBLE_FINISHED, e) - time);
+       STAT(SUPERWEAPONS_FINISHED, e) = max(0, STAT(SUPERWEAPONS_FINISHED, e) - time);
+       STAT(BUFF_TIME, e) = max(0, STAT(BUFF_TIME, e) - time);
+
+       PREGIVE(e, items);
+       PREGIVE_WEAPONS(e);
+       PREGIVE(e, stat_STRENGTH_FINISHED);
+       PREGIVE(e, stat_INVINCIBLE_FINISHED);
+       PREGIVE(e, stat_SUPERWEAPONS_FINISHED);
+       PREGIVE_RESOURCE(e, RES_BULLETS);
+       PREGIVE_RESOURCE(e, RES_CELLS);
+       PREGIVE_RESOURCE(e, RES_PLASMA);
+       PREGIVE_RESOURCE(e, RES_SHELLS);
+       PREGIVE_RESOURCE(e, RES_ROCKETS);
+       PREGIVE_RESOURCE(e, RES_FUEL);
+       PREGIVE_RESOURCE(e, RES_ARMOR);
+       PREGIVE_RESOURCE(e, RES_HEALTH);
+
+       for(i = beginarg; i < endarg; ++i)
+       {
+               cmd = argv(i);
+
+               if(cmd == "0" || stof(cmd))
+               {
+                       val = stof(cmd);
+                       continue;
+               }
+               switch(cmd)
+               {
+                       case "no":
+                               op = OP_MAX;
+                               val = 0;
+                               continue;
+                       case "max":
+                               op = OP_MAX;
+                               continue;
+                       case "min":
+                               op = OP_MIN;
+                               continue;
+                       case "plus":
+                               op = OP_PLUS;
+                               continue;
+                       case "minus":
+                               op = OP_MINUS;
+                               continue;
+                       case "ALL":
+                               got += GiveBit(e, items, ITEM_JetpackRegen.m_itemid, op, val);
+                               got += GiveValue(e, stat_STRENGTH_FINISHED, op, val);
+                               got += GiveValue(e, stat_INVINCIBLE_FINISHED, op, val);
+                               got += GiveValue(e, stat_SUPERWEAPONS_FINISHED, op, val);
+                               got += GiveBit(e, items, IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPERWEAPONS, op, val);
+                       case "all":
+                               got += GiveBit(e, items, ITEM_Jetpack.m_itemid, op, val);
+                               got += GiveResourceValue(e, RES_HEALTH, op, val);
+                               got += GiveResourceValue(e, RES_ARMOR, op, val);
+                       case "allweapons":
+                               FOREACH(Weapons, it != WEP_Null && !(it.spawnflags & (WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_SPECIALATTACK)), got += GiveWeapon(e, it.m_id, op, val));
+                       //case "allbuffs": // all buffs makes a player god, do not want!
+                               //FOREACH(Buffs, it != BUFF_Null, got += GiveBuff(e, it.m_itemid, op, val));
+                       case "allammo":
+                               got += GiveResourceValue(e, RES_CELLS, op, val);
+                               got += GiveResourceValue(e, RES_PLASMA, op, val);
+                               got += GiveResourceValue(e, RES_SHELLS, op, val);
+                               got += GiveResourceValue(e, RES_BULLETS, op, val);
+                               got += GiveResourceValue(e, RES_ROCKETS, op, val);
+                               got += GiveResourceValue(e, RES_FUEL, op, val);
+                               break;
+                       case "unlimited_ammo":
+                               // this is from a time when unlimited superweapons were handled together with ammo in some parts of the code
+                               got += GiveBit(e, items, IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPERWEAPONS, op, val);
+                               break;
+                       case "unlimited_weapon_ammo":
+                               got += GiveBit(e, items, IT_UNLIMITED_AMMO, op, val);
+                               break;
+                       case "unlimited_superweapons":
+                               got += GiveBit(e, items, IT_UNLIMITED_SUPERWEAPONS, op, val);
+                               break;
+                       case "jetpack":
+                               got += GiveBit(e, items, ITEM_Jetpack.m_itemid, op, val);
+                               break;
+                       case "fuel_regen":
+                               got += GiveBit(e, items, ITEM_JetpackRegen.m_itemid, op, val);
+                               break;
+                       case "strength":
+                               got += GiveValue(e, stat_STRENGTH_FINISHED, op, val);
+                               break;
+                       case "invincible":
+                               got += GiveValue(e, stat_INVINCIBLE_FINISHED, op, val);
+                               break;
+                       case "superweapons":
+                               got += GiveValue(e, stat_SUPERWEAPONS_FINISHED, op, val);
+                               break;
+                       case "cells":
+                               got += GiveResourceValue(e, RES_CELLS, op, val);
+                               break;
+                       case "plasma":
+                               got += GiveResourceValue(e, RES_PLASMA, op, val);
+                               break;
+                       case "shells":
+                               got += GiveResourceValue(e, RES_SHELLS, op, val);
+                               break;
+                       case "nails":
+                       case "bullets":
+                               got += GiveResourceValue(e, RES_BULLETS, op, val);
+                               break;
+                       case "rockets":
+                               got += GiveResourceValue(e, RES_ROCKETS, op, val);
+                               break;
+                       case "health":
+                               got += GiveResourceValue(e, RES_HEALTH, op, val);
+                               break;
+                       case "armor":
+                               got += GiveResourceValue(e, RES_ARMOR, op, val);
+                               break;
+                       case "fuel":
+                               got += GiveResourceValue(e, RES_FUEL, op, val);
+                               break;
+                       default:
+                               FOREACH(Buffs, it != BUFF_Null && buff_Available(it) && Buff_UndeprecateName(cmd) == it.netname,
+                               {
+                                       got += GiveBuff(e, it, op, val);
+                                       break;
+                               });
+                               FOREACH(Weapons, it != WEP_Null && W_UndeprecateName(cmd) == it.netname, {
+                    got += GiveWeapon(e, it.m_id, op, val);
+                    break;
+                               });
+                               break;
+               }
+               val = 999;
+               op = OP_SET;
+       }
+
+       POSTGIVE_BIT(e, items, ITEM_JetpackRegen.m_itemid, SND_ITEMPICKUP, SND_Null);
+       POSTGIVE_BIT(e, items, IT_UNLIMITED_SUPERWEAPONS, SND_POWERUP, SND_POWEROFF);
+       POSTGIVE_BIT(e, items, IT_UNLIMITED_AMMO, SND_POWERUP, SND_POWEROFF);
+       POSTGIVE_BIT(e, items, ITEM_Jetpack.m_itemid, SND_ITEMPICKUP, SND_Null);
+       FOREACH(Weapons, it != WEP_Null, {
+               POSTGIVE_WEAPON(e, it, SND_WEAPONPICKUP, SND_Null);
+               if(!(save_weapons & (it.m_wepset)))
+                       if(STAT(WEAPONS, e) & (it.m_wepset))
+                               it.wr_init(it);
+       });
+       POSTGIVE_VALUE(e, stat_STRENGTH_FINISHED, 1, SND_POWERUP, SND_POWEROFF);
+       POSTGIVE_VALUE(e, stat_INVINCIBLE_FINISHED, 1, SND_Shield, SND_POWEROFF);
+       //POSTGIVE_VALUE(e, stat_SUPERWEAPONS_FINISHED, 1, SND_Null, SND_Null);
+       POSTGIVE_RESOURCE(e, RES_BULLETS, 0, SND_ITEMPICKUP, SND_Null);
+       POSTGIVE_RESOURCE(e, RES_CELLS, 0, SND_ITEMPICKUP, SND_Null);
+       POSTGIVE_RESOURCE(e, RES_PLASMA, 0, SND_ITEMPICKUP, SND_Null);
+       POSTGIVE_RESOURCE(e, RES_SHELLS, 0, SND_ITEMPICKUP, SND_Null);
+       POSTGIVE_RESOURCE(e, RES_ROCKETS, 0, SND_ITEMPICKUP, SND_Null);
+       POSTGIVE_RES_ROT(e, RES_FUEL, 1, pauserotfuel_finished, autocvar_g_balance_pause_fuel_rot, pauseregen_finished, autocvar_g_balance_pause_fuel_regen, SND_ITEMPICKUP, SND_Null);
+       POSTGIVE_RES_ROT(e, RES_ARMOR, 1, pauserotarmor_finished, autocvar_g_balance_pause_armor_rot, pauseregen_finished, autocvar_g_balance_pause_health_regen, SND_ARMOR25, SND_Null);
+       POSTGIVE_RES_ROT(e, RES_HEALTH, 1, pauserothealth_finished, autocvar_g_balance_pause_health_rot, pauseregen_finished, autocvar_g_balance_pause_health_regen, SND_MEGAHEALTH, SND_Null);
+
+       if(STAT(SUPERWEAPONS_FINISHED, e) <= 0)
+               if(!g_weaponarena && (STAT(WEAPONS, e) & WEPSET_SUPERWEAPONS))
+                       STAT(SUPERWEAPONS_FINISHED, e) = autocvar_g_balance_superweapons_time;
+
+       if(STAT(STRENGTH_FINISHED, e) <= 0)
+               STAT(STRENGTH_FINISHED, e) = 0;
+       else
+               STAT(STRENGTH_FINISHED, e) += time;
+       if(STAT(INVINCIBLE_FINISHED, e) <= 0)
+               STAT(INVINCIBLE_FINISHED, e) = 0;
+       else
+               STAT(INVINCIBLE_FINISHED, e) += time;
+       if(STAT(SUPERWEAPONS_FINISHED, e) <= 0)
+               STAT(SUPERWEAPONS_FINISHED, e) = 0;
+       else
+               STAT(SUPERWEAPONS_FINISHED, e) += time;
+       if(STAT(BUFF_TIME, e) <= 0)
+               STAT(BUFF_TIME, e) = 0;
+       else
+               STAT(BUFF_TIME, e) += time;
+
+       for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+       {
+               .entity weaponentity = weaponentities[slot];
+               if(e.(weaponentity).m_weapon != WEP_Null || slot == 0)
+               if(!(STAT(WEAPONS, e) & WepSet_FromWeapon(e.(weaponentity).m_switchweapon)))
+                       _switchweapon |= BIT(slot);
+       }
+
+       if(_switchweapon)
+       {
+               for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+               {
+                       .entity weaponentity = weaponentities[slot];
+                       if(_switchweapon & BIT(slot))
+                       {
+                               Weapon wep = w_getbestweapon(e, weaponentity);
+                               if(wep != e.(weaponentity).m_switchweapon)
+                                       W_SwitchWeapon_Force(e, wep, weaponentity);
+                       }
+               }
+       }
+
+       return got;
+}
diff --git a/qcsrc/server/items/items.qh b/qcsrc/server/items/items.qh
new file mode 100644 (file)
index 0000000..8dbb472
--- /dev/null
@@ -0,0 +1,114 @@
+#pragma once
+
+#include <common/sounds/sound.qh>
+
+void StartItem(entity this, entity a);
+.int item_group;
+.int item_group_count;
+
+float autocvar_sv_simple_items;
+bool ItemSend(entity this, entity to, int sf);
+
+bool have_pickup_item(entity this);
+
+const float ITEM_RESPAWN_TICKS = 10;
+
+// string overrides entity
+.string item_pickupsound;
+.entity item_pickupsound_ent;
+.entity item_model_ent;
+
+.float max_armorvalue;
+.float pickup_anyway;
+
+.float scheduledrespawntime;
+.float respawntime;
+.float respawntimejitter;
+.float respawntimestart;
+
+.float item_respawncounter;
+
+.float noalign; // if set to 1, the item or spawnpoint won't be dropped to the floor
+
+.float superweapons_finished; // NOTE: this field is used only by map entities, it does not directly apply the superweapons stat
+
+// delay before this item can be picked up
+.float item_spawnshieldtime;
+
+void Item_Show (entity e, int mode);
+
+void Item_Respawn (entity this);
+
+void Item_RespawnCountdown(entity this);
+void Item_ScheduleRespawnIn(entity e, float t);
+
+void Item_ScheduleRespawn(entity e);
+
+void Item_ScheduleInitialRespawn(entity e);
+
+/// \brief Give several random weapons and ammo to the entity.
+/// \param[in,out] receiver Entity to give weapons to.
+/// \param[in] num_weapons Number of weapons to give.
+/// \param[in] weapon_names Names of weapons to give separated by spaces.
+/// \param[in] ammo Entity containing the ammo amount for each possible weapon.
+/// \return No return.
+void GiveRandomWeapons(entity receiver, int num_weapons, string weapon_names, entity ammo_entity);
+
+bool Item_GiveAmmoTo(entity item, entity player, int res_type, float ammomax);
+
+bool Item_GiveTo(entity item, entity player);
+
+void Item_Touch(entity this, entity toucher);
+
+void Item_Reset(entity this);
+
+void Item_FindTeam(entity this);
+// Savage: used for item garbage-collection
+
+bool ItemSend(entity this, entity to, int sf);
+void ItemUpdate(entity this);
+
+void UpdateItemAfterTeleport(entity this);
+
+// pickup evaluation functions
+// these functions decide how desirable an item is to the bots
+
+float generic_pickupevalfunc(entity player, entity item);// {return item.bot_pickupbasevalue;} // WEAPONTODO
+
+float weapon_pickupevalfunc(entity player, entity item);
+float ammo_pickupevalfunc(entity player, entity item);
+float healtharmor_pickupevalfunc(entity player, entity item);
+
+.bool is_item;
+.entity itemdef;
+void _StartItem(entity this, entity def, float defaultrespawntime, float defaultrespawntimejitter);
+
+void setItemGroup(entity this);
+void setItemGroupCount();
+
+float GiveWeapon(entity e, float wpn, float op, float val);
+
+float GiveBit(entity e, .float fld, float bit, float op, float val);
+
+float GiveValue(entity e, .float fld, float op, float val);
+
+void GiveSound(entity e, float v0, float v1, float t, Sound snd_incr, Sound snd_decr);
+
+void GiveRot(entity e, float v0, float v1, .float rotfield, float rottime, .float regenfield, float regentime);
+
+spawnfunc(target_items);
+
+#define PREGIVE_WEAPONS(e) WepSet save_weapons; save_weapons = STAT(WEAPONS, e)
+#define PREGIVE(e,f) float save_##f; save_##f = (e).f
+#define PREGIVE_RESOURCE(e,f) float save_##f = GetResource((e), (f))
+#define POSTGIVE_WEAPON(e,b,snd_incr,snd_decr) GiveSound((e), !!(save_weapons & WepSet_FromWeapon(b)), !!(STAT(WEAPONS, e) & WepSet_FromWeapon(b)), 0, snd_incr, snd_decr)
+#define POSTGIVE_BIT(e,f,b,snd_incr,snd_decr) GiveSound((e), save_##f & (b), (e).f & (b), 0, snd_incr, snd_decr)
+#define POSTGIVE_RESOURCE(e,f,t,snd_incr,snd_decr) GiveSound((e), save_##f, GetResource((e), (f)), t, snd_incr, snd_decr)
+#define POSTGIVE_RES_ROT(e,f,t,rotfield,rottime,regenfield,regentime,snd_incr,snd_decr) GiveRot((e),save_##f,GetResource((e),(f)),rotfield,rottime,regenfield,regentime);GiveSound((e),save_##f,GetResource((e),(f)),t,snd_incr,snd_decr)
+#define POSTGIVE_VALUE(e,f,t,snd_incr,snd_decr) GiveSound((e), save_##f, (e).f, t, snd_incr, snd_decr)
+#define POSTGIVE_VALUE_ROT(e,f,t,rotfield,rottime,regenfield,regentime,snd_incr,snd_decr) GiveRot((e), save_##f, (e).f, rotfield, rottime, regenfield, regentime); GiveSound((e), save_##f, (e).f, t, snd_incr, snd_decr)
+
+float GiveItems(entity e, float beginarg, float endarg);
+
+IntrusiveList g_items;
+STATIC_INIT(g_items) { g_items = IL_NEW(); }
diff --git a/qcsrc/server/items/spawning.qc b/qcsrc/server/items/spawning.qc
new file mode 100644 (file)
index 0000000..d2f1530
--- /dev/null
@@ -0,0 +1,150 @@
+#include "spawning.qh"
+
+/// \file
+/// \brief Source file that contains implementation of the functions related to
+/// creation of game items.
+/// \copyright GNU GPLv2 or any later version.
+
+#include <server/items/items.qh>
+#include <server/mutators/_mod.qh>
+#include <server/weapons/spawning.qh>
+#include <common/weapons/all.qh>
+#include <common/mapobjects/subs.qh>
+
+.bool m_isloot; ///< Holds whether item is loot.
+/// \brief Holds whether strength, shield or superweapon timers expire while
+/// this item is on the ground.
+.bool m_isexpiring;
+
+entity Item_FindDefinition(string class_name)
+{
+       FOREACH(Items, it.m_canonical_spawnfunc == class_name,
+       {
+               return it;
+       });
+       FOREACH(Weapons, it.m_canonical_spawnfunc == class_name,
+       {
+               return it.m_pickup;
+       });
+       return NULL;
+}
+
+bool Item_IsAllowed(string class_name)
+{
+       entity definition = Item_FindDefinition(class_name);
+       if (definition == NULL)
+       {
+               return false;
+       }
+       return Item_IsDefinitionAllowed(definition);
+}
+
+bool Item_IsDefinitionAllowed(entity definition)
+{
+       return !MUTATOR_CALLHOOK(FilterItemDefinition, definition);
+}
+
+entity Item_Create(string class_name, vector position, bool no_align)
+{
+       entity item = spawn();
+       item.classname = class_name;
+       item.spawnfunc_checked = true;
+       setorigin(item, position);
+       item.noalign = no_align;
+       Item_Initialize(item, class_name);
+       if (wasfreed(item))
+       {
+               return NULL;
+       }
+       return item;
+}
+
+void Item_Initialize(entity item, string class_name)
+{
+       FOREACH(Weapons, it.m_canonical_spawnfunc == class_name,
+       {
+               weapon_defaultspawnfunc(item, it);
+               return;
+       });
+       FOREACH(Items, it.m_canonical_spawnfunc == class_name,
+       {
+               StartItem(item, it);
+               return;
+       });
+       LOG_FATALF("Item_Initialize: Invalid classname: %s", class_name);
+}
+
+entity Item_CreateLoot(string class_name, vector position, vector vel,
+       float time_to_live)
+{
+       entity item = spawn();
+       if (!Item_InitializeLoot(item, class_name, position, vel, time_to_live))
+       {
+               return NULL;
+       }
+       return item;
+}
+
+bool Item_InitializeLoot(entity item, string class_name, vector position,
+       vector vel, float time_to_live)
+{
+       item.classname = class_name;
+       Item_SetLoot(item, true);
+       item.noalign = true;
+       setorigin(item, position);
+       item.pickup_anyway = true;
+       item.spawnfunc_checked = true;
+       Item_Initialize(item, class_name);
+       if (wasfreed(item))
+       {
+               return false;
+       }
+       item.gravity = 1;
+       item.velocity = vel;
+       SUB_SetFade(item, time + time_to_live, 1);
+       return true;
+}
+
+bool Item_IsLoot(entity item)
+{
+       return item.m_isloot || item.classname == "droppedweapon";
+}
+
+void Item_SetLoot(entity item, bool loot)
+{
+       item.m_isloot = loot;
+}
+
+bool Item_ShouldKeepPosition(entity item)
+{
+       return item.noalign || (item.spawnflags & 1);
+}
+
+bool Item_IsExpiring(entity item)
+{
+       return item.m_isexpiring;
+}
+
+void Item_SetExpiring(entity item, bool expiring)
+{
+       item.m_isexpiring = expiring;
+}
+
+// Compatibility spawn functions
+
+// FIXME: in Quake this is green armor, in Xonotic maps it is an armor shard
+SPAWNFUNC_ITEM(item_armor1, ITEM_ArmorSmall)
+
+SPAWNFUNC_ITEM(item_armor25, ITEM_ArmorMega)
+
+SPAWNFUNC_ITEM(item_armor_large, ITEM_ArmorMega)
+
+SPAWNFUNC_ITEM(item_health1, ITEM_HealthSmall)
+
+SPAWNFUNC_ITEM(item_health25, ITEM_HealthMedium)
+
+SPAWNFUNC_ITEM(item_health_large, ITEM_HealthBig)
+
+SPAWNFUNC_ITEM(item_health100, ITEM_HealthMega)
+
+SPAWNFUNC_ITEM(item_quad, ITEM_Strength)
diff --git a/qcsrc/server/items/spawning.qh b/qcsrc/server/items/spawning.qh
new file mode 100644 (file)
index 0000000..b52449e
--- /dev/null
@@ -0,0 +1,94 @@
+#pragma once
+
+/// \file
+/// \brief Header file that describes the functions related to game items.
+/// \copyright GNU GPLv2 or any later version.
+
+bool startitem_failed;
+
+/// \brief Returns the item definition corresponding to the given class name.
+/// \param[in] class_name Class name to search for.
+/// \return Item definition corresponding to the given class name or NULL is not
+/// found.
+entity Item_FindDefinition(string class_name);
+
+/// \brief Checks whether the items with the specified class name are allowed to
+/// spawn.
+/// \param[in] class_name Item class name to check.
+/// \return True items with the specified class name are allowed to spawn, false
+/// otherwise.
+bool Item_IsAllowed(string class_name);
+
+/// \brief Checks whether the items with the specified definition are allowed to
+/// spawn.
+/// \param[in] definition Item definition to check.
+/// \return True items with the specified definition are allowed to spawn, false
+/// otherwise.
+bool Item_IsDefinitionAllowed(entity definition);
+
+/// \brief Creates a new item.
+/// \param[in] class_name Class name of the item.
+/// \param[in] position Position of the item.
+/// \param[in] no_align True if item should be placed directly at specified
+/// position, false to let it drop to the ground.
+/// \return Item on success, NULL otherwise.
+entity Item_Create(string class_name, vector position, bool no_align);
+
+/// \brief Initializes the item according to class name.
+/// \param[in,out] item Item to initialize.
+/// \param[in] class_name Class name to use.
+/// \return No return.
+/// \nore This function is useful if you want to set some item properties before
+/// initialization.
+void Item_Initialize(entity item, string class_name);
+
+/// \brief Creates a loot item.
+/// \param[in] class_name Class name of the item.
+/// \param[in] position Position of the item.
+/// \param[in] velocity of the item.
+/// \param[in] time_to_live Amount of time after which the item will disappear.
+/// \return Item on success, NULL otherwise.
+entity Item_CreateLoot(string class_name, vector position, vector vel,
+       float time_to_live);
+
+/// \brief Initializes the loot item.
+/// \param[in] class_name Class name of the item.
+/// \param[in] position Position of the item.
+/// \param[in] velocity of the item.
+/// \param[in] time_to_live Amount of time after which the item will disappear.
+/// \return True on success, false otherwise.
+/// \nore This function is useful if you want to set some item properties before
+/// initialization.
+bool Item_InitializeLoot(entity item, string class_name, vector position,
+       vector vel, float time_to_live);
+
+/// \brief Returns whether the item is loot.
+/// \param[in] item Item to check.
+/// \return True if the item is loot, false otherwise.
+bool Item_IsLoot(entity item);
+
+/// \brief Sets the item loot status.
+/// \param[in,out] item Item to adjust.
+/// \param[in] loot Whether item is loot.
+/// \return No return.
+void Item_SetLoot(entity item, bool loot);
+
+/// \brief Returns whether item should keep its position or be dropped to the
+/// ground.
+/// \param[in] item Item to check.
+/// \return True if item should keep its position or false if it should be
+/// dropped to the ground.
+bool Item_ShouldKeepPosition(entity item);
+
+/// \brief Returns whether the item is expiring (i.e. its strength, shield and
+/// superweapon timers expire while it is on the ground).
+/// \param[in] item Item to check.
+/// \return True if the item is expiring, false otherwise.
+bool Item_IsExpiring(entity item);
+
+/// \brief Sets the item expiring status (i.e. whether its strength, shield
+/// and superweapon timers expire while it is on the ground).
+/// \param[in,out] item Item to adjust.
+/// \param[in] expiring Whether item is expiring.
+/// \return No return.
+void Item_SetExpiring(entity item, bool expiring);
diff --git a/qcsrc/server/main.qc b/qcsrc/server/main.qc
new file mode 100644 (file)
index 0000000..bbafd02
--- /dev/null
@@ -0,0 +1,406 @@
+#include "main.qh"
+
+#include "anticheat.qh"
+#include "hook.qh"
+#include "damage.qh"
+#include "world.qh"
+#include "spawnpoints.qh"
+#include <server/gamelog.qh>
+
+#include "bot/api.qh"
+
+#include "command/common.qh"
+
+#include <server/mutators/_mod.qh>
+#include "weapons/csqcprojectile.qh"
+#include <server/weapons/common.qh>
+#include <server/compat/quake3.qh>
+
+#include "../common/constants.qh"
+#include "../common/deathtypes/all.qh"
+#include "../common/debug.qh"
+#include "../common/mapinfo.qh"
+#include "../common/util.qh"
+
+#include "../common/vehicles/all.qh"
+#include <common/monsters/sv_monsters.qh>
+#include <common/weapons/_all.qh>
+
+#include "../lib/csqcmodel/sv_model.qh"
+
+#include "../lib/warpzone/common.qh"
+#include "../lib/warpzone/server.qh"
+
+void CreatureFrame_hotliquids(entity this)
+{
+       if (this.contents_damagetime >= time)
+       {
+               return;
+       }
+
+       this.contents_damagetime = time + autocvar_g_balance_contents_damagerate;
+
+       if (this.flags & FL_PROJECTILE)
+       {
+               if (this.watertype == CONTENT_LAVA)
+                       Damage (this, NULL, NULL, autocvar_g_balance_contents_projectiledamage * autocvar_g_balance_contents_damagerate * this.waterlevel, DEATH_LAVA.m_id, DMG_NOWEP, this.origin, '0 0 0');
+               else if (this.watertype == CONTENT_SLIME)
+                       Damage (this, NULL, NULL, autocvar_g_balance_contents_projectiledamage * autocvar_g_balance_contents_damagerate * this.waterlevel, DEATH_SLIME.m_id, DMG_NOWEP, this.origin, '0 0 0');
+       }
+       else
+       {
+               if (STAT(FROZEN, this))
+               {
+                       if (this.watertype == CONTENT_LAVA)
+                               Damage(this, NULL, NULL, 10000, DEATH_LAVA.m_id, DMG_NOWEP, this.origin, '0 0 0');
+                       else if (this.watertype == CONTENT_SLIME)
+                               Damage(this, NULL, NULL, 10000, DEATH_SLIME.m_id, DMG_NOWEP, this.origin, '0 0 0');
+               }
+               else if (this.watertype == CONTENT_LAVA)
+               {
+                       if (this.watersound_finished < time)
+                       {
+                               this.watersound_finished = time + 0.5;
+                               sound (this, CH_PLAYER_SINGLE, SND_LAVA, VOL_BASE, ATTEN_NORM);
+                       }
+                       Damage (this, NULL, NULL, autocvar_g_balance_contents_playerdamage_lava * autocvar_g_balance_contents_damagerate * this.waterlevel, DEATH_LAVA.m_id, DMG_NOWEP, this.origin, '0 0 0');
+                       if(autocvar_g_balance_contents_playerdamage_lava_burn)
+                               Fire_AddDamage(this, NULL, autocvar_g_balance_contents_playerdamage_lava_burn * this.waterlevel, autocvar_g_balance_contents_playerdamage_lava_burn_time * this.waterlevel, DEATH_LAVA.m_id);
+               }
+               else if (this.watertype == CONTENT_SLIME)
+               {
+                       if (this.watersound_finished < time)
+                       {
+                               this.watersound_finished = time + 0.5;
+                               sound (this, CH_PLAYER_SINGLE, SND_SLIME, VOL_BASE, ATTEN_NORM);
+                       }
+                       Damage (this, NULL, NULL, autocvar_g_balance_contents_playerdamage_slime * autocvar_g_balance_contents_damagerate * this.waterlevel, DEATH_SLIME.m_id, DMG_NOWEP, this.origin, '0 0 0');
+               }
+       }
+}
+
+void CreatureFrame_Liquids(entity this)
+{
+       if (this.watertype <= CONTENT_WATER && this.waterlevel > 0) // workaround a retarded bug made by id software :P (yes, it's that old of a bug)
+       {
+               if (!(this.flags & FL_INWATER))
+               {
+                       this.flags |= FL_INWATER;
+                       this.contents_damagetime = 0;
+               }
+
+               CreatureFrame_hotliquids(this);
+       }
+       else
+       {
+               if (this.flags & FL_INWATER)
+               {
+                       // play leave water sound
+                       this.flags &= ~FL_INWATER;
+                       this.contents_damagetime = 0;
+               }
+       }
+}
+
+void CreatureFrame_FallDamage(entity this)
+{
+       if(IS_VEHICLE(this) || (this.flags & FL_PROJECTILE))
+               return; // vehicles and projectiles don't receive fall damage
+       if(!(this.velocity || this.oldvelocity))
+               return; // if the entity hasn't moved and isn't moving, then don't do anything
+
+       // check for falling damage
+       bool have_hook = false;
+       for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+       {
+           .entity weaponentity = weaponentities[slot];
+           if(this.(weaponentity).hook && this.(weaponentity).hook.state)
+           {
+               have_hook = true;
+               break;
+           }
+       }
+       if(!have_hook)
+       {
+               float dm; // dm is the velocity DECREASE. Velocity INCREASE should never cause a sound or any damage.
+               if(autocvar_g_balance_falldamage_onlyvertical)
+                       dm = fabs(this.oldvelocity.z) - vlen(this.velocity);
+               else
+                       dm = vlen(this.oldvelocity) - vlen(this.velocity);
+               if (IS_DEAD(this))
+                       dm = (dm - autocvar_g_balance_falldamage_deadminspeed) * autocvar_g_balance_falldamage_factor;
+               else
+                       dm = min((dm - autocvar_g_balance_falldamage_minspeed) * autocvar_g_balance_falldamage_factor, autocvar_g_balance_falldamage_maxdamage);
+               if (dm > 0)
+               {
+                       tracebox(this.origin, this.mins, this.maxs, this.origin - '0 0 1', MOVE_NOMONSTERS, this);
+                       if (!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NODAMAGE))
+                               Damage (this, NULL, NULL, dm, DEATH_FALL.m_id, DMG_NOWEP, this.origin, '0 0 0');
+               }
+       }
+
+       if(autocvar_g_maxspeed > 0 && vdist(this.velocity, >, autocvar_g_maxspeed))
+               Damage (this, NULL, NULL, 100000, DEATH_SHOOTING_STAR.m_id, DMG_NOWEP, this.origin, '0 0 0');
+}
+
+void CreatureFrame_All()
+{
+       if(game_stopped || time < game_starttime)
+               return;
+
+       IL_EACH(g_damagedbycontents, it.damagedbycontents,
+       {
+               if (it.move_movetype == MOVETYPE_NOCLIP) continue;
+               CreatureFrame_Liquids(it);
+               CreatureFrame_FallDamage(it);
+               it.oldvelocity = it.velocity;
+       });
+}
+
+void Pause_TryPause(bool ispaused)
+{
+       int n = 0;
+       FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), {
+               if (PHYS_INPUT_BUTTON_CHAT(it) != ispaused) return;
+               ++n;
+       });
+       if (!n) return;
+       setpause(ispaused);
+}
+
+void SV_PausedTic(float elapsedtime)
+{
+       if (!server_is_dedicated) Pause_TryPause(false);
+}
+
+/*
+=============
+StartFrame
+
+Called before each frame by the server
+=============
+*/
+
+bool game_delay_last;
+
+bool autocvar_sv_autopause = false;
+void systems_update();
+void sys_phys_update(entity this, float dt);
+void StartFrame()
+{
+    // TODO: if move is more than 50ms, split it into two moves (this matches QWSV behavior and the client prediction)
+    IL_EACH(g_players, IS_FAKE_CLIENT(it), sys_phys_update(it, frametime));
+    IL_EACH(g_players, IS_FAKE_CLIENT(it), PlayerPreThink(it));
+
+       execute_next_frame();
+       if (autocvar_sv_autopause && !server_is_dedicated) Pause_TryPause(true);
+
+       delete_fn = remove_unsafely; // not during spawning!
+       serverprevtime = servertime;
+       servertime = time;
+       serverframetime = frametime;
+
+#ifdef PROFILING
+       if(time > client_cefc_accumulatortime + 1)
+       {
+               float t = client_cefc_accumulator / (time - client_cefc_accumulatortime);
+               int c_seeing = 0;
+               int c_seen = 0;
+               FOREACH_CLIENT(true, {
+                       if(IS_REAL_CLIENT(it))
+                               ++c_seeing;
+                       if(IS_PLAYER(it))
+                               ++c_seen;
+               });
+               LOG_INFO(
+                   "CEFC time: ", ftos(t * 1000), "ms; ",
+            "CEFC calls per second: ", ftos(c_seeing * (c_seen - 1) / t), "; ",
+            "CEFC 100% load at: ", ftos(solve_quadratic(t, -t, -1) * '0 1 0')
+        );
+               client_cefc_accumulatortime = time;
+               client_cefc_accumulator = 0;
+       }
+#endif
+
+       IL_EACH(g_projectiles, it.csqcprojectile_clientanimate, CSQCProjectile_Check(it));
+
+       if (RedirectionThink()) return;
+
+       UncustomizeEntitiesRun();
+       InitializeEntitiesRun();
+
+       WarpZone_StartFrame();
+
+       sys_frametime = autocvar_sys_ticrate * autocvar_slowmo;
+       if (sys_frametime <= 0) sys_frametime = 1.0 / 60.0; // somewhat safe fallback
+
+       if (timeout_status == TIMEOUT_LEADTIME) // just before the timeout (when timeout_status will be TIMEOUT_ACTIVE)
+               orig_slowmo = autocvar_slowmo; // slowmo will be restored after the timeout
+
+       // detect when the pre-game countdown (if any) has ended and the game has started
+       bool game_delay = (time < game_starttime);
+       if (autocvar_sv_eventlog && game_delay_last && !game_delay)
+               GameLogEcho(":startdelay_ended");
+       game_delay_last = game_delay;
+
+       CreatureFrame_All();
+       CheckRules_World();
+
+       if (warmup_stage && !game_stopped && warmup_limit > 0 && time >= warmup_limit) {
+               ReadyRestart();
+               return;
+       }
+
+       bot_serverframe();
+       anticheat_startframe();
+       MUTATOR_CALLHOOK(SV_StartFrame);
+
+       GlobalStats_updateglobal();
+    FOREACH_CLIENT(true, GlobalStats_update(it));
+    IL_EACH(g_players, IS_FAKE_CLIENT(it), PlayerPostThink(it));
+}
+
+.vector originjitter;
+.vector anglesjitter;
+.float anglejitter;
+.string gametypefilter;
+.string cvarfilter;
+
+/**
+ * Evaluate an expression of the form: [+ | -]? [var[op]val | [op]var | val | var] ...
+ * +: all must match. this is the default
+ * -: one must NOT match
+ *
+ * var>x
+ * var<x
+ * var>=x
+ * var<=x
+ * var==x
+ * var!=x
+ * var===x
+ * var!==x
+ */
+bool expr_evaluate(string s)
+{
+    bool ret = false;
+    if (str2chr(s, 0) == '+') {
+        s = substring(s, 1, -1);
+    } else if (str2chr(s, 0) == '-') {
+        ret = true;
+        s = substring(s, 1, -1);
+    }
+    bool expr_fail = false;
+    for (int i = 0, n = tokenize_console(s); i < n; ++i) {
+        int o;
+        string k, v;
+        s = argv(i);
+        #define X(expr) \
+            if (expr) \
+                continue; \
+            expr_fail = true; \
+            break;
+
+        #define BINOP(op, len, expr) \
+            if ((o = strstrofs(s, op, 0)) >= 0) { \
+                k = substring(s, 0, o); \
+                v = substring(s, o + len, -1); \
+                X(expr); \
+            }
+        BINOP(">=", 2, cvar(k) >= stof(v));
+        BINOP("<=", 2, cvar(k) <= stof(v));
+        BINOP(">",  1, cvar(k) >  stof(v));
+        BINOP("<",  1, cvar(k) <  stof(v));
+        BINOP("==", 2, cvar(k) == stof(v));
+        BINOP("!=", 2, cvar(k) != stof(v));
+        BINOP("===", 3, cvar_string(k) == v);
+        BINOP("!==", 3, cvar_string(k) != v);
+        {
+            k = s;
+            bool b = true;
+            if (str2chr(k, 0) == '!') {
+                k = substring(s, 1, -1);
+                b = false;
+            }
+            float f = stof(k);
+            bool isnum = ftos(f) == k;
+            X(boolean(isnum ? f : cvar(k)) == b);
+        }
+        #undef BINOP
+        #undef X
+    }
+    if (!expr_fail) {
+        ret = !ret;
+    }
+    // now ret is true if we want to keep the item, and false if we want to get rid of it
+    return ret;
+}
+
+void SV_OnEntityPreSpawnFunction(entity this)
+{
+       if (this)
+       if (this.gametypefilter != "")
+       if (!isGametypeInFilter(MapInfo_LoadedGametype, teamplay, have_team_spawns, this.gametypefilter))
+       {
+               delete(this);
+               return;
+       }
+       if (this.cvarfilter != "" && !expr_evaluate(this.cvarfilter)) {
+               delete(this);
+               return;
+       }
+
+       if (DoesQ3ARemoveThisEntity(this)) {
+               delete(this);
+               return;
+       }
+
+       set_movetype(this, this.movetype);
+
+       if (this.monster_attack) {
+               IL_PUSH(g_monster_targets, this);
+    }
+
+       // support special -1 and -2 angle from radiant
+       if (this.angles == '0 -1 0') {
+               this.angles = '-90 0 0';
+       } else if (this.angles == '0 -2 0') {
+               this.angles = '+90 0 0';
+    }
+
+    #define X(out, in) MACRO_BEGIN \
+        if (in != 0) { out = out + (random() * 2 - 1) * in; } \
+    MACRO_END
+    X(this.origin.x, this.originjitter.x); X(this.origin.y, this.originjitter.y); X(this.origin.z, this.originjitter.z);
+    X(this.angles.x, this.anglesjitter.x); X(this.angles.y, this.anglesjitter.y); X(this.angles.z, this.anglesjitter.z);
+    X(this.angles.y, this.anglejitter);
+    #undef X
+
+       if (MUTATOR_CALLHOOK(OnEntityPreSpawn, this)) {
+               delete(this);
+               return;
+       }
+}
+
+void WarpZone_PostInitialize_Callback()
+{
+       // create waypoint links for warpzones
+       entity tracetest_ent = spawn();
+       setsize(tracetest_ent, PL_MIN_CONST, PL_MAX_CONST);
+       tracetest_ent.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
+       //for(entity e = warpzone_first; e; e = e.warpzone_next)
+       for(entity e = NULL; (e = find(e, classname, "trigger_warpzone")); )
+               waypoint_spawnforteleporter_wz(e, tracetest_ent);
+       delete(tracetest_ent);
+}
+
+/*
+==================
+main
+
+unused but required by the engine
+==================
+*/
+void main ()
+{
+
+}
diff --git a/qcsrc/server/main.qh b/qcsrc/server/main.qh
new file mode 100644 (file)
index 0000000..dc3d80d
--- /dev/null
@@ -0,0 +1,28 @@
+#pragma once
+
+bool expr_evaluate(string s);
+
+#ifdef PROFILING
+float client_cefc_accumulator;
+float client_cefc_accumulatortime;
+#endif
+
+float servertime, serverprevtime, serverframetime;
+
+.vector oldvelocity; // for fall damage
+
+.float watersound_finished;
+
+.bool iscreature;
+.float species;
+
+.float contents_damagetime;
+
+/*
+==================
+main
+
+unused but required by the engine
+==================
+*/
+void main ();
index e427483069522786f163c6ff9cf6908151c8e84f..ac64f630ff1d5181372a33c21fb4e67bde03588a 100644 (file)
@@ -1,9 +1,11 @@
 #include "mapvoting.qh"
 
-#include <server/defs.qh>
+#include <server/client.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 #include <server/gamelog.qh>
 #include <server/miscfunctions.qh>
-#include "g_world.qh"
+#include "world.qh"
 #include "command/cmd.qh"
 #include "command/getreplies.qh"
 #include "../common/constants.qh"
index 98bd7756a435844daf520e25fba77de9059bca51..e8b4ab681c5bb91a64e7ef650dd89c2dfd3018cd 100644 (file)
@@ -2,17 +2,22 @@
 
 #include "antilag.qh"
 #include "command/common.qh"
-#include "constants.qh"
-#include "g_hook.qh"
+#include "client.qh"
+#include "damage.qh"
+#include "hook.qh"
+#include "world.qh"
 #include <server/gamelog.qh>
 #include "ipban.qh"
+#include <server/items/items.qh>
 #include <server/mutators/_mod.qh>
-#include "../common/t_items.qh"
+#include <server/spawnpoints.qh>
+#include <server/main.qh>
 #include "mapvoting.qh"
 #include "resources.qh"
-#include "items.qh"
+#include <server/items/spawning.qh>
 #include "player.qh"
 #include "weapons/accuracy.qh"
+#include "weapons/common.qh"
 #include "weapons/csqcprojectile.qh"
 #include "weapons/selection.qh"
 #include "../common/command/_mod.qh"
@@ -25,6 +30,8 @@
 #include "../common/playerstats.qh"
 #include "../common/teams.qh"
 #include "../common/mapobjects/subs.qh"
+#include <common/mapobjects/trigger/hurt.qh>
+#include <common/mapobjects/target/location.qh>
 #include "../common/util.qh"
 #include "../common/turrets/sv_turrets.qh"
 #include <common/weapons/_all.qh>
@@ -350,46 +357,6 @@ string W_FixWeaponOrder_ForceComplete_AndBuildImpulseList(entity this, string wo
        return o;
 }
 
-REPLICATE(autoswitch, bool, "cl_autoswitch");
-
-REPLICATE(cvar_cl_allow_uid2name, bool, "cl_allow_uid2name");
-
-REPLICATE(cvar_cl_allow_uidranking, bool, "cl_allow_uidranking");
-
-REPLICATE(cvar_cl_autoscreenshot, int, "cl_autoscreenshot");
-
-REPLICATE(cvar_cl_autotaunt, float, "cl_autotaunt");
-
-REPLICATE(cvar_cl_clippedspectating, bool, "cl_clippedspectating");
-
-REPLICATE(cvar_cl_handicap, float, "cl_handicap");
-
-REPLICATE(cvar_cl_gunalign, int, "cl_gunalign");
-
-REPLICATE(cvar_cl_jetpack_jump, bool, "cl_jetpack_jump");
-
-REPLICATE(cvar_cl_movement_track_canjump, bool, "cl_movement_track_canjump");
-
-REPLICATE(cvar_cl_newusekeysupported, bool, "cl_newusekeysupported");
-
-REPLICATE(cvar_cl_noantilag, bool, "cl_noantilag");
-
-REPLICATE(cvar_cl_physics, string, "cl_physics");
-
-REPLICATE(cvar_cl_voice_directional, int, "cl_voice_directional");
-
-REPLICATE(cvar_cl_voice_directional_taunt_attenuation, float, "cl_voice_directional_taunt_attenuation");
-
-REPLICATE(cvar_cl_weaponimpulsemode, int, "cl_weaponimpulsemode");
-
-REPLICATE(cvar_g_xonoticversion, string, "g_xonoticversion");
-
-REPLICATE(cvar_cl_cts_noautoswitch, bool, "cl_cts_noautoswitch");
-
-REPLICATE(cvar_cl_weapon_switch_reload, bool, "cl_weapon_switch_reload");
-
-REPLICATE(cvar_cl_weapon_switch_fallback_to_impulse, bool, "cl_weapon_switch_fallback_to_impulse");
-
 /**
  * @param f -1: cleanup, 0: request, 1: receive
  */
index 1ec27a7818a1cd900aa05f51368968051d358887..8a2406316cc9038549fc15f38fa303a40c349245 100644 (file)
@@ -1,9 +1,11 @@
 #pragma once
 
-#include <server/defs.qh>
-#include <server/g_world.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
+#include <server/client.qh>
+#include <server/world.qh>
 
-#include <common/t_items.qh>
+#include <server/items/items.qh>
 
 #include <server/mutators/_mod.qh>
 
@@ -198,6 +200,19 @@ void readplayerstartcvars();
 float sv_autotaunt;
 float sv_taunt;
 
+float g_footsteps, g_grappling_hook;
+float g_warmup_allguns;
+float g_warmup_allow_timeout;
+float warmup_stage;
+float g_jetpack;
+
+bool sv_ready_restart;
+bool sv_ready_restart_after_countdown;
+bool sv_ready_restart_repeatable;
+
+float sv_clones;
+float sv_foginterval;
+
 void readlevelcvars()
 {
        if(cvar("sv_allow_fullbright"))
index 7c20b372906b842661b3abfa2e577a88448af81f..f15098766fe069e8b26db3edcb3328508e23d96f 100644 (file)
@@ -1,6 +1,7 @@
 #include "loader.qh"
 
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 #include <server/miscfunctions.qh>
 
 STATIC_INIT_LATE(Gametype) {
index 1449e382a6913daffb425bb5d58d5b7e666cb564..7dcaec8862b3727390a80e16dbd3938ff512e9c6 100644 (file)
@@ -28,10 +28,10 @@ float pathlib_g_euclidean_water(entity parent,vector to, float static_cost)
 
 
 /**
-    Manhattan Menas we expect to move up,down left or right
-    No diagonal moves espected. (like moving bewteen city blocks)
+    Manhattan heuristic means we expect to move up, down left or right
+    No diagonal moves expected. (like moving between city blocks)
 **/
-float pathlib_h_manhattan(vector a,vector b)
+float pathlib_h_manhattan(vector a, vector b)
 {
     //h(n) = D * (abs(n.x-goal.x) + abs(n.y-goal.y))
 
@@ -43,33 +43,33 @@ float pathlib_h_manhattan(vector a,vector b)
 }
 
 /**
-    This heuristic consider both stright and disagonal moves
-    to have teh same cost.
+    This heuristic consider both straight and diagonal moves
+    to have the same cost.
 **/
-float pathlib_h_diagonal(vector a,vector b)
+float pathlib_h_diagonal(vector a, vector b)
 {
     //h(n) = D * max(abs(n.x-goal.x), abs(n.y-goal.y))
 
     float hx = fabs(a.x - b.x);
     float hy = fabs(a.y - b.y);
-    float h = pathlib_movecost * max(hx,hy);
+    float h = pathlib_movecost * max(hx, hy);
 
     return h;
 }
 
 /**
-    This heuristic only considers the stright line distance.
-    Will usualy mean a lower H then G meaning A* Will speand more
-    and run slower.
+    This heuristic only considers the straight line distance.
+    Usually means a lower H then G, resulting in A* spreading more
+    (and running slower).
 **/
-float pathlib_h_euclidean(vector a,vector b)
+float pathlib_h_euclidean(vector a, vector b)
 {
     return vlen(a - b);
 }
 
 /**
-    This heuristic consider both stright and disagonal moves,
-    But has a separate cost for diagonal moves.
+    This heuristic consider both straight and diagonal moves,
+    but has a separate cost for diagonal moves.
 **/
 float pathlib_h_diagonal2(vector a,vector b)
 {
@@ -92,10 +92,10 @@ float pathlib_h_diagonal2(vector a,vector b)
 }
 
 /**
-    This heuristic consider both stright and disagonal moves,
+    This heuristic consider both straight and diagonal moves,
     But has a separate cost for diagonal moves.
 **/
-float pathlib_h_diagonal2sdp(vector preprev,vector prev,vector point,vector end)
+float pathlib_h_diagonal2sdp(vector preprev, vector prev, vector point, vector end)
 {
     //h_diagonal(n) = min(abs(n.x-goal.x), abs(n.y-goal.y))
     //h_straight(n) = (abs(n.x-goal.x) + abs(n.y-goal.y))
@@ -113,13 +113,13 @@ float pathlib_h_diagonal2sdp(vector preprev,vector prev,vector point,vector end)
 
     vector d1 = normalize(preprev - point);
     vector d2 = normalize(prev    - point);
-    float m = vlen(d1-d2);
+    float m = vlen(d1 - d2);
 
     return h * m;
 }
 
 
-float pathlib_h_diagonal3(vector a,vector b)
+float pathlib_h_diagonal3(vector a, vector b)
 {
     float hx = fabs(a.x - b.x);
     float hy = fabs(a.y - b.y);
index b77736b19ad7c098c5ab3a0c8bf9dfeb7ba2f76c..e3ab647487c6f7be297d52441528b313e322de52 100644 (file)
@@ -2,6 +2,7 @@
 #include "pathlib.qh"
 #include "utility.qh"
 
+/*
 vector plib_points2[8];
 vector plib_points[8];
 float  plib_fvals[8];
@@ -73,13 +74,11 @@ float pathlib_expandnode_starf(entity node, vector start, vector goal)
             ++fc2;
         }
 
-        /*
-        nap = pathlib_nodeatpoint(plib_points[i]);
-        if(nap)
-        if not nap.owner == closedlist)
-        {
-        }
-        */
+        //nap = pathlib_nodeatpoint(plib_points[i]);
+        //if(nap)
+        //if not nap.owner == closedlist)
+        //{
+        //}
     }
 
     pathlib_makenode(node, start, bp, goal, pathlib_gridsize);
@@ -91,6 +90,7 @@ float pathlib_expandnode_starf(entity node, vector start, vector goal)
 
     return pathlib_open_cnt;
 }
+*/
 
 float pathlib_expandnode_star(entity node, vector start, vector goal)
 {
@@ -171,6 +171,7 @@ float pathlib_expandnode_star(entity node, vector start, vector goal)
     return pathlib_open_cnt;
 }
 
+/*
 float pathlib_expandnode_octagon(entity node, vector start, vector goal)
 {
     vector point;
@@ -203,12 +204,10 @@ float pathlib_expandnode_octagon(entity node, vector start, vector goal)
     point = where + f + r;
     pathlib_makenode(node, start, point, goal, pathlib_movecost);
 
-
     // Forward-left
     point = where + f - r;
     pathlib_makenode(node, start, point, goal, pathlib_movecost);
 
-
     // Back-right
     point = where - f + r;
     pathlib_makenode(node, start, point, goal, pathlib_movecost);
@@ -219,6 +218,7 @@ float pathlib_expandnode_octagon(entity node, vector start, vector goal)
 
     return pathlib_open_cnt;
 }
+*/
 
 float pathlib_expandnode_box(entity node, vector start, vector goal)
 {
index 4cb8a3806c6883f32cb8550abc9388eda50cef5a..b42e5ef688ec39f2e1879adc8966b0819e61102d 100644 (file)
@@ -1,6 +1,7 @@
 #include "main.qh"
 
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 #include <server/miscfunctions.qh>
 #include "pathlib.qh"
 #include "utility.qh"
index cbcfe3d4c6038f07c00abb44047019d6988748a3..06568ae0d3d99f3a3dbdde94e956262ec219bbdf 100644 (file)
@@ -1,6 +1,8 @@
 #include "movenode.qh"
 
-#include <server/defs.qh>
+#include <common/mapobjects/triggers.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 #include <server/miscfunctions.qh>
 #include "pathlib.qh"
 #include "utility.qh"
index 906ebc7a54b1134d4291648da47e58c878b7831c..0f1c4e85a4c74eb876b9ae53297bd510a1975bef 100644 (file)
@@ -76,38 +76,38 @@ float pathlib_wpp_openncb(entity wp, entity child, float cost)
 
 float pathlib_wpp_expand(entity wp)
 {
-    if(wp.wp00) pathlib_wpp_open(wp,wp.wp00,wp.wp00mincost); else return 0;
-    if(wp.wp01) pathlib_wpp_open(wp,wp.wp01,wp.wp01mincost); else return 1;
-    if(wp.wp02) pathlib_wpp_open(wp,wp.wp02,wp.wp02mincost); else return 2;
-    if(wp.wp03) pathlib_wpp_open(wp,wp.wp03,wp.wp03mincost); else return 3;
-    if(wp.wp04) pathlib_wpp_open(wp,wp.wp04,wp.wp04mincost); else return 4;
-    if(wp.wp05) pathlib_wpp_open(wp,wp.wp05,wp.wp05mincost); else return 5;
-    if(wp.wp06) pathlib_wpp_open(wp,wp.wp06,wp.wp06mincost); else return 6;
-    if(wp.wp07) pathlib_wpp_open(wp,wp.wp07,wp.wp07mincost); else return 7;
-    if(wp.wp08) pathlib_wpp_open(wp,wp.wp08,wp.wp08mincost); else return 8;
-    if(wp.wp09) pathlib_wpp_open(wp,wp.wp09,wp.wp09mincost); else return 9;
-    if(wp.wp10) pathlib_wpp_open(wp,wp.wp10,wp.wp10mincost); else return 10;
-    if(wp.wp11) pathlib_wpp_open(wp,wp.wp11,wp.wp11mincost); else return 11;
-    if(wp.wp12) pathlib_wpp_open(wp,wp.wp12,wp.wp12mincost); else return 12;
-    if(wp.wp13) pathlib_wpp_open(wp,wp.wp13,wp.wp13mincost); else return 13;
-    if(wp.wp14) pathlib_wpp_open(wp,wp.wp14,wp.wp14mincost); else return 14;
-    if(wp.wp15) pathlib_wpp_open(wp,wp.wp15,wp.wp15mincost); else return 15;
-    if(wp.wp16) pathlib_wpp_open(wp,wp.wp16,wp.wp16mincost); else return 16;
-    if(wp.wp17) pathlib_wpp_open(wp,wp.wp17,wp.wp17mincost); else return 17;
-    if(wp.wp18) pathlib_wpp_open(wp,wp.wp18,wp.wp18mincost); else return 18;
-    if(wp.wp19) pathlib_wpp_open(wp,wp.wp19,wp.wp19mincost); else return 19;
-    if(wp.wp20) pathlib_wpp_open(wp,wp.wp20,wp.wp20mincost); else return 20;
-    if(wp.wp21) pathlib_wpp_open(wp,wp.wp21,wp.wp21mincost); else return 21;
-    if(wp.wp22) pathlib_wpp_open(wp,wp.wp22,wp.wp22mincost); else return 22;
-    if(wp.wp23) pathlib_wpp_open(wp,wp.wp23,wp.wp23mincost); else return 23;
-    if(wp.wp24) pathlib_wpp_open(wp,wp.wp24,wp.wp24mincost); else return 24;
-    if(wp.wp25) pathlib_wpp_open(wp,wp.wp25,wp.wp25mincost); else return 25;
-    if(wp.wp26) pathlib_wpp_open(wp,wp.wp26,wp.wp26mincost); else return 26;
-    if(wp.wp27) pathlib_wpp_open(wp,wp.wp27,wp.wp27mincost); else return 27;
-    if(wp.wp28) pathlib_wpp_open(wp,wp.wp28,wp.wp28mincost); else return 28;
-    if(wp.wp29) pathlib_wpp_open(wp,wp.wp29,wp.wp29mincost); else return 29;
-    if(wp.wp30) pathlib_wpp_open(wp,wp.wp30,wp.wp30mincost); else return 30;
-    if(wp.wp31) pathlib_wpp_open(wp,wp.wp31,wp.wp31mincost); else return 31;
+    if(wp.wp00) pathlib_wpp_open(wp,wp.wp00, wp.wp00mincost); else return 0;
+    if(wp.wp01) pathlib_wpp_open(wp,wp.wp01, wp.wp01mincost); else return 1;
+    if(wp.wp02) pathlib_wpp_open(wp,wp.wp02, wp.wp02mincost); else return 2;
+    if(wp.wp03) pathlib_wpp_open(wp,wp.wp03, wp.wp03mincost); else return 3;
+    if(wp.wp04) pathlib_wpp_open(wp,wp.wp04, wp.wp04mincost); else return 4;
+    if(wp.wp05) pathlib_wpp_open(wp,wp.wp05, wp.wp05mincost); else return 5;
+    if(wp.wp06) pathlib_wpp_open(wp,wp.wp06, wp.wp06mincost); else return 6;
+    if(wp.wp07) pathlib_wpp_open(wp,wp.wp07, wp.wp07mincost); else return 7;
+    if(wp.wp08) pathlib_wpp_open(wp,wp.wp08, wp.wp08mincost); else return 8;
+    if(wp.wp09) pathlib_wpp_open(wp,wp.wp09, wp.wp09mincost); else return 9;
+    if(wp.wp10) pathlib_wpp_open(wp,wp.wp10, wp.wp10mincost); else return 10;
+    if(wp.wp11) pathlib_wpp_open(wp,wp.wp11, wp.wp11mincost); else return 11;
+    if(wp.wp12) pathlib_wpp_open(wp,wp.wp12, wp.wp12mincost); else return 12;
+    if(wp.wp13) pathlib_wpp_open(wp,wp.wp13, wp.wp13mincost); else return 13;
+    if(wp.wp14) pathlib_wpp_open(wp,wp.wp14, wp.wp14mincost); else return 14;
+    if(wp.wp15) pathlib_wpp_open(wp,wp.wp15, wp.wp15mincost); else return 15;
+    if(wp.wp16) pathlib_wpp_open(wp,wp.wp16, wp.wp16mincost); else return 16;
+    if(wp.wp17) pathlib_wpp_open(wp,wp.wp17, wp.wp17mincost); else return 17;
+    if(wp.wp18) pathlib_wpp_open(wp,wp.wp18, wp.wp18mincost); else return 18;
+    if(wp.wp19) pathlib_wpp_open(wp,wp.wp19, wp.wp19mincost); else return 19;
+    if(wp.wp20) pathlib_wpp_open(wp,wp.wp20, wp.wp20mincost); else return 20;
+    if(wp.wp21) pathlib_wpp_open(wp,wp.wp21, wp.wp21mincost); else return 21;
+    if(wp.wp22) pathlib_wpp_open(wp,wp.wp22, wp.wp22mincost); else return 22;
+    if(wp.wp23) pathlib_wpp_open(wp,wp.wp23, wp.wp23mincost); else return 23;
+    if(wp.wp24) pathlib_wpp_open(wp,wp.wp24, wp.wp24mincost); else return 24;
+    if(wp.wp25) pathlib_wpp_open(wp,wp.wp25, wp.wp25mincost); else return 25;
+    if(wp.wp26) pathlib_wpp_open(wp,wp.wp26, wp.wp26mincost); else return 26;
+    if(wp.wp27) pathlib_wpp_open(wp,wp.wp27, wp.wp27mincost); else return 27;
+    if(wp.wp28) pathlib_wpp_open(wp,wp.wp28, wp.wp28mincost); else return 28;
+    if(wp.wp29) pathlib_wpp_open(wp,wp.wp29, wp.wp29mincost); else return 29;
+    if(wp.wp30) pathlib_wpp_open(wp,wp.wp30, wp.wp30mincost); else return 30;
+    if(wp.wp31) pathlib_wpp_open(wp,wp.wp31, wp.wp31mincost); else return 31;
 
     return 32;
 }
@@ -146,7 +146,7 @@ entity pathlib_waypointpath(entity wp_from, entity wp_to, float callback)
        else
                pathlib_wpp_open = pathlib_wpp_openncb;
 
-       pathlib_heuristic = pathlib_h_none;
+       pathlib_heuristic = pathlib_h_none; // We run Dijkstra, A* does not make sense with variable distanced nodes.
 
     if (!openlist)
         openlist       = spawn();
index d1bafe392a892e2fae67b165eb9c8b32d1a41a9a..edfb98b2a2104962d736327f377037a1d8d5c13a 100644 (file)
@@ -80,9 +80,10 @@ vector     pathlib_flynode(entity this, vector start, vector end, float doedge);
 vector     pathlib_walknode(entity this, vector start, vector end, float doedge);
 var vector pathlib_movenode(entity this, vector start, vector end, float doedge);
 
+//float      pathlib_expandnode_starf(entity node, vector start, vector goal);
 float      pathlib_expandnode_star(entity node, vector start, vector goal);
 float      pathlib_expandnode_box(entity node, vector start, vector goal);
-float      pathlib_expandnode_octagon(entity node, vector start, vector goal);
+//float      pathlib_expandnode_octagon(entity node, vector start, vector goal);
 var float  pathlib_expandnode(entity node, vector start, vector goal);
 
 float      pathlib_g_static(entity parent, vector to, float static_cost);
@@ -104,3 +105,6 @@ var bool  pathlib_makenode(entity parent,vector start, vector to, vector goal,fl
 var bool  buildpath_nodefilter(vector n,vector c,vector p);
 
 var float  pathlib_wpp_waypointcallback(entity wp, entity wp_prev);
+
+IntrusiveList g_pathlib_nodes;
+STATIC_INIT(g_pathlib_nodes) { g_pathlib_nodes = IL_NEW(); }
index 151fb44b56abec6096379d63b351b42a315e7d9a..51d3f65c9e8f3e8b2dcf7d9789727c9a1573f486 100644 (file)
@@ -1,6 +1,7 @@
 #include "utility.qh"
 
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 #include <server/miscfunctions.qh>
 #include "pathlib.qh"
 
index 1333b2386d81e59d4673858b5f1cac89a81bbc8c..ef60454033748a5c25acbdb3a74cefc8f4cf3447 100644 (file)
@@ -3,14 +3,19 @@
 #include <common/effects/all.qh>
 #include "bot/api.qh"
 #include "cheats.qh"
+#include "client.qh"
 #include "clientkill.qh"
-#include "g_damage.qh"
+#include "damage.qh"
+#include "world.qh"
 #include "handicap.qh"
 #include "miscfunctions.qh"
 #include "portals.qh"
 #include "teamplay.qh"
+#include <server/main.qh>
+#include "weapons/common.qh"
 #include "weapons/throwing.qh"
 #include "command/common.qh"
+#include "command/vote.qh"
 #include "../common/state.qh"
 #include "../common/anim.qh"
 #include "../common/animdecide.qh"
@@ -18,6 +23,7 @@
 #include "../common/gamemodes/sv_rules.qh"
 #include "../common/deathtypes/all.qh"
 #include "../common/mapobjects/subs.qh"
+#include <common/mapobjects/teleporters.qh>
 #include "../common/playerstats.qh"
 #include "../lib/csqcmodel/sv_model.qh"
 
@@ -32,6 +38,7 @@
 #include "../common/wepent.qh"
 
 #include "weapons/weaponstats.qh"
+#include <server/weapons/weaponsystem.qh>
 
 #include "../common/animdecide.qh"
 
@@ -165,7 +172,7 @@ void player_anim(entity this)
                animbits |= ANIMSTATE_FROZEN;
        if(this.move_movetype == MOVETYPE_FOLLOW)
                animbits |= ANIMSTATE_FOLLOW;
-       if(this.crouch)
+       if(IS_DUCKED(this))
                animbits |= ANIMSTATE_DUCK;
        animdecide_setstate(this, animbits, false);
        animdecide_setimplicitstate(this, IS_ONGROUND(this));
@@ -222,92 +229,6 @@ void PlayerCorpseDamage(entity this, entity inflictor, entity attacker, float da
        }
 }
 
-void calculate_player_respawn_time(entity this)
-{
-       if(MUTATOR_CALLHOOK(CalculateRespawnTime, this))
-               return;
-
-       float gametype_setting_tmp;
-       float sdelay_max = GAMETYPE_DEFAULTED_SETTING(respawn_delay_max);
-       float sdelay_small = GAMETYPE_DEFAULTED_SETTING(respawn_delay_small);
-       float sdelay_large = GAMETYPE_DEFAULTED_SETTING(respawn_delay_large);
-       float sdelay_small_count = GAMETYPE_DEFAULTED_SETTING(respawn_delay_small_count);
-       float sdelay_large_count = GAMETYPE_DEFAULTED_SETTING(respawn_delay_large_count);
-       float waves = GAMETYPE_DEFAULTED_SETTING(respawn_waves);
-
-       float pcount = 1;  // Include myself whether or not team is already set right and I'm a "player".
-       if (teamplay)
-       {
-               FOREACH_CLIENT(IS_PLAYER(it) && it != this, {
-                       if(it.team == this.team)
-                               ++pcount;
-               });
-               if (sdelay_small_count == 0)
-                       sdelay_small_count = 1;
-               if (sdelay_large_count == 0)
-                       sdelay_large_count = 1;
-       }
-       else
-       {
-               FOREACH_CLIENT(IS_PLAYER(it) && it != this, {
-                       ++pcount;
-               });
-               if (sdelay_small_count == 0)
-               {
-                       if (IS_INDEPENDENT_PLAYER(this))
-                       {
-                               // Players play independently. No point in requiring enemies.
-                               sdelay_small_count = 1;
-                       }
-                       else
-                       {
-                               // Players play AGAINST each other. Enemies required.
-                               sdelay_small_count = 2;
-                       }
-               }
-               if (sdelay_large_count == 0)
-               {
-                       if (IS_INDEPENDENT_PLAYER(this))
-                       {
-                               // Players play independently. No point in requiring enemies.
-                               sdelay_large_count = 1;
-                       }
-                       else
-                       {
-                               // Players play AGAINST each other. Enemies required.
-                               sdelay_large_count = 2;
-                       }
-               }
-       }
-
-       float sdelay;
-
-       if (pcount <= sdelay_small_count)
-               sdelay = sdelay_small;
-       else if (pcount >= sdelay_large_count)
-               sdelay = sdelay_large;
-       else  // NOTE: this case implies sdelay_large_count > sdelay_small_count.
-               sdelay = sdelay_small + (sdelay_large - sdelay_small) * (pcount - sdelay_small_count) / (sdelay_large_count - sdelay_small_count);
-
-       if(waves)
-               this.respawn_time = ceil((time + sdelay) / waves) * waves;
-       else
-               this.respawn_time = time + sdelay;
-
-       if(sdelay < sdelay_max)
-               this.respawn_time_max = time + sdelay_max;
-       else
-               this.respawn_time_max = this.respawn_time;
-
-       if((sdelay + waves >= 5.0) && (this.respawn_time - time > 1.75))
-               this.respawn_countdown = 10; // first number to count down from is 10
-       else
-               this.respawn_countdown = -1; // do not count down
-
-       if(autocvar_g_forced_respawn)
-               this.respawn_flags = this.respawn_flags | RESPAWN_FORCE;
-}
-
 void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force)
 {
        vector v;
index 514b34726c2edf295dc9c79e00bfca8f6dbc5f00..86433d456f726c62b2d37218b0d3f713e992b7fa 100644 (file)
@@ -4,6 +4,8 @@
 .float pushltime;
 .bool istypefrag;
 
+.float death_time;
+
 .float CopyBody_nextthink;
 .void(entity this) CopyBody_think;
 void CopyBody_Think(entity this);
@@ -15,19 +17,9 @@ void player_anim(entity this);
 
 void PlayerCorpseDamage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force);
 
-// g_<gametype>_str:
-// If 0, default is used.
-// If <0, 0 is used.
-// Otherwise, g_str (default value) is used.
-// For consistency, negative values there are mapped to zero too.
-#define GAMETYPE_DEFAULTED_SETTING(str) \
-       ((gametype_setting_tmp = cvar(strcat("g_", GetGametype(), "_" #str))), \
-       (gametype_setting_tmp < 0) ? 0 \
-       : (gametype_setting_tmp == 0 || autocvar_g_respawn_delay_forced) ? max(0, autocvar_g_##str) \
-       : gametype_setting_tmp)
-
-void calculate_player_respawn_time(entity this);
-
 void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force);
 
 bool PlayerHeal(entity targ, entity inflictor, float amount, float limit);
+
+IntrusiveList g_clones;
+STATIC_INIT(g_clones) { g_clones = IL_NEW(); }
index 0eb325699d8f05716456d332685ab665c21e7ec4..7abe6ae9786bd75941f6b927e214dacf80b6508e 100644 (file)
@@ -1,12 +1,15 @@
 #include "portals.qh"
 
 #include <common/effects/all.qh>
-#include "g_hook.qh"
+#include "hook.qh"
 #include "mutators/_mod.qh"
+#include <server/client.qh>
+#include <server/weapons/common.qh>
 #include "../common/constants.qh"
 #include "../common/deathtypes/all.qh"
 #include "../common/notifications/all.qh"
 #include "../common/mapobjects/teleporters.qh"
+#include <common/mapobjects/triggers.qh>
 #include "../common/mapobjects/subs.qh"
 #include "../common/util.qh"
 #include <common/weapons/_all.qh>
@@ -16,7 +19,9 @@
 #include "../lib/warpzone/common.qh"
 #include "../common/vehicles/vehicle.qh"
 #include "../common/vehicles/sv_vehicles.qh"
+#include <common/weapons/weapon/porto.qh>
 #include <server/player.qh>
+#include <server/damage.qh>
 
 #define PORTALS_ARE_NOT_SOLID
 
index 43443a11ff445a20e0e45d448ae753d62e83a176..c2de3c9cc63e830a1859f7a16989a3e66d08c55e 100644 (file)
@@ -1,8 +1,13 @@
 #include "race.qh"
 
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
+#include <server/damage.qh>
+#include <server/world.qh>
 #include <server/miscfunctions.qh>
+#include <server/weapons/common.qh>
 #include "client.qh"
+#include "cheats.qh"
 #include "portals.qh"
 #include "scores.qh"
 #include "spawnpoints.qh"
index 4dafbcf63710615df0b75b9ee07df04f4e9718d6..129e99da1b7b6e0c7eff802568c3771afc39802a 100644 (file)
@@ -1,5 +1,7 @@
 #pragma once
 
+.string stored_netname; // TODO: store this information independently of race-based gamemodes
+
 float race_teams;
 
 // scores
index d347fcbaf9be95d010a8af0378795ffe3c9fe315..66da6c37c1fb154ec39cac5381e57be04e9978a3 100644 (file)
@@ -1,9 +1,10 @@
 #include "round_handler.qh"
 
-#include <server/defs.qh>
+#include <server/world.qh>
 #include <server/miscfunctions.qh>
 #include "campaign.qh"
 #include "command/vote.qh"
+#include <common/mapobjects/triggers.qh>
 #include "../common/util.qh"
 
 void round_handler_Think(entity this)
index 12175bb764f036435c1f745c0ac2ddc12fe74777..e4e1d236aba4c11690c06c50dc99a03bd9dcb0c1 100644 (file)
@@ -1,8 +1,9 @@
 #include "scores.qh"
 
 #include "command/common.qh"
-#include "defs.qh"
-#include <server/g_world.qh>
+#include <common/weapons/_all.qh>
+#include "client.qh"
+#include <server/world.qh>
 #include <server/miscfunctions.qh>
 #include <server/mutators/_mod.qh>
 #include <server/round_handler.qh>
index 39dbd49a35ddc630c85c849624330e1785d30d01..7511162aa57748ab2f3385185c3bd26f541b814f 100644 (file)
@@ -1,6 +1,7 @@
 #include "scores_rules.qh"
 
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 #include <server/miscfunctions.qh>
 #include "client.qh"
 #include "scores.qh"
index 3dc76afc0df832d926703f7ffd1fa2611af803ce..b629ef168449af6f5280a1fd5469ddacc2bc645b 100644 (file)
@@ -1,20 +1,23 @@
 #include "spawnpoints.qh"
 
 #include <server/mutators/_mod.qh>
-#include "g_world.qh"
+#include "world.qh"
 #include "miscfunctions.qh"
 #include "race.qh"
-#include "defs.qh"
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 #include "../common/constants.qh"
 #include <common/net_linked.qh>
 #include "../common/teams.qh"
 #include <common/gamemodes/_mod.qh>
 #include "../common/mapobjects/subs.qh"
 #include "../common/mapobjects/target/spawnpoint.qh"
+#include <common/mapobjects/triggers.qh>
 #include "../common/util.qh"
 #include "../lib/warpzone/common.qh"
 #include "../lib/warpzone/util_server.qh"
 #include <server/utils.qh>
+#include <server/command/vote.qh>
 
 bool SpawnPoint_Send(entity this, entity to, int sf)
 {
index fe6adaebf2cc7fa7ab47c10a530da0b7e907edf8..39b5492c5e2aab8cfad6b48f0655d0abf4a83139 100644 (file)
@@ -6,6 +6,10 @@ const int SPAWN_PRIO_NEAR_TEAMMATE_SAMETEAM = 100;
 const int SPAWN_PRIO_RACE_PREVIOUS_SPAWN = 50;
 const int SPAWN_PRIO_GOOD_DISTANCE = 10;
 
+bool some_spawn_has_been_used;
+int have_team_spawns; // 0 = no team spawns requested, -1 = team spawns requested but none found, 1 = team spawns requested and found
+int have_team_spawns_forteams; // if Xth bit is 1 then team X has spawns else it has no spawns; team 0 is the "no-team"
+
 .vector spawnpoint_score;
 float spawnpoint_nag;
 bool SpawnEvent_Send(entity this, entity to, int sf);
@@ -13,3 +17,11 @@ entity Spawn_FilterOutBadSpots(entity this, entity firstspot, float mindist, flo
 entity SelectSpawnPoint(entity this, bool anypoint);
 spawnfunc(info_player_deathmatch);
 void spawnpoint_use(entity this, entity actor, entity trigger);
+
+USING(spawn_evalfunc_t, vector(entity this, entity player, entity spot, vector current));
+.spawn_evalfunc_t spawn_evalfunc;
+
+.int restriction;
+
+IntrusiveList g_spawnpoints;
+STATIC_INIT(g_spawnpoints) { g_spawnpoints = IL_NEW(); }
diff --git a/qcsrc/server/sv_main.qc b/qcsrc/server/sv_main.qc
deleted file mode 100644 (file)
index 0944620..0000000
+++ /dev/null
@@ -1,404 +0,0 @@
-#include "sv_main.qh"
-
-#include "anticheat.qh"
-#include "g_hook.qh"
-#include "g_damage.qh"
-#include "g_world.qh"
-#include <server/gamelog.qh>
-
-#include "bot/api.qh"
-
-#include "command/common.qh"
-
-#include <server/mutators/_mod.qh>
-#include "weapons/csqcprojectile.qh"
-#include <server/compat/quake3.qh>
-
-#include "../common/constants.qh"
-#include "../common/deathtypes/all.qh"
-#include "../common/debug.qh"
-#include "../common/mapinfo.qh"
-#include "../common/util.qh"
-
-#include "../common/vehicles/all.qh"
-#include <common/monsters/sv_monsters.qh>
-#include <common/weapons/_all.qh>
-
-#include "../lib/csqcmodel/sv_model.qh"
-
-#include "../lib/warpzone/common.qh"
-#include "../lib/warpzone/server.qh"
-
-void CreatureFrame_hotliquids(entity this)
-{
-       if (this.dmgtime >= time)
-       {
-               return;
-       }
-
-       this.dmgtime = time + autocvar_g_balance_contents_damagerate;
-
-       if (this.flags & FL_PROJECTILE)
-       {
-               if (this.watertype == CONTENT_LAVA)
-                       Damage (this, NULL, NULL, autocvar_g_balance_contents_projectiledamage * autocvar_g_balance_contents_damagerate * this.waterlevel, DEATH_LAVA.m_id, DMG_NOWEP, this.origin, '0 0 0');
-               else if (this.watertype == CONTENT_SLIME)
-                       Damage (this, NULL, NULL, autocvar_g_balance_contents_projectiledamage * autocvar_g_balance_contents_damagerate * this.waterlevel, DEATH_SLIME.m_id, DMG_NOWEP, this.origin, '0 0 0');
-       }
-       else
-       {
-               if (STAT(FROZEN, this))
-               {
-                       if (this.watertype == CONTENT_LAVA)
-                               Damage(this, NULL, NULL, 10000, DEATH_LAVA.m_id, DMG_NOWEP, this.origin, '0 0 0');
-                       else if (this.watertype == CONTENT_SLIME)
-                               Damage(this, NULL, NULL, 10000, DEATH_SLIME.m_id, DMG_NOWEP, this.origin, '0 0 0');
-               }
-               else if (this.watertype == CONTENT_LAVA)
-               {
-                       if (this.watersound_finished < time)
-                       {
-                               this.watersound_finished = time + 0.5;
-                               sound (this, CH_PLAYER_SINGLE, SND_LAVA, VOL_BASE, ATTEN_NORM);
-                       }
-                       Damage (this, NULL, NULL, autocvar_g_balance_contents_playerdamage_lava * autocvar_g_balance_contents_damagerate * this.waterlevel, DEATH_LAVA.m_id, DMG_NOWEP, this.origin, '0 0 0');
-                       if(autocvar_g_balance_contents_playerdamage_lava_burn)
-                               Fire_AddDamage(this, NULL, autocvar_g_balance_contents_playerdamage_lava_burn * this.waterlevel, autocvar_g_balance_contents_playerdamage_lava_burn_time * this.waterlevel, DEATH_LAVA.m_id);
-               }
-               else if (this.watertype == CONTENT_SLIME)
-               {
-                       if (this.watersound_finished < time)
-                       {
-                               this.watersound_finished = time + 0.5;
-                               sound (this, CH_PLAYER_SINGLE, SND_SLIME, VOL_BASE, ATTEN_NORM);
-                       }
-                       Damage (this, NULL, NULL, autocvar_g_balance_contents_playerdamage_slime * autocvar_g_balance_contents_damagerate * this.waterlevel, DEATH_SLIME.m_id, DMG_NOWEP, this.origin, '0 0 0');
-               }
-       }
-}
-
-void CreatureFrame_Liquids(entity this)
-{
-       if (this.watertype <= CONTENT_WATER && this.waterlevel > 0) // workaround a retarded bug made by id software :P (yes, it's that old of a bug)
-       {
-               if (!(this.flags & FL_INWATER))
-               {
-                       this.flags |= FL_INWATER;
-                       this.dmgtime = 0;
-               }
-
-               CreatureFrame_hotliquids(this);
-       }
-       else
-       {
-               if (this.flags & FL_INWATER)
-               {
-                       // play leave water sound
-                       this.flags &= ~FL_INWATER;
-                       this.dmgtime = 0;
-               }
-       }
-}
-
-void CreatureFrame_FallDamage(entity this)
-{
-       if(IS_VEHICLE(this) || (this.flags & FL_PROJECTILE))
-               return; // vehicles and projectiles don't receive fall damage
-       if(!(this.velocity || this.oldvelocity))
-               return; // if the entity hasn't moved and isn't moving, then don't do anything
-
-       // check for falling damage
-       bool have_hook = false;
-       for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
-       {
-           .entity weaponentity = weaponentities[slot];
-           if(this.(weaponentity).hook && this.(weaponentity).hook.state)
-           {
-               have_hook = true;
-               break;
-           }
-       }
-       if(!have_hook)
-       {
-               float dm; // dm is the velocity DECREASE. Velocity INCREASE should never cause a sound or any damage.
-               if(autocvar_g_balance_falldamage_onlyvertical)
-                       dm = fabs(this.oldvelocity.z) - vlen(this.velocity);
-               else
-                       dm = vlen(this.oldvelocity) - vlen(this.velocity);
-               if (IS_DEAD(this))
-                       dm = (dm - autocvar_g_balance_falldamage_deadminspeed) * autocvar_g_balance_falldamage_factor;
-               else
-                       dm = min((dm - autocvar_g_balance_falldamage_minspeed) * autocvar_g_balance_falldamage_factor, autocvar_g_balance_falldamage_maxdamage);
-               if (dm > 0)
-               {
-                       tracebox(this.origin, this.mins, this.maxs, this.origin - '0 0 1', MOVE_NOMONSTERS, this);
-                       if (!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NODAMAGE))
-                               Damage (this, NULL, NULL, dm, DEATH_FALL.m_id, DMG_NOWEP, this.origin, '0 0 0');
-               }
-       }
-
-       if(autocvar_g_maxspeed > 0 && vdist(this.velocity, >, autocvar_g_maxspeed))
-               Damage (this, NULL, NULL, 100000, DEATH_SHOOTING_STAR.m_id, DMG_NOWEP, this.origin, '0 0 0');
-}
-
-void CreatureFrame_All()
-{
-       if(game_stopped || time < game_starttime)
-               return;
-
-       IL_EACH(g_damagedbycontents, it.damagedbycontents,
-       {
-               if (it.move_movetype == MOVETYPE_NOCLIP) continue;
-               CreatureFrame_Liquids(it);
-               CreatureFrame_FallDamage(it);
-               it.oldvelocity = it.velocity;
-       });
-}
-
-void Pause_TryPause(bool ispaused)
-{
-       int n = 0;
-       FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), {
-               if (PHYS_INPUT_BUTTON_CHAT(it) != ispaused) return;
-               ++n;
-       });
-       if (!n) return;
-       setpause(ispaused);
-}
-
-void SV_PausedTic(float elapsedtime)
-{
-       if (!server_is_dedicated) Pause_TryPause(false);
-}
-
-/*
-=============
-StartFrame
-
-Called before each frame by the server
-=============
-*/
-
-bool game_delay_last;
-
-bool autocvar_sv_autopause = false;
-void systems_update();
-void sys_phys_update(entity this, float dt);
-void StartFrame()
-{
-    // TODO: if move is more than 50ms, split it into two moves (this matches QWSV behavior and the client prediction)
-    IL_EACH(g_players, IS_FAKE_CLIENT(it), sys_phys_update(it, frametime));
-    IL_EACH(g_players, IS_FAKE_CLIENT(it), PlayerPreThink(it));
-
-       execute_next_frame();
-       if (autocvar_sv_autopause && !server_is_dedicated) Pause_TryPause(true);
-
-       delete_fn = remove_unsafely; // not during spawning!
-       serverprevtime = servertime;
-       servertime = time;
-       serverframetime = frametime;
-
-#ifdef PROFILING
-       if(time > client_cefc_accumulatortime + 1)
-       {
-               float t = client_cefc_accumulator / (time - client_cefc_accumulatortime);
-               int c_seeing = 0;
-               int c_seen = 0;
-               FOREACH_CLIENT(true, {
-                       if(IS_REAL_CLIENT(it))
-                               ++c_seeing;
-                       if(IS_PLAYER(it))
-                               ++c_seen;
-               });
-               LOG_INFO(
-                   "CEFC time: ", ftos(t * 1000), "ms; ",
-            "CEFC calls per second: ", ftos(c_seeing * (c_seen - 1) / t), "; ",
-            "CEFC 100% load at: ", ftos(solve_quadratic(t, -t, -1) * '0 1 0')
-        );
-               client_cefc_accumulatortime = time;
-               client_cefc_accumulator = 0;
-       }
-#endif
-
-       IL_EACH(g_projectiles, it.csqcprojectile_clientanimate, CSQCProjectile_Check(it));
-
-       if (RedirectionThink()) return;
-
-       UncustomizeEntitiesRun();
-       InitializeEntitiesRun();
-
-       WarpZone_StartFrame();
-
-       sys_frametime = autocvar_sys_ticrate * autocvar_slowmo;
-       if (sys_frametime <= 0) sys_frametime = 1.0 / 60.0; // somewhat safe fallback
-
-       if (timeout_status == TIMEOUT_LEADTIME) // just before the timeout (when timeout_status will be TIMEOUT_ACTIVE)
-               orig_slowmo = autocvar_slowmo; // slowmo will be restored after the timeout
-
-       // detect when the pre-game countdown (if any) has ended and the game has started
-       bool game_delay = (time < game_starttime);
-       if (autocvar_sv_eventlog && game_delay_last && !game_delay)
-               GameLogEcho(":startdelay_ended");
-       game_delay_last = game_delay;
-
-       CreatureFrame_All();
-       CheckRules_World();
-
-       if (warmup_stage && !game_stopped && warmup_limit > 0 && time >= warmup_limit) {
-               ReadyRestart();
-               return;
-       }
-
-       bot_serverframe();
-       anticheat_startframe();
-       MUTATOR_CALLHOOK(SV_StartFrame);
-
-       GlobalStats_updateglobal();
-    FOREACH_CLIENT(true, GlobalStats_update(it));
-    IL_EACH(g_players, IS_FAKE_CLIENT(it), PlayerPostThink(it));
-}
-
-.vector originjitter;
-.vector anglesjitter;
-.float anglejitter;
-.string gametypefilter;
-.string cvarfilter;
-
-/**
- * Evaluate an expression of the form: [+ | -]? [var[op]val | [op]var | val | var] ...
- * +: all must match. this is the default
- * -: one must NOT match
- *
- * var>x
- * var<x
- * var>=x
- * var<=x
- * var==x
- * var!=x
- * var===x
- * var!==x
- */
-bool expr_evaluate(string s)
-{
-    bool ret = false;
-    if (str2chr(s, 0) == '+') {
-        s = substring(s, 1, -1);
-    } else if (str2chr(s, 0) == '-') {
-        ret = true;
-        s = substring(s, 1, -1);
-    }
-    bool expr_fail = false;
-    for (int i = 0, n = tokenize_console(s); i < n; ++i) {
-        int o;
-        string k, v;
-        s = argv(i);
-        #define X(expr) \
-            if (expr) \
-                continue; \
-            expr_fail = true; \
-            break;
-
-        #define BINOP(op, len, expr) \
-            if ((o = strstrofs(s, op, 0)) >= 0) { \
-                k = substring(s, 0, o); \
-                v = substring(s, o + len, -1); \
-                X(expr); \
-            }
-        BINOP(">=", 2, cvar(k) >= stof(v));
-        BINOP("<=", 2, cvar(k) <= stof(v));
-        BINOP(">",  1, cvar(k) >  stof(v));
-        BINOP("<",  1, cvar(k) <  stof(v));
-        BINOP("==", 2, cvar(k) == stof(v));
-        BINOP("!=", 2, cvar(k) != stof(v));
-        BINOP("===", 3, cvar_string(k) == v);
-        BINOP("!==", 3, cvar_string(k) != v);
-        {
-            k = s;
-            bool b = true;
-            if (str2chr(k, 0) == '!') {
-                k = substring(s, 1, -1);
-                b = false;
-            }
-            float f = stof(k);
-            bool isnum = ftos(f) == k;
-            X(boolean(isnum ? f : cvar(k)) == b);
-        }
-        #undef BINOP
-        #undef X
-    }
-    if (!expr_fail) {
-        ret = !ret;
-    }
-    // now ret is true if we want to keep the item, and false if we want to get rid of it
-    return ret;
-}
-
-void SV_OnEntityPreSpawnFunction(entity this)
-{
-       if (this)
-       if (this.gametypefilter != "")
-       if (!isGametypeInFilter(MapInfo_LoadedGametype, teamplay, have_team_spawns, this.gametypefilter))
-       {
-               delete(this);
-               return;
-       }
-       if (this.cvarfilter != "" && !expr_evaluate(this.cvarfilter)) {
-               delete(this);
-               return;
-       }
-
-       if (DoesQ3ARemoveThisEntity(this)) {
-               delete(this);
-               return;
-       }
-
-       set_movetype(this, this.movetype);
-
-       if (this.monster_attack) {
-               IL_PUSH(g_monster_targets, this);
-    }
-
-       // support special -1 and -2 angle from radiant
-       if (this.angles == '0 -1 0') {
-               this.angles = '-90 0 0';
-       } else if (this.angles == '0 -2 0') {
-               this.angles = '+90 0 0';
-    }
-
-    #define X(out, in) MACRO_BEGIN \
-        if (in != 0) { out = out + (random() * 2 - 1) * in; } \
-    MACRO_END
-    X(this.origin.x, this.originjitter.x); X(this.origin.y, this.originjitter.y); X(this.origin.z, this.originjitter.z);
-    X(this.angles.x, this.anglesjitter.x); X(this.angles.y, this.anglesjitter.y); X(this.angles.z, this.anglesjitter.z);
-    X(this.angles.y, this.anglejitter);
-    #undef X
-
-       if (MUTATOR_CALLHOOK(OnEntityPreSpawn, this)) {
-               delete(this);
-               return;
-       }
-}
-
-void WarpZone_PostInitialize_Callback()
-{
-       // create waypoint links for warpzones
-       entity tracetest_ent = spawn();
-       setsize(tracetest_ent, PL_MIN_CONST, PL_MAX_CONST);
-       tracetest_ent.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
-       //for(entity e = warpzone_first; e; e = e.warpzone_next)
-       for(entity e = NULL; (e = find(e, classname, "trigger_warpzone")); )
-               waypoint_spawnforteleporter_wz(e, tracetest_ent);
-       delete(tracetest_ent);
-}
-
-/*
-==================
-main
-
-unused but required by the engine
-==================
-*/
-void main ()
-{
-
-}
diff --git a/qcsrc/server/sv_main.qh b/qcsrc/server/sv_main.qh
deleted file mode 100644 (file)
index 46284fd..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#pragma once
-
-bool expr_evaluate(string s);
-
-#ifdef PROFILING
-float client_cefc_accumulator;
-float client_cefc_accumulatortime;
-#endif
-
-/*
-==================
-main
-
-unused but required by the engine
-==================
-*/
-void main ();
index 6ccb5918caa6990f1dd999036fdc97e22beabaff..2d92f5dfea934572b5809160f7d5e3bdfb5a4d81 100644 (file)
@@ -29,4 +29,9 @@ var void delete_fn(entity e);
 #undef IT_SUIT
 #undef IT_QUAD
 
+#undef STATE_TOP
+#undef STATE_BOTTOM
+#undef STATE_UP
+#undef STATE_DOWN
+
 #pragma noref 0
index f60bb9984d408490a3e52d3dbb32656b90baa835..7e5e10421ac263729bf926a036c0555018eaa5ef 100644 (file)
@@ -27,4 +27,9 @@
 #define IT_SUIT             _IT_SUIT /* BIT(21) */
 #define IT_QUAD             _IT_QUAD /* BIT(22) */
 
+#define STATE_TOP           _STATE_TOP /* 0 */
+#define STATE_BOTTOM        _STATE_BOTTOM /* 1 */
+#define STATE_UP            _STATE_UP /* 2 */
+#define STATE_DOWN          _STATE_DOWN /* 3 */
+
 #pragma noref 1
index d6432d698658f270e9a60764d20f1b720c2cd3d7..1c436da9691b0d555225ef9453286dfab73b9212 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "client.qh"
 #include <server/gamelog.qh>
+#include <server/damage.qh>
 #include "race.qh"
 #include "scores.qh"
 #include "scores_rules.qh"
index ad40da4dd99c8533527c8454cfdc593875a94f7b..7124b1895f5c8082cd3992ef00ca0b34de214a26 100644 (file)
@@ -1,6 +1,5 @@
 #pragma once
 
-#include "defs.qh"
 #include "miscfunctions.qh"
 #include "autocvars.qh"
 #include "client.qh"
@@ -8,6 +7,7 @@
 #include "weapons/common.qh"
 #include "weapons/selection.qh"
 #include <common/items/item.qh>
+#include <common/mapobjects/defs.qh>
 #include <common/physics/player.qh>
 #include <common/weapons/_all.qh>
 #include <common/vehicles/all.qh>
index 0dc71ddcc01c1faa40be8307487b75a378d23067..2ec4fc710433bfbd3785dc698b9785af8ba8013f 100644 (file)
@@ -1,8 +1,11 @@
 #include "accuracy.qh"
 
+#include <server/client.qh>
 #include <server/mutators/_mod.qh>
+#include <server/damage.qh>
 #include <common/constants.qh>
 #include <common/net_linked.qh>
+#include <server/player.qh>
 #include <common/teams.qh>
 #include <common/util.qh>
 #include <common/weapons/_all.qh>
index 5d10e85bdf8dc5d8d74ed468ca20ffc38f466000..d1665b2bd1dadc5f5de95bd925a2c828d5789646 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 #include <server/miscfunctions.qh>
 
 .bool cvar_cl_accuracy_data_share;
index 9486404b9bb008820ad66be17f2b17e001a564fb..7cd56faa758925ee1c37ddce9459361aa3184409 100644 (file)
@@ -1,8 +1,10 @@
 #include "common.qh"
 
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
+#include <server/damage.qh>
+#include <server/items/items.qh>
 #include <server/miscfunctions.qh>
-#include <common/t_items.qh>
 #include <common/constants.qh>
 #include <common/net_linked.qh>
 #include <common/deathtypes/all.qh>
index 1b4b179d2485d32f22fb06665f280f2014b3f22c..83df91eaaf902dc9701a924dd2b97130b3f2810f 100644 (file)
@@ -7,3 +7,32 @@ void W_GiveWeapon (entity e, float wep);
 void W_PlayStrengthSound(entity player);
 float W_CheckProjectileDamage(entity inflictor, entity projowner, int deathtype, float exception);
 void W_PrepareExplosionByDamage(entity this, entity attacker, void(entity this) explode);
+
+.float misc_bulletcounter;
+
+.int projectiledeathtype;
+
+.float fade_time;
+.float fade_rate;
+
+.entity realowner;
+
+#define PROJECTILE_MAKETRIGGER(e) (e).solid = SOLID_CORPSE; (e).dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE
+// when doing this, hagar can go through clones
+// #define PROJECTILE_MAKETRIGGER(e) (e).solid = SOLID_BBOX
+
+.int missile_flags;
+const int MIF_SPLASH = BIT(1);
+const int MIF_ARC = BIT(2);
+const int MIF_PROXY = BIT(3);
+const int MIF_GUIDED_MANUAL = BIT(4);
+const int MIF_GUIDED_HEAT = BIT(5);
+const int MIF_GUIDED_LASER = BIT(6);
+const int MIF_GUIDED_AI = BIT(7);
+const int MIF_GUIDED_TAG = BIT(7);
+const int MIF_GUIDED_ALL = MIF_GUIDED_MANUAL | MIF_GUIDED_HEAT | MIF_GUIDED_LASER | MIF_GUIDED_AI | MIF_GUIDED_TAG;
+const int MIF_GUIDED_TRACKING = MIF_GUIDED_HEAT | MIF_GUIDED_LASER | MIF_GUIDED_AI | MIF_GUIDED_TAG;
+const int MIF_GUIDED_CONFUSABLE = MIF_GUIDED_HEAT | MIF_GUIDED_AI;
+
+IntrusiveList g_projectiles;
+STATIC_INIT(g_projectiles) { g_projectiles = IL_NEW(); }
index 5352b40cde1a8fa1afb3b6058d36a48a3ea0b6cf..758cd51ab33163d8c1265810218a316c24285235 100644 (file)
@@ -1,8 +1,9 @@
 #include "csqcprojectile.qh"
 
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
+#include <server/items/items.qh>
 #include <server/miscfunctions.qh>
-#include <common/t_items.qh>
 
 #include "../command/common.qh"
 
index e79e9ddb6413bb2b86e98e84e4e04793fa1ca5a5..0407ad79923966caaa7a5ea9acbc87e35d3f2e54 100644 (file)
@@ -1,6 +1,9 @@
 #include "hitplot.qh"
 
-#include <server/defs.qh>
+#include <server/client.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
+#include <server/world.qh>
 #include <server/miscfunctions.qh>
 #include "../antilag.qh"
 #include <common/weapons/_all.qh>
index 3f821b44fa8deb3e7507f6c62d0e0ee7525aa892..4a55dab29adf2471e6546743ac4a8ab994e5c8cc 100644 (file)
@@ -1,14 +1,16 @@
 #include "selection.qh"
 
 #include "weaponsystem.qh"
-#include <common/t_items.qh>
-#include <server/items.qh>
+#include <server/items/items.qh>
+#include <server/items/spawning.qh>
 #include <common/constants.qh>
 #include <common/net_linked.qh>
 #include <common/util.qh>
 #include <common/items/item.qh>
 #include <common/weapons/_all.qh>
+#include <common/replicate.qh>
 #include <common/state.qh>
+#include <common/mapobjects/triggers.qh>
 #include <common/mutators/mutator/waypoints/waypointsprites.qh>
 #include <common/wepent.qh>
 
index 2fff84e4fb5a4980064b91f0f0a120295d492f7a..03c203f4e3e20d16454a28eac0ba9278e87e5ab1 100644 (file)
@@ -1,8 +1,13 @@
 #pragma once
 
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 #include <server/miscfunctions.qh>
 
+.int selectweapon; // last selected weapon of the player
+
+.WepSet dual_weapons;
+
 // switch between weapons
 void Send_WeaponComplain(entity e, float wpn, float type);
 
index 881d431ae4d4a8b43d4f68804c6f41c7b0ff8ab9..63bc865e29dc47bf7404474dc9234365f08999bd 100644 (file)
@@ -3,8 +3,8 @@
 #include "weaponsystem.qh"
 #include "../resources.qh"
 #include <server/mutators/_mod.qh>
-#include <common/t_items.qh>
-#include <server/items.qh>
+#include <server/items/items.qh>
+#include <server/items/spawning.qh>
 #include <common/weapons/_all.qh>
 
 .bool m_isreplaced; ///< Holds whether the weapon has been replaced.
index d435002ad69fb3c6784bc68f210051afae856df4..eb40bfc40f24a432b94536cc16862959239dd192 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 #include <server/miscfunctions.qh>
 
 string W_Apply_Weaponreplace(string in);
index e36bc68c62af99b39d543d4811140b9c35cee65a..2408adbf140ef1f75458129a9c72441725fcdad5 100644 (file)
@@ -2,10 +2,10 @@
 
 #include "weaponsystem.qh"
 #include "../resources.qh"
-#include "../items.qh"
+#include <server/items/spawning.qh>
 #include <server/mutators/_mod.qh>
-#include <common/t_items.qh>
-#include "../g_damage.qh"
+#include <server/items/items.qh>
+#include "../damage.qh"
 #include <common/items/item.qh>
 #include <common/mapinfo.qh>
 #include <common/notifications/all.qh>
index 20732753e4fe66f11c1fdd802df01eda300fc658..8ebd4080ca172b6edbac7676eafa268a52bc0e24 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 #include <server/miscfunctions.qh>
 
 .float savenextthink;
index ef1b6bd68d81880e15f018ec4217e4f3fe81b7d4..f4de0e1bf15996ac12aed1a31e64652493d96822 100644 (file)
@@ -7,7 +7,8 @@
 #include "hitplot.qh"
 #include "weaponsystem.qh"
 
-#include "../g_damage.qh"
+#include "../damage.qh"
+#include <server/main.qh>
 #include "../antilag.qh"
 
 #include <common/constants.qh>
index e2f43fb7c13dfb9c2c521432318fd2a2c6210fc6..67246859c0bb043063991ef6da145e37289b9dbf 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 #include <server/miscfunctions.qh>
 
 vector w_shotorg;
@@ -62,6 +63,16 @@ void W_SetupProjVelocity_Explicit(entity proj, vector dir, vector upDir, float p
 //  Ballistics Tracing
 // ====================
 
+.float ballistics_density;
+
+// for railgun damage (hitting multiple enemies)
+.bool railgunhit;
+.float railgunhitsolidbackup;
+.vector railgunhitloc;
+
+IntrusiveList g_railgunhit;
+STATIC_INIT(g_railgunhit) { g_railgunhit = IL_NEW(); }
+
 .float railgundistance;
 .vector railgunforce;
 void FireRailgunBullet (entity this, .entity weaponentity, vector start, vector end, float bdamage, bool headshot_notify, float bforce, float mindist, float maxdist, float halflifedist, float forcehalflifedist, int deathtype);
index 296d10fa6bd0bef9b26f857c6e86ed4db684b9f7..552ab67310b929bb27606b76378519341c042741 100644 (file)
@@ -1,8 +1,9 @@
 #include "weaponstats.qh"
 
-#include <server/defs.qh>
+#include <common/weapons/_all.qh>
+#include <common/stats.qh>
 #include <server/miscfunctions.qh>
-#include "../g_world.qh"
+#include "../world.qh"
 
 #include <common/weapons/_all.qh>
 
index a10274ab6861b620c5d38470daad2f6dc6bf4a0b..7638813882d306ca3e67544c10290ed80231d866 100644 (file)
@@ -3,14 +3,19 @@
 #include "selection.qh"
 
 #include "../command/common.qh"
+#include <server/client.qh>
+#include <server/damage.qh>
+#include <server/world.qh>
+#include <server/items/items.qh>
 #include <server/mutators/_mod.qh>
 #include "../round_handler.qh"
 #include <server/cheats.qh>
 #include <server/resources.qh>
-#include <common/t_items.qh>
 #include <common/animdecide.qh>
 #include <common/constants.qh>
+#include <common/items/_mod.qh>
 #include <common/net_linked.qh>
+#include <common/mapobjects/platforms.qh>
 #include <common/monsters/_mod.qh>
 #include <common/notifications/all.qh>
 #include <common/util.qh>
index 986756aa510344405c4f27e9db7f9b57effef938..d1223c6d575eff72083363b2666dec77667fbcbf 100644 (file)
@@ -1,15 +1,46 @@
 #pragma once
 
-#include <server/defs.qh>
 #include <server/miscfunctions.qh>
 
+#define INDEPENDENT_ATTACK_FINISHED 1
+
+// there is 2 weapon tics that can run in one server frame
+const int W_TICSPERFRAME = 2;
+
+// VorteX: standalone think for weapons, so normal think on weaponentity can be reserved by weaponflashes (which needs update even player dies)
+.float weapon_nextthink;
+.void(Weapon thiswep, entity actor, .entity weaponentity, int fire) weapon_think;
+
 float internalteam;
 entity weapon_dropevent_item;
 
+// reset to 0 on weapon switch
+// may be useful to all weapons
+.float bulletcounter;
+
 ..entity weaponentity_fld;
 
+.float weapon_load[REGISTRY_MAX(Weapons)];
+.int ammo_none; // used by the reloading system, must always be 0
+.int clip_load;
+.int old_clip_load;
+.int clip_size;
+
+.float attack_finished_for[REGISTRY_MAX(Weapons) * MAX_WEAPONSLOTS];
+.float attack_finished_single[MAX_WEAPONSLOTS];
+#if INDEPENDENT_ATTACK_FINISHED
+#define ATTACK_FINISHED_FOR(ent, w, slot) ((ent).(attack_finished_for[((w) - WEP_FIRST) * MAX_WEAPONSLOTS + (slot)]))
+#else
+#define ATTACK_FINISHED_FOR(ent, w, slot) ((ent).attack_finished_single[slot])
+#endif
+#define ATTACK_FINISHED(ent, w) ATTACK_FINISHED_FOR(ent, ent.(w).m_weapon.m_id, weaponslot(w))
+
 void CL_SpawnWeaponentity(entity e, .entity weaponentity);
 
+void w_clear(Weapon thiswep, entity actor, .entity weaponentity, int fire);
+
+void w_ready(Weapon thiswep, entity actor, .entity weaponentity, int fire);
+
 vector CL_Weapon_GetShotOrg(float wpn);
 
 bool weaponUseForbidden(entity player);
diff --git a/qcsrc/server/world.qc b/qcsrc/server/world.qc
new file mode 100644 (file)
index 0000000..b54dde7
--- /dev/null
@@ -0,0 +1,2289 @@
+#include "world.qh"
+
+#include "anticheat.qh"
+#include "antilag.qh"
+#include "bot/api.qh"
+#include "campaign.qh"
+#include "cheats.qh"
+#include "client.qh"
+#include "command/common.qh"
+#include "command/getreplies.qh"
+#include "command/sv_cmd.qh"
+#include "command/vote.qh"
+#include "hook.qh"
+#include <server/gamelog.qh>
+#include <server/damage.qh>
+#include "ipban.qh"
+#include "mapvoting.qh"
+#include <server/mutators/_mod.qh>
+#include "race.qh"
+#include "scores.qh"
+#include "scores_rules.qh"
+#include "spawnpoints.qh"
+#include "teamplay.qh"
+#include "weapons/weaponstats.qh"
+#include <server/weapons/common.qh>
+#include "../common/constants.qh"
+#include <common/net_linked.qh>
+#include "../common/deathtypes/all.qh"
+#include <common/gamemodes/_mod.qh>
+#include "../common/gamemodes/sv_rules.qh"
+#include "../common/mapinfo.qh"
+#include "../common/monsters/_mod.qh"
+#include "../common/monsters/sv_monsters.qh"
+#include "../common/vehicles/all.qh"
+#include "../common/notifications/all.qh"
+#include "../common/physics/player.qh"
+#include "../common/playerstats.qh"
+#include "../common/stats.qh"
+#include "../common/teams.qh"
+#include <common/mapobjects/triggers.qh>
+#include "../common/mapobjects/trigger/secret.qh"
+#include "../common/mapobjects/target/music.qh"
+#include "../common/util.qh"
+#include "../common/items/_mod.qh"
+#include <common/weapons/_all.qh>
+#include "../common/state.qh"
+
+const float LATENCY_THINKRATE = 10;
+.float latency_sum;
+.float latency_cnt;
+.float latency_time;
+entity pingplreport;
+void PingPLReport_Think(entity this)
+{
+       float delta;
+       entity e;
+
+       delta = 3 / maxclients;
+       if(delta < sys_frametime)
+               delta = 0;
+       this.nextthink = time + delta;
+
+       e = edict_num(this.cnt + 1);
+       if(IS_CLIENT(e) && IS_REAL_CLIENT(e))
+       {
+               WriteHeader(MSG_BROADCAST, TE_CSQC_PINGPLREPORT);
+               WriteByte(MSG_BROADCAST, this.cnt);
+               WriteShort(MSG_BROADCAST, bound(1, CS(e).ping, 65535));
+               WriteByte(MSG_BROADCAST, min(ceil(CS(e).ping_packetloss * 255), 255));
+               WriteByte(MSG_BROADCAST, min(ceil(CS(e).ping_movementloss * 255), 255));
+
+               // record latency times for clients throughout the match so we can report it to playerstats
+               if(time > (CS(e).latency_time + LATENCY_THINKRATE))
+               {
+                       CS(e).latency_sum += CS(e).ping;
+                       CS(e).latency_cnt += 1;
+                       CS(e).latency_time = time;
+                       //print("sum: ", ftos(CS(e).latency_sum), ", cnt: ", ftos(CS(e).latency_cnt), ", avg: ", ftos(CS(e).latency_sum / CS(e).latency_cnt), ".\n");
+               }
+       }
+       else
+       {
+               WriteHeader(MSG_BROADCAST, TE_CSQC_PINGPLREPORT);
+               WriteByte(MSG_BROADCAST, this.cnt);
+               WriteShort(MSG_BROADCAST, 0);
+               WriteByte(MSG_BROADCAST, 0);
+               WriteByte(MSG_BROADCAST, 0);
+       }
+       this.cnt = (this.cnt + 1) % maxclients;
+}
+void PingPLReport_Spawn()
+{
+       pingplreport = new_pure(pingplreport);
+       setthink(pingplreport, PingPLReport_Think);
+       pingplreport.nextthink = time;
+}
+
+const float SPAWNFLAG_NO_WAYPOINTS_FOR_ITEMS = 1;
+string redirection_target;
+float world_initialized;
+
+void SetDefaultAlpha()
+{
+       if (!MUTATOR_CALLHOOK(SetDefaultAlpha))
+       {
+               default_player_alpha = autocvar_g_player_alpha;
+               if(default_player_alpha == 0)
+                       default_player_alpha = 1;
+               default_weapon_alpha = default_player_alpha;
+       }
+}
+
+void GotoFirstMap(entity this)
+{
+       float n;
+       if(autocvar__sv_init)
+       {
+               // cvar_set("_sv_init", "0");
+               // we do NOT set this to 0 any more, so someone "accidentally" changing
+               // to this "init" map on a dedicated server will cause no permanent
+               // harm
+               if(autocvar_g_maplist_shuffle)
+                       ShuffleMaplist();
+               n = tokenizebyseparator(autocvar_g_maplist, " ");
+               cvar_set("g_maplist_index", ftos(n - 1)); // jump to map 0 in GotoNextMap
+
+               MapInfo_Enumerate();
+               MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
+
+               if(!DoNextMapOverride(1))
+                       GotoNextMap(1);
+
+               return;
+       }
+
+       if(time < 5)
+       {
+               this.nextthink = time;
+       }
+       else
+       {
+               this.nextthink = time + 1;
+               LOG_INFO("Waiting for _sv_init being set to 1 by initialization scripts...");
+       }
+}
+
+void cvar_changes_init()
+{
+       float h;
+       string k, v, d;
+       float n, i, adding, pureadding;
+
+       strfree(cvar_changes);
+       strfree(cvar_purechanges);
+       cvar_purechanges_count = 0;
+
+       h = buf_create();
+       buf_cvarlist(h, "", "_"); // exclude all _ cvars as they are temporary
+       n = buf_getsize(h);
+
+       adding = true;
+       pureadding = true;
+
+       for(i = 0; i < n; ++i)
+       {
+               k = bufstr_get(h, i);
+
+#define BADPREFIX(p) if(substring(k, 0, strlen(p)) == p) continue
+#define BADPRESUFFIX(p,s) if(substring(k, 0, strlen(p)) == p && substring(k, -strlen(s), -1) == s) continue
+#define BADCVAR(p) if(k == p) continue
+
+               // general excludes and namespaces for server admin used cvars
+               BADPREFIX("help_"); // PN's server has this listed as changed, let's not rat him out for THAT
+
+               // internal
+               BADPREFIX("csqc_");
+               BADPREFIX("cvar_check_");
+               BADCVAR("gamecfg");
+               BADCVAR("g_configversion");
+               BADCVAR("halflifebsp");
+               BADCVAR("sv_mapformat_is_quake2");
+               BADCVAR("sv_mapformat_is_quake3");
+               BADPREFIX("sv_world");
+
+               // client
+               BADPREFIX("chase_");
+               BADPREFIX("cl_");
+               BADPREFIX("con_");
+               BADPREFIX("scoreboard_");
+               BADPREFIX("g_campaign");
+               BADPREFIX("g_waypointsprite_");
+               BADPREFIX("gl_");
+               BADPREFIX("joy");
+               BADPREFIX("hud_");
+               BADPREFIX("m_");
+               BADPREFIX("menu_");
+               BADPREFIX("net_slist_");
+               BADPREFIX("r_");
+               BADPREFIX("sbar_");
+               BADPREFIX("scr_");
+               BADPREFIX("snd_");
+               BADPREFIX("show");
+               BADPREFIX("sensitivity");
+               BADPREFIX("userbind");
+               BADPREFIX("v_");
+               BADPREFIX("vid_");
+               BADPREFIX("crosshair");
+               BADCVAR("mod_q3bsp_lightmapmergepower");
+               BADCVAR("mod_q3bsp_nolightmaps");
+               BADCVAR("fov");
+               BADCVAR("mastervolume");
+               BADCVAR("volume");
+               BADCVAR("bgmvolume");
+               BADCVAR("in_pitch_min");
+               BADCVAR("in_pitch_max");
+
+               // private
+               BADCVAR("developer");
+               BADCVAR("log_dest_udp");
+               BADCVAR("net_address");
+               BADCVAR("net_address_ipv6");
+               BADCVAR("port");
+               BADCVAR("savedgamecfg");
+               BADCVAR("serverconfig");
+               BADCVAR("sv_autoscreenshot");
+               BADCVAR("sv_heartbeatperiod");
+               BADCVAR("sv_vote_master_password");
+               BADCVAR("sys_colortranslation");
+               BADCVAR("sys_specialcharactertranslation");
+               BADCVAR("timeformat");
+               BADCVAR("timestamps");
+               BADCVAR("g_require_stats");
+               BADPREFIX("developer_");
+               BADPREFIX("g_ban_");
+               BADPREFIX("g_banned_list");
+               BADPREFIX("g_require_stats_");
+               BADPREFIX("g_chat_flood_");
+               BADPREFIX("g_ghost_items");
+               BADPREFIX("g_playerstats_");
+               BADPREFIX("g_voice_flood_");
+               BADPREFIX("log_file");
+               BADPREFIX("quit_");
+               BADPREFIX("rcon_");
+               BADPREFIX("sv_allowdownloads");
+               BADPREFIX("sv_autodemo");
+               BADPREFIX("sv_curl_");
+               BADPREFIX("sv_eventlog");
+               BADPREFIX("sv_logscores_");
+               BADPREFIX("sv_master");
+               BADPREFIX("sv_weaponstats_");
+               BADPREFIX("sv_waypointsprite_");
+               BADCVAR("rescan_pending");
+
+               // these can contain player IDs, so better hide
+               BADPREFIX("g_forced_team_");
+               BADCVAR("sv_muteban_list");
+               BADCVAR("sv_voteban_list");
+               BADCVAR("sv_allow_customplayermodels_idlist");
+               BADCVAR("sv_allow_customplayermodels_speciallist");
+
+               // mapinfo
+               BADCVAR("fraglimit");
+               BADCVAR("g_arena");
+               BADCVAR("g_assault");
+               BADCVAR("g_ca");
+               BADCVAR("g_ca_teams");
+               BADCVAR("g_conquest");
+               BADCVAR("g_conquest_teams");
+               BADCVAR("g_ctf");
+               BADCVAR("g_cts");
+               BADCVAR("g_dotc");
+               BADCVAR("g_dm");
+               BADCVAR("g_domination");
+               BADCVAR("g_domination_default_teams");
+               BADCVAR("g_duel");
+               BADCVAR("g_duel_not_dm_maps");
+               BADCVAR("g_freezetag");
+               BADCVAR("g_freezetag_teams");
+               BADCVAR("g_invasion_teams");
+               BADCVAR("g_invasion_type");
+               BADCVAR("g_jailbreak");
+               BADCVAR("g_jailbreak_teams");
+               BADCVAR("g_keepaway");
+               BADCVAR("g_keyhunt");
+               BADCVAR("g_keyhunt_teams");
+               BADCVAR("g_lms");
+               BADCVAR("g_nexball");
+               BADCVAR("g_onslaught");
+               BADCVAR("g_race");
+               BADCVAR("g_race_laps_limit");
+               BADCVAR("g_race_qualifying_timelimit");
+               BADCVAR("g_race_qualifying_timelimit_override");
+               BADCVAR("g_runematch");
+               BADCVAR("g_shootfromeye");
+               BADCVAR("g_snafu");
+               BADCVAR("g_survival");
+               BADCVAR("g_survival_not_dm_maps");
+               BADCVAR("g_tdm");
+               BADCVAR("g_tdm_on_dm_maps");
+               BADCVAR("g_tdm_teams");
+               BADCVAR("g_vip");
+               BADCVAR("leadlimit");
+               BADCVAR("nextmap");
+               BADCVAR("teamplay");
+               BADCVAR("timelimit");
+               BADCVAR("g_mapinfo_settemp_acl");
+               BADCVAR("g_mapinfo_ignore_warnings");
+               BADCVAR("g_maplist_ignore_sizes");
+               BADCVAR("g_maplist_sizes_count_bots");
+
+               // long
+               BADCVAR("hostname");
+               BADCVAR("g_maplist");
+               BADCVAR("g_maplist_mostrecent");
+               BADCVAR("sv_motd");
+
+               v = cvar_string(k);
+               d = cvar_defstring(k);
+               if(v == d)
+                       continue;
+
+               if(adding)
+               {
+                       cvar_changes = strcat(cvar_changes, k, " \"", v, "\" // \"", d, "\"\n");
+                       if(strlen(cvar_changes) > 16384)
+                       {
+                               cvar_changes = "// too many settings have been changed to show them here\n";
+                               adding = 0;
+                       }
+               }
+
+               // now check if the changes are actually gameplay relevant
+
+               // does nothing gameplay relevant
+               BADCVAR("captureleadlimit_override");
+               BADCVAR("condump_stripcolors");
+               BADCVAR("gameversion");
+               BADCVAR("fs_gamedir");
+               BADCVAR("g_allow_oldvortexbeam");
+               BADCVAR("g_balance_kill_delay");
+               BADCVAR("g_buffs_pickup_anyway");
+               BADCVAR("g_buffs_randomize");
+               BADCVAR("g_buffs_randomize_teamplay");
+               BADCVAR("g_campcheck_distance");
+               BADCVAR("g_chatsounds");
+               BADCVAR("g_ca_point_leadlimit");
+               BADCVAR("g_ca_point_limit");
+               BADCVAR("g_ctf_captimerecord_always");
+               BADCVAR("g_ctf_flag_glowtrails");
+               BADCVAR("g_ctf_dynamiclights");
+               BADCVAR("g_ctf_flag_pickup_verbosename");
+               BADPRESUFFIX("g_ctf_flag_", "_model");
+               BADPRESUFFIX("g_ctf_flag_", "_skin");
+               BADCVAR("g_domination_point_leadlimit");
+               BADCVAR("g_forced_respawn");
+               BADCVAR("g_freezetag_point_leadlimit");
+               BADCVAR("g_freezetag_point_limit");
+               BADCVAR("g_glowtrails");
+               BADCVAR("g_hats");
+               BADCVAR("g_casings");
+               BADCVAR("g_invasion_point_limit");
+               BADCVAR("g_jump_grunt");
+               BADCVAR("g_keepaway_ballcarrier_effects");
+               BADCVAR("g_keepawayball_effects");
+               BADCVAR("g_keyhunt_point_leadlimit");
+               BADCVAR("g_nexball_goalleadlimit");
+               BADCVAR("g_new_toys_autoreplace");
+               BADCVAR("g_new_toys_use_pickupsound");
+               BADCVAR("g_physics_predictall");
+               BADCVAR("g_piggyback");
+               BADCVAR("g_playerclip_collisions");
+               BADCVAR("g_spawn_alloweffects");
+               BADCVAR("g_tdm_point_leadlimit");
+               BADCVAR("g_tdm_point_limit");
+               BADCVAR("leadlimit_and_fraglimit");
+               BADCVAR("leadlimit_override");
+               BADCVAR("pausable");
+               BADCVAR("sv_announcer");
+               BADCVAR("sv_checkforpacketsduringsleep");
+               BADCVAR("sv_damagetext");
+               BADCVAR("sv_db_saveasdump");
+               BADCVAR("sv_intermission_cdtrack");
+               BADCVAR("sv_mapchange_delay");
+               BADCVAR("sv_minigames");
+               BADCVAR("sv_namechangetimer");
+               BADCVAR("sv_precacheplayermodels");
+               BADCVAR("sv_radio");
+               BADCVAR("sv_stepheight");
+               BADCVAR("sv_timeout");
+               BADCVAR("sv_weapons_modeloverride");
+               BADCVAR("w_prop_interval");
+               BADPREFIX("chat_");
+               BADPREFIX("crypto_");
+               BADPREFIX("gameversion_");
+               BADPREFIX("g_chat_");
+               BADPREFIX("g_ctf_captimerecord_");
+               BADPREFIX("g_hats_");
+               BADPREFIX("g_maplist_");
+               BADPREFIX("g_mod_");
+               BADPREFIX("g_respawn_");
+               BADPREFIX("net_");
+               BADPREFIX("notification_");
+               BADPREFIX("prvm_");
+               BADPREFIX("skill_");
+               BADPREFIX("sv_allow_");
+               BADPREFIX("sv_cullentities_");
+               BADPREFIX("sv_maxidle_");
+               BADPREFIX("sv_minigames_");
+               BADPREFIX("sv_radio_");
+               BADPREFIX("sv_timeout_");
+               BADPREFIX("sv_vote_");
+               BADPREFIX("timelimit_");
+
+               // allowed changes to server admins (please sync this to server.cfg)
+               // vi commands:
+               //   :/"impure"/,$d
+               //   :g!,^\/\/[^ /],d
+               //   :%s,//\([^ ]*\).*,BADCVAR("\1");,
+               //   :%!sort
+               // yes, this does contain some redundant stuff, don't really care
+               BADPREFIX("bot_ai_");
+               BADCVAR("bot_config_file");
+               BADCVAR("bot_number");
+               BADCVAR("bot_prefix");
+               BADCVAR("bot_suffix");
+               BADCVAR("capturelimit_override");
+               BADCVAR("fraglimit_override");
+               BADCVAR("gametype");
+               BADCVAR("g_antilag");
+               BADCVAR("g_balance_teams");
+               BADCVAR("g_balance_teams_prevent_imbalance");
+               BADCVAR("g_balance_teams_scorefactor");
+               BADCVAR("g_ban_sync_trusted_servers");
+               BADCVAR("g_ban_sync_uri");
+               BADCVAR("g_buffs");
+               BADCVAR("g_ca_teams_override");
+               BADCVAR("g_ctf_fullbrightflags");
+               BADCVAR("g_ctf_ignore_frags");
+               BADCVAR("g_ctf_leaderboard");
+               BADCVAR("g_domination_point_limit");
+               BADCVAR("g_domination_teams_override");
+               BADCVAR("g_freezetag_teams_override");
+               BADCVAR("g_friendlyfire");
+               BADCVAR("g_fullbrightitems");
+               BADCVAR("g_fullbrightplayers");
+               BADCVAR("g_keyhunt_point_limit");
+               BADCVAR("g_keyhunt_teams_override");
+               BADCVAR("g_lms_lives_override");
+               BADCVAR("g_maplist");
+               BADCVAR("g_maxplayers");
+               BADCVAR("g_mirrordamage");
+               BADCVAR("g_nexball_goallimit");
+               BADCVAR("g_norecoil");
+               BADCVAR("g_physics_clientselect");
+               BADCVAR("g_pinata");
+               BADCVAR("g_powerups");
+               BADCVAR("g_player_brightness");
+               BADCVAR("g_rocket_flying");
+               BADCVAR("g_rocket_flying_disabledelays");
+               BADCVAR("g_spawnshieldtime");
+               BADCVAR("g_start_delay");
+               BADCVAR("g_superspectate");
+               BADCVAR("g_tdm_teams_override");
+               BADCVAR("g_warmup");
+               BADCVAR("g_weapon_stay"); BADPRESUFFIX("g_", "_weapon_stay");
+               BADCVAR("hostname");
+               BADCVAR("log_file");
+               BADCVAR("maxplayers");
+               BADCVAR("minplayers");
+               BADCVAR("minplayers_per_team");
+               BADCVAR("net_address");
+               BADCVAR("port");
+               BADCVAR("rcon_password");
+               BADCVAR("rcon_restricted_commands");
+               BADCVAR("rcon_restricted_password");
+               BADCVAR("skill");
+               BADCVAR("sv_adminnick");
+               BADCVAR("sv_autoscreenshot");
+               BADCVAR("sv_autotaunt");
+               BADCVAR("sv_curl_defaulturl");
+               BADCVAR("sv_defaultcharacter");
+               BADCVAR("sv_defaultcharacterskin");
+               BADCVAR("sv_defaultplayercolors");
+               BADCVAR("sv_defaultplayermodel");
+               BADCVAR("sv_defaultplayerskin");
+               BADCVAR("sv_maxidle");
+               BADCVAR("sv_maxrate");
+               BADCVAR("sv_motd");
+               BADCVAR("sv_public");
+               BADCVAR("sv_ready_restart");
+               BADCVAR("sv_status_privacy");
+               BADCVAR("sv_taunt");
+               BADCVAR("sv_vote_call");
+               BADCVAR("sv_vote_commands");
+               BADCVAR("sv_vote_majority_factor");
+               BADCVAR("sv_vote_master");
+               BADCVAR("sv_vote_master_commands");
+               BADCVAR("sv_vote_master_password");
+               BADCVAR("sv_vote_simple_majority_factor");
+               BADCVAR("teamplay_mode");
+               BADCVAR("timelimit_override");
+               BADPREFIX("g_warmup_");
+               BADPREFIX("sv_info_");
+               BADPREFIX("sv_ready_restart_");
+
+               // mutators that announce themselves properly to the server browser
+               BADCVAR("g_instagib");
+               BADCVAR("g_new_toys");
+               BADCVAR("g_nix");
+               BADCVAR("g_grappling_hook");
+               BADCVAR("g_jetpack");
+
+               // temporary for testing
+               // TODO remove before 0.8.3 release
+               BADCVAR("g_ca_weaponarena");
+               BADCVAR("g_freezetag_weaponarena");
+               BADCVAR("g_lms_weaponarena");
+               BADCVAR("g_ctf_stalemate_time");
+
+               if(cvar_string("g_mod_balance") == "Testing")
+               {
+                       // (temporary) while using the Testing balance, any weapon balance cvars are allowed to be changed
+                       BADPREFIX("g_balance_");
+               }
+
+#undef BADPRESUFFIX
+#undef BADPREFIX
+#undef BADCVAR
+
+               if(pureadding)
+               {
+                       cvar_purechanges = strcat(cvar_purechanges, k, " \"", v, "\" // \"", d, "\"\n");
+                       if(strlen(cvar_purechanges) > 16384)
+                       {
+                               cvar_purechanges = "// too many settings have been changed to show them here\n";
+                               pureadding = 0;
+                       }
+               }
+               ++cvar_purechanges_count;
+               // WARNING: this variable is used for the server list
+               // NEVER dare to skip this code!
+               // Hacks to intentionally appearing as "pure server" even though you DO have
+               // modified settings may be punished by removal from the server list.
+               // You can do to the variables cvar_changes and cvar_purechanges all you want,
+               // though.
+       }
+       buf_del(h);
+       if(cvar_changes == "")
+               cvar_changes = "// this server runs at default server settings\n";
+       else
+               cvar_changes = strcat("// this server runs at modified server settings:\n", cvar_changes);
+       cvar_changes = strzone(cvar_changes);
+       if(cvar_purechanges == "")
+               cvar_purechanges = "// this server runs at default gameplay settings\n";
+       else
+               cvar_purechanges = strcat("// this server runs at modified gameplay settings:\n", cvar_purechanges);
+       cvar_purechanges = strzone(cvar_purechanges);
+}
+
+entity randomseed;
+bool RandomSeed_Send(entity this, entity to, int sf)
+{
+       WriteHeader(MSG_ENTITY, ENT_CLIENT_RANDOMSEED);
+       WriteShort(MSG_ENTITY, this.cnt);
+       return true;
+}
+void RandomSeed_Think(entity this)
+{
+       this.cnt = bound(0, floor(random() * 65536), 65535);
+       this.nextthink = time + 5;
+
+       this.SendFlags |= 1;
+}
+void RandomSeed_Spawn()
+{
+       randomseed = new_pure(randomseed);
+       setthink(randomseed, RandomSeed_Think);
+       Net_LinkEntity(randomseed, false, 0, RandomSeed_Send);
+
+       getthink(randomseed)(randomseed); // sets random seed and nextthink
+}
+
+spawnfunc(__init_dedicated_server)
+{
+       // handler for _init/_init map (only for dedicated server initialization)
+
+       world_initialized = -1; // don't complain
+
+       delete_fn = remove_unsafely;
+
+       entity e = spawn();
+       setthink(e, GotoFirstMap);
+       e.nextthink = time; // this is usually 1 at this point
+
+       e = new(info_player_deathmatch);  // safeguard against player joining
+
+    // assign reflectively to avoid "assignment to world" warning
+    for (int i = 0, n = numentityfields(); i < n; ++i) {
+        string k = entityfieldname(i);
+        if (k == "classname") {
+            // safeguard against various stuff ;)
+            putentityfieldstring(i, this, "worldspawn");
+            break;
+        }
+    }
+
+       // needs to be done so early because of the constants they create
+       static_init();
+       static_init_late();
+       static_init_precache();
+
+       IL_PUSH(g_spawnpoints, e); // just incase
+
+       MapInfo_Enumerate();
+       MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
+}
+
+void __init_dedicated_server_shutdown() {
+       MapInfo_Shutdown();
+}
+
+STATIC_INIT_EARLY(maxclients)
+{
+       maxclients = 0;
+       for (entity head = nextent(NULL); head; head = nextent(head)) {
+               ++maxclients;
+       }
+}
+
+void default_delayedinit(entity this)
+{
+       if(!scores_initialized)
+               ScoreRules_generic();
+}
+
+void InitGameplayMode()
+{
+       VoteReset();
+
+       // find out good world mins/maxs bounds, either the static bounds found by looking for solid, or the mapinfo specified bounds
+       get_mi_min_max(1);
+       // assign reflectively to avoid "assignment to world" warning
+       int done = 0; for (int i = 0, n = numentityfields(); i < n; ++i) {
+           string k = entityfieldname(i); vector v = (k == "mins") ? mi_min : (k == "maxs") ? mi_max : '0 0 0';
+           if (v) {
+            putentityfieldstring(i, world, sprintf("%v", v));
+            if (++done == 2) break;
+        }
+       }
+       // currently, NetRadiant's limit is 131072 qu for each side
+       // distance from one corner of a 131072qu cube to the opposite corner is approx. 227023 qu
+       // set the distance according to map size but don't go over the limit to avoid issues with float precision
+       // in case somebody makes extremely large maps
+       max_shot_distance = min(230000, vlen(world.maxs - world.mins));
+
+       MapInfo_LoadMapSettings(mapname);
+       GameRules_teams(false);
+
+       if (!cvar_value_issafe(world.fog))
+       {
+               LOG_INFO("The current map contains a potentially harmful fog setting, ignored");
+               world.fog = string_null;
+       }
+       if(MapInfo_Map_fog != "")
+       {
+               if(MapInfo_Map_fog == "none")
+                       world.fog = string_null;
+               else
+                       world.fog = strzone(MapInfo_Map_fog);
+       }
+       clientstuff = strzone(MapInfo_Map_clientstuff);
+
+       MapInfo_ClearTemps();
+
+       gamemode_name = MapInfo_Type_ToText(MapInfo_LoadedGametype);
+
+       cache_mutatormsg = strzone("");
+       cache_lastmutatormsg = strzone("");
+
+       InitializeEntity(NULL, default_delayedinit, INITPRIO_GAMETYPE_FALLBACK);
+}
+
+void Map_MarkAsRecent(string m);
+float world_already_spawned;
+spawnfunc(worldspawn)
+{
+       server_is_dedicated = boolean(stof(cvar_defstring("is_dedicated")));
+
+       bool wantrestart = false;
+       {
+               if (!server_is_dedicated)
+               {
+                       // force unloading of server pk3 files when starting a listen server
+                       // localcmd("\nfs_rescan\n"); // FIXME: does more harm than good, has unintended side effects. What we really want is to unload temporary pk3s only
+                       // restore csqc_progname too
+                       string expect = "csprogs.dat";
+                       wantrestart = cvar_string("csqc_progname") != expect;
+                       cvar_set("csqc_progname", expect);
+               }
+               else
+               {
+                       // Try to use versioned csprogs from pk3
+                       // Only ever use versioned csprogs.dat files on dedicated servers;
+                       // we need to reset csqc_progname on clients ourselves, and it's easier if the client's release name is constant
+                       string pk3csprogs = "csprogs-" WATERMARK ".dat";
+                       // This always works; fall back to it if a versioned csprogs.dat is suddenly missing
+                       string select = "csprogs.dat";
+                       if (fexists(pk3csprogs)) select = pk3csprogs;
+                       if (cvar_string("csqc_progname") != select)
+                       {
+                               cvar_set("csqc_progname", select);
+                               wantrestart = true;
+                       }
+                       // Check for updates on startup
+                       // We do it this way for atomicity so that connecting clients still match the server progs and don't disconnect
+                       int sentinel = fopen("progs.txt", FILE_READ);
+                       if (sentinel >= 0)
+                       {
+                               string switchversion = fgets(sentinel);
+                               fclose(sentinel);
+                               if (switchversion != "" && switchversion != WATERMARK)
+                               {
+                                       LOG_INFOF("Switching progs: " WATERMARK " -> %s", switchversion);
+                                       // if it doesn't exist, assume either:
+                                       //   a) the current program was overwritten
+                                       //   b) this is a client only update
+                                       string newprogs = sprintf("progs-%s.dat", switchversion);
+                                       if (fexists(newprogs))
+                                       {
+                                               cvar_set("sv_progs", newprogs);
+                                               wantrestart = true;
+                                       }
+                                       string newcsprogs = sprintf("csprogs-%s.dat", switchversion);
+                                       if (fexists(newcsprogs))
+                                       {
+                                               cvar_set("csqc_progname", newcsprogs);
+                                               wantrestart = true;
+                                       }
+                               }
+                       }
+               }
+               if (wantrestart)
+               {
+                       LOG_INFO("Restart requested");
+                       changelevel(mapname);
+                       // let initialization continue, shutdown depends on it
+               }
+       }
+
+       if(world_already_spawned)
+               error("world already spawned - you may have EXACTLY ONE worldspawn!");
+       world_already_spawned = true;
+
+       delete_fn = remove_safely; // during spawning, watch what you remove!
+
+       cvar_changes_init(); // do this very early now so it REALLY matches the server config
+
+       // needs to be done so early because of the constants they create
+       static_init();
+
+       ServerProgsDB = db_load(strcat("server.db", autocvar_sessionid));
+
+       TemporaryDB = db_create();
+
+       // 0 normal
+       lightstyle(0, "m");
+
+       // 1 FLICKER (first variety)
+       lightstyle(1, "mmnmmommommnonmmonqnmmo");
+
+       // 2 SLOW STRONG PULSE
+       lightstyle(2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba");
+
+       // 3 CANDLE (first variety)
+       lightstyle(3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg");
+
+       // 4 FAST STROBE
+       lightstyle(4, "mamamamamama");
+
+       // 5 GENTLE PULSE 1
+       lightstyle(5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj");
+
+       // 6 FLICKER (second variety)
+       lightstyle(6, "nmonqnmomnmomomno");
+
+       // 7 CANDLE (second variety)
+       lightstyle(7, "mmmaaaabcdefgmmmmaaaammmaamm");
+
+       // 8 CANDLE (third variety)
+       lightstyle(8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa");
+
+       // 9 SLOW STROBE (fourth variety)
+       lightstyle(9, "aaaaaaaazzzzzzzz");
+
+       // 10 FLUORESCENT FLICKER
+       lightstyle(10, "mmamammmmammamamaaamammma");
+
+       // 11 SLOW PULSE NOT FADE TO BLACK
+       lightstyle(11, "abcdefghijklmnopqrrqponmlkjihgfedcba");
+
+       // styles 32-62 are assigned by the spawnfunc_light program for switchable lights
+
+       // 63 testing
+       lightstyle(63, "a");
+
+       if(autocvar_g_campaign)
+               CampaignPreInit();
+
+       Map_MarkAsRecent(mapname);
+
+       PlayerStats_GameReport_Init(); // we need this to be initiated before InitGameplayMode
+
+       InitGameplayMode();
+       static_init_late();
+       static_init_precache();
+       readlevelcvars();
+       GrappleHookInit();
+
+       GameRules_limit_fallbacks();
+
+       if(warmup_limit == 0)
+               warmup_limit = (autocvar_timelimit > 0) ? autocvar_timelimit * 60 : autocvar_timelimit;
+
+       player_count = 0;
+       bot_waypoints_for_items = autocvar_g_waypoints_for_items;
+       if(bot_waypoints_for_items == 1)
+               if(this.spawnflags & SPAWNFLAG_NO_WAYPOINTS_FOR_ITEMS)
+                       bot_waypoints_for_items = 0;
+
+       WaypointSprite_Init();
+
+       GameLogInit(); // prepare everything
+       // NOTE for matchid:
+       // changing the logic generating it is okay. But:
+       // it HAS to stay <= 64 chars
+       // character set: ASCII 33-126 without the following characters: : ; ' " \ $
+       if(autocvar_sv_eventlog)
+       {
+               string s = sprintf("%s.%s.%06d", itos(autocvar_sv_eventlog_files_counter), strftime(false, "%s"), floor(random() * 1000000));
+               matchid = strzone(s);
+
+               GameLogEcho(strcat(":gamestart:", GetGametype(), "_", GetMapname(), ":", s));
+               s = ":gameinfo:mutators:LIST";
+
+               MUTATOR_CALLHOOK(BuildMutatorsString, s);
+               s = M_ARGV(0, string);
+
+               // initialiation stuff, not good in the mutator system
+               if(!autocvar_g_use_ammunition)
+                       s = strcat(s, ":no_use_ammunition");
+
+               // initialiation stuff, not good in the mutator system
+               if(autocvar_g_pickup_items == 0)
+                       s = strcat(s, ":no_pickup_items");
+               if(autocvar_g_pickup_items > 0)
+                       s = strcat(s, ":pickup_items");
+
+               // initialiation stuff, not good in the mutator system
+               if(autocvar_g_weaponarena != "0")
+                       s = strcat(s, ":", autocvar_g_weaponarena, " arena");
+
+               // TODO to mutator system
+               if(autocvar_g_norecoil)
+                       s = strcat(s, ":norecoil");
+
+               // TODO to mutator system
+               if(autocvar_g_powerups == 0)
+                       s = strcat(s, ":no_powerups");
+               if(autocvar_g_powerups > 0)
+                       s = strcat(s, ":powerups");
+
+               GameLogEcho(s);
+               GameLogEcho(":gameinfo:end");
+       }
+       else
+               matchid = strzone(ftos(random()));
+
+       cvar_set("nextmap", "");
+
+       SetDefaultAlpha();
+
+       if(autocvar_g_campaign)
+               CampaignPostInit();
+
+       Ban_LoadBans();
+
+       MapInfo_Enumerate();
+       MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 1);
+
+       if(fexists(_MapInfo_FindArenaFile(mapname, ".arena")))
+               cvar_settemp("sv_q3acompat_machineshotgunswap", "1");
+
+       if(fexists(_MapInfo_FindArenaFile(mapname, ".defi")))
+               cvar_settemp("sv_q3defragcompat", "1");
+
+       // quake 3 music support
+       if(world.music || world.noise)
+       {
+               // prefer .music over .noise
+               string chosen_music;
+               string oldstuff;
+               if(world.music)
+                       chosen_music = world.music;
+               else
+                       chosen_music = world.noise;
+               if(
+                       substring(chosen_music, strlen(chosen_music) - 4, 4) == ".wav"
+                       ||
+                       substring(chosen_music, strlen(chosen_music) - 4, 4) == ".ogg"
+               )
+                       oldstuff = strcat(clientstuff, "cd loop \"", chosen_music, "\"\n");
+               else
+                       oldstuff = strcat(clientstuff, "cd loop \"", chosen_music, "\"\n");
+
+               strcpy(clientstuff, oldstuff);
+       }
+
+       if(whichpack(strcat("maps/", mapname, ".cfg")) != "")
+       {
+               int fd = fopen(strcat("maps/", mapname, ".cfg"), FILE_READ);
+               if(fd != -1)
+               {
+                       string s;
+                       while((s = fgets(fd)))
+                       {
+                               int l = tokenize_console(s);
+                               if(l < 2)
+                                       continue;
+                               if(argv(0) == "cd")
+                               {
+                                       string trackname = argv(2);
+                                       LOG_INFO("Found ^1UNSUPPORTED^7 cd loop command in .cfg file; put this line in mapinfo instead:");
+                                       LOG_INFO("  cdtrack ", trackname);
+                                       if (cvar_value_issafe(trackname))
+                                       {
+                                               string newstuff = strcat(clientstuff, "cd loop \"", trackname, "\"\n");
+                                               strcpy(clientstuff, newstuff);
+                                       }
+                               }
+                               else if(argv(0) == "fog")
+                               {
+                                       LOG_INFO("Found ^1UNSUPPORTED^7 fog command in .cfg file; put this line in worldspawn in the .map/.bsp/.ent file instead:");
+                                       LOG_INFO("  \"fog\" \"", s, "\"");
+                               }
+                               else if(argv(0) == "set")
+                               {
+                                       LOG_INFO("Found ^1UNSUPPORTED^7 set command in .cfg file; put this line in mapinfo instead:");
+                                       LOG_INFO("  clientsettemp_for_type all ", argv(1), " ", argv(2));
+                               }
+                               else if(argv(0) != "//")
+                               {
+                                       LOG_INFO("Found ^1UNSUPPORTED^7 set command in .cfg file; put this line in mapinfo instead:");
+                                       LOG_INFO("  clientsettemp_for_type all ", argv(0), " ", argv(1));
+                               }
+                       }
+                       fclose(fd);
+               }
+       }
+
+       WeaponStats_Init();
+
+       Nagger_Init();
+
+       // set up information replies for clients and server to use
+       maplist_reply = strzone(getmaplist());
+       lsmaps_reply = strzone(getlsmaps());
+       monsterlist_reply = strzone(getmonsterlist());
+       for(int i = 0; i < 10; ++i)
+       {
+               string s = getrecords(i);
+               if (s)
+                       records_reply[i] = strzone(s);
+       }
+       ladder_reply = strzone(getladder());
+       rankings_reply = strzone(getrankings());
+
+       // begin other init
+       ClientInit_Spawn();
+       RandomSeed_Spawn();
+       PingPLReport_Spawn();
+
+       CheatInit();
+
+       if (!wantrestart) localcmd("\n_sv_hook_gamestart ", GetGametype(), "\n");
+
+       // fill sv_curl_serverpackages from .serverpackage files
+       if (autocvar_sv_curl_serverpackages_auto)
+       {
+               string s = "csprogs-" WATERMARK ".txt";
+               // remove automatically managed files from the list to prevent duplicates
+               for (int i = 0, n = tokenize_console(cvar_string("sv_curl_serverpackages")); i < n; ++i)
+               {
+                       string pkg = argv(i);
+                       if (startsWith(pkg, "csprogs-")) continue;
+                       if (endsWith(pkg, "-serverpackage.txt")) continue;
+                       if (endsWith(pkg, ".serverpackage")) continue;  // OLD legacy
+                       s = cons(s, pkg);
+               }
+               // add automatically managed files to the list
+               #define X(match) MACRO_BEGIN \
+                       int fd = search_begin(match, true, false); \
+                       if (fd >= 0) \
+                       { \
+                               for (int i = 0, j = search_getsize(fd); i < j; ++i) \
+                               { \
+                                       s = cons(s, search_getfilename(fd, i)); \
+                               } \
+                               search_end(fd); \
+                       } \
+               MACRO_END
+               X("*-serverpackage.txt");
+               X("*.serverpackage");
+               #undef X
+               cvar_set("sv_curl_serverpackages", s);
+       }
+
+       // MOD AUTHORS: change this, and possibly remove a few of the blocks below to ignore certain changes
+       modname = "Xonotic";
+       // physics/balance/config changes that count as mod
+       if(cvar_string("g_mod_physics") != cvar_defstring("g_mod_physics"))
+               modname = cvar_string("g_mod_physics");
+       if(cvar_string("g_mod_balance") != cvar_defstring("g_mod_balance") && cvar_string("g_mod_balance") != "Testing")
+               modname = cvar_string("g_mod_balance");
+       if(cvar_string("g_mod_config") != cvar_defstring("g_mod_config"))
+               modname = cvar_string("g_mod_config");
+       // extra mutators that deserve to count as mod
+       MUTATOR_CALLHOOK(SetModname, modname);
+       modname = M_ARGV(0, string);
+
+       // save it for later
+       modname = strzone(modname);
+
+       WinningConditionHelper(this); // set worldstatus
+
+       world_initialized = 1;
+       __spawnfunc_spawn_all();
+}
+
+spawnfunc(light)
+{
+       //makestatic (this); // Who the f___ did that?
+       delete(this);
+}
+
+string GetGametype()
+{
+       return MapInfo_Type_ToString(MapInfo_LoadedGametype);
+}
+
+string GetMapname()
+{
+       return mapname;
+}
+
+float Map_Count, Map_Current;
+string Map_Current_Name;
+
+// NOTE: this now expects the map list to be already tokenized and the count in Map_Count
+int GetMaplistPosition()
+{
+       string map = GetMapname();
+       int idx = autocvar_g_maplist_index;
+
+       if(idx >= 0)
+       {
+               if(idx < Map_Count)
+               {
+                       if(map == argv(idx))
+                       {
+                               return idx;
+                       }
+               }
+       }
+
+       for(int pos = 0; pos < Map_Count; ++pos)
+       {
+               if(map == argv(pos))
+                       return pos;
+       }
+
+       // resume normal maplist rotation if current map is not in g_maplist
+       return idx;
+}
+
+bool MapHasRightSize(string map)
+{
+       int minplayers = max(0, floor(autocvar_minplayers));
+       if (teamplay)
+               minplayers = max(0, floor(autocvar_minplayers_per_team) * AvailableTeams());
+       if (autocvar_g_maplist_check_waypoints
+               && (currentbots || autocvar_bot_number || player_count < minplayers))
+       {
+               string checkwp_msg = strcat("checkwp ", map);
+               if(!fexists(strcat("maps/", map, ".waypoints")))
+               {
+                       LOG_TRACE(checkwp_msg, ": no waypoints");
+                       return false;
+               }
+               LOG_TRACE(checkwp_msg, ": has waypoints");
+       }
+
+       if(autocvar_g_maplist_ignore_sizes)
+               return true;
+
+       // open map size restriction file
+       string opensize_msg = strcat("opensize ", map);
+       float fh = fopen(strcat("maps/", map, ".sizes"), FILE_READ);
+       int player_limit = ((autocvar_g_maplist_sizes_count_maxplayers) ? GetPlayerLimit() : 0);
+       int pcount = ((player_limit > 0) ? min(player_count, player_limit) : player_count); // bind it to the player limit so that forced spectators don't influence the limits
+       if(!autocvar_g_maplist_sizes_count_bots)
+               pcount -= currentbots;
+       if(fh >= 0)
+       {
+               opensize_msg = strcat(opensize_msg, ": ok, ");
+               int mapmin = stoi(fgets(fh));
+               int mapmax = stoi(fgets(fh));
+               fclose(fh);
+               if(pcount < mapmin)
+               {
+                       LOG_TRACE(opensize_msg, "not enough");
+                       return false;
+               }
+               if(mapmax && pcount > mapmax)
+               {
+                       LOG_TRACE(opensize_msg, "too many");
+                       return false;
+               }
+               LOG_TRACE(opensize_msg, "right size");
+               return true;
+       }
+       LOG_TRACE(opensize_msg, ": not found");
+       return true;
+}
+
+string Map_Filename(float position)
+{
+       return strcat("maps/", argv(position), ".bsp");
+}
+
+void Map_MarkAsRecent(string m)
+{
+       cvar_set("g_maplist_mostrecent", strwords(cons(m, autocvar_g_maplist_mostrecent), max(0, autocvar_g_maplist_mostrecent_count)));
+}
+
+float Map_IsRecent(string m)
+{
+       return strhasword(autocvar_g_maplist_mostrecent, m);
+}
+
+float Map_Check(float position, float pass)
+{
+       string filename;
+       string map_next;
+       map_next = argv(position);
+       if(pass <= 1)
+       {
+               if(Map_IsRecent(map_next))
+                       return 0;
+       }
+       filename = Map_Filename(position);
+       if(MapInfo_CheckMap(map_next))
+       {
+               if(pass == 2)
+                       return 1;
+               if(MapHasRightSize(map_next))
+                       return 1;
+               return 0;
+       }
+       else
+               LOG_DEBUG( "Couldn't select '", filename, "'..." );
+
+       return 0;
+}
+
+void Map_Goto_SetStr(string nextmapname)
+{
+       if(getmapname_stored != "")
+               strunzone(getmapname_stored);
+       if(nextmapname == "")
+               getmapname_stored = "";
+       else
+               getmapname_stored = strzone(nextmapname);
+}
+
+void Map_Goto_SetFloat(float position)
+{
+       cvar_set("g_maplist_index", ftos(position));
+       Map_Goto_SetStr(argv(position));
+}
+
+void Map_Goto(float reinit)
+{
+       MapInfo_LoadMap(getmapname_stored, reinit);
+}
+
+// return codes of map selectors:
+//   -1 = temporary failure (that is, try some method that is guaranteed to succeed)
+//   -2 = permanent failure
+float MaplistMethod_Iterate() // usual method
+{
+       float pass, i;
+
+       LOG_TRACE("Trying MaplistMethod_Iterate");
+
+       for(pass = 1; pass <= 2; ++pass)
+       {
+               for(i = 1; i < Map_Count; ++i)
+               {
+                       float mapindex;
+                       mapindex = (i + Map_Current) % Map_Count;
+                       if(Map_Check(mapindex, pass))
+                               return mapindex;
+               }
+       }
+       return -1;
+}
+
+float MaplistMethod_Repeat() // fallback method
+{
+       LOG_TRACE("Trying MaplistMethod_Repeat");
+
+       if(Map_Check(Map_Current, 2))
+               return Map_Current;
+       return -2;
+}
+
+float MaplistMethod_Random() // random map selection
+{
+       float i, imax;
+
+       LOG_TRACE("Trying MaplistMethod_Random");
+
+       imax = 42;
+
+       for(i = 0; i <= imax; ++i)
+       {
+               float mapindex;
+               mapindex = (Map_Current + floor(random() * (Map_Count - 1) + 1)) % Map_Count; // any OTHER map
+               if(Map_Check(mapindex, 1))
+                       return mapindex;
+       }
+       return -1;
+}
+
+float MaplistMethod_Shuffle(float exponent) // more clever shuffling
+// the exponent sets a bias on the map selection:
+// the higher the exponent, the less likely "shortly repeated" same maps are
+{
+       float i, j, imax, insertpos;
+
+       LOG_TRACE("Trying MaplistMethod_Shuffle");
+
+       imax = 42;
+
+       for(i = 0; i <= imax; ++i)
+       {
+               string newlist;
+
+               // now reinsert this at another position
+               insertpos = (random() ** (1 / exponent));       // ]0, 1]
+               insertpos = insertpos * (Map_Count - 1);       // ]0, Map_Count - 1]
+               insertpos = ceil(insertpos) + 1;               // {2, 3, 4, ..., Map_Count}
+               LOG_TRACE("SHUFFLE: insert pos = ", ftos(insertpos));
+
+               // insert the current map there
+               newlist = "";
+               for(j = 1; j < insertpos; ++j)                 // i == 1: no loop, will be inserted as first; however, i == 1 has been excluded above
+                       newlist = strcat(newlist, " ", argv(j));
+               newlist = strcat(newlist, " ", argv(0));       // now insert the just selected map
+               for(j = insertpos; j < Map_Count; ++j)         // i == Map_Count: no loop, has just been inserted as last
+                       newlist = strcat(newlist, " ", argv(j));
+               newlist = substring(newlist, 1, strlen(newlist) - 1);
+               cvar_set("g_maplist", newlist);
+               Map_Count = tokenizebyseparator(autocvar_g_maplist, " ");
+
+               // NOTE: the selected map has just been inserted at (insertpos-1)th position
+               Map_Current = insertpos - 1; // this is not really valid, but this way the fallback has a chance of working
+               if(Map_Check(Map_Current, 1))
+                       return Map_Current;
+       }
+       return -1;
+}
+
+void Maplist_Init()
+{
+       float i = Map_Count = 0;
+       if(autocvar_g_maplist != "")
+       {
+               Map_Count = tokenizebyseparator(autocvar_g_maplist, " ");
+               for (i = 0; i < Map_Count; ++i)
+               {
+                       if (Map_Check(i, 2))
+                               break;
+               }
+       }
+
+       if (i == Map_Count)
+       {
+               bprint( "Maplist contains no usable maps!  Resetting it to default map list.\n" );
+               cvar_set("g_maplist", MapInfo_ListAllAllowedMaps(MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags() | MAPINFO_FLAG_NOAUTOMAPLIST));
+               if(autocvar_g_maplist_shuffle)
+                       ShuffleMaplist();
+               if(!server_is_dedicated)
+                       localcmd("\nmenu_cmd sync\n");
+               Map_Count = tokenizebyseparator(autocvar_g_maplist, " ");
+       }
+       if(Map_Count == 0)
+               error("empty maplist, cannot select a new map");
+       Map_Current = bound(0, GetMaplistPosition(), Map_Count - 1);
+
+       strcpy(Map_Current_Name, argv(Map_Current)); // will be automatically freed on exit thanks to DP
+       // this may or may not be correct, but who cares, in the worst case a map
+       // isn't chosen in the first pass that should have been
+}
+
+string GetNextMap()
+{
+       Maplist_Init();
+       float nextMap = -1;
+
+       if(nextMap == -1)
+               if(autocvar_g_maplist_shuffle > 0)
+                       nextMap = MaplistMethod_Shuffle(autocvar_g_maplist_shuffle + 1);
+
+       if(nextMap == -1)
+               if(autocvar_g_maplist_selectrandom)
+                       nextMap = MaplistMethod_Random();
+
+       if(nextMap == -1)
+               nextMap = MaplistMethod_Iterate();
+
+       if(nextMap == -1)
+               nextMap = MaplistMethod_Repeat();
+
+       if(nextMap >= 0)
+       {
+               Map_Goto_SetFloat(nextMap);
+               return getmapname_stored;
+       }
+
+       return "";
+}
+
+float DoNextMapOverride(float reinit)
+{
+       if(autocvar_g_campaign)
+       {
+               CampaignPostIntermission();
+               alreadychangedlevel = true;
+               return true;
+       }
+       if(autocvar_quit_when_empty)
+       {
+               if(player_count <= currentbots)
+               {
+                       localcmd("quit\n");
+                       alreadychangedlevel = true;
+                       return true;
+               }
+       }
+       if(autocvar_quit_and_redirect != "")
+       {
+               redirection_target = strzone(autocvar_quit_and_redirect);
+               alreadychangedlevel = true;
+               return true;
+       }
+       if (!reinit && autocvar_samelevel) // if samelevel is set, stay on same level
+       {
+               localcmd("restart\n");
+               alreadychangedlevel = true;
+               return true;
+       }
+       if(autocvar_nextmap != "")
+       {
+               string m;
+               m = GameTypeVote_MapInfo_FixName(autocvar_nextmap);
+               cvar_set("nextmap",m);
+
+               if(!m || gametypevote)
+                       return false;
+               if(autocvar_sv_vote_gametype)
+               {
+                       Map_Goto_SetStr(m);
+                       return false;
+               }
+
+               if(MapInfo_CheckMap(m))
+               {
+                       Map_Goto_SetStr(m);
+                       Map_Goto(reinit);
+                       alreadychangedlevel = true;
+                       return true;
+               }
+       }
+       if(!reinit && autocvar_lastlevel)
+       {
+               cvar_settemp_restore();
+               localcmd("set lastlevel 0\ntogglemenu 1\n");
+               alreadychangedlevel = true;
+               return true;
+       }
+       return false;
+}
+
+void GotoNextMap(float reinit)
+{
+       //string nextmap;
+       //float n, nummaps;
+       //string s;
+       if (alreadychangedlevel)
+               return;
+       alreadychangedlevel = true;
+
+       string nextMap = GetNextMap();
+       if(nextMap == "")
+               error("Everything is broken - cannot find a next map. Please report this to the developers.");
+       Map_Goto(reinit);
+}
+
+
+/*
+============
+IntermissionThink
+
+When the player presses attack or jump, change to the next level
+============
+*/
+.float autoscreenshot;
+void IntermissionThink(entity this)
+{
+       FixIntermissionClient(this);
+
+       float server_screenshot = (autocvar_sv_autoscreenshot && CS(this).cvar_cl_autoscreenshot);
+       float client_screenshot = (CS(this).cvar_cl_autoscreenshot == 2);
+
+       if( (server_screenshot || client_screenshot)
+               && ((this.autoscreenshot > 0) && (time > this.autoscreenshot)) )
+       {
+               this.autoscreenshot = -1;
+               if(IS_REAL_CLIENT(this)) { stuffcmd(this, sprintf("\nscreenshot screenshots/autoscreenshot/%s-%s.jpg; echo \"^5A screenshot has been taken at request of the server.\"\n", GetMapname(), strftime(false, "%s"))); }
+               return;
+       }
+
+       if (time < intermission_exittime)
+               return;
+
+       if(!mapvote_initialized)
+               if (time < intermission_exittime + 10 && !(PHYS_INPUT_BUTTON_ATCK(this) || PHYS_INPUT_BUTTON_JUMP(this) || PHYS_INPUT_BUTTON_ATCK2(this) || PHYS_INPUT_BUTTON_HOOK(this) || PHYS_INPUT_BUTTON_USE(this)))
+                       return;
+
+       MapVote_Start();
+}
+
+/*
+===============================================================================
+
+RULES
+
+===============================================================================
+*/
+
+void DumpStats(float final)
+{
+       float file;
+       string s;
+       float to_console;
+       float to_eventlog;
+       float to_file;
+       float i;
+
+       to_console = autocvar_sv_logscores_console;
+       to_eventlog = autocvar_sv_eventlog;
+       to_file = autocvar_sv_logscores_file;
+
+       if(!final)
+       {
+               to_console = true; // always print printstats replies
+               to_eventlog = false; // but never print them to the event log
+       }
+
+       if(to_eventlog)
+               if(autocvar_sv_eventlog_console)
+                       to_console = false; // otherwise we get the output twice
+
+       if(final)
+               s = ":scores:";
+       else
+               s = ":status:";
+       s = strcat(s, GetGametype(), "_", GetMapname(), ":", ftos(rint(time)));
+
+       if(to_console)
+               LOG_INFO(s);
+       if(to_eventlog)
+               GameLogEcho(s);
+
+       file = -1;
+       if(to_file)
+       {
+               file = fopen(autocvar_sv_logscores_filename, FILE_APPEND);
+               if(file == -1)
+                       to_file = false;
+               else
+                       fputs(file, strcat(s, "\n"));
+       }
+
+       s = strcat(":labels:player:", GetPlayerScoreString(NULL, 0));
+       if(to_console)
+               LOG_INFO(s);
+       if(to_eventlog)
+               GameLogEcho(s);
+       if(to_file)
+               fputs(file, strcat(s, "\n"));
+
+       FOREACH_CLIENT(IS_REAL_CLIENT(it) || (IS_BOT_CLIENT(it) && autocvar_sv_logscores_bots), {
+               s = strcat(":player:see-labels:", GetPlayerScoreString(it, 0), ":");
+               s = strcat(s, ftos(rint(time - CS(it).jointime)), ":");
+               if(IS_PLAYER(it) || MUTATOR_CALLHOOK(GetPlayerStatus, it))
+                       s = strcat(s, ftos(it.team), ":");
+               else
+                       s = strcat(s, "spectator:");
+
+               if(to_console)
+                       LOG_INFO(s, playername(it, false));
+               if(to_eventlog)
+                       GameLogEcho(strcat(s, ftos(it.playerid), ":", playername(it, false)));
+               if(to_file)
+                       fputs(file, strcat(s, playername(it, false), "\n"));
+       });
+
+       if(teamplay)
+       {
+               s = strcat(":labels:teamscores:", GetTeamScoreString(0, 0));
+               if(to_console)
+                       LOG_INFO(s);
+               if(to_eventlog)
+                       GameLogEcho(s);
+               if(to_file)
+                       fputs(file, strcat(s, "\n"));
+
+               for(i = 1; i < 16; ++i)
+               {
+                       s = strcat(":teamscores:see-labels:", GetTeamScoreString(i, 0));
+                       s = strcat(s, ":", ftos(i));
+                       if(to_console)
+                               LOG_INFO(s);
+                       if(to_eventlog)
+                               GameLogEcho(s);
+                       if(to_file)
+                               fputs(file, strcat(s, "\n"));
+               }
+       }
+
+       if(to_console)
+               LOG_INFO(":end");
+       if(to_eventlog)
+               GameLogEcho(":end");
+       if(to_file)
+       {
+               fputs(file, ":end\n");
+               fclose(file);
+       }
+}
+
+void FixIntermissionClient(entity e)
+{
+       if(!e.autoscreenshot) // initial call
+       {
+               e.autoscreenshot = time + 0.8;  // used for autoscreenshot
+               SetResourceExplicit(e, RES_HEALTH, -2342);
+               // first intermission phase; voting phase has positive health (used to decide whether to send SVC_FINALE or not)
+               for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+               {
+                   .entity weaponentity = weaponentities[slot];
+                       if(e.(weaponentity))
+                       {
+                               e.(weaponentity).effects = EF_NODRAW;
+                               if (e.(weaponentity).weaponchild)
+                                       e.(weaponentity).weaponchild.effects = EF_NODRAW;
+                       }
+               }
+               if(IS_REAL_CLIENT(e))
+               {
+                       stuffcmd(e, "\nscr_printspeed 1000000\n");
+                       RandomSelection_Init();
+                       FOREACH_WORD(autocvar_sv_intermission_cdtrack, true, {
+                               RandomSelection_AddString(it, 1, 1);
+                       });
+                       if (RandomSelection_chosen_string != "")
+                       {
+                               stuffcmd(e, sprintf("\ncd loop %s\n", RandomSelection_chosen_string));
+                       }
+                       msg_entity = e;
+                       WriteByte(MSG_ONE, SVC_INTERMISSION);
+               }
+       }
+}
+
+/*
+go to the next level for deathmatch
+only called if a time or frag limit has expired
+*/
+void NextLevel()
+{
+       game_stopped = true;
+       intermission_running = 1; // game over
+
+       // enforce a wait time before allowing changelevel
+       if(player_count > 0)
+               intermission_exittime = time + autocvar_sv_mapchange_delay;
+       else
+               intermission_exittime = -1;
+
+       /*
+       WriteByte (MSG_ALL, SVC_CDTRACK);
+       WriteByte (MSG_ALL, 3);
+       WriteByte (MSG_ALL, 3);
+       // done in FixIntermission
+       */
+
+       //pos = FindIntermission ();
+
+       VoteReset();
+
+       DumpStats(true);
+
+       // send statistics
+       PlayerStats_GameReport(true);
+       WeaponStats_Shutdown();
+
+       Kill_Notification(NOTIF_ALL, NULL, MSG_CENTER, CPID_Null); // kill all centerprints now
+
+       if(autocvar_sv_eventlog)
+               GameLogEcho(":gameover");
+
+       GameLogClose();
+
+       FOREACH_CLIENT(IS_PLAYER(it), {
+               FixIntermissionClient(it);
+               if(it.winning)
+                       bprint(playername(it, false), " ^7wins.\n");
+       });
+
+       target_music_kill();
+
+       if(autocvar_g_campaign)
+               CampaignPreIntermission();
+
+       MUTATOR_CALLHOOK(MatchEnd);
+
+       localcmd("\nsv_hook_gameend\n");
+}
+
+
+float InitiateSuddenDeath()
+{
+       // Check first whether normal overtimes could be added before initiating suddendeath mode
+       // - for this timelimit_overtime needs to be >0 of course
+       // - also check the winning condition calculated in the previous frame and only add normal overtime
+       //   again, if at the point at which timelimit would be extended again, still no winner was found
+       if (!autocvar_g_campaign && checkrules_overtimesadded >= 0
+               && (checkrules_overtimesadded < autocvar_timelimit_overtimes || autocvar_timelimit_overtimes < 0)
+               && autocvar_timelimit_overtime && !(g_race && !g_race_qualifying))
+       {
+               return 1; // need to call InitiateOvertime later
+       }
+       else
+       {
+               if(!checkrules_suddendeathend)
+               {
+                       if(autocvar_g_campaign)
+                               checkrules_suddendeathend = time; // no suddendeath in campaign
+                       else
+                               checkrules_suddendeathend = time + 60 * autocvar_timelimit_suddendeath;
+                       if(g_race && !g_race_qualifying)
+                               race_StartCompleting();
+               }
+               return 0;
+       }
+}
+
+void InitiateOvertime() // ONLY call this if InitiateSuddenDeath returned true
+{
+       ++checkrules_overtimesadded;
+       //add one more overtime by simply extending the timelimit
+       cvar_set("timelimit", ftos(autocvar_timelimit + autocvar_timelimit_overtime));
+       Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_OVERTIME_TIME, autocvar_timelimit_overtime * 60);
+}
+
+float GetWinningCode(float fraglimitreached, float equality)
+{
+       if(autocvar_g_campaign == 1)
+       {
+               if(fraglimitreached)
+                       return WINNING_YES;
+               else
+                       return WINNING_NO;
+       }
+       else
+       {
+               if(equality)
+               {
+                       if(fraglimitreached)
+                               return WINNING_STARTSUDDENDEATHOVERTIME;
+                       else
+                               return WINNING_NEVER;
+               }
+               else
+               {
+                       if(fraglimitreached)
+                               return WINNING_YES;
+                       else
+                               return WINNING_NO;
+               }
+       }
+}
+
+// set the .winning flag for exactly those players with a given field value
+void SetWinners(.float field, float value)
+{
+       FOREACH_CLIENT(IS_PLAYER(it), { it.winning = (it.(field) == value); });
+}
+
+// set the .winning flag for those players with a given field value
+void AddWinners(.float field, float value)
+{
+       FOREACH_CLIENT(IS_PLAYER(it), {
+               if(it.(field) == value)
+                       it.winning = 1;
+       });
+}
+
+// clear the .winning flags
+void ClearWinners()
+{
+       FOREACH_CLIENT(IS_PLAYER(it), { it.winning = 0; });
+}
+
+void ShuffleMaplist()
+{
+       cvar_set("g_maplist", shufflewords(autocvar_g_maplist));
+}
+
+int fragsleft_last;
+float WinningCondition_Scores(float limit, float leadlimit)
+{
+       // TODO make everything use THIS winning condition (except LMS)
+       WinningConditionHelper(NULL);
+
+       if(teamplay)
+       {
+               for (int i = 1; i < 5; ++i)
+               {
+                       Team_SetTeamScore(Team_GetTeamFromIndex(i),
+                               TeamScore_GetCompareValue(Team_IndexToTeam(i)));
+               }
+       }
+
+       ClearWinners();
+       if(WinningConditionHelper_winner)
+               WinningConditionHelper_winner.winning = 1;
+       if(WinningConditionHelper_winnerteam >= 0)
+               SetWinners(team, WinningConditionHelper_winnerteam);
+
+       if(WinningConditionHelper_lowerisbetter)
+       {
+               WinningConditionHelper_topscore = -WinningConditionHelper_topscore;
+               WinningConditionHelper_secondscore = -WinningConditionHelper_secondscore;
+               limit = -limit;
+       }
+
+       if(WinningConditionHelper_zeroisworst)
+               leadlimit = 0; // not supported in this mode
+
+       if(MUTATOR_CALLHOOK(Scores_CountFragsRemaining))
+       {
+               float fragsleft;
+               if (checkrules_suddendeathend && time >= checkrules_suddendeathend)
+               {
+                       fragsleft = 1;
+               }
+               else
+               {
+                       fragsleft = FLOAT_MAX;
+                       float leadingfragsleft = FLOAT_MAX;
+                       if (limit)
+                               fragsleft = limit - WinningConditionHelper_topscore;
+                       if (leadlimit)
+                               leadingfragsleft = WinningConditionHelper_secondscore + leadlimit - WinningConditionHelper_topscore;
+
+                       if (limit && leadlimit && autocvar_leadlimit_and_fraglimit)
+                               fragsleft = max(fragsleft, leadingfragsleft);
+                       else
+                               fragsleft = min(fragsleft, leadingfragsleft);
+               }
+
+               if (fragsleft_last != fragsleft) // do not announce same remaining frags multiple times
+               {
+                       if (fragsleft == 1)
+                               Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_REMAINING_FRAG_1);
+                       else if (fragsleft == 2)
+                               Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_REMAINING_FRAG_2);
+                       else if (fragsleft == 3)
+                               Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_REMAINING_FRAG_3);
+
+                       fragsleft_last = fragsleft;
+               }
+       }
+
+       bool fraglimit_reached = (limit && WinningConditionHelper_topscore >= limit);
+       bool leadlimit_reached = (leadlimit && WinningConditionHelper_topscore - WinningConditionHelper_secondscore >= leadlimit);
+
+       bool limit_reached;
+       // only respect leadlimit_and_fraglimit when both limits are set or the game will never end
+       if (limit && leadlimit && autocvar_leadlimit_and_fraglimit)
+               limit_reached = (fraglimit_reached && leadlimit_reached);
+       else
+               limit_reached = (fraglimit_reached || leadlimit_reached);
+
+       return GetWinningCode(
+               WinningConditionHelper_topscore && limit_reached,
+               WinningConditionHelper_equality
+       );
+}
+
+float WinningCondition_RanOutOfSpawns()
+{
+       if(have_team_spawns <= 0)
+               return WINNING_NO;
+
+       if(!autocvar_g_spawn_useallspawns)
+               return WINNING_NO;
+
+       if(!some_spawn_has_been_used)
+               return WINNING_NO;
+
+       for (int i = 1; i < 5; ++i)
+       {
+               Team_SetTeamScore(Team_GetTeamFromIndex(i), 0);
+       }
+
+       FOREACH_CLIENT(IS_PLAYER(it) && !IS_DEAD(it),
+       {
+               if (Team_IsValidTeam(it.team))
+               {
+                       Team_SetTeamScore(Team_GetTeam(it.team), 1);
+               }
+       });
+
+       IL_EACH(g_spawnpoints, true,
+       {
+               if (Team_IsValidTeam(it.team))
+               {
+                       Team_SetTeamScore(Team_GetTeam(it.team), 1);
+               }
+       });
+
+       ClearWinners();
+       float team1_score = Team_GetTeamScore(Team_GetTeamFromIndex(1));
+       float team2_score = Team_GetTeamScore(Team_GetTeamFromIndex(2));
+       float team3_score = Team_GetTeamScore(Team_GetTeamFromIndex(3));
+       float team4_score = Team_GetTeamScore(Team_GetTeamFromIndex(4));
+       if(team1_score + team2_score + team3_score + team4_score == 0)
+       {
+               checkrules_equality = true;
+               return WINNING_YES;
+       }
+       else if(team1_score + team2_score + team3_score + team4_score == 1)
+       {
+               float t, i;
+               if(team1_score)
+                       t = 1;
+               else if(team2_score)
+                       t = 2;
+               else if(team3_score)
+                       t = 3;
+               else // if(team4_score)
+                       t = 4;
+               entity balance = TeamBalance_CheckAllowedTeams(NULL);
+               for(i = 0; i < MAX_TEAMSCORE; ++i)
+               {
+                       for (int j = 1; j <= NUM_TEAMS; ++j)
+                       {
+                               if (t == j)
+                               {
+                                       continue;
+                               }
+                               if (!TeamBalance_IsTeamAllowed(balance, j))
+                               {
+                                       continue;
+                               }
+                               TeamScore_AddToTeam(Team_IndexToTeam(j), i, -1000);
+                       }
+               }
+
+               AddWinners(team, t);
+               return WINNING_YES;
+       }
+       else
+               return WINNING_NO;
+}
+
+/*
+============
+CheckRules_World
+
+Exit deathmatch games upon conditions
+============
+*/
+void CheckRules_World()
+{
+       VoteThink();
+       MapVote_Think();
+
+       SetDefaultAlpha();
+
+       if (intermission_running) // someone else quit the game already
+       {
+               if(player_count == 0) // Nobody there? Then let's go to the next map
+                       MapVote_Start();
+                       // this will actually check the player count in the next frame
+                       // again, but this shouldn't hurt
+               return;
+       }
+
+       float timelimit = autocvar_timelimit * 60;
+       float fraglimit = autocvar_fraglimit;
+       float leadlimit = autocvar_leadlimit;
+       if (leadlimit < 0) leadlimit = 0;
+
+       if(warmup_stage || time <= game_starttime) // NOTE: this is <= to prevent problems in the very tic where the game starts
+       {
+               if(timelimit > 0)
+                       timelimit = 0; // timelimit is not made for warmup
+               if(fraglimit > 0)
+                       fraglimit = 0; // no fraglimit for now
+               leadlimit = 0; // no leadlimit for now
+       }
+
+       if(timelimit > 0)
+       {
+               timelimit += game_starttime;
+       }
+       else if (timelimit < 0)
+       {
+               // endmatch
+               NextLevel();
+               return;
+       }
+
+       float wantovertime;
+       wantovertime = 0;
+
+       if(checkrules_suddendeathend)
+       {
+               if(!checkrules_suddendeathwarning)
+               {
+                       checkrules_suddendeathwarning = true;
+                       if(g_race && !g_race_qualifying)
+                               Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_RACE_FINISHLAP);
+                       else
+                               Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_OVERTIME_FRAG);
+               }
+       }
+       else
+       {
+               if (timelimit && time >= timelimit)
+               {
+                       if(g_race && (g_race_qualifying == 2) && timelimit > 0)
+                       {
+                               float totalplayers;
+                               float playerswithlaps;
+                               float readyplayers;
+                               totalplayers = playerswithlaps = readyplayers = 0;
+                               FOREACH_CLIENT(IS_PLAYER(it), {
+                                       ++totalplayers;
+                                       if(GameRules_scoring_add(it, RACE_FASTEST, 0))
+                                               ++playerswithlaps;
+                                       if(it.ready)
+                                               ++readyplayers;
+                               });
+
+                               // at least 2 of the players have completed a lap: start the RACE
+                               // otherwise, the players should end the qualifying on their own
+                               if(readyplayers || playerswithlaps >= 2)
+                               {
+                                       checkrules_suddendeathend = 0;
+                                       ReadyRestart(); // go to race
+                                       return;
+                               }
+                               else
+                                       wantovertime |= InitiateSuddenDeath();
+                       }
+                       else
+                               wantovertime |= InitiateSuddenDeath();
+               }
+       }
+
+       if (checkrules_suddendeathend && time >= checkrules_suddendeathend)
+       {
+               NextLevel();
+               return;
+       }
+
+       int checkrules_status = WinningCondition_RanOutOfSpawns();
+       if(checkrules_status == WINNING_YES)
+               bprint("Hey! Someone ran out of spawns!\n");
+       else if(MUTATOR_CALLHOOK(CheckRules_World, checkrules_status, timelimit, fraglimit))
+               checkrules_status = M_ARGV(0, float);
+       else
+               checkrules_status = WinningCondition_Scores(fraglimit, leadlimit);
+
+       if(checkrules_status == WINNING_STARTSUDDENDEATHOVERTIME)
+       {
+               checkrules_status = WINNING_NEVER;
+               checkrules_overtimesadded = -1;
+               wantovertime |= InitiateSuddenDeath();
+       }
+
+       if(checkrules_status == WINNING_NEVER)
+               // equality cases! Nobody wins if the overtime ends in a draw.
+               ClearWinners();
+
+       if(wantovertime)
+       {
+               if(checkrules_status == WINNING_NEVER)
+                       InitiateOvertime();
+               else
+                       checkrules_status = WINNING_YES;
+       }
+
+       if(checkrules_suddendeathend)
+               if(checkrules_status != WINNING_NEVER || time >= checkrules_suddendeathend)
+                       checkrules_status = WINNING_YES;
+
+       if(checkrules_status == WINNING_YES)
+       {
+               //print("WINNING\n");
+               NextLevel();
+       }
+}
+
+string GotoMap(string m)
+{
+       m = GameTypeVote_MapInfo_FixName(m);
+       if (!m)
+               return "The map you suggested is not available on this server.";
+       if (!autocvar_sv_vote_gametype)
+       if(!MapInfo_CheckMap(m))
+               return "The map you suggested does not support the current game mode.";
+       cvar_set("nextmap", m);
+       cvar_set("timelimit", "-1");
+       if(mapvote_initialized || alreadychangedlevel)
+       {
+               if(DoNextMapOverride(0))
+                       return "Map switch initiated.";
+               else
+                       return "Hm... no. For some reason I like THIS map more.";
+       }
+       else
+               return "Map switch will happen after scoreboard.";
+}
+
+bool autocvar_sv_gameplayfix_multiplethinksperframe = true;
+void RunThink(entity this)
+{
+       // don't let things stay in the past.
+       // it is possible to start that way by a trigger with a local time.
+       if(this.nextthink <= 0 || this.nextthink > time + frametime)
+               return;
+
+       float oldtime = time; // do we need to save this?
+
+       for (int iterations = 0; iterations < 128 && !wasfreed(this); iterations++)
+       {
+               time = max(oldtime, this.nextthink);
+               this.nextthink = 0;
+
+               if(getthink(this))
+                       getthink(this)(this);
+               // mods often set nextthink to time to cause a think every frame,
+               // we don't want to loop in that case, so exit if the new nextthink is
+               // <= the time the qc was told, also exit if it is past the end of the
+               // frame
+               if(this.nextthink <= time || this.nextthink > oldtime + frametime || !autocvar_sv_gameplayfix_multiplethinksperframe)
+                       break;
+       }
+
+       time = oldtime;
+}
+
+bool autocvar_sv_freezenonclients;
+void Physics_Frame()
+{
+       if(autocvar_sv_freezenonclients)
+               return;
+
+       IL_EACH(g_moveables, true,
+       {
+               if(IS_CLIENT(it) || it.move_movetype == MOVETYPE_PHYSICS)
+                       continue;
+
+               //set_movetype(it, it.move_movetype);
+               // inline the set_movetype function, since this is called a lot
+               it.movetype = (it.move_qcphysics) ? MOVETYPE_QCENTITY : it.move_movetype;
+
+               if(it.move_qcphysics && it.move_movetype != MOVETYPE_NONE)
+                       Movetype_Physics_NoMatchTicrate(it, PHYS_INPUT_TIMELENGTH, false);
+
+               if(it.movetype >= MOVETYPE_USER_FIRST && it.movetype <= MOVETYPE_USER_LAST) // these cases have no think handling
+               {
+                       if(it.move_movetype == MOVETYPE_PUSH || it.move_movetype == MOVETYPE_FAKEPUSH)
+                               continue; // these movetypes have no regular think function
+                       // handle thinking here
+                       if (getthink(it) && it.nextthink > 0 && it.nextthink <= time + frametime)
+                               RunThink(it);
+               }
+       });
+
+       if(autocvar_sv_gameplayfix_delayprojectiles >= 0)
+               return;
+
+       // make a second pass to see if any ents spawned this frame and make
+       // sure they run their move/think. this is verified by checking .move_time, which will never be 0 if the entity has moved
+       IL_EACH(g_moveables, it.move_qcphysics,
+       {
+               if(IS_CLIENT(it) || it.move_time || it.move_movetype == MOVETYPE_NONE || it.move_movetype == MOVETYPE_PHYSICS)
+                       continue;
+               Movetype_Physics_NoMatchTicrate(it, PHYS_INPUT_TIMELENGTH, false);
+       });
+}
+
+void systems_update();
+void EndFrame()
+{
+       anticheat_endframe();
+
+       Physics_Frame();
+
+       FOREACH_CLIENT(IS_REAL_CLIENT(it), {
+               entity e = IS_SPEC(it) ? it.enemy : it;
+               if (e.typehitsound) {
+                       STAT(TYPEHIT_TIME, it) = time;
+               } else if (e.killsound) {
+                       STAT(KILL_TIME, it) = time;
+               } else if (e.damage_dealt) {
+                       STAT(HIT_TIME, it) = time;
+                       STAT(DAMAGE_DEALT_TOTAL, it) += ceil(e.damage_dealt);
+               }
+       });
+       // add 1 frametime because after this, engine SV_Physics
+       // increases time by a frametime and then networks the frame
+       // add another frametime because client shows everything with
+       // 1 frame of lag (cl_nolerp 0). The last +1 however should not be
+       // needed!
+       float altime = time + frametime * (1 + autocvar_g_antilag_nudge);
+       FOREACH_CLIENT(true, {
+               it.typehitsound = false;
+               it.damage_dealt = 0;
+               it.killsound = false;
+               antilag_record(it, CS(it), altime);
+       });
+       IL_EACH(g_monsters, true,
+       {
+               antilag_record(it, it, altime);
+       });
+       IL_EACH(g_projectiles, it.classname == "nade",
+       {
+               antilag_record(it, it, altime);
+       });
+       systems_update();
+       IL_ENDFRAME();
+}
+
+
+/*
+ * RedirectionThink:
+ * returns true if redirecting
+ */
+float redirection_timeout;
+float redirection_nextthink;
+float RedirectionThink()
+{
+       float clients_found;
+
+       if(redirection_target == "")
+               return false;
+
+       if(!redirection_timeout)
+       {
+               cvar_set("sv_public", "-2");
+               redirection_timeout = time + 0.6; // this will only try twice... should be able to keep more clients
+               if(redirection_target == "self")
+                       bprint("^3SERVER NOTICE:^7 restarting the server\n");
+               else
+                       bprint("^3SERVER NOTICE:^7 redirecting everyone to ", redirection_target, "\n");
+       }
+
+       if(time < redirection_nextthink)
+               return true;
+
+       redirection_nextthink = time + 1;
+
+       clients_found = 0;
+       FOREACH_CLIENT(IS_REAL_CLIENT(it), {
+               // TODO add timer
+               LOG_INFO("Redirecting: sending connect command to ", it.netname);
+               if(redirection_target == "self")
+                       stuffcmd(it, "\ndisconnect; defer ", ftos(autocvar_quit_and_redirect_timer), " reconnect\n");
+               else
+                       stuffcmd(it, strcat("\ndisconnect; defer ", ftos(autocvar_quit_and_redirect_timer), " \"connect ", redirection_target, "\"\n"));
+               ++clients_found;
+       });
+
+       LOG_INFO("Redirecting: ", ftos(clients_found), " clients left.");
+
+       if(time > redirection_timeout || clients_found == 0)
+               localcmd("\nwait; wait; wait; quit\n");
+
+       return true;
+}
+
+void RestoreGame()
+{
+       // Loaded from a save game
+       // some things then break, so let's work around them...
+
+       // Progs DB (capture records)
+       ServerProgsDB = db_load(strcat("server.db", autocvar_sessionid));
+
+       // Mapinfo
+       MapInfo_Shutdown();
+       MapInfo_Enumerate();
+       MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 1);
+       WeaponStats_Init();
+
+       TargetMusic_RestoreGame();
+}
+
+void Shutdown()
+{
+       game_stopped = 2;
+
+       if(world_initialized > 0)
+       {
+               world_initialized = 0;
+
+               // if a timeout is active, reset the slowmo value to normal
+               if(timeout_status == TIMEOUT_ACTIVE)
+                       cvar_set("slowmo", ftos(orig_slowmo));
+
+               LOG_TRACE("Saving persistent data...");
+               Ban_SaveBans();
+
+               // playerstats with unfinished match
+               PlayerStats_GameReport(false);
+
+               if(!cheatcount_total)
+               {
+                       if(autocvar_sv_db_saveasdump)
+                               db_dump(ServerProgsDB, strcat("server.db", autocvar_sessionid));
+                       else
+                               db_save(ServerProgsDB, strcat("server.db", autocvar_sessionid));
+               }
+               if(autocvar_developer > 0)
+               {
+                       if(autocvar_sv_db_saveasdump)
+                               db_dump(TemporaryDB, "server-temp.db");
+                       else
+                               db_save(TemporaryDB, "server-temp.db");
+               }
+               CheatShutdown(); // must be after cheatcount check
+               db_close(ServerProgsDB);
+               db_close(TemporaryDB);
+               LOG_TRACE("Saving persistent data... done!");
+               // tell the bot system the game is ending now
+               bot_endgame();
+
+               WeaponStats_Shutdown();
+               MapInfo_Shutdown();
+       }
+       else if(world_initialized == 0)
+       {
+               LOG_INFO("NOTE: crashed before even initializing the world, not saving persistent data");
+       }
+       else
+       {
+               __init_dedicated_server_shutdown();
+       }
+}
diff --git a/qcsrc/server/world.qh b/qcsrc/server/world.qh
new file mode 100644 (file)
index 0000000..2894299
--- /dev/null
@@ -0,0 +1,69 @@
+#pragma once
+
+float checkrules_equality;
+float checkrules_suddendeathwarning;
+float checkrules_suddendeathend;
+float checkrules_overtimesadded; //how many overtimes have been already added
+
+// flag set on worldspawn so that the code knows if it is dedicated or not
+bool server_is_dedicated;
+
+string cvar_changes;
+string cvar_purechanges;
+float cvar_purechanges_count;
+
+string modname;
+
+string gamemode_name;
+
+string clientstuff;
+
+string matchid;
+
+.string fog;
+
+float intermission_running;
+float intermission_exittime;
+float alreadychangedlevel;
+
+string cache_mutatormsg;
+string cache_lastmutatormsg;
+
+float default_player_alpha;
+float default_weapon_alpha;
+
+// database
+float ServerProgsDB;
+float TemporaryDB;
+
+.float winning;
+const int WINNING_NO = 0; // no winner, but time limits may terminate the game
+const int WINNING_YES = 1; // winner found
+const int WINNING_NEVER = 2; // no winner, enter overtime if time limit is reached
+const int WINNING_STARTSUDDENDEATHOVERTIME = 3; // no winner, enter suddendeath overtime NOW
+
+float WinningCondition_Scores(float limit, float leadlimit);
+void SetWinners(.float field, float value);
+void IntermissionThink(entity this);
+void GotoNextMap(float reinit);
+void ReadyRestart();
+
+string GetGametype();
+
+void DumpStats(float final);
+float Map_IsRecent(string m);
+string GetNextMap();
+void ShuffleMaplist();
+void Map_Goto_SetStr(string nextmapname);
+void Map_Goto(float reinit);
+void Map_MarkAsRecent(string m);
+float DoNextMapOverride(float reinit);
+void CheckRules_World();
+float RedirectionThink();
+
+// quake 3 music compatibility
+.string music;
+.string noise;
+
+IntrusiveList g_moveables;
+STATIC_INIT(g_moveables) { g_moveables = IL_NEW(); }
index 17224b222022d0cd29a942fdb07e8c6c80e49d8f..e39a892fb28d4ef9d7ea5d6a46e8d49af56c40c0 100644 (file)
@@ -732,7 +732,7 @@ set cl_accuracy_data_receive 0 "1 receive weapon accuracy data statistics at the
 set developer_csqcentities 0 "csqc entity spam"
 
 seta cl_forceplayermodels 0 "make everyone look like your own model (requires server to have sv_defaultcharacter 0)"
-seta cl_forceplayercolors 0 "make enemies look like your own color (requires server to have sv_defaultcharacter 0); set it to 2 to enable it even in teamplay (only when there is exactly one enemy team)"
+seta cl_forceplayercolors 0 "make enemies look like your own color (requires server to have sv_defaultcharacter 0); 2: enable it even in teamplay (only when there is exactly one enemy team); 3: enable it only playing Duel"
 seta cl_forcemyplayermodel "" "set to the model file name you want to show yourself as (does not affect how enemies look with cl_forceplayermodels)"
 seta cl_forcemyplayerskin 0 "set to the skin number you want to show yourself as (does not affect how enemies look with cl_forceplayermodels)"
 seta cl_forcemyplayercolors 0 "set to the color value (encoding is same as _cl_color) for your own player model (ignored in teamplay; does not affect how enemies look with cl_forceplayermodels)"