]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'terencehill/texture_names_fix' into 'master'
authorMario <mario.mario@y7mail.com>
Sat, 23 May 2020 11:16:45 +0000 (11:16 +0000)
committerMario <mario.mario@y7mail.com>
Sat, 23 May 2020 11:16:45 +0000 (11:16 +0000)
Fix some texture names: *_spec.tga --> *_gloss.tga

See merge request xonotic/xonotic-data.pk3dir!730

289 files changed:
.gitlab-ci.yml
.tx/merge-base
_hud_common.cfg
_hud_descriptions.cfg
bal-wep-mario.cfg
bal-wep-nexuiz25.cfg
bal-wep-overkill-nerfed.cfg [deleted file]
bal-wep-samual.cfg
bal-wep-testing.cfg [deleted file]
bal-wep-testingxpm.cfg [deleted file]
bal-wep-xdf.cfg
bal-wep-xonotic.cfg
bal-wep-xpm.cfg [deleted file]
balance-mario.cfg
balance-nexuiz25.cfg
balance-overkill.cfg
balance-samual.cfg
balance-testing.cfg
balance-testingxpm.cfg
balance-xdf.cfg
balance-xonotic.cfg
balance-xpm.cfg
binds-xonotic.cfg
check-cvars.sh
commands.cfg
common.ast.po
common.cs.po
common.de.po
common.de_CH.po
common.el.po
common.fi.po
common.he.po
common.pl.po
common.pt_BR.po
common.ru.po
common.tr.po
crosshairs.cfg
effectinfo.txt
effects-high.cfg
effects-low.cfg
effects-med.cfg
effects-normal.cfg
effects-omg.cfg
gamemodes-server.cfg
hud_luma.cfg
hud_luminos.cfg
hud_luminos_minimal.cfg
hud_luminos_minimal_xhair.cfg
hud_luminos_old.cfg
hud_nexuiz.cfg
languages.txt
mutators.cfg
notifications.cfg
physics.cfg
qcsrc/Makefile
qcsrc/client/autocvars.qh
qcsrc/client/csqcmodel_hooks.qc
qcsrc/client/defs.qh
qcsrc/client/hud/hud.qc
qcsrc/client/hud/hud_config.qc
qcsrc/client/hud/panel/centerprint.qc
qcsrc/client/hud/panel/healtharmor.qc
qcsrc/client/hud/panel/pressedkeys.qc
qcsrc/client/hud/panel/quickmenu.qc
qcsrc/client/hud/panel/racetimer.qc
qcsrc/client/hud/panel/scoreboard.qc
qcsrc/client/hud/panel/weapons.qc
qcsrc/client/main.qc
qcsrc/client/miscfunctions.qc
qcsrc/client/miscfunctions.qh
qcsrc/client/shownames.qc
qcsrc/client/teamradar.qc
qcsrc/client/view.qc
qcsrc/client/view.qh
qcsrc/common/campaign_common.qh
qcsrc/common/campaign_file.qc
qcsrc/common/command/generic.qc
qcsrc/common/command/reg.qh
qcsrc/common/command/rpn.qc
qcsrc/common/debug.qh
qcsrc/common/effects/effectinfo.inc
qcsrc/common/effects/effectinfo.qc
qcsrc/common/effects/qc/casings.qc
qcsrc/common/effects/qc/globalsound.qc
qcsrc/common/effects/qc/globalsound.qh
qcsrc/common/gamemodes/gamemode/ctf/cl_ctf.qc
qcsrc/common/gamemodes/gamemode/ctf/sv_ctf.qc
qcsrc/common/gamemodes/gamemode/freezetag/sv_freezetag.qc
qcsrc/common/gamemodes/gamemode/freezetag/sv_freezetag.qh
qcsrc/common/gamemodes/gamemode/keepaway/cl_keepaway.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/lms/sv_lms.qh
qcsrc/common/gamemodes/gamemode/onslaught/sv_onslaught.qc
qcsrc/common/gamemodes/gamemode/onslaught/sv_onslaught.qh
qcsrc/common/items/all.qh
qcsrc/common/items/inventory.qh
qcsrc/common/items/item.qh
qcsrc/common/items/item/pickup.qh
qcsrc/common/mapinfo.qc
qcsrc/common/mapobjects/func/breakable.qc
qcsrc/common/mapobjects/func/button.qc
qcsrc/common/mapobjects/func/rainsnow.qc
qcsrc/common/mapobjects/models.qc
qcsrc/common/mapobjects/subs.qc
qcsrc/common/mapobjects/subs.qh
qcsrc/common/mapobjects/trigger/counter.qc
qcsrc/common/mapobjects/trigger/counter.qh
qcsrc/common/mapobjects/trigger/disablerelay.qc
qcsrc/common/mapobjects/trigger/hurt.qc
qcsrc/common/mapobjects/trigger/jumppads.qc
qcsrc/common/mapobjects/trigger/multi.qc
qcsrc/common/mapobjects/trigger/relay_if.qc
qcsrc/common/mapobjects/trigger/relay_teamcheck.qc
qcsrc/common/mapobjects/trigger/swamp.qc
qcsrc/common/mapobjects/trigger/swamp.qh
qcsrc/common/mapobjects/triggers.qc
qcsrc/common/mapobjects/triggers.qh
qcsrc/common/monsters/monster/mage.qc
qcsrc/common/monsters/monster/shambler.qc
qcsrc/common/monsters/monster/spider.qc
qcsrc/common/monsters/monster/wyvern.qc
qcsrc/common/monsters/sv_monsters.qc
qcsrc/common/mutators/events.qh
qcsrc/common/mutators/mutator/bloodloss/_mod.inc
qcsrc/common/mutators/mutator/bloodloss/_mod.qh
qcsrc/common/mutators/mutator/bloodloss/bloodloss.qc [new file with mode: 0644]
qcsrc/common/mutators/mutator/bloodloss/bloodloss.qh [new file with mode: 0644]
qcsrc/common/mutators/mutator/bloodloss/sv_bloodloss.qc [deleted file]
qcsrc/common/mutators/mutator/bloodloss/sv_bloodloss.qh [deleted file]
qcsrc/common/mutators/mutator/buffs/all.inc
qcsrc/common/mutators/mutator/buffs/cl_buffs.qc
qcsrc/common/mutators/mutator/buffs/sv_buffs.qc
qcsrc/common/mutators/mutator/buffs/sv_buffs.qh
qcsrc/common/mutators/mutator/bugrigs/bugrigs.qc
qcsrc/common/mutators/mutator/campcheck/sv_campcheck.qc
qcsrc/common/mutators/mutator/dodging/cl_dodging.qh
qcsrc/common/mutators/mutator/dodging/sv_dodging.qc
qcsrc/common/mutators/mutator/instagib/sv_instagib.qc
qcsrc/common/mutators/mutator/instagib/sv_instagib.qh
qcsrc/common/mutators/mutator/itemstime/itemstime.qc
qcsrc/common/mutators/mutator/multijump/multijump.qc
qcsrc/common/mutators/mutator/nades/nades.qc
qcsrc/common/mutators/mutator/overkill/okhmg.qc
qcsrc/common/mutators/mutator/overkill/okmachinegun.qc
qcsrc/common/mutators/mutator/overkill/oknex.qc
qcsrc/common/mutators/mutator/overkill/okrpc.qc
qcsrc/common/mutators/mutator/overkill/okshotgun.qc
qcsrc/common/mutators/mutator/overkill/sv_overkill.qc
qcsrc/common/mutators/mutator/pinata/sv_pinata.qc
qcsrc/common/mutators/mutator/superspec/sv_superspec.qc
qcsrc/common/mutators/mutator/walljump/walljump.qc
qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc
qcsrc/common/notifications/all.inc
qcsrc/common/notifications/all.qh
qcsrc/common/physics/movetypes/movetypes.qc
qcsrc/common/physics/movetypes/movetypes.qh
qcsrc/common/physics/movetypes/toss.qc
qcsrc/common/physics/movetypes/walk.qc
qcsrc/common/physics/player.qc
qcsrc/common/playerstats.qc
qcsrc/common/playerstats.qh
qcsrc/common/state.qc
qcsrc/common/stats.qh
qcsrc/common/t_items.qc
qcsrc/common/t_items.qh
qcsrc/common/turrets/all.qh
qcsrc/common/turrets/sv_turrets.qc
qcsrc/common/util.qc
qcsrc/common/vehicles/sv_vehicles.qc
qcsrc/common/vehicles/vehicle/bumblebee.qc
qcsrc/common/vehicles/vehicle/bumblebee_weapons.qc
qcsrc/common/vehicles/vehicle/racer.qc
qcsrc/common/vehicles/vehicle/racer_weapon.qc
qcsrc/common/vehicles/vehicle/raptor.qc
qcsrc/common/vehicles/vehicle/raptor_weapons.qc
qcsrc/common/vehicles/vehicle/raptor_weapons.qh
qcsrc/common/vehicles/vehicle/spiderbot.qc
qcsrc/common/vehicles/vehicle/spiderbot_weapons.qc
qcsrc/common/weapons/all.qc
qcsrc/common/weapons/all.qh
qcsrc/common/weapons/weapon.qh
qcsrc/common/weapons/weapon/arc.qc
qcsrc/common/weapons/weapon/devastator.qc
qcsrc/common/weapons/weapon/electro.qc
qcsrc/common/weapons/weapon/electro.qh
qcsrc/common/weapons/weapon/minelayer.qc
qcsrc/common/weapons/weapon/porto.qc
qcsrc/common/weapons/weapon/shockwave.qc
qcsrc/common/weapons/weapon/shotgun.qc
qcsrc/common/weapons/weapon/vaporizer.qc
qcsrc/dpdefs/csprogsdefs.qh
qcsrc/dpdefs/dpextensions.qh
qcsrc/dpdefs/post.qh
qcsrc/dpdefs/progsdefs.qh
qcsrc/ecs/lib.qh
qcsrc/ecs/systems/physics.qc
qcsrc/i18n-guide.txt
qcsrc/lib/_all.inc
qcsrc/lib/csqcmodel/cl_player.qc
qcsrc/lib/csqcmodel/cl_player.qh
qcsrc/lib/csqcmodel/interpolate.qc
qcsrc/lib/cvar.qh
qcsrc/lib/deglobalization.qh
qcsrc/lib/draw.qh
qcsrc/lib/i18n.qh
qcsrc/lib/intrusivelist.qh
qcsrc/lib/log.qh
qcsrc/lib/map.qh
qcsrc/lib/matrix/command.qc
qcsrc/lib/matrix/matrix.qc
qcsrc/lib/oo.qh
qcsrc/lib/replicate.qh
qcsrc/lib/static.qh
qcsrc/lib/stats.qh
qcsrc/lib/string.qh
qcsrc/lib/vector.qh
qcsrc/lib/warpzone/mathlib.qc
qcsrc/lib/warpzone/server.qc
qcsrc/menu/menu.qc
qcsrc/menu/xonotic/campaign.qc
qcsrc/menu/xonotic/campaign.qh
qcsrc/menu/xonotic/dialog_disconnect.qc
qcsrc/menu/xonotic/dialog_disconnect.qh
qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc
qcsrc/menu/xonotic/dialog_quit.qc
qcsrc/menu/xonotic/dialog_settings_audio.qc
qcsrc/menu/xonotic/dialog_settings_effects.qc
qcsrc/menu/xonotic/dialog_settings_game_view.qc
qcsrc/menu/xonotic/dialog_settings_game_weapons.qc
qcsrc/menu/xonotic/dialog_settings_misc.qc
qcsrc/menu/xonotic/dialog_settings_video.qc
qcsrc/menu/xonotic/dialog_singleplayer.qc
qcsrc/menu/xonotic/keybinder.qc
qcsrc/menu/xonotic/maplist.qc
qcsrc/menu/xonotic/serverlist.qc
qcsrc/menu/xonotic/serverlist.qh
qcsrc/menu/xonotic/slider_particles.qc
qcsrc/menu/xonotic/util.qc
qcsrc/server/autocvars.qh
qcsrc/server/bot/default/bot.qc
qcsrc/server/bot/default/bot.qh
qcsrc/server/bot/default/cvars.qh
qcsrc/server/bot/default/havocbot/havocbot.qc
qcsrc/server/bot/default/havocbot/havocbot.qh
qcsrc/server/bot/default/havocbot/roles.qc
qcsrc/server/bot/default/navigation.qc
qcsrc/server/bot/default/navigation.qh
qcsrc/server/bot/default/scripting.qc
qcsrc/server/bot/default/waypoints.qc
qcsrc/server/bot/default/waypoints.qh
qcsrc/server/campaign.qc
qcsrc/server/campaign.qh
qcsrc/server/cheats.qc
qcsrc/server/client.qc
qcsrc/server/client.qh
qcsrc/server/command/cmd.qc
qcsrc/server/command/sv_cmd.qc
qcsrc/server/command/vote.qc
qcsrc/server/compat/quake3.qc
qcsrc/server/defs.qh
qcsrc/server/g_damage.qc
qcsrc/server/g_hook.qc
qcsrc/server/g_world.qc
qcsrc/server/ipban.qc
qcsrc/server/mapvoting.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/miscfunctions.qh
qcsrc/server/pathlib/main.qc
qcsrc/server/player.qc
qcsrc/server/portals.qc
qcsrc/server/scores.qc
qcsrc/server/spawnpoints.qc
qcsrc/server/sv_main.qc
qcsrc/server/teamplay.qc
qcsrc/server/weapons/spawning.qc
qcsrc/server/weapons/throwing.qc
qcsrc/server/weapons/weaponsystem.qc
qcsrc/server/weapons/weaponsystem.qh
ruleset-overkill.cfg
scripts/electro.shader
sound/weapons/hagar_fire.ogg
sound/weapons/rocket_fire.ogg
testing.cfg [new file with mode: 0644]
vehicles.cfg
xonotic-client.cfg
xonotic-common.cfg
xonotic-server.cfg

index 8724d06617940c0ed8cf76c67ad0fc94a25cb5a9..40d5b0b4072e8ea4a690f6060d9cf528c703ca5c 100644 (file)
@@ -29,7 +29,7 @@ test_sv_game:
     - wget -O data/maps/stormkeep.waypoints https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/stormkeep.waypoints
     - wget -O data/maps/stormkeep.waypoints.cache https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/stormkeep.waypoints.cache
     - make
-    - EXPECT=892e447048e051e51f30cff2affc729a
+    - EXPECT=62fd4d2a4124374b7e0cc1aff445cd88
     - HASH=$(${ENGINE} -noconfig -nohome +exec serverbench.cfg
       | tee /dev/stderr
       | grep '^:'
index 0f5fe0e2f91b385a6cf7a0020d68a99f4046f3fd..76b17ee0d96cbfc3d0e9f6020d21617e2e0f24b3 100644 (file)
@@ -1 +1 @@
-Fri Oct 18 07:24:34 CEST 2019
+Wed May 13 07:23:38 CEST 2020
index c860be99cebd39ff846ded8cba3cdcbc790fb8b9..0479f389bed5449b3e827971b9b3470b938febb8 100644 (file)
@@ -74,6 +74,7 @@ seta hud_panel_weapons_ammo_full_plasma 180 "show 100% of the status bar at this
 seta hud_panel_weapons_ammo_full_rockets 160 "show 100% of the status bar at this ammo count"
 seta hud_panel_weapons_ammo_full_fuel 100 "show 100% of the status bar at this ammo count"
 seta hud_panel_weapons_hide_ondeath 0 "hide this panel when dead"
+seta hud_panel_weapons_orderbyimpulse "1" "List weapons in their impulse order instead of priority"
 
 seta hud_panel_ammo_maxammo "40" "when you have this much ammo, the ammo status bar is full"
 seta hud_panel_ammo_hide_ondeath 0 "hide this panel when dead"
index 6e393e6a57eff4fdba4a60878e94ce0a2d106ead..3f0355b5fd79cae5ecf2db48b96a386d38e4a36d 100644 (file)
@@ -21,6 +21,7 @@ seta hud_progressbar_shield_color "" "R G B vector of the progress bar backgroun
 seta hud_progressbar_health_color "" "R G B vector of the progress bar background color"
 seta hud_progressbar_armor_color "" "R G B vector of the progress bar background color"
 seta hud_progressbar_fuel_color "" "R G B vector of the progress bar background color"
+seta hud_progressbar_oxygen_color "" "R G B vector of the progress bar background color"
 seta hud_progressbar_nexball_color "" "R G B vector of the progress bar background color"
 seta hud_progressbar_speed_color "" "R G B vector of the progress bar background color"
 seta hud_progressbar_acceleration_color "" "R G B vector of the progress bar background color"
@@ -63,7 +64,6 @@ seta hud_panel_weapons_label_scale "" "scale of the weapon text label"
 seta hud_panel_weapons_accuracy "" "show accuracy color as the weapon icon background; colors can be configured with accuracy_color* cvars"
 seta hud_panel_weapons_ammo "" "show ammo as a status bar"
 seta hud_panel_weapons_onlyowned "" "show only owned weapons, set it to 2 to show only the held weapon"
-seta hud_panel_weapons_orderbyimpulse "" "List weapons in their impulse order instead of priority"
 seta hud_panel_weapons_noncurrent_alpha "" "alpha of noncurrent weapons"
 seta hud_panel_weapons_noncurrent_scale "" "scale of noncurrent weapons, relative to the current weapon"
 seta hud_panel_weapons_selection_radius "" "number of weapons that get partially highlighted on each side of the currently selected weapon"
@@ -275,6 +275,7 @@ seta hud_panel_centerprint_bg_padding "" "if set to something else than \"\" = o
 seta hud_panel_centerprint_align "" "text alignment: 0 left, 0.5 center, 1 right"
 seta hud_panel_centerprint_flip "" "invert messages order"
 seta hud_panel_centerprint_fontscale "" "scale the text font by this amount"
+seta hud_panel_centerprint_fontscale_bold "" "scale the bold text font by this amount"
 seta hud_panel_centerprint_time "" "message duration (NOTE: certain messages have a fixed duration)"
 seta hud_panel_centerprint_fade_in "" "how long a message takes to fade in"
 seta hud_panel_centerprint_fade_out "" "how long a message takes to fade out (this time is included in the message duration and can't be > 5)"
index d3270acc83acd29cf991d547f282a43eaa3c0482..5cfa34882b2710471c8e0a44157dda9feff17eb5 100644 (file)
@@ -191,9 +191,13 @@ set g_balance_electro_primary_damage 40
 set g_balance_electro_primary_edgedamage 20
 set g_balance_electro_primary_force 200
 set g_balance_electro_primary_lifetime 5
+set g_balance_electro_primary_midaircombo_enemy 1
 set g_balance_electro_primary_midaircombo_explode 1
 set g_balance_electro_primary_midaircombo_interval 0.1
+set g_balance_electro_primary_midaircombo_own 1
 set g_balance_electro_primary_midaircombo_radius 0
+set g_balance_electro_primary_midaircombo_speed 2000
+set g_balance_electro_primary_midaircombo_teammate 1
 set g_balance_electro_primary_radius 100
 set g_balance_electro_primary_refire 0.6
 set g_balance_electro_primary_speed 2500
index c9d87fd0578f32daff8750b19727a8e76d2006dc..f9659814b3ea91d425b172095dbc9c264a2e5418 100644 (file)
@@ -191,9 +191,13 @@ set g_balance_electro_primary_damage 65
 set g_balance_electro_primary_edgedamage 0
 set g_balance_electro_primary_force 200
 set g_balance_electro_primary_lifetime 30
+set g_balance_electro_primary_midaircombo_enemy 1
 set g_balance_electro_primary_midaircombo_explode 0
 set g_balance_electro_primary_midaircombo_interval 0
+set g_balance_electro_primary_midaircombo_own 1
 set g_balance_electro_primary_midaircombo_radius 0
+set g_balance_electro_primary_midaircombo_speed 2000
+set g_balance_electro_primary_midaircombo_teammate 1
 set g_balance_electro_primary_radius 150
 set g_balance_electro_primary_refire 0.6
 set g_balance_electro_primary_speed 2000
diff --git a/bal-wep-overkill-nerfed.cfg b/bal-wep-overkill-nerfed.cfg
deleted file mode 100644 (file)
index 74dd683..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-// This config file is for overkill weapons that were nerfed to have the same
-// stats as vanilla weapons, secondary attack uses stats of vanilla blaster.
-// Secondary is actually inconsistent, see https://gitlab.com/xonotic/xonotic-data.pk3dir/issues/2258
-
-// {{{ Overkill Shotgun
-set g_balance_okshotgun_primary_ammo 1
-set g_balance_okshotgun_primary_animtime 0.2
-set g_balance_okshotgun_primary_bot_range 512
-set g_balance_okshotgun_primary_bullets 12
-set g_balance_okshotgun_primary_damage 4
-set g_balance_okshotgun_primary_force 15
-set g_balance_okshotgun_primary_refire 0.75
-set g_balance_okshotgun_primary_solidpenetration 3.8
-set g_balance_okshotgun_primary_spread 0.12
-set g_balance_okshotgun_reload_ammo 0
-set g_balance_okshotgun_reload_time 2
-set g_balance_okshotgun_secondary_animtime 0.2
-set g_balance_okshotgun_secondary_damage 20
-set g_balance_okshotgun_secondary_delay 0
-set g_balance_okshotgun_secondary_edgedamage 10
-set g_balance_okshotgun_secondary_force 300
-set g_balance_okshotgun_secondary_force_zscale 1
-set g_balance_okshotgun_secondary_lifetime 5
-set g_balance_okshotgun_secondary_radius 60
-set g_balance_okshotgun_secondary_refire 0.7
-set g_balance_okshotgun_secondary_refire_type 0
-set g_balance_okshotgun_secondary_shotangle 0
-set g_balance_okshotgun_secondary_speed 6000
-set g_balance_okshotgun_secondary_spread 0
-set g_balance_okshotgun_switchdelay_drop 0.2
-set g_balance_okshotgun_switchdelay_raise 0.2
-set g_balance_okshotgun_weaponreplace ""
-set g_balance_okshotgun_weaponstart 0
-set g_balance_okshotgun_weaponstartoverride -1
-set g_balance_okshotgun_weaponthrowable 1
-// }}}
-// {{{ Overkill Machine Gun
-set g_balance_okmachinegun_primary_ammo 1
-set g_balance_okmachinegun_primary_damage 10
-set g_balance_okmachinegun_primary_force 3
-set g_balance_okmachinegun_primary_refire 0.1
-set g_balance_okmachinegun_primary_solidpenetration 13.1
-set g_balance_okmachinegun_primary_spread_add 0.012
-set g_balance_okmachinegun_primary_spread_max 0.05
-set g_balance_okmachinegun_primary_spread_min 0.02
-set g_balance_okmachinegun_reload_ammo 60
-set g_balance_okmachinegun_reload_time 2
-set g_balance_okmachinegun_secondary_animtime 0.2
-set g_balance_okmachinegun_secondary_damage 20
-set g_balance_okmachinegun_secondary_delay 0
-set g_balance_okmachinegun_secondary_edgedamage 10
-set g_balance_okmachinegun_secondary_force 300
-set g_balance_okmachinegun_secondary_force_zscale 1
-set g_balance_okmachinegun_secondary_lifetime 5
-set g_balance_okmachinegun_secondary_radius 60
-set g_balance_okmachinegun_secondary_refire 0.7
-set g_balance_okmachinegun_secondary_refire_type 0
-set g_balance_okmachinegun_secondary_shotangle 0
-set g_balance_okmachinegun_secondary_speed 6000
-set g_balance_okmachinegun_secondary_spread 0
-set g_balance_okmachinegun_switchdelay_drop 0.2
-set g_balance_okmachinegun_switchdelay_raise 0.2
-set g_balance_okmachinegun_weaponreplace ""
-set g_balance_okmachinegun_weaponstart 0
-set g_balance_okmachinegun_weaponstartoverride -1
-set g_balance_okmachinegun_weaponthrowable 1
-// }}}
-// {{{ Overkill Nex
-set g_balance_oknex_charge 1
-set g_balance_oknex_charge_animlimit 0.5
-set g_balance_oknex_charge_limit 1
-set g_balance_oknex_charge_maxspeed 800
-set g_balance_oknex_charge_mindmg 40
-set g_balance_oknex_charge_minspeed 400
-set g_balance_oknex_charge_rate 0.6
-set g_balance_oknex_charge_rot_pause 0
-set g_balance_oknex_charge_rot_rate 0
-set g_balance_oknex_charge_shot_multiplier 0
-set g_balance_oknex_charge_start 0.5
-set g_balance_oknex_charge_velocity_rate 0
-set g_balance_oknex_primary_ammo 6
-set g_balance_oknex_primary_animtime 0.4
-set g_balance_oknex_primary_damage 80
-set g_balance_oknex_primary_damagefalloff_forcehalflife 0
-set g_balance_oknex_primary_damagefalloff_halflife 0
-set g_balance_oknex_primary_damagefalloff_maxdist 0
-set g_balance_oknex_primary_damagefalloff_mindist 0
-set g_balance_oknex_primary_force 400
-set g_balance_oknex_primary_refire 1.5
-set g_balance_oknex_reload_ammo 0
-set g_balance_oknex_reload_time 2
-set g_balance_oknex_secondary 0
-set g_balance_oknex_secondary_ammo 2
-set g_balance_oknex_secondary_animtime 0
-set g_balance_oknex_secondary_chargepool 0
-set g_balance_oknex_secondary_chargepool_pause_regen 1
-set g_balance_oknex_secondary_chargepool_regen 0.15
-set g_balance_oknex_secondary_damage 0
-set g_balance_oknex_secondary_damagefalloff_forcehalflife 0
-set g_balance_oknex_secondary_damagefalloff_halflife 0
-set g_balance_oknex_secondary_damagefalloff_maxdist 0
-set g_balance_oknex_secondary_damagefalloff_mindist 0
-set g_balance_oknex_secondary_force 0
-set g_balance_oknex_secondary_force_zscale 1
-set g_balance_oknex_secondary_refire 0
-set g_balance_oknex_secondary_refire_type 0
-set g_balance_oknex_secondary_delay 0
-set g_balance_oknex_secondary_edgedamage 10
-set g_balance_oknex_secondary_lifetime 5
-set g_balance_oknex_secondary_radius 60
-set g_balance_oknex_secondary_shotangle 0
-set g_balance_oknex_secondary_speed 6000
-set g_balance_oknex_secondary_spread 0
-set g_balance_oknex_switchdelay_drop 0.2
-set g_balance_oknex_switchdelay_raise 0.2
-set g_balance_oknex_weaponreplace ""
-set g_balance_oknex_weaponstart 0
-set g_balance_oknex_weaponstartoverride -1
-set g_balance_oknex_weaponthrowable 1
-// }}}
index e32b54ff4b17e3851896ec7a40839484b1be136c..6896f5f5e0be99131c379ea538b28a0ff7e3b252 100644 (file)
@@ -191,9 +191,13 @@ set g_balance_electro_primary_damage 40
 set g_balance_electro_primary_edgedamage 20
 set g_balance_electro_primary_force 200
 set g_balance_electro_primary_lifetime 5
+set g_balance_electro_primary_midaircombo_enemy 1
 set g_balance_electro_primary_midaircombo_explode 1
 set g_balance_electro_primary_midaircombo_interval 0.1
+set g_balance_electro_primary_midaircombo_own 1
 set g_balance_electro_primary_midaircombo_radius 100
+set g_balance_electro_primary_midaircombo_speed 2000
+set g_balance_electro_primary_midaircombo_teammate 1
 set g_balance_electro_primary_radius 100
 set g_balance_electro_primary_refire 0.6
 set g_balance_electro_primary_speed 2500
diff --git a/bal-wep-testing.cfg b/bal-wep-testing.cfg
deleted file mode 100644 (file)
index c1cb576..0000000
+++ /dev/null
@@ -1,970 +0,0 @@
-// {{{ #1: Blaster
-set g_balance_blaster_primary_animtime 0.2
-set g_balance_blaster_primary_damage 20
-set g_balance_blaster_primary_delay 0
-set g_balance_blaster_primary_edgedamage 10
-set g_balance_blaster_primary_force 375
-set g_balance_blaster_primary_force_zscale 1
-set g_balance_blaster_primary_lifetime 5
-set g_balance_blaster_primary_radius 60
-set g_balance_blaster_primary_refire 0.7
-set g_balance_blaster_primary_shotangle 0
-set g_balance_blaster_primary_speed 6000
-set g_balance_blaster_primary_spread 0
-set g_balance_blaster_secondary 0
-set g_balance_blaster_secondary_animtime 0.2
-set g_balance_blaster_secondary_damage 25
-set g_balance_blaster_secondary_delay 0
-set g_balance_blaster_secondary_edgedamage 12.5
-set g_balance_blaster_secondary_force 360
-set g_balance_blaster_secondary_force_zscale 1
-set g_balance_blaster_secondary_lifetime 5
-set g_balance_blaster_secondary_radius 70
-set g_balance_blaster_secondary_refire 0.7
-set g_balance_blaster_secondary_shotangle 0
-set g_balance_blaster_secondary_speed 6000
-set g_balance_blaster_secondary_spread 0
-set g_balance_blaster_switchdelay_drop 0.2
-set g_balance_blaster_switchdelay_raise 0.2
-set g_balance_blaster_weaponreplace ""
-set g_balance_blaster_weaponstart 1
-set g_balance_blaster_weaponstartoverride -1
-set g_balance_blaster_weaponthrowable 0
-// }}}
-// {{{ #2: Shotgun
-set g_balance_shotgun_primary_ammo 1
-set g_balance_shotgun_primary_animtime 0.2
-set g_balance_shotgun_primary_bullets 12
-set g_balance_shotgun_primary_damage 4
-set g_balance_shotgun_primary_force 15
-set g_balance_shotgun_primary_refire 0.75
-set g_balance_shotgun_primary_solidpenetration 3.8
-set g_balance_shotgun_primary_spread 0.12
-set g_balance_shotgun_reload_ammo 0
-set g_balance_shotgun_reload_time 2
-set g_balance_shotgun_secondary 1
-set g_balance_shotgun_secondary_alt_animtime 0.2
-set g_balance_shotgun_secondary_alt_refire 1.2
-set g_balance_shotgun_secondary_animtime 1.15
-set g_balance_shotgun_secondary_damage 70
-set g_balance_shotgun_secondary_force 200
-set g_balance_shotgun_secondary_melee_delay 0.25
-set g_balance_shotgun_secondary_melee_multihit 1
-set g_balance_shotgun_secondary_melee_no_doubleslap 1
-set g_balance_shotgun_secondary_melee_nonplayerdamage 40
-set g_balance_shotgun_secondary_melee_range 120
-set g_balance_shotgun_secondary_melee_swing_side 120
-set g_balance_shotgun_secondary_melee_swing_up 30
-set g_balance_shotgun_secondary_melee_time 0.15
-set g_balance_shotgun_secondary_melee_traces 10
-set g_balance_shotgun_secondary_refire 1.25
-set g_balance_shotgun_switchdelay_drop 0.2
-set g_balance_shotgun_switchdelay_raise 0.2
-set g_balance_shotgun_weaponreplace ""
-set g_balance_shotgun_weaponstart 1
-set g_balance_shotgun_weaponstartoverride -1
-set g_balance_shotgun_weaponthrowable 1
-// }}}
-// {{{ #3: MachineGun
-set g_balance_machinegun_burst 3
-set g_balance_machinegun_burst_ammo 3
-set g_balance_machinegun_burst_animtime 0.3
-set g_balance_machinegun_burst_refire 0.06
-set g_balance_machinegun_burst_refire2 0.45
-set g_balance_machinegun_burst_spread 0
-set g_balance_machinegun_first 1
-set g_balance_machinegun_first_ammo 1
-set g_balance_machinegun_first_damage 14
-set g_balance_machinegun_first_force 3
-set g_balance_machinegun_first_refire 0.125
-set g_balance_machinegun_first_spread 0.03
-set g_balance_machinegun_mode 1
-set g_balance_machinegun_reload_ammo 60
-set g_balance_machinegun_reload_time 2
-set g_balance_machinegun_solidpenetration 63
-set g_balance_machinegun_spread_add 0.012
-set g_balance_machinegun_spread_max 0.05
-set g_balance_machinegun_spread_min 0.02
-set g_balance_machinegun_sustained_ammo 1
-set g_balance_machinegun_sustained_damage 10
-set g_balance_machinegun_sustained_force 3
-set g_balance_machinegun_sustained_refire 0.1
-set g_balance_machinegun_sustained_spread 0.03
-set g_balance_machinegun_switchdelay_drop 0.2
-set g_balance_machinegun_switchdelay_raise 0.2
-set g_balance_machinegun_weaponreplace ""
-set g_balance_machinegun_weaponstart 0
-set g_balance_machinegun_weaponstartoverride -1
-set g_balance_machinegun_weaponthrowable 1
-// }}}
-// {{{ #4: Mortar
-set g_balance_mortar_bouncefactor 0.5
-set g_balance_mortar_bouncestop 0.075
-set g_balance_mortar_primary_ammo 2
-set g_balance_mortar_primary_animtime 0.3
-set g_balance_mortar_primary_damage 55
-set g_balance_mortar_primary_damageforcescale 0
-set g_balance_mortar_primary_edgedamage 25
-set g_balance_mortar_primary_force 250
-set g_balance_mortar_primary_health 15
-set g_balance_mortar_primary_lifetime 5
-set g_balance_mortar_primary_lifetime_stick 0
-set g_balance_mortar_primary_radius 120
-set g_balance_mortar_primary_refire 0.8
-set g_balance_mortar_primary_remote_minbouncecnt 0
-set g_balance_mortar_primary_speed 1900
-set g_balance_mortar_primary_speed_up 225
-set g_balance_mortar_primary_speed_z 0
-set g_balance_mortar_primary_spread 0
-set g_balance_mortar_primary_type 0
-set g_balance_mortar_reload_ammo 0
-set g_balance_mortar_reload_time 2
-set g_balance_mortar_secondary_ammo 2
-set g_balance_mortar_secondary_animtime 0.3
-set g_balance_mortar_secondary_damage 55
-set g_balance_mortar_secondary_damageforcescale 4
-set g_balance_mortar_secondary_edgedamage 30
-set g_balance_mortar_secondary_force 250
-set g_balance_mortar_secondary_health 30
-set g_balance_mortar_secondary_lifetime 5
-set g_balance_mortar_secondary_lifetime_bounce 0.5
-set g_balance_mortar_secondary_lifetime_stick 0
-set g_balance_mortar_secondary_radius 120
-set g_balance_mortar_secondary_refire 0.7
-set g_balance_mortar_secondary_remote_detonateprimary 0
-set g_balance_mortar_secondary_speed 1400
-set g_balance_mortar_secondary_speed_up 150
-set g_balance_mortar_secondary_speed_z 0
-set g_balance_mortar_secondary_spread 0
-set g_balance_mortar_secondary_type 1
-set g_balance_mortar_switchdelay_drop 0.2
-set g_balance_mortar_switchdelay_raise 0.2
-set g_balance_mortar_weaponreplace ""
-set g_balance_mortar_weaponstart 0
-set g_balance_mortar_weaponstartoverride -1
-set g_balance_mortar_weaponthrowable 1
-// }}}
-// {{{ #5: Mine Layer (MUTATOR WEAPON)
-set g_balance_minelayer_ammo 4
-set g_balance_minelayer_animtime 0.4
-set g_balance_minelayer_damage 40
-set g_balance_minelayer_damageforcescale 0
-set g_balance_minelayer_detonatedelay -1
-set g_balance_minelayer_edgedamage 20
-set g_balance_minelayer_force 250
-set g_balance_minelayer_health 15
-set g_balance_minelayer_lifetime 10
-set g_balance_minelayer_lifetime_countdown 0.5
-set g_balance_minelayer_limit 3
-set g_balance_minelayer_protection 0
-set g_balance_minelayer_proximityradius 150
-set g_balance_minelayer_radius 175
-set g_balance_minelayer_refire 1.5
-set g_balance_minelayer_reload_ammo 0
-set g_balance_minelayer_reload_time 2
-set g_balance_minelayer_remote_damage 45
-set g_balance_minelayer_remote_edgedamage 40
-set g_balance_minelayer_remote_force 300
-set g_balance_minelayer_remote_radius 200
-set g_balance_minelayer_speed 1000
-set g_balance_minelayer_switchdelay_drop 0.2
-set g_balance_minelayer_switchdelay_raise 0.2
-set g_balance_minelayer_time 0.5
-set g_balance_minelayer_weaponreplace ""
-set g_balance_minelayer_weaponstart 0
-set g_balance_minelayer_weaponstartoverride -1
-set g_balance_minelayer_weaponthrowable 1
-// }}}
-// {{{ #6: Electro
-set g_balance_electro_combo_comboradius 300
-set g_balance_electro_combo_comboradius_thruwall 200
-set g_balance_electro_combo_damage 50
-set g_balance_electro_combo_edgedamage 25
-set g_balance_electro_combo_force 120
-set g_balance_electro_combo_radius 150
-set g_balance_electro_combo_safeammocheck 1
-set g_balance_electro_combo_speed 2000
-set g_balance_electro_primary_ammo 4
-set g_balance_electro_primary_animtime 0.3
-set g_balance_electro_primary_comboradius 300
-set g_balance_electro_primary_damage 40
-set g_balance_electro_primary_edgedamage 20
-set g_balance_electro_primary_force 200
-set g_balance_electro_primary_lifetime 5
-set g_balance_electro_primary_midaircombo_explode 1
-set g_balance_electro_primary_midaircombo_interval 0.1
-set g_balance_electro_primary_midaircombo_radius 0
-set g_balance_electro_primary_radius 100
-set g_balance_electro_primary_refire 0.6
-set g_balance_electro_primary_speed 2500
-set g_balance_electro_primary_spread 0
-set g_balance_electro_reload_ammo 0
-set g_balance_electro_reload_time 2
-set g_balance_electro_secondary_ammo 2
-set g_balance_electro_secondary_animtime 0.2
-set g_balance_electro_secondary_bouncefactor 0.3
-set g_balance_electro_secondary_bouncestop 0.05
-set g_balance_electro_secondary_count 3
-set g_balance_electro_secondary_damage 30
-set g_balance_electro_secondary_damagedbycontents 1
-set g_balance_electro_secondary_damageforcescale 4
-set g_balance_electro_secondary_edgedamage 15
-set g_balance_electro_secondary_force 50
-set g_balance_electro_secondary_health 5
-set g_balance_electro_secondary_lifetime 4
-set g_balance_electro_secondary_radius 150
-set g_balance_electro_secondary_refire 0.2
-set g_balance_electro_secondary_refire2 1.6
-set g_balance_electro_secondary_speed 1000
-set g_balance_electro_secondary_speed_up 200
-set g_balance_electro_secondary_speed_z 0
-set g_balance_electro_secondary_spread 0
-set g_balance_electro_secondary_stick 0
-set g_balance_electro_secondary_touchexplode 1
-set g_balance_electro_switchdelay_drop 0.2
-set g_balance_electro_switchdelay_raise 0.2
-set g_balance_electro_weaponreplace ""
-set g_balance_electro_weaponstart 0
-set g_balance_electro_weaponstartoverride -1
-set g_balance_electro_weaponthrowable 1
-// }}}
-// {{{ #7: Crylink
-set g_balance_crylink_primary_ammo 3
-set g_balance_crylink_primary_animtime 0.3
-set g_balance_crylink_primary_bouncedamagefactor 0.5
-set g_balance_crylink_primary_bounces 1
-set g_balance_crylink_primary_damage 10
-set g_balance_crylink_primary_edgedamage 5
-set g_balance_crylink_primary_force -50
-set g_balance_crylink_primary_joindelay 0.1
-set g_balance_crylink_primary_joinexplode 1
-set g_balance_crylink_primary_joinexplode_damage 0
-set g_balance_crylink_primary_joinexplode_edgedamage 0
-set g_balance_crylink_primary_joinexplode_force 0
-set g_balance_crylink_primary_joinexplode_radius 0
-set g_balance_crylink_primary_joinspread 0.2
-set g_balance_crylink_primary_linkexplode 1
-set g_balance_crylink_primary_middle_fadetime 5
-set g_balance_crylink_primary_middle_lifetime 5
-set g_balance_crylink_primary_other_fadetime 5
-set g_balance_crylink_primary_other_lifetime 5
-set g_balance_crylink_primary_radius 80
-set g_balance_crylink_primary_refire 0.7
-set g_balance_crylink_primary_shots 6
-set g_balance_crylink_primary_speed 2000
-set g_balance_crylink_primary_spread 0.08
-set g_balance_crylink_reload_ammo 0
-set g_balance_crylink_reload_time 2
-set g_balance_crylink_secondary 1
-set g_balance_crylink_secondary_ammo 3
-set g_balance_crylink_secondary_animtime 0.2
-set g_balance_crylink_secondary_bouncedamagefactor 0.5
-set g_balance_crylink_secondary_bounces 0
-set g_balance_crylink_secondary_damage 8
-set g_balance_crylink_secondary_edgedamage 4
-set g_balance_crylink_secondary_force -200
-set g_balance_crylink_secondary_joindelay 0
-set g_balance_crylink_secondary_joinexplode 0
-set g_balance_crylink_secondary_joinexplode_damage 0
-set g_balance_crylink_secondary_joinexplode_edgedamage 0
-set g_balance_crylink_secondary_joinexplode_force 0
-set g_balance_crylink_secondary_joinexplode_radius 0
-set g_balance_crylink_secondary_joinspread 0
-set g_balance_crylink_secondary_linkexplode 0
-set g_balance_crylink_secondary_middle_fadetime 5
-set g_balance_crylink_secondary_middle_lifetime 5
-set g_balance_crylink_secondary_other_fadetime 2
-set g_balance_crylink_secondary_other_lifetime 2
-set g_balance_crylink_secondary_radius 100
-set g_balance_crylink_secondary_refire 0.7
-set g_balance_crylink_secondary_shots 5
-set g_balance_crylink_secondary_speed 4000
-set g_balance_crylink_secondary_spread 0.08
-set g_balance_crylink_secondary_spreadtype 0
-set g_balance_crylink_switchdelay_drop 0.2
-set g_balance_crylink_switchdelay_raise 0.2
-set g_balance_crylink_weaponreplace ""
-set g_balance_crylink_weaponstart 0
-set g_balance_crylink_weaponstartoverride -1
-set g_balance_crylink_weaponthrowable 1
-// }}}
-// {{{ #8: Vortex
-set g_balance_vortex_charge 0
-set g_balance_vortex_charge_always 0
-set g_balance_vortex_charge_animlimit 0.5
-set g_balance_vortex_charge_limit 1
-set g_balance_vortex_charge_maxspeed 800
-set g_balance_vortex_charge_mindmg 40
-set g_balance_vortex_charge_minspeed 400
-set g_balance_vortex_charge_rate 0.6
-set g_balance_vortex_charge_rot_pause 0
-set g_balance_vortex_charge_rot_rate 0
-set g_balance_vortex_charge_shot_multiplier 0
-set g_balance_vortex_charge_start 0.5
-set g_balance_vortex_charge_velocity_rate 0
-set g_balance_vortex_primary_ammo 6
-set g_balance_vortex_primary_animtime 0.4
-set g_balance_vortex_primary_armorpierce 0
-set g_balance_vortex_primary_damage 65
-set g_balance_vortex_primary_damagefalloff_forcehalflife 0
-set g_balance_vortex_primary_damagefalloff_halflife 0
-set g_balance_vortex_primary_damagefalloff_maxdist 0
-set g_balance_vortex_primary_damagefalloff_mindist 0
-set g_balance_vortex_primary_force 400
-set g_balance_vortex_primary_refire 1.5
-set g_balance_vortex_reload_ammo 0
-set g_balance_vortex_reload_time 2
-set g_balance_vortex_secondary 0
-set g_balance_vortex_secondary_ammo 2
-set g_balance_vortex_secondary_animtime 0
-set g_balance_vortex_secondary_armorpierce 0
-set g_balance_vortex_secondary_chargepool 0
-set g_balance_vortex_secondary_chargepool_pause_regen 1
-set g_balance_vortex_secondary_chargepool_regen 0.15
-set g_balance_vortex_secondary_damage 0
-set g_balance_vortex_secondary_damagefalloff_forcehalflife 0
-set g_balance_vortex_secondary_damagefalloff_halflife 0
-set g_balance_vortex_secondary_damagefalloff_maxdist 0
-set g_balance_vortex_secondary_damagefalloff_mindist 0
-set g_balance_vortex_secondary_force 0
-set g_balance_vortex_secondary_refire 0
-set g_balance_vortex_switchdelay_drop 0.2
-set g_balance_vortex_switchdelay_raise 0.2
-set g_balance_vortex_weaponreplace ""
-set g_balance_vortex_weaponstart 0
-set g_balance_vortex_weaponstartoverride -1
-set g_balance_vortex_weaponthrowable 1
-// }}}
-// {{{ #9: Hagar
-set g_balance_hagar_primary_ammo 1
-set g_balance_hagar_primary_damage 25
-set g_balance_hagar_primary_damageforcescale 0
-set g_balance_hagar_primary_edgedamage 12.5
-set g_balance_hagar_primary_force 100
-set g_balance_hagar_primary_health 15
-set g_balance_hagar_primary_lifetime 5
-set g_balance_hagar_primary_radius 65
-set g_balance_hagar_primary_refire 0.16667
-set g_balance_hagar_primary_speed 2200
-set g_balance_hagar_primary_spread 0
-set g_balance_hagar_reload_ammo 0
-set g_balance_hagar_reload_time 2
-set g_balance_hagar_secondary 1
-set g_balance_hagar_secondary_ammo 1
-set g_balance_hagar_secondary_damage 35
-set g_balance_hagar_secondary_damageforcescale 0
-set g_balance_hagar_secondary_edgedamage 17.5
-set g_balance_hagar_secondary_force 75
-set g_balance_hagar_secondary_health 15
-set g_balance_hagar_secondary_lifetime_min 10
-set g_balance_hagar_secondary_lifetime_rand 0
-set g_balance_hagar_secondary_load 1
-set g_balance_hagar_secondary_load_abort 1
-set g_balance_hagar_secondary_load_animtime 0.2
-set g_balance_hagar_secondary_load_hold 4
-set g_balance_hagar_secondary_load_linkexplode 0
-set g_balance_hagar_secondary_load_max 4
-set g_balance_hagar_secondary_load_releasedeath 0
-set g_balance_hagar_secondary_load_speed 0.5
-set g_balance_hagar_secondary_load_spread 0.075
-set g_balance_hagar_secondary_load_spread_bias 0.5
-set g_balance_hagar_secondary_radius 80
-set g_balance_hagar_secondary_refire 0.5
-set g_balance_hagar_secondary_speed 2000
-set g_balance_hagar_secondary_spread 0
-set g_balance_hagar_switchdelay_drop 0.2
-set g_balance_hagar_switchdelay_raise 0.2
-set g_balance_hagar_weaponreplace ""
-set g_balance_hagar_weaponstart 0
-set g_balance_hagar_weaponstartoverride -1
-set g_balance_hagar_weaponthrowable 1
-// }}}
-// {{{ #10: Devastator
-set g_balance_devastator_ammo 4
-set g_balance_devastator_animtime 0.4
-set g_balance_devastator_damage 80
-set g_balance_devastator_damageforcescale 1
-set g_balance_devastator_detonatedelay 0.02
-set g_balance_devastator_edgedamage 40
-set g_balance_devastator_force 400
-set g_balance_devastator_guidedelay 0.2
-set g_balance_devastator_guidegoal 512
-set g_balance_devastator_guiderate 90
-set g_balance_devastator_guideratedelay 0.01
-set g_balance_devastator_guidestop 0
-set g_balance_devastator_health 30
-set g_balance_devastator_lifetime 10
-set g_balance_devastator_radius 110
-set g_balance_devastator_refire 1.1
-set g_balance_devastator_reload_ammo 0
-set g_balance_devastator_reload_time 2
-set g_balance_devastator_remote_damage 70
-set g_balance_devastator_remote_edgedamage 35
-set g_balance_devastator_remote_force 300
-set g_balance_devastator_remote_jump 1
-set g_balance_devastator_remote_jump_damage 70
-set g_balance_devastator_remote_jump_force 450
-set g_balance_devastator_remote_jump_radius 100
-set g_balance_devastator_remote_jump_velocity_z_add 0
-set g_balance_devastator_remote_jump_velocity_z_max 1500
-set g_balance_devastator_remote_jump_velocity_z_min 400
-set g_balance_devastator_remote_radius 110
-set g_balance_devastator_speed 1300
-set g_balance_devastator_speedaccel 1300
-set g_balance_devastator_speedstart 1000
-set g_balance_devastator_switchdelay_drop 0.2
-set g_balance_devastator_switchdelay_raise 0.2
-set g_balance_devastator_weaponreplace ""
-set g_balance_devastator_weaponstart 0
-set g_balance_devastator_weaponstartoverride -1
-set g_balance_devastator_weaponthrowable 1
-// }}}
-// {{{ #11: Port-O-Launch
-set g_balance_porto_primary_animtime 0.3
-set g_balance_porto_primary_lifetime 5
-set g_balance_porto_primary_refire 1.5
-set g_balance_porto_primary_speed 1000
-set g_balance_porto_secondary 1
-set g_balance_porto_secondary_animtime 0.3
-set g_balance_porto_secondary_lifetime 5
-set g_balance_porto_secondary_refire 1.5
-set g_balance_porto_secondary_speed 1000
-set g_balance_porto_switchdelay_drop 0.2
-set g_balance_porto_switchdelay_raise 0.2
-set g_balance_porto_weaponreplace ""
-set g_balance_porto_weaponstart 0
-set g_balance_porto_weaponstartoverride -1
-set g_balance_porto_weaponthrowable 1
-// }}}
-// {{{ #12: Vaporizer
-set g_balance_vaporizer_primary_ammo 10
-set g_balance_vaporizer_primary_animtime 0.3
-set g_balance_vaporizer_primary_damage 150
-set g_balance_vaporizer_primary_force 800
-set g_balance_vaporizer_primary_refire 1
-set g_balance_vaporizer_reload_ammo 0
-set g_balance_vaporizer_reload_time 0
-set g_balance_vaporizer_secondary_ammo 0
-set g_balance_vaporizer_secondary_animtime 0.2
-set g_balance_vaporizer_secondary_damage 25
-set g_balance_vaporizer_secondary_delay 0
-set g_balance_vaporizer_secondary_edgedamage 12.5
-set g_balance_vaporizer_secondary_force 480
-set g_balance_vaporizer_secondary_force_zscale 1
-set g_balance_vaporizer_secondary_lifetime 5
-set g_balance_vaporizer_secondary_radius 70
-set g_balance_vaporizer_secondary_refire 0.7
-set g_balance_vaporizer_secondary_shotangle 0
-set g_balance_vaporizer_secondary_speed 6000
-set g_balance_vaporizer_secondary_spread 0
-set g_balance_vaporizer_switchdelay_drop 0.2
-set g_balance_vaporizer_switchdelay_raise 0.2
-set g_balance_vaporizer_weaponreplace ""
-set g_balance_vaporizer_weaponstart 0
-set g_balance_vaporizer_weaponstartoverride -1
-set g_balance_vaporizer_weaponthrowable 1
-// }}}
-// {{{ #13: Grappling Hook
-set g_balance_hook_primary_ammo 5
-set g_balance_hook_primary_animtime 0.3
-set g_balance_hook_primary_hooked_ammo 5
-set g_balance_hook_primary_hooked_time_free 2
-set g_balance_hook_primary_hooked_time_max 0
-set g_balance_hook_primary_refire 0.2
-set g_balance_hook_secondary_animtime 0.3
-set g_balance_hook_secondary_damage 25
-set g_balance_hook_secondary_damageforcescale 0
-set g_balance_hook_secondary_duration 1.5
-set g_balance_hook_secondary_edgedamage 5
-set g_balance_hook_secondary_force -2000
-set g_balance_hook_secondary_gravity 5
-set g_balance_hook_secondary_health 15
-set g_balance_hook_secondary_lifetime 5
-set g_balance_hook_secondary_power 3
-set g_balance_hook_secondary_radius 500
-set g_balance_hook_secondary_refire 3
-set g_balance_hook_secondary_speed 0
-set g_balance_hook_switchdelay_drop 0.2
-set g_balance_hook_switchdelay_raise 0.2
-set g_balance_hook_weaponreplace ""
-set g_balance_hook_weaponstart 0
-set g_balance_hook_weaponstartoverride -1
-set g_balance_hook_weaponthrowable 1
-// }}}
-// {{{ #14: Heavy Laser Assault Cannon (MUTATOR WEAPON)
-set g_balance_hlac_primary_ammo 1
-set g_balance_hlac_primary_animtime 0.4
-set g_balance_hlac_primary_damage 18
-set g_balance_hlac_primary_edgedamage 9
-set g_balance_hlac_primary_force 90
-set g_balance_hlac_primary_lifetime 5
-set g_balance_hlac_primary_radius 70
-set g_balance_hlac_primary_refire 0.15
-set g_balance_hlac_primary_speed 9000
-set g_balance_hlac_primary_spread_add 0.0045
-set g_balance_hlac_primary_spread_crouchmod 0.25
-set g_balance_hlac_primary_spread_max 0.25
-set g_balance_hlac_primary_spread_min 0.01
-set g_balance_hlac_reload_ammo 0
-set g_balance_hlac_reload_time 2
-set g_balance_hlac_secondary 1
-set g_balance_hlac_secondary_ammo 10
-set g_balance_hlac_secondary_animtime 0.3
-set g_balance_hlac_secondary_damage 15
-set g_balance_hlac_secondary_edgedamage 7.5
-set g_balance_hlac_secondary_force 90
-set g_balance_hlac_secondary_lifetime 5
-set g_balance_hlac_secondary_radius 70
-set g_balance_hlac_secondary_refire 1
-set g_balance_hlac_secondary_shots 6
-set g_balance_hlac_secondary_speed 9000
-set g_balance_hlac_secondary_spread 0.15
-set g_balance_hlac_secondary_spread_crouchmod 0.5
-set g_balance_hlac_switchdelay_drop 0.2
-set g_balance_hlac_switchdelay_raise 0.2
-set g_balance_hlac_weaponreplace ""
-set g_balance_hlac_weaponstart 0
-set g_balance_hlac_weaponstartoverride -1
-set g_balance_hlac_weaponthrowable 1
-// }}}
-// {{{ #15: @!#%'n Tuba
-set g_balance_tuba_animtime 0.05
-set g_balance_tuba_attenuation 0.5
-set g_balance_tuba_damage 5
-set g_balance_tuba_edgedamage 0
-set g_balance_tuba_fadetime 0.25
-set g_balance_tuba_force 40
-set g_balance_tuba_pitchstep 6
-set g_balance_tuba_radius 200
-set g_balance_tuba_refire 0.05
-set g_balance_tuba_switchdelay_drop 0.2
-set g_balance_tuba_switchdelay_raise 0.2
-set g_balance_tuba_volume 1
-set g_balance_tuba_weaponreplace ""
-set g_balance_tuba_weaponstart 0
-set g_balance_tuba_weaponstartoverride -1
-set g_balance_tuba_weaponthrowable 1
-// }}}
-// {{{ #16: Rifle (MUTATOR WEAPON)
-set g_balance_rifle_bursttime 0
-set g_balance_rifle_primary_ammo 10
-set g_balance_rifle_primary_animtime 0.4
-set g_balance_rifle_primary_bullethail 0
-set g_balance_rifle_primary_burstcost 0
-set g_balance_rifle_primary_damage 80
-set g_balance_rifle_primary_force 100
-set g_balance_rifle_primary_refire 1.2
-set g_balance_rifle_primary_shots 1
-set g_balance_rifle_primary_solidpenetration 62.2
-set g_balance_rifle_primary_spread 0
-set g_balance_rifle_primary_tracer 1
-set g_balance_rifle_reload_ammo 80
-set g_balance_rifle_reload_time 2
-set g_balance_rifle_secondary 1
-set g_balance_rifle_secondary_ammo 10
-set g_balance_rifle_secondary_animtime 0.3
-set g_balance_rifle_secondary_bullethail 0
-set g_balance_rifle_secondary_burstcost 0
-set g_balance_rifle_secondary_damage 20
-set g_balance_rifle_secondary_force 50
-set g_balance_rifle_secondary_refire 0.9
-set g_balance_rifle_secondary_reload 0
-set g_balance_rifle_secondary_shots 4
-set g_balance_rifle_secondary_solidpenetration 15.5
-set g_balance_rifle_secondary_spread 0.04
-set g_balance_rifle_secondary_tracer 0
-set g_balance_rifle_switchdelay_drop 0.2
-set g_balance_rifle_switchdelay_raise 0.2
-set g_balance_rifle_weaponreplace ""
-set g_balance_rifle_weaponstart 0
-set g_balance_rifle_weaponstartoverride -1
-set g_balance_rifle_weaponthrowable 1
-// }}}
-// {{{ #17: Fireball
-set g_balance_fireball_primary_animtime 0.4
-set g_balance_fireball_primary_bfgdamage 100
-set g_balance_fireball_primary_bfgforce 0
-set g_balance_fireball_primary_bfgradius 1000
-set g_balance_fireball_primary_damage 200
-set g_balance_fireball_primary_damageforcescale 0
-set g_balance_fireball_primary_edgedamage 50
-set g_balance_fireball_primary_force 600
-set g_balance_fireball_primary_health 0
-set g_balance_fireball_primary_laserburntime 0.5
-set g_balance_fireball_primary_laserdamage 80
-set g_balance_fireball_primary_laseredgedamage 20
-set g_balance_fireball_primary_laserradius 256
-set g_balance_fireball_primary_lifetime 15
-set g_balance_fireball_primary_radius 200
-set g_balance_fireball_primary_refire 2
-set g_balance_fireball_primary_refire2 0
-set g_balance_fireball_primary_speed 1200
-set g_balance_fireball_primary_spread 0
-set g_balance_fireball_secondary_animtime 0.3
-set g_balance_fireball_secondary_damage 40
-set g_balance_fireball_secondary_damageforcescale 4
-set g_balance_fireball_secondary_damagetime 5
-set g_balance_fireball_secondary_laserburntime 0.5
-set g_balance_fireball_secondary_laserdamage 50
-set g_balance_fireball_secondary_laseredgedamage 20
-set g_balance_fireball_secondary_laserradius 110
-set g_balance_fireball_secondary_lifetime 7
-set g_balance_fireball_secondary_refire 1.5
-set g_balance_fireball_secondary_speed 900
-set g_balance_fireball_secondary_speed_up 100
-set g_balance_fireball_secondary_speed_z 0
-set g_balance_fireball_secondary_spread 0
-set g_balance_fireball_switchdelay_drop 0.2
-set g_balance_fireball_switchdelay_raise 0.2
-set g_balance_fireball_weaponreplace ""
-set g_balance_fireball_weaponstart 0
-set g_balance_fireball_weaponstartoverride -1
-set g_balance_fireball_weaponthrowable 0
-// }}}
-// {{{ #18: T.A.G. Seeker (MUTATOR WEAPON)
-set g_balance_seeker_flac_ammo 1
-set g_balance_seeker_flac_animtime 0.1
-set g_balance_seeker_flac_damage 15
-set g_balance_seeker_flac_edgedamage 10
-set g_balance_seeker_flac_force 50
-set g_balance_seeker_flac_lifetime 0.1
-set g_balance_seeker_flac_lifetime_rand 0.05
-set g_balance_seeker_flac_radius 100
-set g_balance_seeker_flac_refire 0.1
-set g_balance_seeker_flac_speed 3000
-set g_balance_seeker_flac_speed_up 1000
-set g_balance_seeker_flac_speed_z 0
-set g_balance_seeker_flac_spread 0.4
-set g_balance_seeker_missile_accel 1400
-set g_balance_seeker_missile_ammo 2
-set g_balance_seeker_missile_animtime 0.2
-set g_balance_seeker_missile_count 3
-set g_balance_seeker_missile_damage 30
-set g_balance_seeker_missile_damageforcescale 4
-set g_balance_seeker_missile_decel 1400
-set g_balance_seeker_missile_delay 0.25
-set g_balance_seeker_missile_edgedamage 10
-set g_balance_seeker_missile_force 150
-set g_balance_seeker_missile_health 5
-set g_balance_seeker_missile_lifetime 15
-set g_balance_seeker_missile_proxy 0
-set g_balance_seeker_missile_proxy_delay 0.2
-set g_balance_seeker_missile_proxy_maxrange 45
-set g_balance_seeker_missile_radius 80
-set g_balance_seeker_missile_refire 0.5
-set g_balance_seeker_missile_smart 1
-set g_balance_seeker_missile_smart_mindist 800
-set g_balance_seeker_missile_smart_trace_max 2500
-set g_balance_seeker_missile_smart_trace_min 1000
-set g_balance_seeker_missile_speed 700
-set g_balance_seeker_missile_speed_max 1300
-set g_balance_seeker_missile_speed_up 300
-set g_balance_seeker_missile_speed_z 0
-set g_balance_seeker_missile_spread 0
-set g_balance_seeker_missile_turnrate 0.65
-set g_balance_seeker_reload_ammo 0
-set g_balance_seeker_reload_time 2
-set g_balance_seeker_switchdelay_drop 0.2
-set g_balance_seeker_switchdelay_raise 0.2
-set g_balance_seeker_tag_ammo 1
-set g_balance_seeker_tag_animtime 0.2
-set g_balance_seeker_tag_damageforcescale 4
-set g_balance_seeker_tag_health 5
-set g_balance_seeker_tag_lifetime 15
-set g_balance_seeker_tag_refire 0.75
-set g_balance_seeker_tag_speed 5000
-set g_balance_seeker_tag_spread 0
-set g_balance_seeker_tag_tracker_lifetime 10
-set g_balance_seeker_type 0
-set g_balance_seeker_weaponreplace ""
-set g_balance_seeker_weaponstart 0
-set g_balance_seeker_weaponstartoverride -1
-set g_balance_seeker_weaponthrowable 1
-// }}}
-// {{{ #19: Shockwave
-set g_balance_shockwave_blast_animtime 0.3
-set g_balance_shockwave_blast_damage 40
-set g_balance_shockwave_blast_distance 1000
-set g_balance_shockwave_blast_edgedamage 0
-set g_balance_shockwave_blast_force 15
-set g_balance_shockwave_blast_force_forwardbias 50
-set g_balance_shockwave_blast_force_zscale 1
-set g_balance_shockwave_blast_jump_damage 20
-set g_balance_shockwave_blast_jump_edgedamage 0
-set g_balance_shockwave_blast_jump_force 100
-set g_balance_shockwave_blast_jump_force_velocitybias 1
-set g_balance_shockwave_blast_jump_force_zscale 1
-set g_balance_shockwave_blast_jump_multiplier_accuracy 0.5
-set g_balance_shockwave_blast_jump_multiplier_distance 0.5
-set g_balance_shockwave_blast_jump_multiplier_min 0
-set g_balance_shockwave_blast_jump_radius 150
-set g_balance_shockwave_blast_multiplier_accuracy 0.45
-set g_balance_shockwave_blast_multiplier_distance 0.2
-set g_balance_shockwave_blast_multiplier_min 0
-set g_balance_shockwave_blast_refire 0.75
-set g_balance_shockwave_blast_splash_damage 15
-set g_balance_shockwave_blast_splash_edgedamage 0
-set g_balance_shockwave_blast_splash_force 100
-set g_balance_shockwave_blast_splash_force_forwardbias 50
-set g_balance_shockwave_blast_splash_multiplier_accuracy 0.5
-set g_balance_shockwave_blast_splash_multiplier_distance 0.5
-set g_balance_shockwave_blast_splash_multiplier_min 0
-set g_balance_shockwave_blast_splash_radius 70
-set g_balance_shockwave_blast_spread_max 120
-set g_balance_shockwave_blast_spread_min 25
-set g_balance_shockwave_melee_animtime 1.3
-set g_balance_shockwave_melee_damage 80
-set g_balance_shockwave_melee_delay 0.25
-set g_balance_shockwave_melee_force 200
-set g_balance_shockwave_melee_multihit 1
-set g_balance_shockwave_melee_no_doubleslap 1
-set g_balance_shockwave_melee_nonplayerdamage 40
-set g_balance_shockwave_melee_range 120
-set g_balance_shockwave_melee_refire 1.25
-set g_balance_shockwave_melee_swing_side 120
-set g_balance_shockwave_melee_swing_up 30
-set g_balance_shockwave_melee_time 0.15
-set g_balance_shockwave_melee_traces 10
-set g_balance_shockwave_switchdelay_drop 0.2
-set g_balance_shockwave_switchdelay_raise 0.2
-set g_balance_shockwave_weaponreplace ""
-set g_balance_shockwave_weaponstart 0
-set g_balance_shockwave_weaponstartoverride -1
-set g_balance_shockwave_weaponthrowable 0
-// }}}
-// {{{ #20: Arc
-set g_balance_arc_beam_ammo 6
-set g_balance_arc_beam_animtime 0.1
-set g_balance_arc_beam_botaimlifetime 0
-set g_balance_arc_beam_botaimspeed 0
-set g_balance_arc_beam_damage 100
-set g_balance_arc_beam_degreespersegment 1
-set g_balance_arc_beam_distancepersegment 0
-set g_balance_arc_beam_falloff_halflifedist 0
-set g_balance_arc_beam_falloff_maxdist 0
-set g_balance_arc_beam_falloff_mindist 0
-set g_balance_arc_beam_force 600
-set g_balance_arc_beam_healing_amax 0
-set g_balance_arc_beam_healing_aps 50
-set g_balance_arc_beam_healing_hmax 150
-set g_balance_arc_beam_healing_hps 50
-set g_balance_arc_beam_heat 0
-set g_balance_arc_beam_maxangle 10
-set g_balance_arc_beam_nonplayerdamage 80
-set g_balance_arc_beam_range 1500
-set g_balance_arc_beam_refire 0.25
-set g_balance_arc_beam_returnspeed 8
-set g_balance_arc_beam_tightness 0.6
-set g_balance_arc_bolt 1
-set g_balance_arc_bolt_ammo 1
-set g_balance_arc_bolt_damage 25
-set g_balance_arc_bolt_damageforcescale 0
-set g_balance_arc_bolt_edgedamage 12.5
-set g_balance_arc_bolt_force 120
-set g_balance_arc_bolt_health 15
-set g_balance_arc_bolt_lifetime 5
-set g_balance_arc_bolt_radius 65
-set g_balance_arc_bolt_refire 0.16667
-set g_balance_arc_bolt_speed 2300
-set g_balance_arc_bolt_spread 0
-set g_balance_arc_burst_ammo 15
-set g_balance_arc_burst_damage 250
-set g_balance_arc_burst_healing_aps 100
-set g_balance_arc_burst_healing_hps 100
-set g_balance_arc_burst_heat 5
-set g_balance_arc_cooldown 2.5
-set g_balance_arc_cooldown_release 0
-set g_balance_arc_overheat_max 5
-set g_balance_arc_overheat_min 3
-set g_balance_arc_switchdelay_drop 0.2
-set g_balance_arc_switchdelay_raise 0.2
-set g_balance_arc_weaponreplace ""
-set g_balance_arc_weaponstart 0
-set g_balance_arc_weaponstartoverride -1
-set g_balance_arc_weaponthrowable 1
-// }}}
-// {{{ #21: Overkill Heavy Machine Gun (MUTATOR WEAPON)
-set g_balance_okhmg_primary_ammo 1
-set g_balance_okhmg_primary_damage 30
-set g_balance_okhmg_primary_force 10
-set g_balance_okhmg_primary_refire 0.05
-set g_balance_okhmg_primary_solidpenetration 127
-set g_balance_okhmg_primary_spread_add 0.005
-set g_balance_okhmg_primary_spread_max 0.06
-set g_balance_okhmg_primary_spread_min 0.01
-set g_balance_okhmg_reload_ammo 120
-set g_balance_okhmg_reload_time 1
-set g_balance_okhmg_secondary_ammo 0
-set g_balance_okhmg_secondary_animtime 0.2
-set g_balance_okhmg_secondary_damage 25
-set g_balance_okhmg_secondary_delay 0
-set g_balance_okhmg_secondary_edgedamage 12.5
-set g_balance_okhmg_secondary_force 360
-set g_balance_okhmg_secondary_force_zscale 1
-set g_balance_okhmg_secondary_lifetime 5
-set g_balance_okhmg_secondary_radius 70
-set g_balance_okhmg_secondary_refire 0.7
-set g_balance_okhmg_secondary_refire_type 1
-set g_balance_okhmg_secondary_shotangle 0
-set g_balance_okhmg_secondary_speed 6000
-set g_balance_okhmg_secondary_spread 0
-set g_balance_okhmg_switchdelay_drop 0.2
-set g_balance_okhmg_switchdelay_raise 0.2
-set g_balance_okhmg_weaponreplace ""
-set g_balance_okhmg_weaponstart 0
-set g_balance_okhmg_weaponstartoverride 0
-set g_balance_okhmg_weaponthrowable 0
-// }}}
-// {{{ #22: Overkill MachineGun (MUTATOR WEAPON)
-set g_balance_okmachinegun_primary_ammo 1
-set g_balance_okmachinegun_primary_damage 25
-set g_balance_okmachinegun_primary_force 5
-set g_balance_okmachinegun_primary_refire 0.1
-set g_balance_okmachinegun_primary_solidpenetration 100
-set g_balance_okmachinegun_primary_spread_add 0.012
-set g_balance_okmachinegun_primary_spread_max 0.05
-set g_balance_okmachinegun_primary_spread_min 0
-set g_balance_okmachinegun_reload_ammo 30
-set g_balance_okmachinegun_reload_time 1.5
-set g_balance_okmachinegun_secondary_animtime 0.2
-set g_balance_okmachinegun_secondary_damage 25
-set g_balance_okmachinegun_secondary_delay 0
-set g_balance_okmachinegun_secondary_edgedamage 12.5
-set g_balance_okmachinegun_secondary_force 360
-set g_balance_okmachinegun_secondary_force_zscale 1
-set g_balance_okmachinegun_secondary_lifetime 5
-set g_balance_okmachinegun_secondary_radius 70
-set g_balance_okmachinegun_secondary_refire 0.7
-set g_balance_okmachinegun_secondary_refire_type 1
-set g_balance_okmachinegun_secondary_shotangle 0
-set g_balance_okmachinegun_secondary_speed 6000
-set g_balance_okmachinegun_secondary_spread 0
-set g_balance_okmachinegun_switchdelay_drop 0.2
-set g_balance_okmachinegun_switchdelay_raise 0.2
-set g_balance_okmachinegun_weaponreplace ""
-set g_balance_okmachinegun_weaponstart 0
-set g_balance_okmachinegun_weaponstartoverride -1
-set g_balance_okmachinegun_weaponthrowable 1
-// }}}
-// {{{ #23: Overkill Nex (MUTATOR WEAPON)
-set g_balance_oknex_charge 0
-set g_balance_oknex_charge_animlimit 0.5
-set g_balance_oknex_charge_limit 1
-set g_balance_oknex_charge_maxspeed 800
-set g_balance_oknex_charge_mindmg 40
-set g_balance_oknex_charge_minspeed 400
-set g_balance_oknex_charge_rate 0.6
-set g_balance_oknex_charge_rot_pause 0
-set g_balance_oknex_charge_rot_rate 0
-set g_balance_oknex_charge_shot_multiplier 0
-set g_balance_oknex_charge_start 0.5
-set g_balance_oknex_charge_velocity_rate 0
-set g_balance_oknex_primary_ammo 10
-set g_balance_oknex_primary_animtime 0.65
-set g_balance_oknex_primary_damage 100
-set g_balance_oknex_primary_damagefalloff_forcehalflife 0
-set g_balance_oknex_primary_damagefalloff_halflife 0
-set g_balance_oknex_primary_damagefalloff_maxdist 0
-set g_balance_oknex_primary_damagefalloff_mindist 0
-set g_balance_oknex_primary_force 500
-set g_balance_oknex_primary_refire 1
-set g_balance_oknex_reload_ammo 50
-set g_balance_oknex_reload_time 2
-set g_balance_oknex_secondary 2
-set g_balance_oknex_secondary_ammo 0
-set g_balance_oknex_secondary_animtime 0.2
-set g_balance_oknex_secondary_chargepool 0
-set g_balance_oknex_secondary_chargepool_pause_regen 1
-set g_balance_oknex_secondary_chargepool_regen 0.15
-set g_balance_oknex_secondary_damage 25
-set g_balance_oknex_secondary_damagefalloff_forcehalflife 0
-set g_balance_oknex_secondary_damagefalloff_halflife 0
-set g_balance_oknex_secondary_damagefalloff_maxdist 0
-set g_balance_oknex_secondary_damagefalloff_mindist 0
-set g_balance_oknex_secondary_delay 0
-set g_balance_oknex_secondary_edgedamage 12.5
-set g_balance_oknex_secondary_force 360
-set g_balance_oknex_secondary_force_zscale 1
-set g_balance_oknex_secondary_lifetime 5
-set g_balance_oknex_secondary_radius 70
-set g_balance_oknex_secondary_refire 0.7
-set g_balance_oknex_secondary_refire_type 1
-set g_balance_oknex_secondary_shotangle 0
-set g_balance_oknex_secondary_speed 6000
-set g_balance_oknex_secondary_spread 0
-set g_balance_oknex_switchdelay_drop 0.2
-set g_balance_oknex_switchdelay_raise 0.2
-set g_balance_oknex_weaponreplace ""
-set g_balance_oknex_weaponstart 0
-set g_balance_oknex_weaponstartoverride -1
-set g_balance_oknex_weaponthrowable 1
-// }}}
-// {{{ #24: Overkill Rocket Propelled Chainsaw (MUTATOR WEAPON)
-set g_balance_okrpc_primary_ammo 10
-set g_balance_okrpc_primary_animtime 1
-set g_balance_okrpc_primary_damage 150
-set g_balance_okrpc_primary_damage2 500
-set g_balance_okrpc_primary_damageforcescale 2
-set g_balance_okrpc_primary_edgedamage 50
-set g_balance_okrpc_primary_force 400
-set g_balance_okrpc_primary_health 25
-set g_balance_okrpc_primary_lifetime 30
-set g_balance_okrpc_primary_radius 300
-set g_balance_okrpc_primary_refire 1
-set g_balance_okrpc_primary_speed 2500
-set g_balance_okrpc_primary_speedaccel 5000
-set g_balance_okrpc_reload_ammo 10
-set g_balance_okrpc_reload_time 1
-set g_balance_okrpc_secondary_ammo 0
-set g_balance_okrpc_secondary_animtime 0.2
-set g_balance_okrpc_secondary_damage 25
-set g_balance_okrpc_secondary_delay 0
-set g_balance_okrpc_secondary_edgedamage 12.5
-set g_balance_okrpc_secondary_force 360
-set g_balance_okrpc_secondary_force_zscale 1
-set g_balance_okrpc_secondary_lifetime 5
-set g_balance_okrpc_secondary_radius 70
-set g_balance_okrpc_secondary_refire 0.7
-set g_balance_okrpc_secondary_refire_type 1
-set g_balance_okrpc_secondary_shotangle 0
-set g_balance_okrpc_secondary_speed 6000
-set g_balance_okrpc_secondary_spread 0
-set g_balance_okrpc_switchdelay_drop 0.2
-set g_balance_okrpc_switchdelay_raise 0.2
-set g_balance_okrpc_weaponreplace ""
-set g_balance_okrpc_weaponstart 0
-set g_balance_okrpc_weaponstartoverride 0
-set g_balance_okrpc_weaponthrowable 0
-// }}}
-// {{{ #25: Overkill Shotgun (MUTATOR WEAPON)
-set g_balance_okshotgun_primary_ammo 3
-set g_balance_okshotgun_primary_animtime 0.65
-set g_balance_okshotgun_primary_bot_range 512
-set g_balance_okshotgun_primary_bullets 10
-set g_balance_okshotgun_primary_damage 17
-set g_balance_okshotgun_primary_force 80
-set g_balance_okshotgun_primary_refire 0.75
-set g_balance_okshotgun_primary_solidpenetration 3.8
-set g_balance_okshotgun_primary_spread 0.07
-set g_balance_okshotgun_reload_ammo 24
-set g_balance_okshotgun_reload_time 2
-set g_balance_okshotgun_secondary_animtime 0.2
-set g_balance_okshotgun_secondary_damage 25
-set g_balance_okshotgun_secondary_delay 0
-set g_balance_okshotgun_secondary_edgedamage 12.5
-set g_balance_okshotgun_secondary_force 360
-set g_balance_okshotgun_secondary_force_zscale 1
-set g_balance_okshotgun_secondary_lifetime 5
-set g_balance_okshotgun_secondary_radius 70
-set g_balance_okshotgun_secondary_refire 0.7
-set g_balance_okshotgun_secondary_refire_type 1
-set g_balance_okshotgun_secondary_shotangle 0
-set g_balance_okshotgun_secondary_speed 6000
-set g_balance_okshotgun_secondary_spread 0
-set g_balance_okshotgun_switchdelay_drop 0.2
-set g_balance_okshotgun_switchdelay_raise 0.2
-set g_balance_okshotgun_weaponreplace ""
-set g_balance_okshotgun_weaponstart 0
-set g_balance_okshotgun_weaponstartoverride -1
-set g_balance_okshotgun_weaponthrowable 1
-// }}}
diff --git a/bal-wep-testingxpm.cfg b/bal-wep-testingxpm.cfg
deleted file mode 100644 (file)
index 3bfe7a7..0000000
+++ /dev/null
@@ -1,970 +0,0 @@
-// {{{ #1: Blaster
-set g_balance_blaster_primary_animtime 0.2
-set g_balance_blaster_primary_damage 20
-set g_balance_blaster_primary_delay 0
-set g_balance_blaster_primary_edgedamage 10
-set g_balance_blaster_primary_force 375
-set g_balance_blaster_primary_force_zscale 1
-set g_balance_blaster_primary_lifetime 5
-set g_balance_blaster_primary_radius 60
-set g_balance_blaster_primary_refire 0.7
-set g_balance_blaster_primary_shotangle 0
-set g_balance_blaster_primary_speed 6000
-set g_balance_blaster_primary_spread 0
-set g_balance_blaster_secondary 0
-set g_balance_blaster_secondary_animtime 0.2
-set g_balance_blaster_secondary_damage 25
-set g_balance_blaster_secondary_delay 0
-set g_balance_blaster_secondary_edgedamage 12.5
-set g_balance_blaster_secondary_force 360
-set g_balance_blaster_secondary_force_zscale 1
-set g_balance_blaster_secondary_lifetime 5
-set g_balance_blaster_secondary_radius 70
-set g_balance_blaster_secondary_refire 0.7
-set g_balance_blaster_secondary_shotangle 0
-set g_balance_blaster_secondary_speed 6000
-set g_balance_blaster_secondary_spread 0
-set g_balance_blaster_switchdelay_drop 0.2
-set g_balance_blaster_switchdelay_raise 0.2
-set g_balance_blaster_weaponreplace ""
-set g_balance_blaster_weaponstart 1
-set g_balance_blaster_weaponstartoverride -1
-set g_balance_blaster_weaponthrowable 0
-// }}}
-// {{{ #2: Shotgun
-set g_balance_shotgun_primary_ammo 1
-set g_balance_shotgun_primary_animtime 0.2
-set g_balance_shotgun_primary_bullets 12
-set g_balance_shotgun_primary_damage 4
-set g_balance_shotgun_primary_force 15
-set g_balance_shotgun_primary_refire 0.75
-set g_balance_shotgun_primary_solidpenetration 3.8
-set g_balance_shotgun_primary_spread 0.12
-set g_balance_shotgun_reload_ammo 0
-set g_balance_shotgun_reload_time 2
-set g_balance_shotgun_secondary 1
-set g_balance_shotgun_secondary_alt_animtime 0.2
-set g_balance_shotgun_secondary_alt_refire 1.2
-set g_balance_shotgun_secondary_animtime 1.15
-set g_balance_shotgun_secondary_damage 70
-set g_balance_shotgun_secondary_force 200
-set g_balance_shotgun_secondary_melee_delay 0.25
-set g_balance_shotgun_secondary_melee_multihit 1
-set g_balance_shotgun_secondary_melee_no_doubleslap 1
-set g_balance_shotgun_secondary_melee_nonplayerdamage 40
-set g_balance_shotgun_secondary_melee_range 120
-set g_balance_shotgun_secondary_melee_swing_side 120
-set g_balance_shotgun_secondary_melee_swing_up 30
-set g_balance_shotgun_secondary_melee_time 0.15
-set g_balance_shotgun_secondary_melee_traces 10
-set g_balance_shotgun_secondary_refire 1.25
-set g_balance_shotgun_switchdelay_drop 0.2
-set g_balance_shotgun_switchdelay_raise 0.2
-set g_balance_shotgun_weaponreplace ""
-set g_balance_shotgun_weaponstart 1
-set g_balance_shotgun_weaponstartoverride -1
-set g_balance_shotgun_weaponthrowable 1
-// }}}
-// {{{ #3: MachineGun
-set g_balance_machinegun_burst 3
-set g_balance_machinegun_burst_ammo 3
-set g_balance_machinegun_burst_animtime 0.3
-set g_balance_machinegun_burst_refire 0.06
-set g_balance_machinegun_burst_refire2 0.45
-set g_balance_machinegun_burst_spread 0
-set g_balance_machinegun_first 1
-set g_balance_machinegun_first_ammo 1
-set g_balance_machinegun_first_damage 14
-set g_balance_machinegun_first_force 3
-set g_balance_machinegun_first_refire 0.125
-set g_balance_machinegun_first_spread 0.03
-set g_balance_machinegun_mode 1
-set g_balance_machinegun_reload_ammo 60
-set g_balance_machinegun_reload_time 2
-set g_balance_machinegun_solidpenetration 63
-set g_balance_machinegun_spread_add 0.012
-set g_balance_machinegun_spread_max 0.05
-set g_balance_machinegun_spread_min 0.02
-set g_balance_machinegun_sustained_ammo 1
-set g_balance_machinegun_sustained_damage 10
-set g_balance_machinegun_sustained_force 3
-set g_balance_machinegun_sustained_refire 0.1
-set g_balance_machinegun_sustained_spread 0.03
-set g_balance_machinegun_switchdelay_drop 0.2
-set g_balance_machinegun_switchdelay_raise 0.2
-set g_balance_machinegun_weaponreplace ""
-set g_balance_machinegun_weaponstart 0
-set g_balance_machinegun_weaponstartoverride -1
-set g_balance_machinegun_weaponthrowable 1
-// }}}
-// {{{ #4: Mortar
-set g_balance_mortar_bouncefactor 0.5
-set g_balance_mortar_bouncestop 0.075
-set g_balance_mortar_primary_ammo 2
-set g_balance_mortar_primary_animtime 0.3
-set g_balance_mortar_primary_damage 55
-set g_balance_mortar_primary_damageforcescale 0
-set g_balance_mortar_primary_edgedamage 25
-set g_balance_mortar_primary_force 250
-set g_balance_mortar_primary_health 15
-set g_balance_mortar_primary_lifetime 5
-set g_balance_mortar_primary_lifetime_stick 0
-set g_balance_mortar_primary_radius 120
-set g_balance_mortar_primary_refire 0.8
-set g_balance_mortar_primary_remote_minbouncecnt 0
-set g_balance_mortar_primary_speed 1900
-set g_balance_mortar_primary_speed_up 225
-set g_balance_mortar_primary_speed_z 0
-set g_balance_mortar_primary_spread 0
-set g_balance_mortar_primary_type 0
-set g_balance_mortar_reload_ammo 0
-set g_balance_mortar_reload_time 2
-set g_balance_mortar_secondary_ammo 2
-set g_balance_mortar_secondary_animtime 0.3
-set g_balance_mortar_secondary_damage 55
-set g_balance_mortar_secondary_damageforcescale 4
-set g_balance_mortar_secondary_edgedamage 30
-set g_balance_mortar_secondary_force 250
-set g_balance_mortar_secondary_health 30
-set g_balance_mortar_secondary_lifetime 5
-set g_balance_mortar_secondary_lifetime_bounce 0.5
-set g_balance_mortar_secondary_lifetime_stick 0
-set g_balance_mortar_secondary_radius 120
-set g_balance_mortar_secondary_refire 0.7
-set g_balance_mortar_secondary_remote_detonateprimary 0
-set g_balance_mortar_secondary_speed 1400
-set g_balance_mortar_secondary_speed_up 150
-set g_balance_mortar_secondary_speed_z 0
-set g_balance_mortar_secondary_spread 0
-set g_balance_mortar_secondary_type 1
-set g_balance_mortar_switchdelay_drop 0.2
-set g_balance_mortar_switchdelay_raise 0.2
-set g_balance_mortar_weaponreplace ""
-set g_balance_mortar_weaponstart 0
-set g_balance_mortar_weaponstartoverride -1
-set g_balance_mortar_weaponthrowable 1
-// }}}
-// {{{ #5: Mine Layer (MUTATOR WEAPON)
-set g_balance_minelayer_ammo 4
-set g_balance_minelayer_animtime 0.4
-set g_balance_minelayer_damage 40
-set g_balance_minelayer_damageforcescale 0
-set g_balance_minelayer_detonatedelay -1
-set g_balance_minelayer_edgedamage 20
-set g_balance_minelayer_force 250
-set g_balance_minelayer_health 15
-set g_balance_minelayer_lifetime 10
-set g_balance_minelayer_lifetime_countdown 0.5
-set g_balance_minelayer_limit 3
-set g_balance_minelayer_protection 0
-set g_balance_minelayer_proximityradius 150
-set g_balance_minelayer_radius 175
-set g_balance_minelayer_refire 1.5
-set g_balance_minelayer_reload_ammo 0
-set g_balance_minelayer_reload_time 2
-set g_balance_minelayer_remote_damage 45
-set g_balance_minelayer_remote_edgedamage 40
-set g_balance_minelayer_remote_force 300
-set g_balance_minelayer_remote_radius 200
-set g_balance_minelayer_speed 1000
-set g_balance_minelayer_switchdelay_drop 0.2
-set g_balance_minelayer_switchdelay_raise 0.2
-set g_balance_minelayer_time 0.5
-set g_balance_minelayer_weaponreplace ""
-set g_balance_minelayer_weaponstart 0
-set g_balance_minelayer_weaponstartoverride -1
-set g_balance_minelayer_weaponthrowable 1
-// }}}
-// {{{ #6: Electro
-set g_balance_electro_combo_comboradius 300
-set g_balance_electro_combo_comboradius_thruwall 200
-set g_balance_electro_combo_damage 50
-set g_balance_electro_combo_edgedamage 25
-set g_balance_electro_combo_force 120
-set g_balance_electro_combo_radius 150
-set g_balance_electro_combo_safeammocheck 1
-set g_balance_electro_combo_speed 2000
-set g_balance_electro_primary_ammo 4
-set g_balance_electro_primary_animtime 0.3
-set g_balance_electro_primary_comboradius 300
-set g_balance_electro_primary_damage 40
-set g_balance_electro_primary_edgedamage 20
-set g_balance_electro_primary_force 200
-set g_balance_electro_primary_lifetime 5
-set g_balance_electro_primary_midaircombo_explode 1
-set g_balance_electro_primary_midaircombo_interval 0.1
-set g_balance_electro_primary_midaircombo_radius 0
-set g_balance_electro_primary_radius 100
-set g_balance_electro_primary_refire 0.6
-set g_balance_electro_primary_speed 2500
-set g_balance_electro_primary_spread 0
-set g_balance_electro_reload_ammo 0
-set g_balance_electro_reload_time 2
-set g_balance_electro_secondary_ammo 2
-set g_balance_electro_secondary_animtime 0.2
-set g_balance_electro_secondary_bouncefactor 0.3
-set g_balance_electro_secondary_bouncestop 0.05
-set g_balance_electro_secondary_count 3
-set g_balance_electro_secondary_damage 30
-set g_balance_electro_secondary_damagedbycontents 1
-set g_balance_electro_secondary_damageforcescale 4
-set g_balance_electro_secondary_edgedamage 15
-set g_balance_electro_secondary_force 50
-set g_balance_electro_secondary_health 5
-set g_balance_electro_secondary_lifetime 4
-set g_balance_electro_secondary_radius 150
-set g_balance_electro_secondary_refire 0.2
-set g_balance_electro_secondary_refire2 1.6
-set g_balance_electro_secondary_speed 1000
-set g_balance_electro_secondary_speed_up 200
-set g_balance_electro_secondary_speed_z 0
-set g_balance_electro_secondary_spread 0
-set g_balance_electro_secondary_stick 0
-set g_balance_electro_secondary_touchexplode 1
-set g_balance_electro_switchdelay_drop 0.2
-set g_balance_electro_switchdelay_raise 0.2
-set g_balance_electro_weaponreplace ""
-set g_balance_electro_weaponstart 0
-set g_balance_electro_weaponstartoverride -1
-set g_balance_electro_weaponthrowable 1
-// }}}
-// {{{ #7: Crylink
-set g_balance_crylink_primary_ammo 3
-set g_balance_crylink_primary_animtime 0.3
-set g_balance_crylink_primary_bouncedamagefactor 0.5
-set g_balance_crylink_primary_bounces 1
-set g_balance_crylink_primary_damage 10
-set g_balance_crylink_primary_edgedamage 5
-set g_balance_crylink_primary_force -50
-set g_balance_crylink_primary_joindelay 0.1
-set g_balance_crylink_primary_joinexplode 1
-set g_balance_crylink_primary_joinexplode_damage 0
-set g_balance_crylink_primary_joinexplode_edgedamage 0
-set g_balance_crylink_primary_joinexplode_force 0
-set g_balance_crylink_primary_joinexplode_radius 0
-set g_balance_crylink_primary_joinspread 0.2
-set g_balance_crylink_primary_linkexplode 1
-set g_balance_crylink_primary_middle_fadetime 5
-set g_balance_crylink_primary_middle_lifetime 5
-set g_balance_crylink_primary_other_fadetime 5
-set g_balance_crylink_primary_other_lifetime 5
-set g_balance_crylink_primary_radius 80
-set g_balance_crylink_primary_refire 0.7
-set g_balance_crylink_primary_shots 6
-set g_balance_crylink_primary_speed 2000
-set g_balance_crylink_primary_spread 0.08
-set g_balance_crylink_reload_ammo 0
-set g_balance_crylink_reload_time 2
-set g_balance_crylink_secondary 1
-set g_balance_crylink_secondary_ammo 3
-set g_balance_crylink_secondary_animtime 0.2
-set g_balance_crylink_secondary_bouncedamagefactor 0.5
-set g_balance_crylink_secondary_bounces 0
-set g_balance_crylink_secondary_damage 8
-set g_balance_crylink_secondary_edgedamage 4
-set g_balance_crylink_secondary_force -200
-set g_balance_crylink_secondary_joindelay 0
-set g_balance_crylink_secondary_joinexplode 0
-set g_balance_crylink_secondary_joinexplode_damage 0
-set g_balance_crylink_secondary_joinexplode_edgedamage 0
-set g_balance_crylink_secondary_joinexplode_force 0
-set g_balance_crylink_secondary_joinexplode_radius 0
-set g_balance_crylink_secondary_joinspread 0
-set g_balance_crylink_secondary_linkexplode 0
-set g_balance_crylink_secondary_middle_fadetime 5
-set g_balance_crylink_secondary_middle_lifetime 5
-set g_balance_crylink_secondary_other_fadetime 2
-set g_balance_crylink_secondary_other_lifetime 2
-set g_balance_crylink_secondary_radius 100
-set g_balance_crylink_secondary_refire 0.7
-set g_balance_crylink_secondary_shots 5
-set g_balance_crylink_secondary_speed 4000
-set g_balance_crylink_secondary_spread 0.08
-set g_balance_crylink_secondary_spreadtype 0
-set g_balance_crylink_switchdelay_drop 0.2
-set g_balance_crylink_switchdelay_raise 0.2
-set g_balance_crylink_weaponreplace ""
-set g_balance_crylink_weaponstart 0
-set g_balance_crylink_weaponstartoverride -1
-set g_balance_crylink_weaponthrowable 1
-// }}}
-// {{{ #8: Vortex
-set g_balance_vortex_charge 0
-set g_balance_vortex_charge_always 0
-set g_balance_vortex_charge_animlimit 0.5
-set g_balance_vortex_charge_limit 1
-set g_balance_vortex_charge_maxspeed 800
-set g_balance_vortex_charge_mindmg 40
-set g_balance_vortex_charge_minspeed 400
-set g_balance_vortex_charge_rate 0.6
-set g_balance_vortex_charge_rot_pause 0
-set g_balance_vortex_charge_rot_rate 0
-set g_balance_vortex_charge_shot_multiplier 0
-set g_balance_vortex_charge_start 0.5
-set g_balance_vortex_charge_velocity_rate 0
-set g_balance_vortex_primary_ammo 6
-set g_balance_vortex_primary_animtime 0.4
-set g_balance_vortex_primary_armorpierce 0
-set g_balance_vortex_primary_damage 65
-set g_balance_vortex_primary_damagefalloff_forcehalflife 0
-set g_balance_vortex_primary_damagefalloff_halflife 0
-set g_balance_vortex_primary_damagefalloff_maxdist 0
-set g_balance_vortex_primary_damagefalloff_mindist 0
-set g_balance_vortex_primary_force 400
-set g_balance_vortex_primary_refire 1.5
-set g_balance_vortex_reload_ammo 0
-set g_balance_vortex_reload_time 2
-set g_balance_vortex_secondary 0
-set g_balance_vortex_secondary_ammo 2
-set g_balance_vortex_secondary_animtime 0
-set g_balance_vortex_secondary_armorpierce 0
-set g_balance_vortex_secondary_chargepool 0
-set g_balance_vortex_secondary_chargepool_pause_regen 1
-set g_balance_vortex_secondary_chargepool_regen 0.15
-set g_balance_vortex_secondary_damage 0
-set g_balance_vortex_secondary_damagefalloff_forcehalflife 0
-set g_balance_vortex_secondary_damagefalloff_halflife 0
-set g_balance_vortex_secondary_damagefalloff_maxdist 0
-set g_balance_vortex_secondary_damagefalloff_mindist 0
-set g_balance_vortex_secondary_force 0
-set g_balance_vortex_secondary_refire 0
-set g_balance_vortex_switchdelay_drop 0.2
-set g_balance_vortex_switchdelay_raise 0.2
-set g_balance_vortex_weaponreplace ""
-set g_balance_vortex_weaponstart 0
-set g_balance_vortex_weaponstartoverride -1
-set g_balance_vortex_weaponthrowable 1
-// }}}
-// {{{ #9: Hagar
-set g_balance_hagar_primary_ammo 1
-set g_balance_hagar_primary_damage 25
-set g_balance_hagar_primary_damageforcescale 0
-set g_balance_hagar_primary_edgedamage 12.5
-set g_balance_hagar_primary_force 100
-set g_balance_hagar_primary_health 15
-set g_balance_hagar_primary_lifetime 5
-set g_balance_hagar_primary_radius 65
-set g_balance_hagar_primary_refire 0.16667
-set g_balance_hagar_primary_speed 2200
-set g_balance_hagar_primary_spread 0
-set g_balance_hagar_reload_ammo 0
-set g_balance_hagar_reload_time 2
-set g_balance_hagar_secondary 1
-set g_balance_hagar_secondary_ammo 1
-set g_balance_hagar_secondary_damage 35
-set g_balance_hagar_secondary_damageforcescale 0
-set g_balance_hagar_secondary_edgedamage 17.5
-set g_balance_hagar_secondary_force 75
-set g_balance_hagar_secondary_health 15
-set g_balance_hagar_secondary_lifetime_min 10
-set g_balance_hagar_secondary_lifetime_rand 0
-set g_balance_hagar_secondary_load 1
-set g_balance_hagar_secondary_load_abort 1
-set g_balance_hagar_secondary_load_animtime 0.2
-set g_balance_hagar_secondary_load_hold 4
-set g_balance_hagar_secondary_load_linkexplode 0
-set g_balance_hagar_secondary_load_max 4
-set g_balance_hagar_secondary_load_releasedeath 0
-set g_balance_hagar_secondary_load_speed 0.5
-set g_balance_hagar_secondary_load_spread 0.075
-set g_balance_hagar_secondary_load_spread_bias 0.5
-set g_balance_hagar_secondary_radius 80
-set g_balance_hagar_secondary_refire 0.5
-set g_balance_hagar_secondary_speed 2000
-set g_balance_hagar_secondary_spread 0
-set g_balance_hagar_switchdelay_drop 0.2
-set g_balance_hagar_switchdelay_raise 0.2
-set g_balance_hagar_weaponreplace ""
-set g_balance_hagar_weaponstart 0
-set g_balance_hagar_weaponstartoverride -1
-set g_balance_hagar_weaponthrowable 1
-// }}}
-// {{{ #10: Devastator
-set g_balance_devastator_ammo 4
-set g_balance_devastator_animtime 0.4
-set g_balance_devastator_damage 80
-set g_balance_devastator_damageforcescale 1
-set g_balance_devastator_detonatedelay 0.02
-set g_balance_devastator_edgedamage 40
-set g_balance_devastator_force 400
-set g_balance_devastator_guidedelay 0.2
-set g_balance_devastator_guidegoal 512
-set g_balance_devastator_guiderate 90
-set g_balance_devastator_guideratedelay 0.01
-set g_balance_devastator_guidestop 0
-set g_balance_devastator_health 30
-set g_balance_devastator_lifetime 10
-set g_balance_devastator_radius 110
-set g_balance_devastator_refire 1.1
-set g_balance_devastator_reload_ammo 0
-set g_balance_devastator_reload_time 2
-set g_balance_devastator_remote_damage 70
-set g_balance_devastator_remote_edgedamage 35
-set g_balance_devastator_remote_force 300
-set g_balance_devastator_remote_jump 1
-set g_balance_devastator_remote_jump_damage 70
-set g_balance_devastator_remote_jump_force 450
-set g_balance_devastator_remote_jump_radius 100
-set g_balance_devastator_remote_jump_velocity_z_add 0
-set g_balance_devastator_remote_jump_velocity_z_max 1500
-set g_balance_devastator_remote_jump_velocity_z_min 400
-set g_balance_devastator_remote_radius 110
-set g_balance_devastator_speed 1300
-set g_balance_devastator_speedaccel 1300
-set g_balance_devastator_speedstart 1000
-set g_balance_devastator_switchdelay_drop 0.2
-set g_balance_devastator_switchdelay_raise 0.2
-set g_balance_devastator_weaponreplace ""
-set g_balance_devastator_weaponstart 0
-set g_balance_devastator_weaponstartoverride -1
-set g_balance_devastator_weaponthrowable 1
-// }}}
-// {{{ #11: Port-O-Launch
-set g_balance_porto_primary_animtime 0.3
-set g_balance_porto_primary_lifetime 5
-set g_balance_porto_primary_refire 1.5
-set g_balance_porto_primary_speed 1000
-set g_balance_porto_secondary 1
-set g_balance_porto_secondary_animtime 0.3
-set g_balance_porto_secondary_lifetime 5
-set g_balance_porto_secondary_refire 1.5
-set g_balance_porto_secondary_speed 1000
-set g_balance_porto_switchdelay_drop 0.2
-set g_balance_porto_switchdelay_raise 0.2
-set g_balance_porto_weaponreplace ""
-set g_balance_porto_weaponstart 0
-set g_balance_porto_weaponstartoverride -1
-set g_balance_porto_weaponthrowable 1
-// }}}
-// {{{ #12: Vaporizer
-set g_balance_vaporizer_primary_ammo 10
-set g_balance_vaporizer_primary_animtime 0.3
-set g_balance_vaporizer_primary_damage 150
-set g_balance_vaporizer_primary_force 800
-set g_balance_vaporizer_primary_refire 1
-set g_balance_vaporizer_reload_ammo 0
-set g_balance_vaporizer_reload_time 0
-set g_balance_vaporizer_secondary_ammo 0
-set g_balance_vaporizer_secondary_animtime 0.2
-set g_balance_vaporizer_secondary_damage 25
-set g_balance_vaporizer_secondary_delay 0
-set g_balance_vaporizer_secondary_edgedamage 12.5
-set g_balance_vaporizer_secondary_force 480
-set g_balance_vaporizer_secondary_force_zscale 1
-set g_balance_vaporizer_secondary_lifetime 5
-set g_balance_vaporizer_secondary_radius 70
-set g_balance_vaporizer_secondary_refire 0.7
-set g_balance_vaporizer_secondary_shotangle 0
-set g_balance_vaporizer_secondary_speed 6000
-set g_balance_vaporizer_secondary_spread 0
-set g_balance_vaporizer_switchdelay_drop 0.2
-set g_balance_vaporizer_switchdelay_raise 0.2
-set g_balance_vaporizer_weaponreplace ""
-set g_balance_vaporizer_weaponstart 0
-set g_balance_vaporizer_weaponstartoverride -1
-set g_balance_vaporizer_weaponthrowable 1
-// }}}
-// {{{ #13: Grappling Hook
-set g_balance_hook_primary_ammo 5
-set g_balance_hook_primary_animtime 0.3
-set g_balance_hook_primary_hooked_ammo 5
-set g_balance_hook_primary_hooked_time_free 2
-set g_balance_hook_primary_hooked_time_max 0
-set g_balance_hook_primary_refire 0.2
-set g_balance_hook_secondary_animtime 0.3
-set g_balance_hook_secondary_damage 25
-set g_balance_hook_secondary_damageforcescale 0
-set g_balance_hook_secondary_duration 1.5
-set g_balance_hook_secondary_edgedamage 5
-set g_balance_hook_secondary_force -2000
-set g_balance_hook_secondary_gravity 5
-set g_balance_hook_secondary_health 15
-set g_balance_hook_secondary_lifetime 5
-set g_balance_hook_secondary_power 3
-set g_balance_hook_secondary_radius 500
-set g_balance_hook_secondary_refire 3
-set g_balance_hook_secondary_speed 0
-set g_balance_hook_switchdelay_drop 0.2
-set g_balance_hook_switchdelay_raise 0.2
-set g_balance_hook_weaponreplace ""
-set g_balance_hook_weaponstart 0
-set g_balance_hook_weaponstartoverride -1
-set g_balance_hook_weaponthrowable 1
-// }}}
-// {{{ #14: Heavy Laser Assault Cannon (MUTATOR WEAPON)
-set g_balance_hlac_primary_ammo 1
-set g_balance_hlac_primary_animtime 0.4
-set g_balance_hlac_primary_damage 18
-set g_balance_hlac_primary_edgedamage 9
-set g_balance_hlac_primary_force 90
-set g_balance_hlac_primary_lifetime 5
-set g_balance_hlac_primary_radius 70
-set g_balance_hlac_primary_refire 0.15
-set g_balance_hlac_primary_speed 9000
-set g_balance_hlac_primary_spread_add 0.0045
-set g_balance_hlac_primary_spread_crouchmod 0.25
-set g_balance_hlac_primary_spread_max 0.25
-set g_balance_hlac_primary_spread_min 0.01
-set g_balance_hlac_reload_ammo 0
-set g_balance_hlac_reload_time 2
-set g_balance_hlac_secondary 1
-set g_balance_hlac_secondary_ammo 10
-set g_balance_hlac_secondary_animtime 0.3
-set g_balance_hlac_secondary_damage 15
-set g_balance_hlac_secondary_edgedamage 7.5
-set g_balance_hlac_secondary_force 90
-set g_balance_hlac_secondary_lifetime 5
-set g_balance_hlac_secondary_radius 70
-set g_balance_hlac_secondary_refire 1
-set g_balance_hlac_secondary_shots 6
-set g_balance_hlac_secondary_speed 9000
-set g_balance_hlac_secondary_spread 0.15
-set g_balance_hlac_secondary_spread_crouchmod 0.5
-set g_balance_hlac_switchdelay_drop 0.2
-set g_balance_hlac_switchdelay_raise 0.2
-set g_balance_hlac_weaponreplace ""
-set g_balance_hlac_weaponstart 0
-set g_balance_hlac_weaponstartoverride -1
-set g_balance_hlac_weaponthrowable 1
-// }}}
-// {{{ #15: @!#%'n Tuba
-set g_balance_tuba_animtime 0.05
-set g_balance_tuba_attenuation 0.5
-set g_balance_tuba_damage 5
-set g_balance_tuba_edgedamage 0
-set g_balance_tuba_fadetime 0.25
-set g_balance_tuba_force 40
-set g_balance_tuba_pitchstep 6
-set g_balance_tuba_radius 200
-set g_balance_tuba_refire 0.05
-set g_balance_tuba_switchdelay_drop 0.2
-set g_balance_tuba_switchdelay_raise 0.2
-set g_balance_tuba_volume 1
-set g_balance_tuba_weaponreplace ""
-set g_balance_tuba_weaponstart 0
-set g_balance_tuba_weaponstartoverride -1
-set g_balance_tuba_weaponthrowable 1
-// }}}
-// {{{ #16: Rifle (MUTATOR WEAPON)
-set g_balance_rifle_bursttime 0
-set g_balance_rifle_primary_ammo 10
-set g_balance_rifle_primary_animtime 0.4
-set g_balance_rifle_primary_bullethail 0
-set g_balance_rifle_primary_burstcost 0
-set g_balance_rifle_primary_damage 80
-set g_balance_rifle_primary_force 100
-set g_balance_rifle_primary_refire 1.2
-set g_balance_rifle_primary_shots 1
-set g_balance_rifle_primary_solidpenetration 62.2
-set g_balance_rifle_primary_spread 0
-set g_balance_rifle_primary_tracer 1
-set g_balance_rifle_reload_ammo 80
-set g_balance_rifle_reload_time 2
-set g_balance_rifle_secondary 1
-set g_balance_rifle_secondary_ammo 10
-set g_balance_rifle_secondary_animtime 0.3
-set g_balance_rifle_secondary_bullethail 0
-set g_balance_rifle_secondary_burstcost 0
-set g_balance_rifle_secondary_damage 20
-set g_balance_rifle_secondary_force 50
-set g_balance_rifle_secondary_refire 0.9
-set g_balance_rifle_secondary_reload 0
-set g_balance_rifle_secondary_shots 4
-set g_balance_rifle_secondary_solidpenetration 15.5
-set g_balance_rifle_secondary_spread 0.04
-set g_balance_rifle_secondary_tracer 0
-set g_balance_rifle_switchdelay_drop 0.2
-set g_balance_rifle_switchdelay_raise 0.2
-set g_balance_rifle_weaponreplace ""
-set g_balance_rifle_weaponstart 0
-set g_balance_rifle_weaponstartoverride -1
-set g_balance_rifle_weaponthrowable 1
-// }}}
-// {{{ #17: Fireball
-set g_balance_fireball_primary_animtime 0.4
-set g_balance_fireball_primary_bfgdamage 100
-set g_balance_fireball_primary_bfgforce 0
-set g_balance_fireball_primary_bfgradius 1000
-set g_balance_fireball_primary_damage 200
-set g_balance_fireball_primary_damageforcescale 0
-set g_balance_fireball_primary_edgedamage 50
-set g_balance_fireball_primary_force 600
-set g_balance_fireball_primary_health 0
-set g_balance_fireball_primary_laserburntime 0.5
-set g_balance_fireball_primary_laserdamage 80
-set g_balance_fireball_primary_laseredgedamage 20
-set g_balance_fireball_primary_laserradius 256
-set g_balance_fireball_primary_lifetime 15
-set g_balance_fireball_primary_radius 200
-set g_balance_fireball_primary_refire 2
-set g_balance_fireball_primary_refire2 0
-set g_balance_fireball_primary_speed 1200
-set g_balance_fireball_primary_spread 0
-set g_balance_fireball_secondary_animtime 0.3
-set g_balance_fireball_secondary_damage 40
-set g_balance_fireball_secondary_damageforcescale 4
-set g_balance_fireball_secondary_damagetime 5
-set g_balance_fireball_secondary_laserburntime 0.5
-set g_balance_fireball_secondary_laserdamage 50
-set g_balance_fireball_secondary_laseredgedamage 20
-set g_balance_fireball_secondary_laserradius 110
-set g_balance_fireball_secondary_lifetime 7
-set g_balance_fireball_secondary_refire 1.5
-set g_balance_fireball_secondary_speed 900
-set g_balance_fireball_secondary_speed_up 100
-set g_balance_fireball_secondary_speed_z 0
-set g_balance_fireball_secondary_spread 0
-set g_balance_fireball_switchdelay_drop 0.2
-set g_balance_fireball_switchdelay_raise 0.2
-set g_balance_fireball_weaponreplace ""
-set g_balance_fireball_weaponstart 0
-set g_balance_fireball_weaponstartoverride -1
-set g_balance_fireball_weaponthrowable 0
-// }}}
-// {{{ #18: T.A.G. Seeker (MUTATOR WEAPON)
-set g_balance_seeker_flac_ammo 1
-set g_balance_seeker_flac_animtime 0.1
-set g_balance_seeker_flac_damage 15
-set g_balance_seeker_flac_edgedamage 10
-set g_balance_seeker_flac_force 50
-set g_balance_seeker_flac_lifetime 0.1
-set g_balance_seeker_flac_lifetime_rand 0.05
-set g_balance_seeker_flac_radius 100
-set g_balance_seeker_flac_refire 0.1
-set g_balance_seeker_flac_speed 3000
-set g_balance_seeker_flac_speed_up 1000
-set g_balance_seeker_flac_speed_z 0
-set g_balance_seeker_flac_spread 0.4
-set g_balance_seeker_missile_accel 1400
-set g_balance_seeker_missile_ammo 2
-set g_balance_seeker_missile_animtime 0.2
-set g_balance_seeker_missile_count 3
-set g_balance_seeker_missile_damage 30
-set g_balance_seeker_missile_damageforcescale 4
-set g_balance_seeker_missile_decel 1400
-set g_balance_seeker_missile_delay 0.25
-set g_balance_seeker_missile_edgedamage 10
-set g_balance_seeker_missile_force 150
-set g_balance_seeker_missile_health 5
-set g_balance_seeker_missile_lifetime 15
-set g_balance_seeker_missile_proxy 0
-set g_balance_seeker_missile_proxy_delay 0.2
-set g_balance_seeker_missile_proxy_maxrange 45
-set g_balance_seeker_missile_radius 80
-set g_balance_seeker_missile_refire 0.5
-set g_balance_seeker_missile_smart 1
-set g_balance_seeker_missile_smart_mindist 800
-set g_balance_seeker_missile_smart_trace_max 2500
-set g_balance_seeker_missile_smart_trace_min 1000
-set g_balance_seeker_missile_speed 700
-set g_balance_seeker_missile_speed_max 1300
-set g_balance_seeker_missile_speed_up 300
-set g_balance_seeker_missile_speed_z 0
-set g_balance_seeker_missile_spread 0
-set g_balance_seeker_missile_turnrate 0.65
-set g_balance_seeker_reload_ammo 0
-set g_balance_seeker_reload_time 2
-set g_balance_seeker_switchdelay_drop 0.2
-set g_balance_seeker_switchdelay_raise 0.2
-set g_balance_seeker_tag_ammo 1
-set g_balance_seeker_tag_animtime 0.2
-set g_balance_seeker_tag_damageforcescale 4
-set g_balance_seeker_tag_health 5
-set g_balance_seeker_tag_lifetime 15
-set g_balance_seeker_tag_refire 0.75
-set g_balance_seeker_tag_speed 5000
-set g_balance_seeker_tag_spread 0
-set g_balance_seeker_tag_tracker_lifetime 10
-set g_balance_seeker_type 0
-set g_balance_seeker_weaponreplace ""
-set g_balance_seeker_weaponstart 0
-set g_balance_seeker_weaponstartoverride -1
-set g_balance_seeker_weaponthrowable 1
-// }}}
-// {{{ #19: Shockwave
-set g_balance_shockwave_blast_animtime 0.3
-set g_balance_shockwave_blast_damage 40
-set g_balance_shockwave_blast_distance 1000
-set g_balance_shockwave_blast_edgedamage 0
-set g_balance_shockwave_blast_force 15
-set g_balance_shockwave_blast_force_forwardbias 50
-set g_balance_shockwave_blast_force_zscale 1
-set g_balance_shockwave_blast_jump_damage 20
-set g_balance_shockwave_blast_jump_edgedamage 0
-set g_balance_shockwave_blast_jump_force 100
-set g_balance_shockwave_blast_jump_force_velocitybias 1
-set g_balance_shockwave_blast_jump_force_zscale 1
-set g_balance_shockwave_blast_jump_multiplier_accuracy 0.5
-set g_balance_shockwave_blast_jump_multiplier_distance 0.5
-set g_balance_shockwave_blast_jump_multiplier_min 0
-set g_balance_shockwave_blast_jump_radius 150
-set g_balance_shockwave_blast_multiplier_accuracy 0.45
-set g_balance_shockwave_blast_multiplier_distance 0.2
-set g_balance_shockwave_blast_multiplier_min 0
-set g_balance_shockwave_blast_refire 0.75
-set g_balance_shockwave_blast_splash_damage 15
-set g_balance_shockwave_blast_splash_edgedamage 0
-set g_balance_shockwave_blast_splash_force 100
-set g_balance_shockwave_blast_splash_force_forwardbias 50
-set g_balance_shockwave_blast_splash_multiplier_accuracy 0.5
-set g_balance_shockwave_blast_splash_multiplier_distance 0.5
-set g_balance_shockwave_blast_splash_multiplier_min 0
-set g_balance_shockwave_blast_splash_radius 70
-set g_balance_shockwave_blast_spread_max 120
-set g_balance_shockwave_blast_spread_min 25
-set g_balance_shockwave_melee_animtime 1.3
-set g_balance_shockwave_melee_damage 80
-set g_balance_shockwave_melee_delay 0.25
-set g_balance_shockwave_melee_force 200
-set g_balance_shockwave_melee_multihit 1
-set g_balance_shockwave_melee_no_doubleslap 1
-set g_balance_shockwave_melee_nonplayerdamage 40
-set g_balance_shockwave_melee_range 120
-set g_balance_shockwave_melee_refire 1.25
-set g_balance_shockwave_melee_swing_side 120
-set g_balance_shockwave_melee_swing_up 30
-set g_balance_shockwave_melee_time 0.15
-set g_balance_shockwave_melee_traces 10
-set g_balance_shockwave_switchdelay_drop 0.2
-set g_balance_shockwave_switchdelay_raise 0.2
-set g_balance_shockwave_weaponreplace ""
-set g_balance_shockwave_weaponstart 0
-set g_balance_shockwave_weaponstartoverride -1
-set g_balance_shockwave_weaponthrowable 0
-// }}}
-// {{{ #20: Arc
-set g_balance_arc_beam_ammo 6
-set g_balance_arc_beam_animtime 0.1
-set g_balance_arc_beam_botaimlifetime 0
-set g_balance_arc_beam_botaimspeed 0
-set g_balance_arc_beam_damage 100
-set g_balance_arc_beam_degreespersegment 1
-set g_balance_arc_beam_distancepersegment 0
-set g_balance_arc_beam_falloff_halflifedist 0
-set g_balance_arc_beam_falloff_maxdist 0
-set g_balance_arc_beam_falloff_mindist 0
-set g_balance_arc_beam_force 600
-set g_balance_arc_beam_healing_amax 0
-set g_balance_arc_beam_healing_aps 50
-set g_balance_arc_beam_healing_hmax 150
-set g_balance_arc_beam_healing_hps 50
-set g_balance_arc_beam_heat 0
-set g_balance_arc_beam_maxangle 10
-set g_balance_arc_beam_nonplayerdamage 80
-set g_balance_arc_beam_range 1000
-set g_balance_arc_beam_refire 0.25
-set g_balance_arc_beam_returnspeed 8
-set g_balance_arc_beam_tightness 0.5
-set g_balance_arc_bolt 0
-set g_balance_arc_bolt_ammo 1
-set g_balance_arc_bolt_damage 25
-set g_balance_arc_bolt_damageforcescale 0
-set g_balance_arc_bolt_edgedamage 12.5
-set g_balance_arc_bolt_force 120
-set g_balance_arc_bolt_health 15
-set g_balance_arc_bolt_lifetime 5
-set g_balance_arc_bolt_radius 65
-set g_balance_arc_bolt_refire 0.16667
-set g_balance_arc_bolt_speed 2300
-set g_balance_arc_bolt_spread 0
-set g_balance_arc_burst_ammo 15
-set g_balance_arc_burst_damage 250
-set g_balance_arc_burst_healing_aps 100
-set g_balance_arc_burst_healing_hps 100
-set g_balance_arc_burst_heat 5
-set g_balance_arc_cooldown 2.5
-set g_balance_arc_cooldown_release 0
-set g_balance_arc_overheat_max 5
-set g_balance_arc_overheat_min 3
-set g_balance_arc_switchdelay_drop 0.2
-set g_balance_arc_switchdelay_raise 0.2
-set g_balance_arc_weaponreplace ""
-set g_balance_arc_weaponstart 0
-set g_balance_arc_weaponstartoverride -1
-set g_balance_arc_weaponthrowable 1
-// }}}
-// {{{ #21: Overkill Heavy Machine Gun (MUTATOR WEAPON)
-set g_balance_okhmg_primary_ammo 1
-set g_balance_okhmg_primary_damage 30
-set g_balance_okhmg_primary_force 10
-set g_balance_okhmg_primary_refire 0.05
-set g_balance_okhmg_primary_solidpenetration 127
-set g_balance_okhmg_primary_spread_add 0.005
-set g_balance_okhmg_primary_spread_max 0.06
-set g_balance_okhmg_primary_spread_min 0.01
-set g_balance_okhmg_reload_ammo 120
-set g_balance_okhmg_reload_time 1
-set g_balance_okhmg_secondary_ammo 0
-set g_balance_okhmg_secondary_animtime 0.2
-set g_balance_okhmg_secondary_damage 25
-set g_balance_okhmg_secondary_delay 0
-set g_balance_okhmg_secondary_edgedamage 12.5
-set g_balance_okhmg_secondary_force 360
-set g_balance_okhmg_secondary_force_zscale 1
-set g_balance_okhmg_secondary_lifetime 5
-set g_balance_okhmg_secondary_radius 70
-set g_balance_okhmg_secondary_refire 0.7
-set g_balance_okhmg_secondary_refire_type 1
-set g_balance_okhmg_secondary_shotangle 0
-set g_balance_okhmg_secondary_speed 6000
-set g_balance_okhmg_secondary_spread 0
-set g_balance_okhmg_switchdelay_drop 0.2
-set g_balance_okhmg_switchdelay_raise 0.2
-set g_balance_okhmg_weaponreplace ""
-set g_balance_okhmg_weaponstart 0
-set g_balance_okhmg_weaponstartoverride 0
-set g_balance_okhmg_weaponthrowable 0
-// }}}
-// {{{ #22: Overkill MachineGun (MUTATOR WEAPON)
-set g_balance_okmachinegun_primary_ammo 1
-set g_balance_okmachinegun_primary_damage 25
-set g_balance_okmachinegun_primary_force 5
-set g_balance_okmachinegun_primary_refire 0.1
-set g_balance_okmachinegun_primary_solidpenetration 100
-set g_balance_okmachinegun_primary_spread_add 0.012
-set g_balance_okmachinegun_primary_spread_max 0.05
-set g_balance_okmachinegun_primary_spread_min 0
-set g_balance_okmachinegun_reload_ammo 30
-set g_balance_okmachinegun_reload_time 1.5
-set g_balance_okmachinegun_secondary_animtime 0.2
-set g_balance_okmachinegun_secondary_damage 25
-set g_balance_okmachinegun_secondary_delay 0
-set g_balance_okmachinegun_secondary_edgedamage 12.5
-set g_balance_okmachinegun_secondary_force 360
-set g_balance_okmachinegun_secondary_force_zscale 1
-set g_balance_okmachinegun_secondary_lifetime 5
-set g_balance_okmachinegun_secondary_radius 70
-set g_balance_okmachinegun_secondary_refire 0.7
-set g_balance_okmachinegun_secondary_refire_type 1
-set g_balance_okmachinegun_secondary_shotangle 0
-set g_balance_okmachinegun_secondary_speed 6000
-set g_balance_okmachinegun_secondary_spread 0
-set g_balance_okmachinegun_switchdelay_drop 0.2
-set g_balance_okmachinegun_switchdelay_raise 0.2
-set g_balance_okmachinegun_weaponreplace ""
-set g_balance_okmachinegun_weaponstart 0
-set g_balance_okmachinegun_weaponstartoverride -1
-set g_balance_okmachinegun_weaponthrowable 1
-// }}}
-// {{{ #23: Overkill Nex (MUTATOR WEAPON)
-set g_balance_oknex_charge 0
-set g_balance_oknex_charge_animlimit 0.5
-set g_balance_oknex_charge_limit 1
-set g_balance_oknex_charge_maxspeed 800
-set g_balance_oknex_charge_mindmg 40
-set g_balance_oknex_charge_minspeed 400
-set g_balance_oknex_charge_rate 0.6
-set g_balance_oknex_charge_rot_pause 0
-set g_balance_oknex_charge_rot_rate 0
-set g_balance_oknex_charge_shot_multiplier 0
-set g_balance_oknex_charge_start 0.5
-set g_balance_oknex_charge_velocity_rate 0
-set g_balance_oknex_primary_ammo 10
-set g_balance_oknex_primary_animtime 0.65
-set g_balance_oknex_primary_damage 100
-set g_balance_oknex_primary_damagefalloff_forcehalflife 0
-set g_balance_oknex_primary_damagefalloff_halflife 0
-set g_balance_oknex_primary_damagefalloff_maxdist 0
-set g_balance_oknex_primary_damagefalloff_mindist 0
-set g_balance_oknex_primary_force 500
-set g_balance_oknex_primary_refire 1
-set g_balance_oknex_reload_ammo 50
-set g_balance_oknex_reload_time 2
-set g_balance_oknex_secondary 2
-set g_balance_oknex_secondary_ammo 0
-set g_balance_oknex_secondary_animtime 0.2
-set g_balance_oknex_secondary_chargepool 0
-set g_balance_oknex_secondary_chargepool_pause_regen 1
-set g_balance_oknex_secondary_chargepool_regen 0.15
-set g_balance_oknex_secondary_damage 25
-set g_balance_oknex_secondary_damagefalloff_forcehalflife 0
-set g_balance_oknex_secondary_damagefalloff_halflife 0
-set g_balance_oknex_secondary_damagefalloff_maxdist 0
-set g_balance_oknex_secondary_damagefalloff_mindist 0
-set g_balance_oknex_secondary_delay 0
-set g_balance_oknex_secondary_edgedamage 12.5
-set g_balance_oknex_secondary_force 360
-set g_balance_oknex_secondary_force_zscale 1
-set g_balance_oknex_secondary_lifetime 5
-set g_balance_oknex_secondary_radius 70
-set g_balance_oknex_secondary_refire 0.7
-set g_balance_oknex_secondary_refire_type 1
-set g_balance_oknex_secondary_shotangle 0
-set g_balance_oknex_secondary_speed 6000
-set g_balance_oknex_secondary_spread 0
-set g_balance_oknex_switchdelay_drop 0.2
-set g_balance_oknex_switchdelay_raise 0.2
-set g_balance_oknex_weaponreplace ""
-set g_balance_oknex_weaponstart 0
-set g_balance_oknex_weaponstartoverride -1
-set g_balance_oknex_weaponthrowable 1
-// }}}
-// {{{ #24: Overkill Rocket Propelled Chainsaw (MUTATOR WEAPON)
-set g_balance_okrpc_primary_ammo 10
-set g_balance_okrpc_primary_animtime 1
-set g_balance_okrpc_primary_damage 150
-set g_balance_okrpc_primary_damage2 500
-set g_balance_okrpc_primary_damageforcescale 2
-set g_balance_okrpc_primary_edgedamage 50
-set g_balance_okrpc_primary_force 400
-set g_balance_okrpc_primary_health 25
-set g_balance_okrpc_primary_lifetime 30
-set g_balance_okrpc_primary_radius 300
-set g_balance_okrpc_primary_refire 1
-set g_balance_okrpc_primary_speed 2500
-set g_balance_okrpc_primary_speedaccel 5000
-set g_balance_okrpc_reload_ammo 10
-set g_balance_okrpc_reload_time 1
-set g_balance_okrpc_secondary_ammo 0
-set g_balance_okrpc_secondary_animtime 0.2
-set g_balance_okrpc_secondary_damage 25
-set g_balance_okrpc_secondary_delay 0
-set g_balance_okrpc_secondary_edgedamage 12.5
-set g_balance_okrpc_secondary_force 360
-set g_balance_okrpc_secondary_force_zscale 1
-set g_balance_okrpc_secondary_lifetime 5
-set g_balance_okrpc_secondary_radius 70
-set g_balance_okrpc_secondary_refire 0.7
-set g_balance_okrpc_secondary_refire_type 1
-set g_balance_okrpc_secondary_shotangle 0
-set g_balance_okrpc_secondary_speed 6000
-set g_balance_okrpc_secondary_spread 0
-set g_balance_okrpc_switchdelay_drop 0.2
-set g_balance_okrpc_switchdelay_raise 0.2
-set g_balance_okrpc_weaponreplace ""
-set g_balance_okrpc_weaponstart 0
-set g_balance_okrpc_weaponstartoverride 0
-set g_balance_okrpc_weaponthrowable 0
-// }}}
-// {{{ #25: Overkill Shotgun (MUTATOR WEAPON)
-set g_balance_okshotgun_primary_ammo 3
-set g_balance_okshotgun_primary_animtime 0.65
-set g_balance_okshotgun_primary_bot_range 512
-set g_balance_okshotgun_primary_bullets 10
-set g_balance_okshotgun_primary_damage 17
-set g_balance_okshotgun_primary_force 80
-set g_balance_okshotgun_primary_refire 0.75
-set g_balance_okshotgun_primary_solidpenetration 3.8
-set g_balance_okshotgun_primary_spread 0.07
-set g_balance_okshotgun_reload_ammo 24
-set g_balance_okshotgun_reload_time 2
-set g_balance_okshotgun_secondary_animtime 0.2
-set g_balance_okshotgun_secondary_damage 25
-set g_balance_okshotgun_secondary_delay 0
-set g_balance_okshotgun_secondary_edgedamage 12.5
-set g_balance_okshotgun_secondary_force 360
-set g_balance_okshotgun_secondary_force_zscale 1
-set g_balance_okshotgun_secondary_lifetime 5
-set g_balance_okshotgun_secondary_radius 70
-set g_balance_okshotgun_secondary_refire 0.7
-set g_balance_okshotgun_secondary_refire_type 1
-set g_balance_okshotgun_secondary_shotangle 0
-set g_balance_okshotgun_secondary_speed 6000
-set g_balance_okshotgun_secondary_spread 0
-set g_balance_okshotgun_switchdelay_drop 0.2
-set g_balance_okshotgun_switchdelay_raise 0.2
-set g_balance_okshotgun_weaponreplace ""
-set g_balance_okshotgun_weaponstart 0
-set g_balance_okshotgun_weaponstartoverride -1
-set g_balance_okshotgun_weaponthrowable 1
-// }}}
index 1fe4044cab7f25ce1e1a624e1c895680224ed668..ec8029c74bf28647cae83bf57d806178f6120640 100644 (file)
@@ -191,9 +191,13 @@ set g_balance_electro_primary_damage 40
 set g_balance_electro_primary_edgedamage 20
 set g_balance_electro_primary_force 200
 set g_balance_electro_primary_lifetime 5
+set g_balance_electro_primary_midaircombo_enemy 1
 set g_balance_electro_primary_midaircombo_explode 1
 set g_balance_electro_primary_midaircombo_interval 0.1
+set g_balance_electro_primary_midaircombo_own 1
 set g_balance_electro_primary_midaircombo_radius 100
+set g_balance_electro_primary_midaircombo_speed 2000
+set g_balance_electro_primary_midaircombo_teammate 1
 set g_balance_electro_primary_radius 100
 set g_balance_electro_primary_refire 0.6
 set g_balance_electro_primary_speed 2500
index 52d63dfa2bbcd26332d1d551b05778f8a536cd67..c38ea832f3e2c53576a9cd2d9c15538d81ca1633 100644 (file)
@@ -191,9 +191,13 @@ set g_balance_electro_primary_damage 40
 set g_balance_electro_primary_edgedamage 20
 set g_balance_electro_primary_force 200
 set g_balance_electro_primary_lifetime 5
+set g_balance_electro_primary_midaircombo_enemy 1
 set g_balance_electro_primary_midaircombo_explode 1
 set g_balance_electro_primary_midaircombo_interval 0.1
+set g_balance_electro_primary_midaircombo_own 1
 set g_balance_electro_primary_midaircombo_radius 0
+set g_balance_electro_primary_midaircombo_speed 2000
+set g_balance_electro_primary_midaircombo_teammate 1
 set g_balance_electro_primary_radius 100
 set g_balance_electro_primary_refire 0.6
 set g_balance_electro_primary_speed 2500
@@ -243,7 +247,7 @@ set g_balance_crylink_primary_joinexplode_edgedamage 0
 set g_balance_crylink_primary_joinexplode_force 0
 set g_balance_crylink_primary_joinexplode_radius 0
 set g_balance_crylink_primary_joinspread 0.2
-set g_balance_crylink_primary_linkexplode 0
+set g_balance_crylink_primary_linkexplode 1
 set g_balance_crylink_primary_middle_fadetime 5
 set g_balance_crylink_primary_middle_lifetime 5
 set g_balance_crylink_primary_other_fadetime 5
diff --git a/bal-wep-xpm.cfg b/bal-wep-xpm.cfg
deleted file mode 100644 (file)
index 9174311..0000000
+++ /dev/null
@@ -1,970 +0,0 @@
-// {{{ #1: Blaster
-set g_balance_blaster_primary_animtime 0.2
-set g_balance_blaster_primary_damage 20
-set g_balance_blaster_primary_delay 0
-set g_balance_blaster_primary_edgedamage 10
-set g_balance_blaster_primary_force 375
-set g_balance_blaster_primary_force_zscale 1
-set g_balance_blaster_primary_lifetime 5
-set g_balance_blaster_primary_radius 60
-set g_balance_blaster_primary_refire 0.7
-set g_balance_blaster_primary_shotangle 0
-set g_balance_blaster_primary_speed 6000
-set g_balance_blaster_primary_spread 0
-set g_balance_blaster_secondary 0
-set g_balance_blaster_secondary_animtime 0.2
-set g_balance_blaster_secondary_damage 25
-set g_balance_blaster_secondary_delay 0
-set g_balance_blaster_secondary_edgedamage 12.5
-set g_balance_blaster_secondary_force 360
-set g_balance_blaster_secondary_force_zscale 1
-set g_balance_blaster_secondary_lifetime 5
-set g_balance_blaster_secondary_radius 70
-set g_balance_blaster_secondary_refire 0.7
-set g_balance_blaster_secondary_shotangle 0
-set g_balance_blaster_secondary_speed 6000
-set g_balance_blaster_secondary_spread 0
-set g_balance_blaster_switchdelay_drop 0.2
-set g_balance_blaster_switchdelay_raise 0.2
-set g_balance_blaster_weaponreplace ""
-set g_balance_blaster_weaponstart 1
-set g_balance_blaster_weaponstartoverride -1
-set g_balance_blaster_weaponthrowable 0
-// }}}
-// {{{ #2: Shotgun
-set g_balance_shotgun_primary_ammo 1
-set g_balance_shotgun_primary_animtime 0.2
-set g_balance_shotgun_primary_bullets 12
-set g_balance_shotgun_primary_damage 4
-set g_balance_shotgun_primary_force 15
-set g_balance_shotgun_primary_refire 0.75
-set g_balance_shotgun_primary_solidpenetration 3.8
-set g_balance_shotgun_primary_spread 0.12
-set g_balance_shotgun_reload_ammo 0
-set g_balance_shotgun_reload_time 2
-set g_balance_shotgun_secondary 1
-set g_balance_shotgun_secondary_alt_animtime 0.2
-set g_balance_shotgun_secondary_alt_refire 1.2
-set g_balance_shotgun_secondary_animtime 1.15
-set g_balance_shotgun_secondary_damage 70
-set g_balance_shotgun_secondary_force 200
-set g_balance_shotgun_secondary_melee_delay 0.25
-set g_balance_shotgun_secondary_melee_multihit 1
-set g_balance_shotgun_secondary_melee_no_doubleslap 1
-set g_balance_shotgun_secondary_melee_nonplayerdamage 40
-set g_balance_shotgun_secondary_melee_range 120
-set g_balance_shotgun_secondary_melee_swing_side 120
-set g_balance_shotgun_secondary_melee_swing_up 30
-set g_balance_shotgun_secondary_melee_time 0.15
-set g_balance_shotgun_secondary_melee_traces 10
-set g_balance_shotgun_secondary_refire 1.25
-set g_balance_shotgun_switchdelay_drop 0.2
-set g_balance_shotgun_switchdelay_raise 0.2
-set g_balance_shotgun_weaponreplace ""
-set g_balance_shotgun_weaponstart 1
-set g_balance_shotgun_weaponstartoverride -1
-set g_balance_shotgun_weaponthrowable 1
-// }}}
-// {{{ #3: MachineGun
-set g_balance_machinegun_burst 3
-set g_balance_machinegun_burst_ammo 3
-set g_balance_machinegun_burst_animtime 0.3
-set g_balance_machinegun_burst_refire 0.06
-set g_balance_machinegun_burst_refire2 0.45
-set g_balance_machinegun_burst_spread 0
-set g_balance_machinegun_first 1
-set g_balance_machinegun_first_ammo 1
-set g_balance_machinegun_first_damage 14
-set g_balance_machinegun_first_force 3
-set g_balance_machinegun_first_refire 0.125
-set g_balance_machinegun_first_spread 0.03
-set g_balance_machinegun_mode 1
-set g_balance_machinegun_reload_ammo 60
-set g_balance_machinegun_reload_time 2
-set g_balance_machinegun_solidpenetration 13.1
-set g_balance_machinegun_spread_add 0.012
-set g_balance_machinegun_spread_max 0.05
-set g_balance_machinegun_spread_min 0.02
-set g_balance_machinegun_sustained_ammo 1
-set g_balance_machinegun_sustained_damage 10
-set g_balance_machinegun_sustained_force 3
-set g_balance_machinegun_sustained_refire 0.1
-set g_balance_machinegun_sustained_spread 0.03
-set g_balance_machinegun_switchdelay_drop 0.2
-set g_balance_machinegun_switchdelay_raise 0.2
-set g_balance_machinegun_weaponreplace ""
-set g_balance_machinegun_weaponstart 0
-set g_balance_machinegun_weaponstartoverride -1
-set g_balance_machinegun_weaponthrowable 1
-// }}}
-// {{{ #4: Mortar
-set g_balance_mortar_bouncefactor 0.5
-set g_balance_mortar_bouncestop 0.075
-set g_balance_mortar_primary_ammo 2
-set g_balance_mortar_primary_animtime 0.3
-set g_balance_mortar_primary_damage 55
-set g_balance_mortar_primary_damageforcescale 0
-set g_balance_mortar_primary_edgedamage 25
-set g_balance_mortar_primary_force 250
-set g_balance_mortar_primary_health 15
-set g_balance_mortar_primary_lifetime 5
-set g_balance_mortar_primary_lifetime_stick 0
-set g_balance_mortar_primary_radius 120
-set g_balance_mortar_primary_refire 0.8
-set g_balance_mortar_primary_remote_minbouncecnt 0
-set g_balance_mortar_primary_speed 1900
-set g_balance_mortar_primary_speed_up 225
-set g_balance_mortar_primary_speed_z 0
-set g_balance_mortar_primary_spread 0
-set g_balance_mortar_primary_type 0
-set g_balance_mortar_reload_ammo 0
-set g_balance_mortar_reload_time 2
-set g_balance_mortar_secondary_ammo 2
-set g_balance_mortar_secondary_animtime 0.3
-set g_balance_mortar_secondary_damage 55
-set g_balance_mortar_secondary_damageforcescale 4
-set g_balance_mortar_secondary_edgedamage 30
-set g_balance_mortar_secondary_force 250
-set g_balance_mortar_secondary_health 30
-set g_balance_mortar_secondary_lifetime 5
-set g_balance_mortar_secondary_lifetime_bounce 0.5
-set g_balance_mortar_secondary_lifetime_stick 0
-set g_balance_mortar_secondary_radius 120
-set g_balance_mortar_secondary_refire 0.7
-set g_balance_mortar_secondary_remote_detonateprimary 0
-set g_balance_mortar_secondary_speed 1400
-set g_balance_mortar_secondary_speed_up 150
-set g_balance_mortar_secondary_speed_z 0
-set g_balance_mortar_secondary_spread 0
-set g_balance_mortar_secondary_type 1
-set g_balance_mortar_switchdelay_drop 0.2
-set g_balance_mortar_switchdelay_raise 0.2
-set g_balance_mortar_weaponreplace ""
-set g_balance_mortar_weaponstart 0
-set g_balance_mortar_weaponstartoverride -1
-set g_balance_mortar_weaponthrowable 1
-// }}}
-// {{{ #5: Mine Layer (MUTATOR WEAPON)
-set g_balance_minelayer_ammo 4
-set g_balance_minelayer_animtime 0.4
-set g_balance_minelayer_damage 40
-set g_balance_minelayer_damageforcescale 0
-set g_balance_minelayer_detonatedelay -1
-set g_balance_minelayer_edgedamage 20
-set g_balance_minelayer_force 250
-set g_balance_minelayer_health 15
-set g_balance_minelayer_lifetime 10
-set g_balance_minelayer_lifetime_countdown 0.5
-set g_balance_minelayer_limit 3
-set g_balance_minelayer_protection 0
-set g_balance_minelayer_proximityradius 150
-set g_balance_minelayer_radius 175
-set g_balance_minelayer_refire 1.5
-set g_balance_minelayer_reload_ammo 0
-set g_balance_minelayer_reload_time 2
-set g_balance_minelayer_remote_damage 45
-set g_balance_minelayer_remote_edgedamage 40
-set g_balance_minelayer_remote_force 300
-set g_balance_minelayer_remote_radius 200
-set g_balance_minelayer_speed 1000
-set g_balance_minelayer_switchdelay_drop 0.2
-set g_balance_minelayer_switchdelay_raise 0.2
-set g_balance_minelayer_time 0.5
-set g_balance_minelayer_weaponreplace ""
-set g_balance_minelayer_weaponstart 0
-set g_balance_minelayer_weaponstartoverride -1
-set g_balance_minelayer_weaponthrowable 1
-// }}}
-// {{{ #6: Electro
-set g_balance_electro_combo_comboradius 300
-set g_balance_electro_combo_comboradius_thruwall 200
-set g_balance_electro_combo_damage 50
-set g_balance_electro_combo_edgedamage 25
-set g_balance_electro_combo_force 120
-set g_balance_electro_combo_radius 150
-set g_balance_electro_combo_safeammocheck 1
-set g_balance_electro_combo_speed 2000
-set g_balance_electro_primary_ammo 4
-set g_balance_electro_primary_animtime 0.3
-set g_balance_electro_primary_comboradius 300
-set g_balance_electro_primary_damage 40
-set g_balance_electro_primary_edgedamage 20
-set g_balance_electro_primary_force 200
-set g_balance_electro_primary_lifetime 5
-set g_balance_electro_primary_midaircombo_explode 1
-set g_balance_electro_primary_midaircombo_interval 0.1
-set g_balance_electro_primary_midaircombo_radius 0
-set g_balance_electro_primary_radius 100
-set g_balance_electro_primary_refire 0.6
-set g_balance_electro_primary_speed 2500
-set g_balance_electro_primary_spread 0
-set g_balance_electro_reload_ammo 0
-set g_balance_electro_reload_time 2
-set g_balance_electro_secondary_ammo 2
-set g_balance_electro_secondary_animtime 0.2
-set g_balance_electro_secondary_bouncefactor 0.3
-set g_balance_electro_secondary_bouncestop 0.05
-set g_balance_electro_secondary_count 3
-set g_balance_electro_secondary_damage 30
-set g_balance_electro_secondary_damagedbycontents 1
-set g_balance_electro_secondary_damageforcescale 4
-set g_balance_electro_secondary_edgedamage 15
-set g_balance_electro_secondary_force 50
-set g_balance_electro_secondary_health 5
-set g_balance_electro_secondary_lifetime 4
-set g_balance_electro_secondary_radius 150
-set g_balance_electro_secondary_refire 0.2
-set g_balance_electro_secondary_refire2 1.6
-set g_balance_electro_secondary_speed 1000
-set g_balance_electro_secondary_speed_up 200
-set g_balance_electro_secondary_speed_z 0
-set g_balance_electro_secondary_spread 0
-set g_balance_electro_secondary_stick 0
-set g_balance_electro_secondary_touchexplode 1
-set g_balance_electro_switchdelay_drop 0.2
-set g_balance_electro_switchdelay_raise 0.2
-set g_balance_electro_weaponreplace ""
-set g_balance_electro_weaponstart 0
-set g_balance_electro_weaponstartoverride -1
-set g_balance_electro_weaponthrowable 1
-// }}}
-// {{{ #7: Crylink
-set g_balance_crylink_primary_ammo 3
-set g_balance_crylink_primary_animtime 0.3
-set g_balance_crylink_primary_bouncedamagefactor 0.5
-set g_balance_crylink_primary_bounces 1
-set g_balance_crylink_primary_damage 10
-set g_balance_crylink_primary_edgedamage 5
-set g_balance_crylink_primary_force -50
-set g_balance_crylink_primary_joindelay 0.1
-set g_balance_crylink_primary_joinexplode 1
-set g_balance_crylink_primary_joinexplode_damage 0
-set g_balance_crylink_primary_joinexplode_edgedamage 0
-set g_balance_crylink_primary_joinexplode_force 0
-set g_balance_crylink_primary_joinexplode_radius 0
-set g_balance_crylink_primary_joinspread 0.2
-set g_balance_crylink_primary_linkexplode 0
-set g_balance_crylink_primary_middle_fadetime 5
-set g_balance_crylink_primary_middle_lifetime 5
-set g_balance_crylink_primary_other_fadetime 5
-set g_balance_crylink_primary_other_lifetime 5
-set g_balance_crylink_primary_radius 80
-set g_balance_crylink_primary_refire 0.7
-set g_balance_crylink_primary_shots 6
-set g_balance_crylink_primary_speed 2000
-set g_balance_crylink_primary_spread 0.08
-set g_balance_crylink_reload_ammo 0
-set g_balance_crylink_reload_time 2
-set g_balance_crylink_secondary 1
-set g_balance_crylink_secondary_ammo 3
-set g_balance_crylink_secondary_animtime 0.2
-set g_balance_crylink_secondary_bouncedamagefactor 0.5
-set g_balance_crylink_secondary_bounces 0
-set g_balance_crylink_secondary_damage 8
-set g_balance_crylink_secondary_edgedamage 4
-set g_balance_crylink_secondary_force -200
-set g_balance_crylink_secondary_joindelay 0
-set g_balance_crylink_secondary_joinexplode 0
-set g_balance_crylink_secondary_joinexplode_damage 0
-set g_balance_crylink_secondary_joinexplode_edgedamage 0
-set g_balance_crylink_secondary_joinexplode_force 0
-set g_balance_crylink_secondary_joinexplode_radius 0
-set g_balance_crylink_secondary_joinspread 0
-set g_balance_crylink_secondary_linkexplode 1
-set g_balance_crylink_secondary_middle_fadetime 5
-set g_balance_crylink_secondary_middle_lifetime 5
-set g_balance_crylink_secondary_other_fadetime 5
-set g_balance_crylink_secondary_other_lifetime 5
-set g_balance_crylink_secondary_radius 100
-set g_balance_crylink_secondary_refire 0.7
-set g_balance_crylink_secondary_shots 5
-set g_balance_crylink_secondary_speed 3000
-set g_balance_crylink_secondary_spread 0.01
-set g_balance_crylink_secondary_spreadtype 1
-set g_balance_crylink_switchdelay_drop 0.2
-set g_balance_crylink_switchdelay_raise 0.2
-set g_balance_crylink_weaponreplace ""
-set g_balance_crylink_weaponstart 0
-set g_balance_crylink_weaponstartoverride -1
-set g_balance_crylink_weaponthrowable 1
-// }}}
-// {{{ #8: Vortex
-set g_balance_vortex_charge 1
-set g_balance_vortex_charge_always 0
-set g_balance_vortex_charge_animlimit 0.5
-set g_balance_vortex_charge_limit 1
-set g_balance_vortex_charge_maxspeed 800
-set g_balance_vortex_charge_mindmg 40
-set g_balance_vortex_charge_minspeed 400
-set g_balance_vortex_charge_rate 0.6
-set g_balance_vortex_charge_rot_pause 0
-set g_balance_vortex_charge_rot_rate 0
-set g_balance_vortex_charge_shot_multiplier 0
-set g_balance_vortex_charge_start 0.5
-set g_balance_vortex_charge_velocity_rate 0
-set g_balance_vortex_primary_ammo 6
-set g_balance_vortex_primary_animtime 0.4
-set g_balance_vortex_primary_armorpierce 0
-set g_balance_vortex_primary_damage 80
-set g_balance_vortex_primary_damagefalloff_forcehalflife 0
-set g_balance_vortex_primary_damagefalloff_halflife 0
-set g_balance_vortex_primary_damagefalloff_maxdist 0
-set g_balance_vortex_primary_damagefalloff_mindist 0
-set g_balance_vortex_primary_force 400
-set g_balance_vortex_primary_refire 1.5
-set g_balance_vortex_reload_ammo 0
-set g_balance_vortex_reload_time 2
-set g_balance_vortex_secondary 0
-set g_balance_vortex_secondary_ammo 2
-set g_balance_vortex_secondary_animtime 0
-set g_balance_vortex_secondary_armorpierce 0
-set g_balance_vortex_secondary_chargepool 0
-set g_balance_vortex_secondary_chargepool_pause_regen 1
-set g_balance_vortex_secondary_chargepool_regen 0.15
-set g_balance_vortex_secondary_damage 0
-set g_balance_vortex_secondary_damagefalloff_forcehalflife 0
-set g_balance_vortex_secondary_damagefalloff_halflife 0
-set g_balance_vortex_secondary_damagefalloff_maxdist 0
-set g_balance_vortex_secondary_damagefalloff_mindist 0
-set g_balance_vortex_secondary_force 0
-set g_balance_vortex_secondary_refire 0
-set g_balance_vortex_switchdelay_drop 0.2
-set g_balance_vortex_switchdelay_raise 0.2
-set g_balance_vortex_weaponreplace ""
-set g_balance_vortex_weaponstart 0
-set g_balance_vortex_weaponstartoverride -1
-set g_balance_vortex_weaponthrowable 1
-// }}}
-// {{{ #9: Hagar
-set g_balance_hagar_primary_ammo 1
-set g_balance_hagar_primary_damage 25
-set g_balance_hagar_primary_damageforcescale 0
-set g_balance_hagar_primary_edgedamage 12.5
-set g_balance_hagar_primary_force 100
-set g_balance_hagar_primary_health 15
-set g_balance_hagar_primary_lifetime 5
-set g_balance_hagar_primary_radius 65
-set g_balance_hagar_primary_refire 0.16667
-set g_balance_hagar_primary_speed 2200
-set g_balance_hagar_primary_spread 0
-set g_balance_hagar_reload_ammo 0
-set g_balance_hagar_reload_time 2
-set g_balance_hagar_secondary 1
-set g_balance_hagar_secondary_ammo 1
-set g_balance_hagar_secondary_damage 35
-set g_balance_hagar_secondary_damageforcescale 0
-set g_balance_hagar_secondary_edgedamage 17.5
-set g_balance_hagar_secondary_force 75
-set g_balance_hagar_secondary_health 15
-set g_balance_hagar_secondary_lifetime_min 10
-set g_balance_hagar_secondary_lifetime_rand 0
-set g_balance_hagar_secondary_load 1
-set g_balance_hagar_secondary_load_abort 1
-set g_balance_hagar_secondary_load_animtime 0.2
-set g_balance_hagar_secondary_load_hold 4
-set g_balance_hagar_secondary_load_linkexplode 0
-set g_balance_hagar_secondary_load_max 4
-set g_balance_hagar_secondary_load_releasedeath 0
-set g_balance_hagar_secondary_load_speed 0.5
-set g_balance_hagar_secondary_load_spread 0.075
-set g_balance_hagar_secondary_load_spread_bias 0.5
-set g_balance_hagar_secondary_radius 80
-set g_balance_hagar_secondary_refire 0.5
-set g_balance_hagar_secondary_speed 2000
-set g_balance_hagar_secondary_spread 0
-set g_balance_hagar_switchdelay_drop 0.2
-set g_balance_hagar_switchdelay_raise 0.2
-set g_balance_hagar_weaponreplace ""
-set g_balance_hagar_weaponstart 0
-set g_balance_hagar_weaponstartoverride -1
-set g_balance_hagar_weaponthrowable 1
-// }}}
-// {{{ #10: Devastator
-set g_balance_devastator_ammo 4
-set g_balance_devastator_animtime 0.4
-set g_balance_devastator_damage 80
-set g_balance_devastator_damageforcescale 1
-set g_balance_devastator_detonatedelay 0.02
-set g_balance_devastator_edgedamage 40
-set g_balance_devastator_force 400
-set g_balance_devastator_guidedelay 0.2
-set g_balance_devastator_guidegoal 512
-set g_balance_devastator_guiderate 90
-set g_balance_devastator_guideratedelay 0.01
-set g_balance_devastator_guidestop 0
-set g_balance_devastator_health 30
-set g_balance_devastator_lifetime 10
-set g_balance_devastator_radius 110
-set g_balance_devastator_refire 1.1
-set g_balance_devastator_reload_ammo 0
-set g_balance_devastator_reload_time 2
-set g_balance_devastator_remote_damage 70
-set g_balance_devastator_remote_edgedamage 35
-set g_balance_devastator_remote_force 300
-set g_balance_devastator_remote_jump 0
-set g_balance_devastator_remote_jump_damage 70
-set g_balance_devastator_remote_jump_force 450
-set g_balance_devastator_remote_jump_radius 100
-set g_balance_devastator_remote_jump_velocity_z_add 0
-set g_balance_devastator_remote_jump_velocity_z_max 1500
-set g_balance_devastator_remote_jump_velocity_z_min 400
-set g_balance_devastator_remote_radius 110
-set g_balance_devastator_speed 1300
-set g_balance_devastator_speedaccel 1300
-set g_balance_devastator_speedstart 1000
-set g_balance_devastator_switchdelay_drop 0.2
-set g_balance_devastator_switchdelay_raise 0.2
-set g_balance_devastator_weaponreplace ""
-set g_balance_devastator_weaponstart 0
-set g_balance_devastator_weaponstartoverride -1
-set g_balance_devastator_weaponthrowable 1
-// }}}
-// {{{ #11: Port-O-Launch
-set g_balance_porto_primary_animtime 0.3
-set g_balance_porto_primary_lifetime 5
-set g_balance_porto_primary_refire 1.5
-set g_balance_porto_primary_speed 1000
-set g_balance_porto_secondary 1
-set g_balance_porto_secondary_animtime 0.3
-set g_balance_porto_secondary_lifetime 5
-set g_balance_porto_secondary_refire 1.5
-set g_balance_porto_secondary_speed 1000
-set g_balance_porto_switchdelay_drop 0.2
-set g_balance_porto_switchdelay_raise 0.2
-set g_balance_porto_weaponreplace ""
-set g_balance_porto_weaponstart 0
-set g_balance_porto_weaponstartoverride -1
-set g_balance_porto_weaponthrowable 1
-// }}}
-// {{{ #12: Vaporizer
-set g_balance_vaporizer_primary_ammo 10
-set g_balance_vaporizer_primary_animtime 0.3
-set g_balance_vaporizer_primary_damage 150
-set g_balance_vaporizer_primary_force 800
-set g_balance_vaporizer_primary_refire 1
-set g_balance_vaporizer_reload_ammo 0
-set g_balance_vaporizer_reload_time 0
-set g_balance_vaporizer_secondary_ammo 0
-set g_balance_vaporizer_secondary_animtime 0.2
-set g_balance_vaporizer_secondary_damage 25
-set g_balance_vaporizer_secondary_delay 0
-set g_balance_vaporizer_secondary_edgedamage 12.5
-set g_balance_vaporizer_secondary_force 480
-set g_balance_vaporizer_secondary_force_zscale 1
-set g_balance_vaporizer_secondary_lifetime 5
-set g_balance_vaporizer_secondary_radius 70
-set g_balance_vaporizer_secondary_refire 0.7
-set g_balance_vaporizer_secondary_shotangle 0
-set g_balance_vaporizer_secondary_speed 6000
-set g_balance_vaporizer_secondary_spread 0
-set g_balance_vaporizer_switchdelay_drop 0.2
-set g_balance_vaporizer_switchdelay_raise 0.2
-set g_balance_vaporizer_weaponreplace ""
-set g_balance_vaporizer_weaponstart 0
-set g_balance_vaporizer_weaponstartoverride -1
-set g_balance_vaporizer_weaponthrowable 1
-// }}}
-// {{{ #13: Grappling Hook
-set g_balance_hook_primary_ammo 5
-set g_balance_hook_primary_animtime 0.3
-set g_balance_hook_primary_hooked_ammo 5
-set g_balance_hook_primary_hooked_time_free 2
-set g_balance_hook_primary_hooked_time_max 0
-set g_balance_hook_primary_refire 0.2
-set g_balance_hook_secondary_animtime 0.3
-set g_balance_hook_secondary_damage 25
-set g_balance_hook_secondary_damageforcescale 0
-set g_balance_hook_secondary_duration 1.5
-set g_balance_hook_secondary_edgedamage 5
-set g_balance_hook_secondary_force -2000
-set g_balance_hook_secondary_gravity 5
-set g_balance_hook_secondary_health 15
-set g_balance_hook_secondary_lifetime 5
-set g_balance_hook_secondary_power 3
-set g_balance_hook_secondary_radius 500
-set g_balance_hook_secondary_refire 3
-set g_balance_hook_secondary_speed 0
-set g_balance_hook_switchdelay_drop 0.2
-set g_balance_hook_switchdelay_raise 0.2
-set g_balance_hook_weaponreplace ""
-set g_balance_hook_weaponstart 0
-set g_balance_hook_weaponstartoverride -1
-set g_balance_hook_weaponthrowable 1
-// }}}
-// {{{ #14: Heavy Laser Assault Cannon (MUTATOR WEAPON)
-set g_balance_hlac_primary_ammo 1
-set g_balance_hlac_primary_animtime 0.4
-set g_balance_hlac_primary_damage 18
-set g_balance_hlac_primary_edgedamage 9
-set g_balance_hlac_primary_force 90
-set g_balance_hlac_primary_lifetime 5
-set g_balance_hlac_primary_radius 70
-set g_balance_hlac_primary_refire 0.15
-set g_balance_hlac_primary_speed 9000
-set g_balance_hlac_primary_spread_add 0.0045
-set g_balance_hlac_primary_spread_crouchmod 0.25
-set g_balance_hlac_primary_spread_max 0.25
-set g_balance_hlac_primary_spread_min 0.01
-set g_balance_hlac_reload_ammo 0
-set g_balance_hlac_reload_time 2
-set g_balance_hlac_secondary 1
-set g_balance_hlac_secondary_ammo 10
-set g_balance_hlac_secondary_animtime 0.3
-set g_balance_hlac_secondary_damage 15
-set g_balance_hlac_secondary_edgedamage 7.5
-set g_balance_hlac_secondary_force 90
-set g_balance_hlac_secondary_lifetime 5
-set g_balance_hlac_secondary_radius 70
-set g_balance_hlac_secondary_refire 1
-set g_balance_hlac_secondary_shots 6
-set g_balance_hlac_secondary_speed 9000
-set g_balance_hlac_secondary_spread 0.15
-set g_balance_hlac_secondary_spread_crouchmod 0.5
-set g_balance_hlac_switchdelay_drop 0.2
-set g_balance_hlac_switchdelay_raise 0.2
-set g_balance_hlac_weaponreplace ""
-set g_balance_hlac_weaponstart 0
-set g_balance_hlac_weaponstartoverride -1
-set g_balance_hlac_weaponthrowable 1
-// }}}
-// {{{ #15: @!#%'n Tuba
-set g_balance_tuba_animtime 0.05
-set g_balance_tuba_attenuation 0.5
-set g_balance_tuba_damage 5
-set g_balance_tuba_edgedamage 0
-set g_balance_tuba_fadetime 0.25
-set g_balance_tuba_force 40
-set g_balance_tuba_pitchstep 6
-set g_balance_tuba_radius 200
-set g_balance_tuba_refire 0.05
-set g_balance_tuba_switchdelay_drop 0.2
-set g_balance_tuba_switchdelay_raise 0.2
-set g_balance_tuba_volume 1
-set g_balance_tuba_weaponreplace ""
-set g_balance_tuba_weaponstart 0
-set g_balance_tuba_weaponstartoverride -1
-set g_balance_tuba_weaponthrowable 1
-// }}}
-// {{{ #16: Rifle (MUTATOR WEAPON)
-set g_balance_rifle_bursttime 0
-set g_balance_rifle_primary_ammo 10
-set g_balance_rifle_primary_animtime 0.4
-set g_balance_rifle_primary_bullethail 0
-set g_balance_rifle_primary_burstcost 0
-set g_balance_rifle_primary_damage 80
-set g_balance_rifle_primary_force 100
-set g_balance_rifle_primary_refire 1.2
-set g_balance_rifle_primary_shots 1
-set g_balance_rifle_primary_solidpenetration 62.2
-set g_balance_rifle_primary_spread 0
-set g_balance_rifle_primary_tracer 1
-set g_balance_rifle_reload_ammo 80
-set g_balance_rifle_reload_time 2
-set g_balance_rifle_secondary 1
-set g_balance_rifle_secondary_ammo 10
-set g_balance_rifle_secondary_animtime 0.3
-set g_balance_rifle_secondary_bullethail 0
-set g_balance_rifle_secondary_burstcost 0
-set g_balance_rifle_secondary_damage 20
-set g_balance_rifle_secondary_force 50
-set g_balance_rifle_secondary_refire 0.9
-set g_balance_rifle_secondary_reload 0
-set g_balance_rifle_secondary_shots 4
-set g_balance_rifle_secondary_solidpenetration 15.5
-set g_balance_rifle_secondary_spread 0.04
-set g_balance_rifle_secondary_tracer 0
-set g_balance_rifle_switchdelay_drop 0.2
-set g_balance_rifle_switchdelay_raise 0.2
-set g_balance_rifle_weaponreplace ""
-set g_balance_rifle_weaponstart 0
-set g_balance_rifle_weaponstartoverride -1
-set g_balance_rifle_weaponthrowable 1
-// }}}
-// {{{ #17: Fireball
-set g_balance_fireball_primary_animtime 0.4
-set g_balance_fireball_primary_bfgdamage 100
-set g_balance_fireball_primary_bfgforce 0
-set g_balance_fireball_primary_bfgradius 1000
-set g_balance_fireball_primary_damage 200
-set g_balance_fireball_primary_damageforcescale 0
-set g_balance_fireball_primary_edgedamage 50
-set g_balance_fireball_primary_force 600
-set g_balance_fireball_primary_health 0
-set g_balance_fireball_primary_laserburntime 0.5
-set g_balance_fireball_primary_laserdamage 80
-set g_balance_fireball_primary_laseredgedamage 20
-set g_balance_fireball_primary_laserradius 256
-set g_balance_fireball_primary_lifetime 15
-set g_balance_fireball_primary_radius 200
-set g_balance_fireball_primary_refire 2
-set g_balance_fireball_primary_refire2 0
-set g_balance_fireball_primary_speed 1200
-set g_balance_fireball_primary_spread 0
-set g_balance_fireball_secondary_animtime 0.3
-set g_balance_fireball_secondary_damage 40
-set g_balance_fireball_secondary_damageforcescale 4
-set g_balance_fireball_secondary_damagetime 5
-set g_balance_fireball_secondary_laserburntime 0.5
-set g_balance_fireball_secondary_laserdamage 50
-set g_balance_fireball_secondary_laseredgedamage 20
-set g_balance_fireball_secondary_laserradius 110
-set g_balance_fireball_secondary_lifetime 7
-set g_balance_fireball_secondary_refire 1.5
-set g_balance_fireball_secondary_speed 900
-set g_balance_fireball_secondary_speed_up 100
-set g_balance_fireball_secondary_speed_z 0
-set g_balance_fireball_secondary_spread 0
-set g_balance_fireball_switchdelay_drop 0.2
-set g_balance_fireball_switchdelay_raise 0.2
-set g_balance_fireball_weaponreplace ""
-set g_balance_fireball_weaponstart 0
-set g_balance_fireball_weaponstartoverride -1
-set g_balance_fireball_weaponthrowable 0
-// }}}
-// {{{ #18: T.A.G. Seeker (MUTATOR WEAPON)
-set g_balance_seeker_flac_ammo 1
-set g_balance_seeker_flac_animtime 0.1
-set g_balance_seeker_flac_damage 15
-set g_balance_seeker_flac_edgedamage 10
-set g_balance_seeker_flac_force 50
-set g_balance_seeker_flac_lifetime 0.1
-set g_balance_seeker_flac_lifetime_rand 0.05
-set g_balance_seeker_flac_radius 100
-set g_balance_seeker_flac_refire 0.1
-set g_balance_seeker_flac_speed 3000
-set g_balance_seeker_flac_speed_up 1000
-set g_balance_seeker_flac_speed_z 0
-set g_balance_seeker_flac_spread 0.4
-set g_balance_seeker_missile_accel 1400
-set g_balance_seeker_missile_ammo 2
-set g_balance_seeker_missile_animtime 0.2
-set g_balance_seeker_missile_count 3
-set g_balance_seeker_missile_damage 30
-set g_balance_seeker_missile_damageforcescale 4
-set g_balance_seeker_missile_decel 1400
-set g_balance_seeker_missile_delay 0.25
-set g_balance_seeker_missile_edgedamage 10
-set g_balance_seeker_missile_force 150
-set g_balance_seeker_missile_health 5
-set g_balance_seeker_missile_lifetime 15
-set g_balance_seeker_missile_proxy 0
-set g_balance_seeker_missile_proxy_delay 0.2
-set g_balance_seeker_missile_proxy_maxrange 45
-set g_balance_seeker_missile_radius 80
-set g_balance_seeker_missile_refire 0.5
-set g_balance_seeker_missile_smart 1
-set g_balance_seeker_missile_smart_mindist 800
-set g_balance_seeker_missile_smart_trace_max 2500
-set g_balance_seeker_missile_smart_trace_min 1000
-set g_balance_seeker_missile_speed 700
-set g_balance_seeker_missile_speed_max 1300
-set g_balance_seeker_missile_speed_up 300
-set g_balance_seeker_missile_speed_z 0
-set g_balance_seeker_missile_spread 0
-set g_balance_seeker_missile_turnrate 0.65
-set g_balance_seeker_reload_ammo 0
-set g_balance_seeker_reload_time 2
-set g_balance_seeker_switchdelay_drop 0.2
-set g_balance_seeker_switchdelay_raise 0.2
-set g_balance_seeker_tag_ammo 1
-set g_balance_seeker_tag_animtime 0.2
-set g_balance_seeker_tag_damageforcescale 4
-set g_balance_seeker_tag_health 5
-set g_balance_seeker_tag_lifetime 15
-set g_balance_seeker_tag_refire 0.75
-set g_balance_seeker_tag_speed 5000
-set g_balance_seeker_tag_spread 0
-set g_balance_seeker_tag_tracker_lifetime 10
-set g_balance_seeker_type 0
-set g_balance_seeker_weaponreplace ""
-set g_balance_seeker_weaponstart 0
-set g_balance_seeker_weaponstartoverride -1
-set g_balance_seeker_weaponthrowable 1
-// }}}
-// {{{ #19: Shockwave
-set g_balance_shockwave_blast_animtime 0.3
-set g_balance_shockwave_blast_damage 40
-set g_balance_shockwave_blast_distance 1000
-set g_balance_shockwave_blast_edgedamage 0
-set g_balance_shockwave_blast_force 15
-set g_balance_shockwave_blast_force_forwardbias 50
-set g_balance_shockwave_blast_force_zscale 1
-set g_balance_shockwave_blast_jump_damage 20
-set g_balance_shockwave_blast_jump_edgedamage 0
-set g_balance_shockwave_blast_jump_force 100
-set g_balance_shockwave_blast_jump_force_velocitybias 1
-set g_balance_shockwave_blast_jump_force_zscale 1
-set g_balance_shockwave_blast_jump_multiplier_accuracy 0.5
-set g_balance_shockwave_blast_jump_multiplier_distance 0.5
-set g_balance_shockwave_blast_jump_multiplier_min 0
-set g_balance_shockwave_blast_jump_radius 150
-set g_balance_shockwave_blast_multiplier_accuracy 0.45
-set g_balance_shockwave_blast_multiplier_distance 0.2
-set g_balance_shockwave_blast_multiplier_min 0
-set g_balance_shockwave_blast_refire 0.75
-set g_balance_shockwave_blast_splash_damage 15
-set g_balance_shockwave_blast_splash_edgedamage 0
-set g_balance_shockwave_blast_splash_force 100
-set g_balance_shockwave_blast_splash_force_forwardbias 50
-set g_balance_shockwave_blast_splash_multiplier_accuracy 0.5
-set g_balance_shockwave_blast_splash_multiplier_distance 0.5
-set g_balance_shockwave_blast_splash_multiplier_min 0
-set g_balance_shockwave_blast_splash_radius 70
-set g_balance_shockwave_blast_spread_max 120
-set g_balance_shockwave_blast_spread_min 25
-set g_balance_shockwave_melee_animtime 1.3
-set g_balance_shockwave_melee_damage 80
-set g_balance_shockwave_melee_delay 0.25
-set g_balance_shockwave_melee_force 200
-set g_balance_shockwave_melee_multihit 1
-set g_balance_shockwave_melee_no_doubleslap 1
-set g_balance_shockwave_melee_nonplayerdamage 40
-set g_balance_shockwave_melee_range 120
-set g_balance_shockwave_melee_refire 1.25
-set g_balance_shockwave_melee_swing_side 120
-set g_balance_shockwave_melee_swing_up 30
-set g_balance_shockwave_melee_time 0.15
-set g_balance_shockwave_melee_traces 10
-set g_balance_shockwave_switchdelay_drop 0.2
-set g_balance_shockwave_switchdelay_raise 0.2
-set g_balance_shockwave_weaponreplace ""
-set g_balance_shockwave_weaponstart 0
-set g_balance_shockwave_weaponstartoverride -1
-set g_balance_shockwave_weaponthrowable 0
-// }}}
-// {{{ #20: Arc
-set g_balance_arc_beam_ammo 6
-set g_balance_arc_beam_animtime 0.1
-set g_balance_arc_beam_botaimlifetime 0
-set g_balance_arc_beam_botaimspeed 0
-set g_balance_arc_beam_damage 100
-set g_balance_arc_beam_degreespersegment 1
-set g_balance_arc_beam_distancepersegment 0
-set g_balance_arc_beam_falloff_halflifedist 0
-set g_balance_arc_beam_falloff_maxdist 0
-set g_balance_arc_beam_falloff_mindist 0
-set g_balance_arc_beam_force 600
-set g_balance_arc_beam_healing_amax 0
-set g_balance_arc_beam_healing_aps 50
-set g_balance_arc_beam_healing_hmax 150
-set g_balance_arc_beam_healing_hps 50
-set g_balance_arc_beam_heat 0
-set g_balance_arc_beam_maxangle 10
-set g_balance_arc_beam_nonplayerdamage 80
-set g_balance_arc_beam_range 1000
-set g_balance_arc_beam_refire 0.25
-set g_balance_arc_beam_returnspeed 8
-set g_balance_arc_beam_tightness 0.5
-set g_balance_arc_bolt 0
-set g_balance_arc_bolt_ammo 1
-set g_balance_arc_bolt_damage 25
-set g_balance_arc_bolt_damageforcescale 0
-set g_balance_arc_bolt_edgedamage 12.5
-set g_balance_arc_bolt_force 120
-set g_balance_arc_bolt_health 15
-set g_balance_arc_bolt_lifetime 5
-set g_balance_arc_bolt_radius 65
-set g_balance_arc_bolt_refire 0.16667
-set g_balance_arc_bolt_speed 2300
-set g_balance_arc_bolt_spread 0
-set g_balance_arc_burst_ammo 15
-set g_balance_arc_burst_damage 250
-set g_balance_arc_burst_healing_aps 100
-set g_balance_arc_burst_healing_hps 100
-set g_balance_arc_burst_heat 5
-set g_balance_arc_cooldown 2.5
-set g_balance_arc_cooldown_release 0
-set g_balance_arc_overheat_max 5
-set g_balance_arc_overheat_min 3
-set g_balance_arc_switchdelay_drop 0.2
-set g_balance_arc_switchdelay_raise 0.2
-set g_balance_arc_weaponreplace ""
-set g_balance_arc_weaponstart 0
-set g_balance_arc_weaponstartoverride -1
-set g_balance_arc_weaponthrowable 1
-// }}}
-// {{{ #21: Overkill Heavy Machine Gun (MUTATOR WEAPON)
-set g_balance_okhmg_primary_ammo 1
-set g_balance_okhmg_primary_damage 30
-set g_balance_okhmg_primary_force 10
-set g_balance_okhmg_primary_refire 0.05
-set g_balance_okhmg_primary_solidpenetration 127
-set g_balance_okhmg_primary_spread_add 0.005
-set g_balance_okhmg_primary_spread_max 0.06
-set g_balance_okhmg_primary_spread_min 0.01
-set g_balance_okhmg_reload_ammo 120
-set g_balance_okhmg_reload_time 1
-set g_balance_okhmg_secondary_ammo 0
-set g_balance_okhmg_secondary_animtime 0.2
-set g_balance_okhmg_secondary_damage 25
-set g_balance_okhmg_secondary_delay 0
-set g_balance_okhmg_secondary_edgedamage 12.5
-set g_balance_okhmg_secondary_force 360
-set g_balance_okhmg_secondary_force_zscale 1
-set g_balance_okhmg_secondary_lifetime 5
-set g_balance_okhmg_secondary_radius 70
-set g_balance_okhmg_secondary_refire 0.7
-set g_balance_okhmg_secondary_refire_type 1
-set g_balance_okhmg_secondary_shotangle 0
-set g_balance_okhmg_secondary_speed 6000
-set g_balance_okhmg_secondary_spread 0
-set g_balance_okhmg_switchdelay_drop 0.2
-set g_balance_okhmg_switchdelay_raise 0.2
-set g_balance_okhmg_weaponreplace ""
-set g_balance_okhmg_weaponstart 0
-set g_balance_okhmg_weaponstartoverride 0
-set g_balance_okhmg_weaponthrowable 0
-// }}}
-// {{{ #22: Overkill MachineGun (MUTATOR WEAPON)
-set g_balance_okmachinegun_primary_ammo 1
-set g_balance_okmachinegun_primary_damage 25
-set g_balance_okmachinegun_primary_force 5
-set g_balance_okmachinegun_primary_refire 0.1
-set g_balance_okmachinegun_primary_solidpenetration 100
-set g_balance_okmachinegun_primary_spread_add 0.012
-set g_balance_okmachinegun_primary_spread_max 0.05
-set g_balance_okmachinegun_primary_spread_min 0
-set g_balance_okmachinegun_reload_ammo 30
-set g_balance_okmachinegun_reload_time 1.5
-set g_balance_okmachinegun_secondary_animtime 0.2
-set g_balance_okmachinegun_secondary_damage 25
-set g_balance_okmachinegun_secondary_delay 0
-set g_balance_okmachinegun_secondary_edgedamage 12.5
-set g_balance_okmachinegun_secondary_force 360
-set g_balance_okmachinegun_secondary_force_zscale 1
-set g_balance_okmachinegun_secondary_lifetime 5
-set g_balance_okmachinegun_secondary_radius 70
-set g_balance_okmachinegun_secondary_refire 0.7
-set g_balance_okmachinegun_secondary_refire_type 1
-set g_balance_okmachinegun_secondary_shotangle 0
-set g_balance_okmachinegun_secondary_speed 6000
-set g_balance_okmachinegun_secondary_spread 0
-set g_balance_okmachinegun_switchdelay_drop 0.2
-set g_balance_okmachinegun_switchdelay_raise 0.2
-set g_balance_okmachinegun_weaponreplace ""
-set g_balance_okmachinegun_weaponstart 0
-set g_balance_okmachinegun_weaponstartoverride -1
-set g_balance_okmachinegun_weaponthrowable 1
-// }}}
-// {{{ #23: Overkill Nex (MUTATOR WEAPON)
-set g_balance_oknex_charge 0
-set g_balance_oknex_charge_animlimit 0.5
-set g_balance_oknex_charge_limit 1
-set g_balance_oknex_charge_maxspeed 800
-set g_balance_oknex_charge_mindmg 40
-set g_balance_oknex_charge_minspeed 400
-set g_balance_oknex_charge_rate 0.6
-set g_balance_oknex_charge_rot_pause 0
-set g_balance_oknex_charge_rot_rate 0
-set g_balance_oknex_charge_shot_multiplier 0
-set g_balance_oknex_charge_start 0.5
-set g_balance_oknex_charge_velocity_rate 0
-set g_balance_oknex_primary_ammo 10
-set g_balance_oknex_primary_animtime 0.65
-set g_balance_oknex_primary_damage 100
-set g_balance_oknex_primary_damagefalloff_forcehalflife 0
-set g_balance_oknex_primary_damagefalloff_halflife 0
-set g_balance_oknex_primary_damagefalloff_maxdist 0
-set g_balance_oknex_primary_damagefalloff_mindist 0
-set g_balance_oknex_primary_force 500
-set g_balance_oknex_primary_refire 1
-set g_balance_oknex_reload_ammo 50
-set g_balance_oknex_reload_time 2
-set g_balance_oknex_secondary 2
-set g_balance_oknex_secondary_ammo 0
-set g_balance_oknex_secondary_animtime 0.2
-set g_balance_oknex_secondary_chargepool 0
-set g_balance_oknex_secondary_chargepool_pause_regen 1
-set g_balance_oknex_secondary_chargepool_regen 0.15
-set g_balance_oknex_secondary_damage 25
-set g_balance_oknex_secondary_damagefalloff_forcehalflife 0
-set g_balance_oknex_secondary_damagefalloff_halflife 0
-set g_balance_oknex_secondary_damagefalloff_maxdist 0
-set g_balance_oknex_secondary_damagefalloff_mindist 0
-set g_balance_oknex_secondary_delay 0
-set g_balance_oknex_secondary_edgedamage 12.5
-set g_balance_oknex_secondary_force 360
-set g_balance_oknex_secondary_force_zscale 1
-set g_balance_oknex_secondary_lifetime 5
-set g_balance_oknex_secondary_radius 70
-set g_balance_oknex_secondary_refire 0.7
-set g_balance_oknex_secondary_refire_type 1
-set g_balance_oknex_secondary_shotangle 0
-set g_balance_oknex_secondary_speed 6000
-set g_balance_oknex_secondary_spread 0
-set g_balance_oknex_switchdelay_drop 0.2
-set g_balance_oknex_switchdelay_raise 0.2
-set g_balance_oknex_weaponreplace ""
-set g_balance_oknex_weaponstart 0
-set g_balance_oknex_weaponstartoverride -1
-set g_balance_oknex_weaponthrowable 1
-// }}}
-// {{{ #24: Overkill Rocket Propelled Chainsaw (MUTATOR WEAPON)
-set g_balance_okrpc_primary_ammo 10
-set g_balance_okrpc_primary_animtime 1
-set g_balance_okrpc_primary_damage 150
-set g_balance_okrpc_primary_damage2 500
-set g_balance_okrpc_primary_damageforcescale 2
-set g_balance_okrpc_primary_edgedamage 50
-set g_balance_okrpc_primary_force 400
-set g_balance_okrpc_primary_health 25
-set g_balance_okrpc_primary_lifetime 30
-set g_balance_okrpc_primary_radius 300
-set g_balance_okrpc_primary_refire 1
-set g_balance_okrpc_primary_speed 2500
-set g_balance_okrpc_primary_speedaccel 5000
-set g_balance_okrpc_reload_ammo 10
-set g_balance_okrpc_reload_time 1
-set g_balance_okrpc_secondary_ammo 0
-set g_balance_okrpc_secondary_animtime 0.2
-set g_balance_okrpc_secondary_damage 25
-set g_balance_okrpc_secondary_delay 0
-set g_balance_okrpc_secondary_edgedamage 12.5
-set g_balance_okrpc_secondary_force 360
-set g_balance_okrpc_secondary_force_zscale 1
-set g_balance_okrpc_secondary_lifetime 5
-set g_balance_okrpc_secondary_radius 70
-set g_balance_okrpc_secondary_refire 0.7
-set g_balance_okrpc_secondary_refire_type 1
-set g_balance_okrpc_secondary_shotangle 0
-set g_balance_okrpc_secondary_speed 6000
-set g_balance_okrpc_secondary_spread 0
-set g_balance_okrpc_switchdelay_drop 0.2
-set g_balance_okrpc_switchdelay_raise 0.2
-set g_balance_okrpc_weaponreplace ""
-set g_balance_okrpc_weaponstart 0
-set g_balance_okrpc_weaponstartoverride 0
-set g_balance_okrpc_weaponthrowable 0
-// }}}
-// {{{ #25: Overkill Shotgun (MUTATOR WEAPON)
-set g_balance_okshotgun_primary_ammo 3
-set g_balance_okshotgun_primary_animtime 0.65
-set g_balance_okshotgun_primary_bot_range 512
-set g_balance_okshotgun_primary_bullets 10
-set g_balance_okshotgun_primary_damage 17
-set g_balance_okshotgun_primary_force 80
-set g_balance_okshotgun_primary_refire 0.75
-set g_balance_okshotgun_primary_solidpenetration 3.8
-set g_balance_okshotgun_primary_spread 0.07
-set g_balance_okshotgun_reload_ammo 24
-set g_balance_okshotgun_reload_time 2
-set g_balance_okshotgun_secondary_animtime 0.2
-set g_balance_okshotgun_secondary_damage 25
-set g_balance_okshotgun_secondary_delay 0
-set g_balance_okshotgun_secondary_edgedamage 12.5
-set g_balance_okshotgun_secondary_force 360
-set g_balance_okshotgun_secondary_force_zscale 1
-set g_balance_okshotgun_secondary_lifetime 5
-set g_balance_okshotgun_secondary_radius 70
-set g_balance_okshotgun_secondary_refire 0.7
-set g_balance_okshotgun_secondary_refire_type 1
-set g_balance_okshotgun_secondary_shotangle 0
-set g_balance_okshotgun_secondary_speed 6000
-set g_balance_okshotgun_secondary_spread 0
-set g_balance_okshotgun_switchdelay_drop 0.2
-set g_balance_okshotgun_switchdelay_raise 0.2
-set g_balance_okshotgun_weaponreplace ""
-set g_balance_okshotgun_weaponstart 0
-set g_balance_okshotgun_weaponstartoverride -1
-set g_balance_okshotgun_weaponthrowable 1
-// }}}
index 1974ad6c811d130e2ad129424d24e5824b5135c9..ea4c4dbb600ff07ff440f8e4a84b708999e33af6 100644 (file)
@@ -1,4 +1,5 @@
 g_mod_balance Mario
+testing_disable
 
 // {{{ starting gear
 set g_balance_health_start 100
@@ -185,6 +186,7 @@ set g_balance_falldamage_deadminspeed 250
 set g_balance_falldamage_minspeed 900
 set g_balance_falldamage_factor 0.20
 set g_balance_falldamage_maxdamage 40
+set g_balance_falldamage_onlyvertical 0
 set g_balance_damagepush_speedfactor 2.5
 set g_balance_contents_damagerate 0.2 // ticrate interval for applying damage with playerdamage/projectiledamage
 set g_balance_contents_drowndelay 10 // time under water before a player begins drowning
index 73c63df9b7277014a78e9be149afa5dd222e9a23..b3d856c054bb6493295fdd3f088c2c5819aa8926 100644 (file)
@@ -1,4 +1,5 @@
 g_mod_balance Nexuiz25
+testing_disable
 
 // {{{ starting gear
 set g_balance_health_start 150
@@ -185,6 +186,7 @@ set g_balance_falldamage_deadminspeed 150
 set g_balance_falldamage_minspeed 1400
 set g_balance_falldamage_factor 0.15
 set g_balance_falldamage_maxdamage 25
+set g_balance_falldamage_onlyvertical 0
 set g_balance_damagepush_speedfactor 0
 set g_balance_contents_damagerate 0.2 // ticrate interval for applying damage with playerdamage/projectiledamage
 set g_balance_contents_drowndelay 10 // time under water before a player begins drowning
index 0e929ee74009f8038dc864228374d0af17766eb5..7aea6f87f41d7d8db4ee79e8c022955d57af6baf 100644 (file)
@@ -1,4 +1,5 @@
 g_mod_balance Overkill
+testing_disable
 
 // {{{ starting gear
 set g_balance_health_start 100
@@ -185,6 +186,7 @@ set g_balance_falldamage_deadminspeed 250
 set g_balance_falldamage_minspeed 900
 set g_balance_falldamage_factor 0.20
 set g_balance_falldamage_maxdamage 40
+set g_balance_falldamage_onlyvertical 0
 set g_balance_damagepush_speedfactor 2.5
 set g_balance_contents_damagerate 0.2 // ticrate interval for applying damage with playerdamage/projectiledamage
 set g_balance_contents_drowndelay 10 // time under water before a player begins drowning
index 9bcb976b60853f8dda7a81c66d22806766eaac02..c177f30ff2502411b4da4886370fba5347f714f9 100644 (file)
@@ -1,4 +1,5 @@
 g_mod_balance Samual
+testing_disable
 
 // {{{ starting gear
 set g_balance_health_start 100
@@ -185,6 +186,7 @@ set g_balance_falldamage_deadminspeed 250
 set g_balance_falldamage_minspeed 900
 set g_balance_falldamage_factor 0.20
 set g_balance_falldamage_maxdamage 40
+set g_balance_falldamage_onlyvertical 0
 set g_balance_damagepush_speedfactor 2.5
 set g_balance_contents_damagerate 0.2 // ticrate interval for applying damage with playerdamage/projectiledamage
 set g_balance_contents_drowndelay 10 // time under water before a player begins drowning
index 96426aaa5ca191453edd6020b5ab131c83d50937..9baac183f416d9ff31b85405667f027ac7e279f7 100644 (file)
@@ -1,243 +1,3 @@
+exec balance-xonotic.cfg
 g_mod_balance Testing
-
-// {{{ starting gear
-set g_balance_health_start 100
-set g_balance_armor_start 0
-set g_start_ammo_shells 15
-set g_start_ammo_nails 0
-set g_start_ammo_rockets 0
-set g_start_ammo_cells 0
-set g_start_ammo_plasma 0
-set g_start_ammo_fuel 0
-set g_random_start_weapons_count 0
-set g_random_start_weapons "machinegun mortar electro crylink vortex hagar devastator"
-set g_random_start_shells 15
-set g_random_start_bullets 80
-set g_random_start_rockets 40
-set g_random_start_cells 30
-set g_random_start_plasma 30
-set g_warmup_start_health 100 "starting values when being in warmup-stage"
-set g_warmup_start_armor 100 "starting values when being in warmup-stage"
-set g_warmup_start_ammo_shells 30 "starting values when being in warmup-stage"
-set g_warmup_start_ammo_nails 160 "starting values when being in warmup-stage"
-set g_warmup_start_ammo_rockets 80 "starting values when being in warmup-stage"
-set g_warmup_start_ammo_cells 90 "starting values when being in warmup-stage"
-set g_warmup_start_ammo_plasma 90 "starting values when being in warmup-stage"
-set g_warmup_start_ammo_fuel 0 "starting values when being in warmup-stage"
-set g_lms_start_health 200
-set g_lms_start_armor 200
-set g_lms_start_ammo_shells 60
-set g_lms_start_ammo_nails 320
-set g_lms_start_ammo_rockets 160
-set g_lms_start_ammo_cells 180
-set g_lms_start_ammo_plasma 180
-set g_lms_start_ammo_fuel 0
-set g_balance_nix_roundtime 25
-set g_balance_nix_incrtime 1.6
-set g_balance_nix_ammo_shells 60
-set g_balance_nix_ammo_nails 320
-set g_balance_nix_ammo_rockets 160
-set g_balance_nix_ammo_cells 180
-set g_balance_nix_ammo_plasma 180
-set g_balance_nix_ammo_fuel 100
-set g_balance_nix_ammoincr_shells 2 // eh this will need figured out later I assume
-set g_balance_nix_ammoincr_nails 6
-set g_balance_nix_ammoincr_rockets 2
-set g_balance_nix_ammoincr_cells 2
-set g_balance_nix_ammoincr_plasma 2
-set g_balance_nix_ammoincr_fuel 2
-// }}}
-
-// {{{ pickup items
-set g_pickup_ammo_anyway 1
-set g_pickup_weapons_anyway 1
-set g_pickup_shells 15
-set g_pickup_shells_weapon 15
-set g_pickup_shells_max 60
-set g_pickup_nails 80
-set g_pickup_nails_weapon 80
-set g_pickup_nails_max 320
-set g_pickup_rockets 40
-set g_pickup_rockets_weapon 40
-set g_pickup_rockets_max 160
-set g_pickup_cells 30
-set g_pickup_cells_weapon 30
-set g_pickup_cells_max 180
-set g_pickup_plasma 30
-set g_pickup_plasma_weapon 30
-set g_pickup_plasma_max 180
-set g_pickup_fuel 50
-set g_pickup_fuel_weapon 50
-set g_pickup_fuel_jetpack 100
-set g_pickup_fuel_max 100
-set g_pickup_armorsmall 5
-set g_pickup_armorsmall_max 200
-set g_pickup_armorsmall_anyway 1
-set g_pickup_armormedium 25
-set g_pickup_armormedium_max 200
-set g_pickup_armormedium_anyway 1
-set g_pickup_armorbig 50
-set g_pickup_armorbig_max 200
-set g_pickup_armorbig_anyway 1
-set g_pickup_armormega 100
-set g_pickup_armormega_max 200
-set g_pickup_armormega_anyway 1
-set g_pickup_healthsmall 5
-set g_pickup_healthsmall_max 200
-set g_pickup_healthsmall_anyway 1
-set g_pickup_healthmedium 25
-set g_pickup_healthmedium_max 200
-set g_pickup_healthmedium_anyway 1
-set g_pickup_healthbig 50
-set g_pickup_healthbig_max 200
-set g_pickup_healthbig_anyway 1
-set g_pickup_healthmega 100
-set g_pickup_healthmega_max 200
-set g_pickup_healthmega_anyway 1
-set g_pickup_respawntime_short 15
-set g_pickup_respawntime_medium 20
-set g_pickup_respawntime_long 30
-set g_pickup_respawntime_powerup 120
-set g_pickup_respawntime_weapon 10
-set g_pickup_respawntime_superweapon 120
-set g_pickup_respawntime_ammo 10
-set g_pickup_respawntime_initial_random 1
-set g_pickup_respawntimejitter_short 0
-set g_pickup_respawntimejitter_medium 0
-set g_pickup_respawntimejitter_long 0
-set g_pickup_respawntimejitter_powerup 0
-set g_pickup_respawntimejitter_weapon 0
-set g_pickup_respawntimejitter_superweapon 10
-set g_pickup_respawntimejitter_ammo 0
-// }}}
-
-// {{{ regen/rot
-set g_balance_health_regen 0.08
-set g_balance_health_regenlinear 0.5
-set g_balance_pause_health_regen 5
-set g_balance_pause_health_regen_spawn 0
-set g_balance_health_rot 0.02
-set g_balance_health_rotlinear 1
-set g_balance_pause_health_rot 1
-set g_balance_pause_health_rot_spawn 5
-set g_balance_health_regenstable 100
-set g_balance_health_rotstable 100
-set g_balance_health_limit 200
-set g_balance_armor_regen 0
-set g_balance_armor_regenlinear 0
-set g_balance_armor_rot 0.02
-set g_balance_armor_rotlinear 1
-set g_balance_pause_armor_rot 1
-set g_balance_pause_armor_rot_spawn 5
-set g_balance_armor_regenstable 100
-set g_balance_armor_rotstable 100
-set g_balance_armor_limit 200
-set g_balance_armor_blockpercent 0.7
-set g_balance_fuel_regen 0.1 "fuel regeneration (only applies if the player owns IT_FUEL_REGEN)"
-set g_balance_fuel_regenlinear 0
-set g_balance_pause_fuel_regen 2 // other than this, fuel uses the health regen counter
-set g_balance_fuel_rot 0.05
-set g_balance_fuel_rotlinear 0
-set g_balance_pause_fuel_rot 5
-set g_balance_pause_fuel_rot_spawn 10
-set g_balance_fuel_regenstable 50
-set g_balance_fuel_rotstable 100
-set g_balance_fuel_limit 100
-// }}}
-
-// {{{ misc
-set g_balance_selfdamagepercent 0.65
-set g_weaponspeedfactor 1 "weapon projectile speed multiplier"
-set g_weaponratefactor 1 "weapon fire rate multiplier"
-set g_weapondamagefactor 1 "weapon damage multiplier"
-set g_weaponforcefactor 1 "weapon force multiplier"
-set g_weaponspreadfactor 1 "weapon spread multiplier"
-set g_balance_firetransfer_time 0.9
-set g_balance_firetransfer_damage 0.8
-set g_throughfloor_damage 0.75
-set g_throughfloor_force 0.75
-set g_projectiles_damage -2
-// possible values:
-// -2: absolutely no damage to projectiles (no exceptions)
-// -1: no damage other than the exceptions (electro combo, hagar join explode, ML mines)
-// 0: only damage from contents (lava/slime) or exceptions
-// 1: only self damage or damage from contents or exceptions
-// 2: allow all damage to projectiles normally
-set g_projectiles_keep_owner 1
-set g_projectiles_newton_style 0
-// possible values:
-// 0: absolute velocity projectiles (like Quake)
-// 1: relative velocity projectiles, "Newtonian" (like Tribes 2)
-// 2: relative velocity projectiles, but aim is precorrected so projectiles hit the crosshair (note: strafe rockets then are SLOWER than ones shot while standing, happens in 1 too when aiming correctly which is hard)
-set g_projectiles_newton_style_2_minfactor 0.8
-set g_projectiles_newton_style_2_maxfactor 1.5
-set g_projectiles_spread_style 7
-// possible values:
-// 0: forward + solid sphere (like Quake) - varies velocity
-// 1: forward + flattened solid sphere
-// 2: forward + solid circle
-// 3: forward + normal distribution 3D - varies velocity
-// 4: forward + normal distribution on a plane
-// 5: forward + circle with 1-r falloff
-// 6: forward + circle with 1-r^2 falloff
-// 7: forward + circle with (1-r)(2-r) falloff
-set g_balance_falldamage_deadminspeed 250
-set g_balance_falldamage_minspeed 900
-set g_balance_falldamage_factor 0.20
-set g_balance_falldamage_maxdamage 40
-set g_balance_damagepush_speedfactor 2.5
-set g_balance_contents_damagerate 0.2 // ticrate interval for applying damage with playerdamage/projectiledamage
-set g_balance_contents_drowndelay 10 // time under water before a player begins drowning
-set g_balance_contents_playerdamage_drowning 20 // damage per second for while player is drowning
-set g_balance_contents_playerdamage_lava 50 // damage per second for while player is inside lava
-set g_balance_contents_playerdamage_lava_burn 0 // extra burning damage after leaving lava
-set g_balance_contents_playerdamage_lava_burn_time 2.5 // time across which the damage is applied (note: not dps!)
-set g_balance_contents_playerdamage_slime 30 // damage per second for while player is inside slime
-set g_balance_contents_projectiledamage 10000 // instantly kill projectiles upon touching lava/slime
-set g_maxpushtime 8.0 "timeout for kill credit when your damage knocks someone into a death trap"
-// }}}
-
-// {{{ powerups
-set g_balance_powerup_invincible_takedamage 0.33 // only 1/3rd damage is taken
-set g_balance_powerup_invincible_takeforce 0.33
-set g_balance_powerup_invincible_time 30
-set g_balance_powerup_strength_damage 3
-set g_balance_powerup_strength_force 3
-set g_balance_powerup_strength_time 30
-set g_balance_powerup_strength_selfdamage 1.5
-set g_balance_powerup_strength_selfforce 1.5
-set g_balance_superweapons_time 30
-// }}}
-
-// {{{ jetpack/hook
-set g_jetpack_antigravity 0.8 "factor of gravity compensation of the jetpack"
-set g_jetpack_acceleration_side 1200 "acceleration of the jetpack in xy direction"
-set g_jetpack_acceleration_up 600 "acceleration of the jetpack in z direction (note: you have to factor in gravity here, if antigravity is not 1)"
-set g_jetpack_maxspeed_side 1200 "max speed of the jetpack in xy direction"
-set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
-set g_jetpack_fuel 8 "fuel per second for jetpack"
-set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
-
-set g_grappling_hook_tarzan 2 // 2: can also pull players
-set g_balance_grapplehook_speed_fly 1800
-set g_balance_grapplehook_speed_pull 2000
-set g_balance_grapplehook_force_rubber 2000
-set g_balance_grapplehook_force_rubber_overstretch 1000
-set g_balance_grapplehook_length_min 50
-set g_balance_grapplehook_stretch 50
-set g_balance_grapplehook_airfriction 0.2
-set g_balance_grapplehook_health 50
-set g_balance_grapplehook_damagedbycontents 1
-set g_balance_grapplehook_refire 0.2
-set g_balance_grapplehook_nade_time 0.7
-set g_balance_grapplehook_crouchslide 0
-set g_balance_grapplehook_gravity 0
-set g_balance_grapplehook_pull_frozen 0
-// }}}
-
-// {{{ port-o-launch
-set g_balance_portal_health 200 // these get recharged whenever the portal is used
-set g_balance_portal_lifetime 15 // these get recharged whenever the portal is used
-// }}}
-
-exec bal-wep-testing.cfg
+testing_enable
index 7c2da46cef1f7d446ca193ee16706f1f45221c15..93cdc11cecae71bc6ee0703243fa2ab1b92d46b4 100644 (file)
@@ -1,243 +1,3 @@
-g_mod_balance XPM
-
-// {{{ starting gear
-set g_balance_health_start 100
-set g_balance_armor_start 0
-set g_start_ammo_shells 15
-set g_start_ammo_nails 0
-set g_start_ammo_rockets 0
-set g_start_ammo_cells 0
-set g_start_ammo_plasma 0
-set g_start_ammo_fuel 0
-set g_random_start_weapons_count 0
-set g_random_start_weapons "machinegun mortar electro crylink vortex hagar devastator"
-set g_random_start_shells 15
-set g_random_start_bullets 80
-set g_random_start_rockets 40
-set g_random_start_cells 30
-set g_random_start_plasma 30
-set g_warmup_start_health 100 "starting values when being in warmup-stage"
-set g_warmup_start_armor 100 "starting values when being in warmup-stage"
-set g_warmup_start_ammo_shells 30 "starting values when being in warmup-stage"
-set g_warmup_start_ammo_nails 160 "starting values when being in warmup-stage"
-set g_warmup_start_ammo_rockets 80 "starting values when being in warmup-stage"
-set g_warmup_start_ammo_cells 90 "starting values when being in warmup-stage"
-set g_warmup_start_ammo_plasma 90 "starting values when being in warmup-stage"
-set g_warmup_start_ammo_fuel 0 "starting values when being in warmup-stage"
-set g_lms_start_health 200
-set g_lms_start_armor 200
-set g_lms_start_ammo_shells 60
-set g_lms_start_ammo_nails 320
-set g_lms_start_ammo_rockets 160
-set g_lms_start_ammo_cells 180
-set g_lms_start_ammo_plasma 180
-set g_lms_start_ammo_fuel 0
-set g_balance_nix_roundtime 25
-set g_balance_nix_incrtime 1.6
-set g_balance_nix_ammo_shells 60
-set g_balance_nix_ammo_nails 320
-set g_balance_nix_ammo_rockets 160
-set g_balance_nix_ammo_cells 180
-set g_balance_nix_ammo_plasma 180
-set g_balance_nix_ammo_fuel 100
-set g_balance_nix_ammoincr_shells 2 // eh this will need figured out later I assume
-set g_balance_nix_ammoincr_nails 6
-set g_balance_nix_ammoincr_rockets 2
-set g_balance_nix_ammoincr_cells 2
-set g_balance_nix_ammoincr_plasma 2
-set g_balance_nix_ammoincr_fuel 2
-// }}}
-
-// {{{ pickup items
-set g_pickup_ammo_anyway 1
-set g_pickup_weapons_anyway 1
-set g_pickup_shells 15
-set g_pickup_shells_weapon 15
-set g_pickup_shells_max 60
-set g_pickup_nails 80
-set g_pickup_nails_weapon 80
-set g_pickup_nails_max 320
-set g_pickup_rockets 40
-set g_pickup_rockets_weapon 40
-set g_pickup_rockets_max 160
-set g_pickup_cells 30
-set g_pickup_cells_weapon 30
-set g_pickup_cells_max 180
-set g_pickup_plasma 30
-set g_pickup_plasma_weapon 30
-set g_pickup_plasma_max 180
-set g_pickup_fuel 50
-set g_pickup_fuel_weapon 50
-set g_pickup_fuel_jetpack 100
-set g_pickup_fuel_max 100
-set g_pickup_armorsmall 5
-set g_pickup_armorsmall_max 200
-set g_pickup_armorsmall_anyway 0
-set g_pickup_armormedium 25
-set g_pickup_armormedium_max 100
-set g_pickup_armormedium_anyway 0
-set g_pickup_armorbig 50
-set g_pickup_armorbig_max 100
-set g_pickup_armorbig_anyway 0
-set g_pickup_armormega 100
-set g_pickup_armormega_max 200
-set g_pickup_armormega_anyway 0
-set g_pickup_healthsmall 5
-set g_pickup_healthsmall_max 200
-set g_pickup_healthsmall_anyway 0
-set g_pickup_healthmedium 25
-set g_pickup_healthmedium_max 100
-set g_pickup_healthmedium_anyway 0
-set g_pickup_healthbig 50
-set g_pickup_healthbig_max 100
-set g_pickup_healthbig_anyway 0
-set g_pickup_healthmega 100
-set g_pickup_healthmega_max 200
-set g_pickup_healthmega_anyway 0
-set g_pickup_respawntime_short 15
-set g_pickup_respawntime_medium 20
-set g_pickup_respawntime_long 30
-set g_pickup_respawntime_powerup 120
-set g_pickup_respawntime_weapon 10
-set g_pickup_respawntime_superweapon 120
-set g_pickup_respawntime_ammo 10
-set g_pickup_respawntime_initial_random 1
-set g_pickup_respawntimejitter_short 0
-set g_pickup_respawntimejitter_medium 0
-set g_pickup_respawntimejitter_long 0
-set g_pickup_respawntimejitter_powerup 0
-set g_pickup_respawntimejitter_weapon 0
-set g_pickup_respawntimejitter_superweapon 10
-set g_pickup_respawntimejitter_ammo 0
-// }}}
-
-// {{{ regen/rot
-set g_balance_health_regen 0.08
-set g_balance_health_regenlinear 0.5
-set g_balance_pause_health_regen 5
-set g_balance_pause_health_regen_spawn 0
-set g_balance_health_rot 0.02
-set g_balance_health_rotlinear 1
-set g_balance_pause_health_rot 1
-set g_balance_pause_health_rot_spawn 5
-set g_balance_health_regenstable 100
-set g_balance_health_rotstable 100
-set g_balance_health_limit 200
-set g_balance_armor_regen 0
-set g_balance_armor_regenlinear 0
-set g_balance_armor_rot 0.02
-set g_balance_armor_rotlinear 1
-set g_balance_pause_armor_rot 1
-set g_balance_pause_armor_rot_spawn 5
-set g_balance_armor_regenstable 100
-set g_balance_armor_rotstable 100
-set g_balance_armor_limit 200
-set g_balance_armor_blockpercent 0.7
-set g_balance_fuel_regen 0.1 "fuel regeneration (only applies if the player owns IT_FUEL_REGEN)"
-set g_balance_fuel_regenlinear 0
-set g_balance_pause_fuel_regen 2 // other than this, fuel uses the health regen counter
-set g_balance_fuel_rot 0.05
-set g_balance_fuel_rotlinear 0
-set g_balance_pause_fuel_rot 5
-set g_balance_pause_fuel_rot_spawn 10
-set g_balance_fuel_regenstable 50
-set g_balance_fuel_rotstable 100
-set g_balance_fuel_limit 100
-// }}}
-
-// {{{ misc
-set g_balance_selfdamagepercent 0.65
-set g_weaponspeedfactor 1 "weapon projectile speed multiplier"
-set g_weaponratefactor 1 "weapon fire rate multiplier"
-set g_weapondamagefactor 1 "weapon damage multiplier"
-set g_weaponforcefactor 1 "weapon force multiplier"
-set g_weaponspreadfactor 1 "weapon spread multiplier"
-set g_balance_firetransfer_time 0.9
-set g_balance_firetransfer_damage 0.8
-set g_throughfloor_damage 0.75
-set g_throughfloor_force 0.75
-set g_projectiles_damage -2
-// possible values:
-// -2: absolutely no damage to projectiles (no exceptions)
-// -1: no damage other than the exceptions (electro combo, hagar join explode, ML mines)
-// 0: only damage from contents (lava/slime) or exceptions
-// 1: only self damage or damage from contents or exceptions
-// 2: allow all damage to projectiles normally
-set g_projectiles_keep_owner 1
-set g_projectiles_newton_style 0
-// possible values:
-// 0: absolute velocity projectiles (like Quake)
-// 1: relative velocity projectiles, "Newtonian" (like Tribes 2)
-// 2: relative velocity projectiles, but aim is precorrected so projectiles hit the crosshair (note: strafe rockets then are SLOWER than ones shot while standing, happens in 1 too when aiming correctly which is hard)
-set g_projectiles_newton_style_2_minfactor 0.8
-set g_projectiles_newton_style_2_maxfactor 1.5
-set g_projectiles_spread_style 7
-// possible values:
-// 0: forward + solid sphere (like Quake) - varies velocity
-// 1: forward + flattened solid sphere
-// 2: forward + solid circle
-// 3: forward + normal distribution 3D - varies velocity
-// 4: forward + normal distribution on a plane
-// 5: forward + circle with 1-r falloff
-// 6: forward + circle with 1-r^2 falloff
-// 7: forward + circle with (1-r)(2-r) falloff
-set g_balance_falldamage_deadminspeed 250
-set g_balance_falldamage_minspeed 900
-set g_balance_falldamage_factor 0.20
-set g_balance_falldamage_maxdamage 40
-set g_balance_damagepush_speedfactor 2.5
-set g_balance_contents_damagerate 0.2 // ticrate interval for applying damage with playerdamage/projectiledamage
-set g_balance_contents_drowndelay 10 // time under water before a player begins drowning
-set g_balance_contents_playerdamage_drowning 20 // damage per second for while player is drowning
-set g_balance_contents_playerdamage_lava 50 // damage per second for while player is inside lava
-set g_balance_contents_playerdamage_lava_burn 0 // extra burning damage after leaving lava
-set g_balance_contents_playerdamage_lava_burn_time 2.5 // time across which the damage is applied (note: not dps!)
-set g_balance_contents_playerdamage_slime 30 // damage per second for while player is inside slime
-set g_balance_contents_projectiledamage 10000 // instantly kill projectiles upon touching lava/slime
-set g_maxpushtime 8.0 "timeout for kill credit when your damage knocks someone into a death trap"
-// }}}
-
-// {{{ powerups
-set g_balance_powerup_invincible_takedamage 0.33 // only 1/3rd damage is taken
-set g_balance_powerup_invincible_takeforce 0.33
-set g_balance_powerup_invincible_time 30
-set g_balance_powerup_strength_damage 3
-set g_balance_powerup_strength_force 3
-set g_balance_powerup_strength_time 30
-set g_balance_powerup_strength_selfdamage 1.5
-set g_balance_powerup_strength_selfforce 1.5
-set g_balance_superweapons_time 30
-// }}}
-
-// {{{ jetpack/hook
-set g_jetpack_antigravity 0.8 "factor of gravity compensation of the jetpack"
-set g_jetpack_acceleration_side 1200 "acceleration of the jetpack in xy direction"
-set g_jetpack_acceleration_up 600 "acceleration of the jetpack in z direction (note: you have to factor in gravity here, if antigravity is not 1)"
-set g_jetpack_maxspeed_side 1200 "max speed of the jetpack in xy direction"
-set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
-set g_jetpack_fuel 8 "fuel per second for jetpack"
-set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
-
-set g_grappling_hook_tarzan 2 // 2: can also pull players
-set g_balance_grapplehook_speed_fly 1800
-set g_balance_grapplehook_speed_pull 2000
-set g_balance_grapplehook_force_rubber 2000
-set g_balance_grapplehook_force_rubber_overstretch 1000
-set g_balance_grapplehook_length_min 50
-set g_balance_grapplehook_stretch 50
-set g_balance_grapplehook_airfriction 0.2
-set g_balance_grapplehook_health 50
-set g_balance_grapplehook_damagedbycontents 1
-set g_balance_grapplehook_refire 0.2
-set g_balance_grapplehook_nade_time 0.7
-set g_balance_grapplehook_crouchslide 0
-set g_balance_grapplehook_gravity 0
-set g_balance_grapplehook_pull_frozen 0
-// }}}
-
-// {{{ port-o-launch
-set g_balance_portal_health 200 // these get recharged whenever the portal is used
-set g_balance_portal_lifetime 15 // these get recharged whenever the portal is used
-// }}}
-
-exec bal-wep-testingxpm.cfg
+exec balance-xpm.cfg
+g_mod_balance XPM // XPM is technically modified anyway, this way it'll stay in the right category
+testing_enable
index 6a1622c2c42c5dc1a85148cd6d84e380c63c88a7..5ba025a88ba04c0c00718a83888c8ec267206a57 100644 (file)
@@ -1,4 +1,5 @@
 g_mod_balance XDF
+testing_disable
 
 // {{{ starting gear
 set g_balance_health_start 100
@@ -185,6 +186,7 @@ set g_balance_falldamage_deadminspeed 250
 set g_balance_falldamage_minspeed 900
 set g_balance_falldamage_factor 0.20
 set g_balance_falldamage_maxdamage 40
+set g_balance_falldamage_onlyvertical 0
 set g_balance_damagepush_speedfactor 2.5
 set g_balance_contents_damagerate 0.2 // ticrate interval for applying damage with playerdamage/projectiledamage
 set g_balance_contents_drowndelay 10 // time under water before a player begins drowning
index e19872454fa57d9b9cdfdd77ac6319763f390432..8c36402ab5c49cce391eff869608b88b316ab132 100644 (file)
@@ -1,4 +1,5 @@
 g_mod_balance Xonotic
+testing_disable
 
 // {{{ starting gear
 set g_balance_health_start 100
@@ -185,6 +186,7 @@ set g_balance_falldamage_deadminspeed 250
 set g_balance_falldamage_minspeed 900
 set g_balance_falldamage_factor 0.20
 set g_balance_falldamage_maxdamage 40
+set g_balance_falldamage_onlyvertical 0
 set g_balance_damagepush_speedfactor 2.5
 set g_balance_contents_damagerate 0.2 // ticrate interval for applying damage with playerdamage/projectiledamage
 set g_balance_contents_drowndelay 10 // time under water before a player begins drowning
index 5b8c67d2f5f9395af13f8fadde4a28c613a930e8..46e04a9504d5a55160dc20ce3e60f025e357a565 100644 (file)
@@ -1,4 +1,5 @@
 g_mod_balance XPM
+testing_disable
 
 // {{{ starting gear
 set g_balance_health_start 100
@@ -185,6 +186,7 @@ set g_balance_falldamage_deadminspeed 250
 set g_balance_falldamage_minspeed 900
 set g_balance_falldamage_factor 0.20
 set g_balance_falldamage_maxdamage 40
+set g_balance_falldamage_onlyvertical 0
 set g_balance_damagepush_speedfactor 2.5
 set g_balance_contents_damagerate 0.2 // ticrate interval for applying damage with playerdamage/projectiledamage
 set g_balance_contents_drowndelay 10 // time under water before a player begins drowning
@@ -240,4 +242,4 @@ set g_balance_portal_health 200 // these get recharged whenever the portal is us
 set g_balance_portal_lifetime 15 // these get recharged whenever the portal is used
 // }}}
 
-exec bal-wep-xpm.cfg
+exec bal-wep-xonotic.cfg
index 3bdf7909633a288625182623498ba8a4106bc8b7..3046579ae4788b2524c51474aaf8b86590d10ead 100644 (file)
@@ -121,7 +121,7 @@ bind F2 vno
 bind F3 spec
 
 // usercommands. These can be edited and bound by the menu.
-seta "userbind1_press" "say_team quad soon";  seta "userbind1_release" "";  seta "userbind1_description" "team: quad soon"
+seta "userbind1_press" "say_team strength soon";  seta "userbind1_release" "";  seta "userbind1_description" "team: strength soon"
 seta "userbind2_press" "say_team free item %x^7 (l:%y^7); g_waypointsprite_team_here_p";  seta "userbind2_release" "";  seta "userbind2_description" "team: free item, icon"
 seta "userbind3_press" "say_team took item (l:%l^7); g_waypointsprite_team_here";  seta "userbind3_release" "";  seta "userbind3_description" "team: took item, icon"
 seta "userbind4_press" "say_team negative";  seta "userbind4_release" "";  seta "userbind4_description" "team: negative"
index 43683feb8270802ad0c5abb52fa30356eeab4b16..387d93720392d660fccf6b43b8dd9ca37c05a0ad 100755 (executable)
@@ -6,16 +6,20 @@ check_files()
 {
        countw=`awk ''"$3"' { print $2; }' "$1" | sort -u | tr -d '\r' | git hash-object --stdin | cut -c 1-32`
        for b in $2; do
+               if [ "$b" = "balance-testing.cfg" ] || [ "$b" = "balance-testingxpm.cfg" ]; then
+                       continue
+               fi
+
                countb=`awk ''"$3"' { print $2; }' "$b" | sort -u | tr -d '\r' | git hash-object --stdin | cut -c 1-32`
                if [ "$countw" != "$countb" ]; then
-                       echo "Mismatch between "$1" and $b. Aborting."
+                       echo "Mismatch between $1 and $b. Aborting."
                        echo "Differences are:"
                        echo "< missing in $b"
                        echo "> must get removed from $b"
                        A=`mktemp || echo a.tmp`
                        B=`mktemp || echo b.tmp`
-                       awk ''"$3"' { print $2; }' "$1"      | sort -u | tr -d '\r' > "$A"
-                       awk ''"$3"' { print $2; }' "$b"                     | sort -u | tr -d '\r' > "$B"
+                       awk ''"$3"' { print $2; }' "$1" | sort -u | tr -d '\r' > "$A"
+                       awk ''"$3"' { print $2; }' "$b" | sort -u | tr -d '\r' > "$B"
                        diff "$A" "$B" | grep '^[<>]' | sort
                        rm -f "$A" "$B"
                        errord=true
@@ -24,6 +28,7 @@ check_files()
 }
 
 check_files "balance-xonotic.cfg" "balance-*.cfg" "/^seta? g_/"
+check_files "bal-wep-xonotic.cfg" "bal-wep-*.cfg" "/^seta? g_/"
 check_files "_hud_descriptions.cfg" "hud_*.cfg" "/^seta? hud_/"
 
 if $errord; then
index 584ac0f1e4c27afcbf09cd8ca0ad2b113f39a684..1375a78871d11b51c9abb68ccbc2f801f46f1af5 100644 (file)
@@ -83,12 +83,14 @@ alias g_hitplots_remove "qc_cmd_svmenu rpn /g_hitplots_individuals g_hitplots_in
 
 alias g_maplist_add    "qc_cmd_svmenu maplist add ${* ?}"
 alias g_maplist_remove "qc_cmd_svmenu maplist remove ${* ?}"
-alias g_maplist_putfirst       "qc_cmd_svmenu maplist remove ${* ?} ; qc_cmd maplist add ${* ?}"
+alias g_maplist_putfirst       "qc_cmd_svmenu maplist remove ${* ?} ; qc_cmd_svmenu maplist add ${* ?}"
 alias g_maplist_shufflenow     "qc_cmd_svmenu maplist shuffle"
 alias g_maplist_cleanup        "qc_cmd_svmenu maplist cleanup" // removes maps that don't exist from the map list
 
 alias addfav "qc_cmd_svmenu addtolist net_slist_favorites ${* ?}"
+alias delfav "qc_cmd_svmenu removefromlist net_slist_favorites ${* ?}"
 alias addvote "qc_cmd_svmenu addtolist sv_vote_commands ${* ?}"
+alias delvote "qc_cmd_svmenu removefromlist sv_vote_commands ${* ?}"
 
 
 // ========================
@@ -324,7 +326,7 @@ set sv_vote_command_help_gotomap "\nUsage:^3 vcall gotomap mapname\n^7  Where 'm
 // =================================
 set sv_vote_call 1 "Allow users to call a vote for the commands in sv_vote_commands"
 set sv_vote_change 1 "Allow voters to change their mind after already voting"
-set sv_vote_commands "restart fraglimit chmap gotomap nextmap endmatch reducematchtime extendmatchtime allready kick cointoss movetoauto shuffleteams bots nobots" "these commands can be voted by players or used directly by masters (vdo) in addition to sv_vote_master_commands"
+set sv_vote_commands "restart fraglimit gotomap nextmap endmatch reducematchtime extendmatchtime allready kick cointoss movetoauto shuffleteams bots nobots" "these commands can be voted by players or used directly by masters (vdo) in addition to sv_vote_master_commands"
 set sv_vote_only_commands ""
 set sv_vote_limit 160 "Maximum allowed length of a vote command"
 set sv_vote_master_commands "movetored movetoblue movetoyellow movetopink movetospec" "Extra commands which vote masters can execute by themselves, along with the normal sv_vote_commands." // maybe add kickban here (but then sv_vote_master 0)
index 68a14f48f61f05c0570a6149e46ceb12adb602a3..2e397ca68a06e9e0fc2ac95dbf6b6754292d907d 100644 (file)
@@ -4,8 +4,9 @@
 #
 # Translators:
 # Ximielga <dorian@openmailbox.org>, 2014-2015
-# Ḷḷumex03 <tornes@opmbx.org>, 2014
-# Ḷḷumex03 <tornes@opmbx.org>, 2014-2015
+# Ḷḷumex03, 2014
+# Ḷḷumex03, 2014
+# Ḷḷumex03, 2014-2015
 # Tornes Ḷḷume <tornes.llume@openmailbox.org>, 2015-2017
 # Ximielga <dorian@openmailbox.org>, 2014
 msgid ""
index 3ef1de28097b0d08d3b6bdd5abdf6367063fa472..1a08002a549569b59be57bac1343859cca797ea5 100644 (file)
@@ -4,6 +4,8 @@
 #
 # Translators:
 # Martin Taibr <taibr.martin@gmail.com>, 2017
+# GamingasCZ <gamingforyou875@gmail.com>, 2019
+# Jan Kocka <kockahonza@gmail.com>, 2019
 # Martin Taibr <taibr.martin@gmail.com>, 2017
 # NONE <nechtom@gmail.com>, 2015
 # Tomáš Volavka <czheron@gmail.com>, 2015,2018
@@ -13,8 +15,8 @@ msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2019-05-19 07:23+0200\n"
-"PO-Revision-Date: 2019-05-19 05:23+0000\n"
-"Last-Translator: divVerent <divVerent@xonotic.org>\n"
+"PO-Revision-Date: 2019-12-11 18:36+0000\n"
+"Last-Translator: GamingasCZ <gamingforyou875@gmail.com>\n"
 "Language-Team: Czech (http://www.transifex.com/team-xonotic/xonotic/language/"
 "cs/)\n"
 "Language: cs\n"
@@ -27,12 +29,12 @@ msgstr ""
 #: qcsrc/client/hud/hud_config.qc:243
 #, c-format
 msgid "^2Successfully exported to %s! (Note: It's saved in data/data/)"
-msgstr ""
+msgstr "^2Úspěšně exportováno do %s! (Poznámka: Uloženo v data/data/)"
 
 #: qcsrc/client/hud/hud_config.qc:247
 #, c-format
 msgid "^1Couldn't write to %s"
-msgstr ""
+msgstr "^1Nešlo zapsat do 1%s"
 
 #: qcsrc/client/hud/panel/centerprint.qc:140
 #, c-format
@@ -45,15 +47,17 @@ msgid ""
 "^1Multiline message at time %s that\n"
 "^1lasts longer than normal"
 msgstr ""
+"^1Víceřádková zpráva v čase %s že\n"
+"^1trvá déle než normálně"
 
 #: qcsrc/client/hud/panel/centerprint.qc:144
 #, c-format
 msgid "Message at time %s"
-msgstr ""
+msgstr "Zpráva v čase %s"
 
 #: qcsrc/client/hud/panel/centerprint.qc:149
 msgid "Generic message"
-msgstr ""
+msgstr "Obecná zpráva"
 
 #: qcsrc/client/hud/panel/chat.qc:84
 msgid "^3Player^7: This is the chat area."
@@ -126,7 +130,7 @@ msgstr "^1Stiskni ^3%s^1 pro informace o herním módu"
 #: qcsrc/client/hud/panel/infomessages.qc:113
 #: qcsrc/menu/xonotic/keybinder.qc:105
 msgid "server info"
-msgstr ""
+msgstr "info o serveru"
 
 #: qcsrc/client/hud/panel/infomessages.qc:126
 msgid "^1Match has already begun"
@@ -154,37 +158,37 @@ msgstr "^1Hra začíná za ^3%d^1 sekund"
 
 #: qcsrc/client/hud/panel/infomessages.qc:147
 msgid "^2Currently in ^1warmup^2 stage!"
-msgstr ""
+msgstr "^2Momentálně v ^1zahřívací^2 fázi!"
 
 #: qcsrc/client/hud/panel/infomessages.qc:162
 #, c-format
 msgid "%sPress ^3%s%s to end warmup"
-msgstr ""
+msgstr "%sZmáčkni ^3%s%s pro ukončení zahřívací fáze"
 
 #: qcsrc/client/hud/panel/infomessages.qc:162
 #: qcsrc/client/hud/panel/infomessages.qc:164
 #: qcsrc/client/hud/panel/infomessages.qc:177
 #: qcsrc/menu/xonotic/keybinder.qc:101
 msgid "ready"
-msgstr ""
+msgstr "připraven"
 
 #: qcsrc/client/hud/panel/infomessages.qc:164
 #, c-format
 msgid "%sPress ^3%s%s once you are ready"
-msgstr ""
+msgstr "%sZmáčkni ^3%s%s až budeš připravený"
 
 #: qcsrc/client/hud/panel/infomessages.qc:169
 msgid "^2Waiting for others to ready up to end warmup..."
-msgstr ""
+msgstr "^2Čeká se než ostatní hráči ukončí zahřívací fázi..."
 
 #: qcsrc/client/hud/panel/infomessages.qc:171
 msgid "^2Waiting for others to ready up..."
-msgstr ""
+msgstr "^2Čeká se než budou ostatní hráči připraveni..."
 
 #: qcsrc/client/hud/panel/infomessages.qc:177
 #, c-format
 msgid "^2Press ^3%s^2 to end warmup"
-msgstr ""
+msgstr "^2Zmáčkni ^3%s^2 pro ukončení zahřívací fáze"
 
 #: qcsrc/client/hud/panel/infomessages.qc:198
 msgid "Teamnumbers are unbalanced!"
@@ -193,24 +197,24 @@ msgstr "Týmy jsou nevyvážené"
 #: qcsrc/client/hud/panel/infomessages.qc:201
 #, c-format
 msgid " Press ^3%s%s to adjust"
-msgstr ""
+msgstr " Zmáčkni ^3%s%s pro upravení"
 
 #: qcsrc/client/hud/panel/infomessages.qc:201
 #: qcsrc/menu/xonotic/keybinder.qc:117
 msgid "team menu"
-msgstr ""
+msgstr "týmové menu"
 
 #: qcsrc/client/hud/panel/infomessages.qc:211
 msgid "^1Spectating this player:"
-msgstr ""
+msgstr "^1Sleduješ tohoto hráče:"
 
 #: qcsrc/client/hud/panel/infomessages.qc:211
 msgid "^1Spectating you:"
-msgstr ""
+msgstr "^1Sledují tě:"
 
 #: qcsrc/client/hud/panel/infomessages.qc:227
 msgid "^7Press ^3ESC ^7to show HUD options."
-msgstr ""
+msgstr "^7Zmáčkni ^3ESC ^7pro zobrazení nastavení HUD."
 
 #: qcsrc/client/hud/panel/infomessages.qc:228
 msgid "^3Doubleclick ^7a panel for panel-specific options."
@@ -247,49 +251,49 @@ msgstr ""
 #: qcsrc/client/hud/panel/quickmenu.qc:598
 #, c-format
 msgid "Command%d"
-msgstr ""
+msgstr "Příkaz%d"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:624
 msgid "Continue..."
-msgstr ""
+msgstr "Pokračovat..."
 
 #: qcsrc/client/hud/panel/quickmenu.qc:781
 #: qcsrc/client/hud/panel/quickmenu.qc:788
 msgid "Chat"
-msgstr ""
+msgstr "Chat"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:782
 msgid "QMCMD^Send public message to"
-msgstr ""
+msgstr "QMCMD^Poslat veřejnou zprávu do"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:783
 msgid "QMCMD^:-) / nice one"
-msgstr ""
+msgstr "QMCMD^:-) / hezký"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:783
 msgid "QMCMD^nice one"
-msgstr ""
+msgstr "QMCMD^hezký"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:784
 msgid "QMCMD^good game"
-msgstr ""
+msgstr "QMCMD^dobrá hra"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:785
 msgid "QMCMD^hi / good luck"
-msgstr ""
+msgstr "QMCMD^ahoj/hodně štěstí"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:785
 msgid "QMCMD^hi / good luck and have fun"
-msgstr ""
+msgstr "QMCMD^ahoj/hodně štěstí a užijte si hru"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:787
 msgid "QMCMD^Send in English"
-msgstr ""
+msgstr "QMCMD^Pošli v angličtině"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:792
 #: qcsrc/client/hud/panel/quickmenu.qc:808
 msgid "QMCMD^Team chat"
-msgstr ""
+msgstr "QMCMD^Týmový chat"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:793
 msgid "QMCMD^quad soon"
@@ -313,11 +317,11 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/quickmenu.qc:796
 msgid "QMCMD^negative"
-msgstr ""
+msgstr "QMCMD^negativní"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:797
 msgid "QMCMD^positive"
-msgstr ""
+msgstr "QMCMD^pozitivní"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:798
 msgid "QMCMD^need help (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
@@ -432,7 +436,7 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/quickmenu.qc:819
 msgid "QMCMD^FPS"
-msgstr ""
+msgstr "QMCMD^FPS"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:820
 msgid "QMCMD^Net graph"
@@ -441,15 +445,15 @@ msgstr ""
 #: qcsrc/client/hud/panel/quickmenu.qc:823
 #: qcsrc/client/hud/panel/quickmenu.qc:826
 msgid "QMCMD^Sound settings"
-msgstr ""
+msgstr "QMCMD^Nastavení zvuku"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:824
 msgid "QMCMD^Hit sound"
-msgstr ""
+msgstr "QMCMD^Zvuk zásahu"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:825
 msgid "QMCMD^Chat sound"
-msgstr ""
+msgstr "QMCMD^Zvuk chatu"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:830
 #: qcsrc/client/hud/panel/quickmenu.qc:834
@@ -596,7 +600,7 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/scoreboard.qc:91
 msgid "Number of deaths"
-msgstr ""
+msgstr "Počet smrtí"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:91
 msgid "SCO^deaths"
@@ -608,7 +612,7 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/scoreboard.qc:92
 msgid "SCO^destroyed"
-msgstr ""
+msgstr "SCO^zničen"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:93
 msgid "SCO^damage"
@@ -616,7 +620,7 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/scoreboard.qc:93
 msgid "The total damage done"
-msgstr ""
+msgstr "Celkový udělený damage"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:94
 msgid "SCO^dmgtaken"
@@ -644,7 +648,7 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/scoreboard.qc:97
 msgid "SCO^fastest"
-msgstr ""
+msgstr "SCO^nejrychlejší"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:97
 msgid "Time of fastest lap (Race/CTS)"
@@ -668,11 +672,11 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/scoreboard.qc:100
 msgid "FPS"
-msgstr ""
+msgstr "FPS"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:100
 msgid "SCO^fps"
-msgstr ""
+msgstr "SCO^fps"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:101
 msgid "Number of kills minus suicides"
@@ -730,36 +734,36 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/scoreboard.qc:108
 msgid "SCO^laps"
-msgstr ""
+msgstr "SCO^kola"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:109
 msgid "Number of lives (LMS)"
-msgstr ""
+msgstr "Počet životů (LMS)"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:109
 msgid "SCO^lives"
-msgstr ""
+msgstr "SCO^životy"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:110
 msgid "Number of times a key was lost"
-msgstr ""
+msgstr "Kolikrát byl ztracen klíč"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:110
 msgid "SCO^losses"
-msgstr ""
+msgstr "SCO^prohry"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:111
 #: qcsrc/client/hud/panel/scoreboard.qc:112
 msgid "Player name"
-msgstr ""
+msgstr "Jméno hráče"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:111
 msgid "SCO^name"
-msgstr ""
+msgstr "SCO^jméno"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:112
 msgid "SCO^nick"
-msgstr ""
+msgstr "SCO^přezdívka"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:113
 msgid "Number of objectives destroyed"
@@ -780,11 +784,11 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/scoreboard.qc:115
 msgid "Ping time"
-msgstr ""
+msgstr "Čas pingu"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:115
 msgid "SCO^ping"
-msgstr ""
+msgstr "SCO^ping"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:116
 msgid "Packet loss"
@@ -828,27 +832,27 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/scoreboard.qc:121
 msgid "Number of rounds won"
-msgstr ""
+msgstr "Počet vyhraných kol"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:121
 msgid "SCO^rounds won"
-msgstr ""
+msgstr "SCO^vyhraných kol"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:122
 msgid "SCO^score"
-msgstr ""
+msgstr "SCO^skóre"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:122
 msgid "Total score"
-msgstr ""
+msgstr "Celkové skóre"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:123
 msgid "Number of suicides"
-msgstr ""
+msgstr "Počet sebevražd"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:123
 msgid "SCO^suicides"
-msgstr ""
+msgstr "SCO^sebevraždy"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:124
 msgid "Number of kills minus deaths"
@@ -856,7 +860,7 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/scoreboard.qc:124
 msgid "SCO^sum"
-msgstr ""
+msgstr "SCO^součet"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:125
 msgid "Number of domination points taken (Domination)"
@@ -884,7 +888,7 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/scoreboard.qc:128
 msgid "SCO^time"
-msgstr ""
+msgstr "SCO^čas"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:128
 msgid "Total time raced (Race/CTS)"
@@ -897,7 +901,7 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/scoreboard.qc:313
 msgid "Usage:"
-msgstr ""
+msgstr "Použití:"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:315
 msgid "^2scoreboard_columns_set ^3field1 field2 ..."
@@ -978,11 +982,11 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1336
 msgid "Map stats:"
-msgstr ""
+msgstr "Statistiky mapy:"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1366
 msgid "Monsters killed:"
-msgstr ""
+msgstr "Zabitých monster:"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1373
 msgid "Secrets found:"
@@ -999,38 +1003,38 @@ msgstr ""
 #: qcsrc/client/hud/panel/scoreboard.qc:1613
 #, c-format
 msgid "^3%1.0f minutes"
-msgstr ""
+msgstr "^3%1.0f minuty"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1622
 #: qcsrc/client/hud/panel/scoreboard.qc:1629
 #, c-format
 msgid "^5%s %s"
-msgstr ""
+msgstr "^5%s %s"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1623
 #: qcsrc/client/hud/panel/scoreboard.qc:1630
 #: qcsrc/client/hud/panel/scoreboard.qc:1642
 #: qcsrc/client/hud/panel/scoreboard.qc:1649
 msgid "SCO^points"
-msgstr ""
+msgstr "SCO^body"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1624
 #: qcsrc/client/hud/panel/scoreboard.qc:1631
 #: qcsrc/client/hud/panel/scoreboard.qc:1643
 #: qcsrc/client/hud/panel/scoreboard.qc:1650
 msgid "SCO^is beaten"
-msgstr ""
+msgstr "SCO^je poražen"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1641
 #: qcsrc/client/hud/panel/scoreboard.qc:1648
 #, c-format
 msgid "^2+%s %s"
-msgstr ""
+msgstr "^2+%s %s"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1659
 #, c-format
 msgid "^7Map: ^2%s"
-msgstr ""
+msgstr "^7Mapa: ^2%s"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1798
 #, c-format
@@ -1060,7 +1064,7 @@ msgstr ""
 #: qcsrc/client/hud/panel/scoreboard.qc:1864
 #, c-format
 msgid "You are dead, press ^2%s^7 to respawn"
-msgstr ""
+msgstr "Jsi mrtvý, zmáčkni ^2%s^7 pro respawnutí"
 
 #: qcsrc/client/hud/panel/timer.qc:67
 msgid "WARMUP"
@@ -1095,7 +1099,7 @@ msgstr "^1Nastavit HUD"
 #: qcsrc/menu/xonotic/dialog_settings_misc_reset.qc:16
 #: qcsrc/menu/xonotic/dialog_uid2name.qc:15
 msgid "Yes"
-msgstr ""
+msgstr "Ano"
 
 #: qcsrc/client/hud/panel/vote.qc:128 qcsrc/menu/xonotic/dialog_firstrun.qc:83
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qc:21
@@ -1106,7 +1110,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_settings_misc_reset.qc:17
 #: qcsrc/menu/xonotic/dialog_uid2name.qc:17
 msgid "No"
-msgstr ""
+msgstr "Ne"
 
 #: qcsrc/client/hud/panel/weapons.qc:546
 msgid "Out of ammo"
@@ -1126,15 +1130,15 @@ msgstr ""
 
 #: qcsrc/client/main.qc:1029
 msgid " m/s"
-msgstr ""
+msgstr " m/s"
 
 #: qcsrc/client/main.qc:1031
 msgid " km/h"
-msgstr ""
+msgstr " km/h"
 
 #: qcsrc/client/main.qc:1033
 msgid " mph"
-msgstr ""
+msgstr " mph"
 
 #: qcsrc/client/main.qc:1035
 msgid " knots"
@@ -1147,12 +1151,12 @@ msgstr ""
 
 #: qcsrc/client/mapvoting.qc:52
 msgid " (1 vote)"
-msgstr ""
+msgstr "(1 hlas)"
 
 #: qcsrc/client/mapvoting.qc:54
 #, c-format
 msgid " (%d votes)"
-msgstr ""
+msgstr " (%d hlasů)"
 
 #: qcsrc/client/mapvoting.qc:274
 msgid "Don't care"
@@ -1164,12 +1168,12 @@ msgstr ""
 
 #: qcsrc/client/mapvoting.qc:375
 msgid "Vote for a map"
-msgstr ""
+msgstr "Hlasovat pro mapu"
 
 #: qcsrc/client/mapvoting.qc:392
 #, c-format
 msgid "%d seconds left"
-msgstr ""
+msgstr "zbývá%d sekund"
 
 #: qcsrc/client/mapvoting.qc:505
 msgid "mv_mapdownload: ^3You're not supposed to use this command on your own!"
@@ -1213,7 +1217,7 @@ msgstr ""
 
 #: qcsrc/common/items/item/ammo.qh:66
 msgid "bullets"
-msgstr ""
+msgstr "náboje"
 
 #: qcsrc/common/items/item/ammo.qh:96
 msgid "cells"
@@ -1221,11 +1225,11 @@ msgstr ""
 
 #: qcsrc/common/items/item/ammo.qh:126
 msgid "plasma"
-msgstr ""
+msgstr "plazma"
 
 #: qcsrc/common/items/item/ammo.qh:156
 msgid "rockets"
-msgstr ""
+msgstr "rakety"
 
 #: qcsrc/common/items/item/ammo.qh:190
 msgid "shells"
@@ -1233,7 +1237,7 @@ msgstr ""
 
 #: qcsrc/common/items/item/armor.qh:42
 msgid "Small armor"
-msgstr ""
+msgstr "malé brnění"
 
 #: qcsrc/common/items/item/armor.qh:80
 msgid "Medium armor"
@@ -4987,32 +4991,32 @@ msgstr ""
 #: qcsrc/common/util.qc:1584
 #, c-format
 msgid "UP"
-msgstr ""
+msgstr "NAHORU"
 
 #: qcsrc/common/util.qc:1585
 #, c-format
 msgid "DOWN"
-msgstr ""
+msgstr "DOLŮ"
 
 #: qcsrc/common/util.qc:1586
 #, c-format
 msgid "LEFT"
-msgstr ""
+msgstr "DOLEVA"
 
 #: qcsrc/common/util.qc:1587
 #, c-format
 msgid "RIGHT"
-msgstr ""
+msgstr "DOPRAVA"
 
 #: qcsrc/common/util.qc:1593
 #, c-format
 msgid "MIDINOTE%d"
-msgstr ""
+msgstr "MIDI NOTA%d"
 
 #: qcsrc/common/vehicles/cl_vehicles.qc:190
 #, c-format
 msgid "Press %s"
-msgstr ""
+msgstr "Zmáčkni %s"
 
 #: qcsrc/common/vehicles/vehicle/bumblebee.qc:947
 msgid "No right gunner!"
@@ -5080,11 +5084,11 @@ msgstr ""
 
 #: qcsrc/common/weapons/weapon/fireball.qh:18
 msgid "Fireball"
-msgstr ""
+msgstr "Ohnivá koule"
 
 #: qcsrc/common/weapons/weapon/hagar.qh:18
 msgid "Hagar"
-msgstr ""
+msgstr "Hagar"
 
 #: qcsrc/common/weapons/weapon/hlac.qh:18
 msgid "Heavy Laser Assault Cannon"
@@ -5322,26 +5326,26 @@ msgstr ""
 #: qcsrc/lib/counting.qh:79
 #, c-format
 msgid "%dst"
-msgstr ""
+msgstr "%d."
 
 #: qcsrc/lib/counting.qh:80
 #, c-format
 msgid "%dnd"
-msgstr ""
+msgstr "%d."
 
 #: qcsrc/lib/counting.qh:81
 #, c-format
 msgid "%drd"
-msgstr ""
+msgstr "%d."
 
 #: qcsrc/lib/counting.qh:82 qcsrc/lib/counting.qh:85
 #, c-format
 msgid "%dth"
-msgstr ""
+msgstr "%d."
 
 #: qcsrc/lib/oo.qh:330
 msgid "No description"
-msgstr ""
+msgstr "Bez popisu"
 
 #: qcsrc/lib/spawnfunc.qh:240
 #, c-format
@@ -5378,7 +5382,7 @@ msgstr ""
 
 #: qcsrc/menu/command/menu_cmd.qc:81
 msgid "Available options:"
-msgstr ""
+msgstr "Dostupné možnosti:"
 
 #: qcsrc/menu/command/menu_cmd.qc:130
 msgid "Invalid command. For a list of supported commands, try menu_cmd help."
@@ -5387,19 +5391,19 @@ msgstr ""
 #: qcsrc/menu/item/listbox.qc:413
 #, c-format
 msgid "Item %d"
-msgstr ""
+msgstr "Item %d"
 
 #: 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 ""
+msgstr "Vlastní"
 
 #: qcsrc/menu/xonotic/campaign.qc:235
 #, c-format
 msgid "Level %d: %s"
-msgstr ""
+msgstr "Level %d: %s"
 
 #: qcsrc/menu/xonotic/credits.qc:4
 msgid "Core Team"
@@ -5411,11 +5415,11 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/credits.qc:48
 msgid "Website"
-msgstr ""
+msgstr "Stránka"
 
 #: qcsrc/menu/xonotic/credits.qc:53
 msgid "Stats"
-msgstr ""
+msgstr "Statistiky"
 
 #: qcsrc/menu/xonotic/credits.qc:57
 msgid "Art"
@@ -5423,19 +5427,19 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/credits.qc:65
 msgid "Animation"
-msgstr ""
+msgstr "Animace"
 
 #: qcsrc/menu/xonotic/credits.qc:69
 msgid "Level Design"
-msgstr ""
+msgstr "Design levelů"
 
 #: qcsrc/menu/xonotic/credits.qc:92
 msgid "Music / Sound FX"
-msgstr ""
+msgstr "Hudba / Zvuky FX"
 
 #: qcsrc/menu/xonotic/credits.qc:108
 msgid "Game Code"
-msgstr ""
+msgstr "Kód hry"
 
 #: qcsrc/menu/xonotic/credits.qc:116
 msgid "Marketing / PR"
@@ -5583,23 +5587,23 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/cvarlist.qc:79 qcsrc/menu/xonotic/cvarlist.qc:89
 msgid "will not be saved"
-msgstr ""
+msgstr "nebude uloženo"
 
 #: qcsrc/menu/xonotic/cvarlist.qc:84
 msgid "will be saved to config.cfg"
-msgstr ""
+msgstr "bude uloženo do config.cfg"
 
 #: qcsrc/menu/xonotic/cvarlist.qc:93
 msgid "private"
-msgstr ""
+msgstr "soukromé"
 
 #: qcsrc/menu/xonotic/cvarlist.qc:95
 msgid "engine setting"
-msgstr ""
+msgstr "nastavení enginu"
 
 #: qcsrc/menu/xonotic/cvarlist.qc:97
 msgid "read only"
-msgstr ""
+msgstr "jen ke čtení"
 
 #: qcsrc/menu/xonotic/dialog_credits.qc:13
 #: qcsrc/menu/xonotic/dialog_monstertools.qc:38
@@ -5608,7 +5612,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc:75
 #: qcsrc/menu/xonotic/dialog_singleplayer_winner.qc:14
 msgid "OK"
-msgstr ""
+msgstr "OK"
 
 #: qcsrc/menu/xonotic/dialog_credits.qh:7
 msgid "Credits"
@@ -5624,20 +5628,22 @@ msgid ""
 "player name to get started.  You can change these options later through the "
 "menu system."
 msgstr ""
+"Vítej v Xonotic, abys mohl začít, vyber si prosím svůj jazyk a zvol si "
+"jméno. Tyto možnosti si potom můžeš změnit v nastavení."
 
 #: qcsrc/menu/xonotic/dialog_firstrun.qc:45
 #: qcsrc/menu/xonotic/dialog_settings_input_userbind.qc:28
 msgid "Name:"
-msgstr ""
+msgstr "Jméno:"
 
 #: qcsrc/menu/xonotic/dialog_firstrun.qc:53
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:64
 msgid "Name under which you will appear in the game"
-msgstr ""
+msgstr "Jméno pod kterým budeš vystupovat ve hře"
 
 #: qcsrc/menu/xonotic/dialog_firstrun.qc:69
 msgid "Text language:"
-msgstr ""
+msgstr "Jazyk textu:"
 
 #: qcsrc/menu/xonotic/dialog_firstrun.qc:78
 msgid "Allow player statistics to use your nickname at stats.xonotic.org?"
@@ -5646,15 +5652,15 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_firstrun.qc:84
 msgid "Undecided"
-msgstr ""
+msgstr "Nerozhodnutý"
 
 #: qcsrc/menu/xonotic/dialog_firstrun.qc:88
 msgid "Save settings"
-msgstr ""
+msgstr "Uložit nastavení"
 
 #: qcsrc/menu/xonotic/dialog_firstrun.qh:6
 msgid "Welcome"
-msgstr ""
+msgstr "Vítej"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc:18
 msgid "Ammunition display:"
@@ -5689,7 +5695,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_hudpanel_quickmenu.qc:21
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:57
 msgid "Left"
-msgstr ""
+msgstr "Levý"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc:34
 #: qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc:34
@@ -5701,7 +5707,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_hudpanel_quickmenu.qc:23
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:59
 msgid "Right"
-msgstr ""
+msgstr "Pravý"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_ammo.qh:6
 msgid "Ammo Panel"
@@ -5728,11 +5734,11 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_hudpanel_quickmenu.qc:22
 #: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:71
 msgid "Center"
-msgstr ""
+msgstr "Střed"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qc:37
 msgid "Font scale:"
-msgstr ""
+msgstr "Škála písma"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qh:6
 msgid "Centerprint Panel"
@@ -5744,23 +5750,23 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_chat.qc:20
 msgid "Chat size:"
-msgstr ""
+msgstr "Velikost chatu:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_chat.qc:24
 msgid "Chat lifetime:"
-msgstr ""
+msgstr "Životnost chatu:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_chat.qc:28
 msgid "Chat beep sound"
-msgstr ""
+msgstr "Zvuk pípnutí chatu"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_chat.qh:6
 msgid "Chat Panel"
-msgstr ""
+msgstr "Panel chatu"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_engineinfo.qc:16
 msgid "Engine info:"
-msgstr ""
+msgstr "Info o enginu:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_engineinfo.qc:19
 msgid "Use an averaging algorithm for fps"
@@ -5772,7 +5778,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:17
 msgid "Combine health and armor"
-msgstr ""
+msgstr "Kombinovat životy a brnění"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:19
 #: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:28
@@ -5835,7 +5841,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/util.qc:778 qcsrc/menu/xonotic/util.qc:794
 #: qcsrc/menu/xonotic/util.qc:811
 msgid "Disable"
-msgstr ""
+msgstr "Zákázat"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:17
 #: qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qc:15
@@ -5852,7 +5858,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:32
 msgid "Text/icon ratio:"
-msgstr ""
+msgstr "Poměr textu/ikon:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:35
 msgid "Hide spawned items"
@@ -5864,7 +5870,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:39
 msgid "Dynamic size"
-msgstr ""
+msgstr "Dynamická velikost"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qh:6
 msgid "Items Time Panel"
@@ -5876,7 +5882,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_notification.qc:17
 msgid "Notifications:"
-msgstr ""
+msgstr "Notifikace:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_notification.qc:20
 msgid "Also print notifications to the console"
@@ -5896,12 +5902,12 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_notification.qh:6
 msgid "Notification Panel"
-msgstr ""
+msgstr "Panel notifikací"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:16
 #: qcsrc/menu/xonotic/util.qc:766
 msgid "Enable"
-msgstr ""
+msgstr "Povolit"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:17
 msgid "Enable even observing"
@@ -5939,7 +5945,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:37
 msgid "Speed:"
-msgstr ""
+msgstr "Rychlost:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:38
 msgid "Include vertical speed"
@@ -5951,19 +5957,19 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:51
 msgid "qu/s"
-msgstr ""
+msgstr "qu/s"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:52
 msgid "m/s"
-msgstr ""
+msgstr "m/s"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:53
 msgid "km/h"
-msgstr ""
+msgstr "km/h"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:54
 msgid "mph"
-msgstr ""
+msgstr "mph"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:55
 msgid "knots"
@@ -5971,15 +5977,15 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:57
 msgid "Show"
-msgstr ""
+msgstr "Ukázat"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:60
 msgid "Top speed"
-msgstr ""
+msgstr "Nejvyšší rychlost"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:66
 msgid "Acceleration:"
-msgstr ""
+msgstr "Zrychlování:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:67
 msgid "Include vertical acceleration"
@@ -5987,7 +5993,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qh:6
 msgid "Physics Panel"
-msgstr ""
+msgstr "Panel fyziky"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_powerups.qh:6
 msgid "Powerups Panel"
@@ -5996,7 +6002,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qc:16
 #: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:17
 msgid "Always enable"
-msgstr ""
+msgstr "Vždy povolit"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qc:23
 msgid "Forced aspect:"
@@ -6020,7 +6026,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:23
 msgid "Radar:"
-msgstr ""
+msgstr "Radar:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:26
 #: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:68
@@ -6041,39 +6047,39 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:32
 msgid "Forward"
-msgstr ""
+msgstr "Vpřed"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:33
 msgid "West"
-msgstr ""
+msgstr "Západ"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:34
 msgid "South"
-msgstr ""
+msgstr "Jih"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:35
 msgid "East"
-msgstr ""
+msgstr "Východ"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:36
 msgid "North"
-msgstr ""
+msgstr "Sever"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:40
 msgid "Scale:"
-msgstr ""
+msgstr "Škála:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:44
 msgid "Zoom mode:"
-msgstr ""
+msgstr "Režim přibližování:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:46
 msgid "Zoomed in"
-msgstr ""
+msgstr "Přiblížen"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:47
 msgid "Zoomed out"
-msgstr ""
+msgstr "Oddálený"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:48
 msgid "Always zoomed"
@@ -8501,11 +8507,11 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:40
 msgid "Up"
-msgstr ""
+msgstr "Nahoru"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:44
 msgid "Down"
-msgstr ""
+msgstr "Dolů"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:50
 msgid "Use priority list for weapon cycling"
@@ -8518,17 +8524,19 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:53
 msgid "Cycle through only usable weapon selections"
-msgstr ""
+msgstr "Cyklovat jen mezi použitelnými výběry zbraní"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:57
 msgid "Auto switch weapons on pickup"
-msgstr ""
+msgstr "Automaticky měnit zbraň po sebrání"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:58
 msgid ""
 "Automatically switch to newly picked up weapons if they are better than what "
 "you are carrying"
 msgstr ""
+"Automaticky změnit na právě sebranou zbraň, jestli je novější lepší než "
+"starší"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:61
 msgid "Release attack buttons when you switch weapons"
@@ -8563,39 +8571,39 @@ msgstr "Zbraně"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:34
 msgid "Key Bindings"
-msgstr ""
+msgstr "Klávesové zkratky"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:38
 msgid "Change key..."
-msgstr ""
+msgstr "Změnit klávesu"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:42
 msgid "Edit..."
-msgstr ""
+msgstr "Upravit"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:48
 msgid "Clear"
-msgstr ""
+msgstr "Vymazat"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:53
 msgid "Reset all"
-msgstr ""
+msgstr "Resetovat vše"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:58
 msgid "Mouse"
-msgstr ""
+msgstr "Myš"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:60
 msgid "Sensitivity:"
-msgstr ""
+msgstr "Sensitivita:"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:62
 msgid "Mouse speed multiplier"
-msgstr ""
+msgstr "Násobič rychlosti myši"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:64
 msgid "Smooth aiming"
-msgstr ""
+msgstr "Jemné míření"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:65
 msgid "Smoothes the mouse movement, but makes aiming slightly less responsive"
@@ -8603,7 +8611,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:67
 msgid "Invert aiming"
-msgstr ""
+msgstr "Invertovat míření"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:68
 msgid "Invert mouse movement on the Y-axis"
@@ -8615,13 +8623,13 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:75
 msgid "Enable built in mouse acceleration"
-msgstr ""
+msgstr "Použít zabudované zrychlení myši"
 
 #: 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 ""
+msgstr "Zakázat systémové zrychlení myši"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:80
 msgid "Make use of DGA mouse input"
@@ -8649,7 +8657,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:103
 msgid "Air only"
-msgstr ""
+msgstr "Jen vzduch"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:104
 msgid "JPJUMP^All"
@@ -8659,7 +8667,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:115
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:120
 msgid "Use joystick input"
-msgstr ""
+msgstr "Použít vstup joysticku"
 
 #: qcsrc/menu/xonotic/dialog_settings_input_userbind.qc:31
 msgid "Command when pressed:"
@@ -8671,30 +8679,30 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_input_userbind.qc:40
 msgid "Cancel"
-msgstr ""
+msgstr "Zrušit"
 
 #: qcsrc/menu/xonotic/dialog_settings_input_userbind.qh:7
 msgid "User defined key bind"
-msgstr ""
+msgstr "Uživatelem definovaná kláv. zkratka"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:11
 #, c-format
 msgid "%d fps"
-msgstr ""
+msgstr "%d fps"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:12
 #, c-format
 msgid "%d KB/s"
-msgstr ""
+msgstr "%d KB/s"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:13
 #, c-format
 msgid "%d MB/s"
-msgstr ""
+msgstr "%d MB/s"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
 msgid "Network"
-msgstr ""
+msgstr "Síť"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
 msgid "Client UDP port:"
@@ -8710,7 +8718,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
 msgid "Specify your network speed"
-msgstr ""
+msgstr "Upřesní svou rychlost internetu"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
 msgid "56k"
@@ -8718,15 +8726,15 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "ISDN"
-msgstr ""
+msgstr "ISDN"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "Slow ADSL"
-msgstr ""
+msgstr "Pomalé ADSL"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Fast ADSL"
-msgstr ""
+msgstr "Rychlé ADSL"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Broadband"
@@ -8746,7 +8754,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
 msgid "Downloads:"
-msgstr ""
+msgstr "Stahování:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
 msgid "Maximum number of concurrent HTTP/FTP downloads"
@@ -8754,7 +8762,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:56
 msgid "Download speed:"
-msgstr ""
+msgstr "Rychlost stahování:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Local latency:"
@@ -8786,7 +8794,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
 msgid "Maximum:"
-msgstr ""
+msgstr "Maximum:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:99
 msgid "MAXFPS^Unlimited"
@@ -8794,7 +8802,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
 msgid "Target:"
-msgstr ""
+msgstr "Cíl:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
 msgid "TRGT^Disabled"
@@ -8814,11 +8822,11 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:129
 msgid "Show frames per second"
-msgstr ""
+msgstr "Ukázat snímky za sekundu"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:130
 msgid "Show your rendered frames per second"
-msgstr ""
+msgstr "Ukáže tvé vyrenderované snímky za sekundu"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:135
 msgid "Menu tooltips:"
@@ -8844,23 +8852,23 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:143
 msgid "Show current date and time"
-msgstr ""
+msgstr "Ukázat aktuální datum a čas"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:144
 msgid "Show current date and time of day, useful on screenshots"
-msgstr ""
+msgstr "Ukázat aktuální datum a čas, užitečné na snímcích obrazovky"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:147
 msgid "Enable developer mode"
-msgstr ""
+msgstr "Povolit vývojářský režim"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:151
 msgid "Advanced settings..."
-msgstr ""
+msgstr "Pokročilé nastavení..."
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:152
 msgid "Advanced settings where you can tweak every single variable of the game"
-msgstr ""
+msgstr "Pokročilé nastavení, kde můžeš měnit každou proměnou ve hře"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:157
 #: qcsrc/menu/xonotic/dialog_settings_misc_reset.qh:6
@@ -8869,43 +8877,43 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc:31
 msgid "Cvar filter:"
-msgstr ""
+msgstr "Filtr cvar:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc:38
 msgid "Modified cvars only"
-msgstr ""
+msgstr "Jen modifikované cvary"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc:45
 msgid "Setting:"
-msgstr ""
+msgstr "Nastavení:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc:49
 msgid "Type:"
-msgstr ""
+msgstr "Typ:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc:53
 msgid "Value:"
-msgstr ""
+msgstr "Hodnota:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc:70
 msgid "Description:"
-msgstr ""
+msgstr "Popis:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qh:7
 msgid "Advanced settings"
-msgstr ""
+msgstr "Pokročilé nastavení"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc_reset.qc:11
 msgid "Are you sure you want to reset all settings?"
-msgstr ""
+msgstr "Jsi si jistý, že chceš resetovat všechna nastavení?"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc_reset.qc:13
 msgid "This will create a backup config in your data directory"
-msgstr ""
+msgstr "Tohle vytvoří zálohu configu v tvé data složce"
 
 #: qcsrc/menu/xonotic/dialog_settings_user.qc:25
 msgid "Menu Skins"
-msgstr ""
+msgstr "Skiny menu"
 
 #: qcsrc/menu/xonotic/dialog_settings_user.qc:64
 msgid "Text Language"
@@ -8913,11 +8921,11 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_user.qc:69
 msgid "Set language"
-msgstr ""
+msgstr "Nastavit jazyk"
 
 #: qcsrc/menu/xonotic/dialog_settings_user.qc:74
 msgid "Disable gore effects and harsh language"
-msgstr ""
+msgstr "Zakázat násilí a sprostý jazyk"
 
 #: qcsrc/menu/xonotic/dialog_settings_user.qc:75
 msgid "Replace blood and gibs with content that does not have any gore effects"
@@ -8933,23 +8941,23 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc:16
 msgid "Disconnect now"
-msgstr ""
+msgstr "Odpojit teď"
 
 #: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc:17
 msgid "Switch language"
-msgstr ""
+msgstr "Změnit jazyk"
 
 #: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qh:6
 msgid "Warning"
-msgstr ""
+msgstr "Varování"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:33
 msgid "Resolution:"
-msgstr ""
+msgstr "Rozlišení:"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:37
 msgid "Font/UI size:"
-msgstr ""
+msgstr "Velikost písma/UI"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:39
 msgid "SZ^Unreadable"
@@ -8989,7 +8997,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:51
 msgid "Color depth:"
-msgstr ""
+msgstr "Hloubka barev:"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:53
 msgid "How many bits per pixel (BPP) to render at, 32 is recommended"
@@ -8997,19 +9005,19 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:54
 msgid "16bit"
-msgstr ""
+msgstr "16bitový"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:55
 msgid "32bit"
-msgstr ""
+msgstr "32bitový"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:59
 msgid "Full screen"
-msgstr ""
+msgstr "Celá obrazovka"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:61
 msgid "Vertical Synchronization"
-msgstr ""
+msgstr "Vertikální synchronizace"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:62
 msgid ""
@@ -9031,7 +9039,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:73
 msgid "Anisotropic filtering quality"
-msgstr ""
+msgstr "Kvalita anizotropního filtrování"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid "ANISO^Disabled"
@@ -9040,20 +9048,20 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:75
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:86
 msgid "2x"
-msgstr ""
+msgstr "2x"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:76
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:87
 msgid "4x"
-msgstr ""
+msgstr "4x"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:77
 msgid "8x"
-msgstr ""
+msgstr "8x"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:78
 msgid "16x"
-msgstr ""
+msgstr "16x"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:81
 msgid "Antialiasing:"
@@ -9075,7 +9083,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:97
 msgid "Depth first:"
-msgstr ""
+msgstr "Hloubka prvně:"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:99
 msgid ""
@@ -9125,23 +9133,23 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:119
 msgid "Brightness:"
-msgstr ""
+msgstr "Jas:"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:121
 msgid "Brightness of black"
-msgstr ""
+msgstr "Jas černé"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:123
 msgid "Contrast:"
-msgstr ""
+msgstr "Kontrast:"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "Brightness of white"
-msgstr ""
+msgstr "Jas bílé"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:127
 msgid "Gamma:"
-msgstr ""
+msgstr "Gamma:"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:130
 msgid ""
@@ -9155,17 +9163,19 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:136
 msgid "By how much to multiply the contrast in dark areas"
-msgstr ""
+msgstr "Kolikati násobit kontrast v tmavých oblastech"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Saturation:"
-msgstr ""
+msgstr "Sytost:"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:142
 msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control"
 msgstr ""
+"Upravení sytosti (0 = černobílé, 1 = normální, 2 = přesycené), potřebuje "
+"kontrolování barev GLSL "
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:146
 msgid "LIT^Ambient:"
@@ -9179,15 +9189,15 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Intensity:"
-msgstr ""
+msgstr "Intenzita:"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:152
 msgid "Global rendering brightness"
-msgstr ""
+msgstr "Globální jas renderování"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:155
 msgid "Wait for GPU to finish each frame"
-msgstr ""
+msgstr "Počkat než GPU dokončí každý snímek"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:156
 msgid ""
@@ -9197,7 +9207,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:158
 msgid "Use OpenGL 2.0 shaders (GLSL)"
-msgstr ""
+msgstr "Použít OpenGL 2.0 shadery (GLSL)"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:162
 msgid "Use GLSL to handle color control"
@@ -9219,7 +9229,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_singleplayer.qc:110
 msgid "Instant action! (random map with bots)"
-msgstr ""
+msgstr "Instantní akce! (náhodná mapa s boty)"
 
 #: qcsrc/menu/xonotic/dialog_singleplayer.qc:117
 msgid "???"
@@ -9243,11 +9253,11 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_singleplayer.qc:135
 msgid "Start Singleplayer!"
-msgstr ""
+msgstr "Začít hru jednoho hráče"
 
 #: qcsrc/menu/xonotic/dialog_singleplayer.qh:6
 msgid "Singleplayer"
-msgstr ""
+msgstr "Hra jednoho hráče"
 
 #: qcsrc/menu/xonotic/dialog_singleplayer.qh:7
 msgid "Play the singleplayer campaign or instant action matches against bots"
@@ -9255,31 +9265,31 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_singleplayer_winner.qh:7
 msgid "Winner"
-msgstr ""
+msgstr "Vítěz"
 
 #: qcsrc/menu/xonotic/dialog_teamselect.qc:32
 msgid "join 'best' team (auto-select)"
-msgstr ""
+msgstr "připojit se k 'nejlepšímu' týmu (automatický výběr)"
 
 #: qcsrc/menu/xonotic/dialog_teamselect.qc:33
 msgid "Autoselect team (recommended)"
-msgstr ""
+msgstr "Automaticky vybrat tým (doporučeno)"
 
 #: qcsrc/menu/xonotic/dialog_teamselect.qc:37
 msgid "red"
-msgstr ""
+msgstr "červená"
 
 #: qcsrc/menu/xonotic/dialog_teamselect.qc:38
 msgid "blue"
-msgstr ""
+msgstr "modrá"
 
 #: qcsrc/menu/xonotic/dialog_teamselect.qc:39
 msgid "yellow"
-msgstr ""
+msgstr "žlutá"
 
 #: qcsrc/menu/xonotic/dialog_teamselect.qc:40
 msgid "pink"
-msgstr ""
+msgstr "růžová"
 
 #: qcsrc/menu/xonotic/dialog_teamselect.qc:43
 msgid "spectate"
@@ -9287,15 +9297,15 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_teamselect.qh:7
 msgid "Team Selection"
-msgstr ""
+msgstr "Vybírání týmů"
 
 #: qcsrc/menu/xonotic/dialog_uid2name.qc:10
 msgid "Allow player statistics to use your nickname?"
-msgstr ""
+msgstr "Povolit používání Vaší přezdívky v hráčské statistice?"
 
 #: qcsrc/menu/xonotic/dialog_uid2name.qc:12
 msgid "Answering \"No\" you will appear as \"Anonymous player\""
-msgstr ""
+msgstr "Pokud odpovíš \"ne\", objevíš se jako \"Anonymní hráč\""
 
 #: qcsrc/menu/xonotic/gametypelist.qc:87
 msgid "teamplay"
@@ -9311,7 +9321,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/keybinder.qc:36
 msgid "forward"
-msgstr ""
+msgstr "dopředu"
 
 #: qcsrc/menu/xonotic/keybinder.qc:37
 msgid "backpedal"
@@ -9339,11 +9349,11 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/keybinder.qc:43
 msgid "jetpack"
-msgstr ""
+msgstr "jetpack"
 
 #: qcsrc/menu/xonotic/keybinder.qc:46
 msgid "Attacking"
-msgstr ""
+msgstr "Útočení"
 
 #: qcsrc/menu/xonotic/keybinder.qc:52
 msgid "WEAPON^previous"
@@ -9379,19 +9389,19 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/keybinder.qc:88
 msgid "show scores"
-msgstr ""
+msgstr "ukázat skóre"
 
 #: qcsrc/menu/xonotic/keybinder.qc:89
 msgid "screen shot"
-msgstr ""
+msgstr "snímek obrazovky"
 
 #: qcsrc/menu/xonotic/keybinder.qc:90
 msgid "maximize radar"
-msgstr ""
+msgstr "maximalizovat radar"
 
 #: qcsrc/menu/xonotic/keybinder.qc:91
 msgid "3rd person view"
-msgstr ""
+msgstr "pohled 3. osoby"
 
 #: qcsrc/menu/xonotic/keybinder.qc:92
 msgid "enter spectator mode"
@@ -9399,43 +9409,43 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/keybinder.qc:95
 msgid "Communicate"
-msgstr ""
+msgstr "Komunikovat"
 
 #: qcsrc/menu/xonotic/keybinder.qc:96
 msgid "public chat"
-msgstr ""
+msgstr "veřejný chat"
 
 #: qcsrc/menu/xonotic/keybinder.qc:97 qcsrc/menu/xonotic/keybinder.qc:115
 msgid "team chat"
-msgstr ""
+msgstr "týmový chat"
 
 #: qcsrc/menu/xonotic/keybinder.qc:98
 msgid "show chat history"
-msgstr ""
+msgstr "ukázat historii chatu"
 
 #: qcsrc/menu/xonotic/keybinder.qc:99
 msgid "vote YES"
-msgstr ""
+msgstr "volit ANO"
 
 #: qcsrc/menu/xonotic/keybinder.qc:100
 msgid "vote NO"
-msgstr ""
+msgstr "volit NE"
 
 #: qcsrc/menu/xonotic/keybinder.qc:104
 msgid "Client"
-msgstr ""
+msgstr "Klient"
 
 #: qcsrc/menu/xonotic/keybinder.qc:108
 msgid "enter console"
-msgstr ""
+msgstr "vstoupit do konzole"
 
 #: qcsrc/menu/xonotic/keybinder.qc:110
 msgid "disconnect"
-msgstr ""
+msgstr "odpojit"
 
 #: qcsrc/menu/xonotic/keybinder.qc:111
 msgid "quit"
-msgstr ""
+msgstr "opustit"
 
 #: qcsrc/menu/xonotic/keybinder.qc:116
 msgid "auto-join team"
@@ -9467,7 +9477,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/mainwindow.qc:65 qcsrc/menu/xonotic/mainwindow.qc:68
 msgid "Do not press this button again!"
-msgstr ""
+msgstr "Neklikej znova na tohle tlačítko!"
 
 #: qcsrc/menu/xonotic/maplist.qc:288
 msgid ""
@@ -9491,21 +9501,22 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/playermodel.qc:161
 msgid "<no model found>"
-msgstr ""
+msgstr "<no model found>"
 
 #: qcsrc/menu/xonotic/serverlist.qc:267
 msgid "Favorite"
-msgstr ""
+msgstr "Oblíbené"
 
 #: qcsrc/menu/xonotic/serverlist.qc:268
 msgid ""
 "Bookmark the currently highlighted server so that it's faster to find in the "
 "future"
 msgstr ""
+"Přidat označený server do záložek, aby byl jednodušší najít v budoucnosti."
 
 #: qcsrc/menu/xonotic/serverlist.qc:747
 msgid "Ping"
-msgstr ""
+msgstr "Odezva"
 
 #: qcsrc/menu/xonotic/serverlist.qc:748
 msgid "Hostname"
@@ -9513,11 +9524,11 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.qc:749
 msgid "Map"
-msgstr ""
+msgstr "Mapa"
 
 #: qcsrc/menu/xonotic/serverlist.qc:750
 msgid "Type"
-msgstr ""
+msgstr "Typ"
 
 #: qcsrc/menu/xonotic/serverlist.qc:1043
 #, c-format
@@ -9530,7 +9541,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.qc:1043
 msgid "encryption:"
-msgstr ""
+msgstr "šifrování:"
 
 #: qcsrc/menu/xonotic/serverlist.qc:1044
 #, c-format
@@ -9540,20 +9551,20 @@ msgstr ""
 #: qcsrc/menu/xonotic/serverlist.qc:1046
 #, c-format
 msgid "modified settings"
-msgstr ""
+msgstr "modifikované nastavení"
 
 #: qcsrc/menu/xonotic/serverlist.qc:1046
 #, c-format
 msgid "official settings"
-msgstr ""
+msgstr "oficiální nastavení"
 
 #: qcsrc/menu/xonotic/serverlist.qc:1048
 msgid "stats disabled"
-msgstr ""
+msgstr "statistiky zakázány"
 
 #: qcsrc/menu/xonotic/serverlist.qc:1048
 msgid "stats enabled"
-msgstr ""
+msgstr "statistiky povoleny"
 
 #: qcsrc/menu/xonotic/serverlist.qh:152
 msgid "SLCAT^Favorites"
@@ -9593,11 +9604,11 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/skinlist.qc:70
 msgid "<TITLE>"
-msgstr ""
+msgstr "<TITLE>"
 
 #: qcsrc/menu/xonotic/skinlist.qc:71
 msgid "<AUTHOR>"
-msgstr ""
+msgstr "<AUTHOR>"
 
 #: qcsrc/menu/xonotic/slider_decibels.qc:72
 msgid "VOL^MAX"
@@ -9610,7 +9621,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/slider_decibels.qc:82
 #, c-format
 msgid "%s dB"
-msgstr ""
+msgstr "%s db"
 
 #: qcsrc/menu/xonotic/slider_particles.qc:14
 msgid "PART^OMG"
@@ -9649,7 +9660,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/slider_resolution.qc:115
 msgid "Screen resolution"
-msgstr ""
+msgstr "Rozlišení obrazovky"
 
 #: qcsrc/menu/xonotic/slider_sbfadetime.qc:13
 msgid "PART^Slow"
@@ -9665,51 +9676,51 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/statslist.qc:29
 msgid "January"
-msgstr ""
+msgstr "Leden"
 
 #: qcsrc/menu/xonotic/statslist.qc:30
 msgid "February"
-msgstr ""
+msgstr "Únor"
 
 #: qcsrc/menu/xonotic/statslist.qc:31
 msgid "March"
-msgstr ""
+msgstr "Březen"
 
 #: qcsrc/menu/xonotic/statslist.qc:32
 msgid "April"
-msgstr ""
+msgstr "Duben"
 
 #: qcsrc/menu/xonotic/statslist.qc:33
 msgid "May"
-msgstr ""
+msgstr "Květen"
 
 #: qcsrc/menu/xonotic/statslist.qc:34
 msgid "June"
-msgstr ""
+msgstr "Červen"
 
 #: qcsrc/menu/xonotic/statslist.qc:35
 msgid "July"
-msgstr ""
+msgstr "Červenec"
 
 #: qcsrc/menu/xonotic/statslist.qc:36
 msgid "August"
-msgstr ""
+msgstr "Srpen"
 
 #: qcsrc/menu/xonotic/statslist.qc:37
 msgid "September"
-msgstr ""
+msgstr "Září"
 
 #: qcsrc/menu/xonotic/statslist.qc:38
 msgid "October"
-msgstr ""
+msgstr "Říjen"
 
 #: qcsrc/menu/xonotic/statslist.qc:39
 msgid "November"
-msgstr ""
+msgstr "Listopad"
 
 #: qcsrc/menu/xonotic/statslist.qc:40
 msgid "December"
-msgstr ""
+msgstr "Prosinec"
 
 #: qcsrc/menu/xonotic/statslist.qc:96
 msgid "Joined:"
@@ -9717,26 +9728,26 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/statslist.qc:103
 msgid "Last match:"
-msgstr ""
+msgstr "Poslední zápas:"
 
 #: qcsrc/menu/xonotic/statslist.qc:110
 msgid "Time played:"
-msgstr ""
+msgstr "Odehraný čas:"
 
 #: qcsrc/menu/xonotic/statslist.qc:117 qcsrc/menu/xonotic/statslist.qc:230
 msgid "Favorite map:"
-msgstr ""
+msgstr "Oblíbená mapa:"
 
 #: qcsrc/menu/xonotic/statslist.qc:149 qcsrc/menu/xonotic/statslist.qc:201
 #: qcsrc/menu/xonotic/statslist.qc:244
 #, c-format
 msgid "Matches:"
-msgstr ""
+msgstr "Zápasy:"
 
 #: qcsrc/menu/xonotic/statslist.qc:154
 #, c-format
 msgid "Wins/Losses:"
-msgstr ""
+msgstr "Výhry/Prohry:"
 
 #: qcsrc/menu/xonotic/statslist.qc:155
 #, c-format
@@ -9772,7 +9783,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/util.qc:417
 msgid "Update can be downloaded at:"
-msgstr ""
+msgstr "Update je ke stažení na:"
 
 #: qcsrc/menu/xonotic/util.qc:525
 msgid "Autogenerating mapinfo for newly added maps..."
@@ -9786,7 +9797,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/util.qc:574
 #, c-format
 msgid "Update to %s now!"
-msgstr ""
+msgstr "Updatuj na 1%s teď!"
 
 #: qcsrc/menu/xonotic/util.qc:658
 msgid ""
@@ -9796,8 +9807,8 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/util.qc:788
 msgid "Use default"
-msgstr ""
+msgstr "Použít výchozí"
 
 #: qcsrc/menu/xonotic/util.qc:808
 msgid "Team Color:"
-msgstr ""
+msgstr "Barva týmu:"
index b6f26bad547fcf639f28fa77c5ba5b7f96b4f628..67d054ca62230cadabe9e8d3dbe83042fc733a63 100644 (file)
@@ -27,7 +27,7 @@ msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2019-05-19 07:23+0200\n"
-"PO-Revision-Date: 2019-10-06 00:10+0000\n"
+"PO-Revision-Date: 2019-11-09 23:02+0000\n"
 "Last-Translator: Wuzzy <almikes@aol.com>\n"
 "Language-Team: German (http://www.transifex.com/team-xonotic/xonotic/"
 "language/de/)\n"
@@ -236,7 +236,7 @@ msgstr "^3Doppelklicke ^7ein Panel für Panel-spezifische Optionen."
 
 #: qcsrc/client/hud/panel/infomessages.qc:229
 msgid "^3CTRL ^7to disable collision testing, ^3SHIFT ^7and"
-msgstr "^3CTRL^7, um Kollisionstests zu deaktivieren, ^3SHIFT ^7und"
+msgstr "^3STRG^7, um Kollisionstests zu deaktivieren, ^3UMSCHALT ^7und"
 
 #: qcsrc/client/hud/panel/infomessages.qc:230
 msgid "^3ALT ^7+ ^3ARROW KEYS ^7for fine adjustments."
@@ -1833,7 +1833,7 @@ msgstr "Geschwindigkeit"
 
 #: qcsrc/common/mutators/mutator/buffs/all.inc:43
 msgid "Medic"
-msgstr "Medizin"
+msgstr "Sanitäter"
 
 #: qcsrc/common/mutators/mutator/buffs/all.inc:54
 msgid "Bash"
@@ -1955,7 +1955,7 @@ msgstr "Spawn-Granate"
 
 #: qcsrc/common/mutators/mutator/nades/nades.inc:50
 msgid "Heal grenade"
-msgstr "Heilgranate"
+msgstr "Medizingranate"
 
 #: qcsrc/common/mutators/mutator/nades/nades.inc:58
 msgid "Monster grenade"
@@ -2314,13 +2314,13 @@ msgstr "^F2Du wirst in der nächsten Runde zuschauen"
 #: qcsrc/common/notifications/all.inc:274
 #, c-format
 msgid "^BG%s%s^K1 was killed by ^BG%s^K1's ^BG%s^K1 buff ^K1%s%s"
-msgstr "^BG%s%s^K1 wurde durch ^BG%s^K1s ^BG%s^K1 Bonus getötet ^K1%s%s"
+msgstr "^BG%s%s^K1 wurde durch ^BG%s^K1s ^BG%s^K1-Bonus getötet ^K1%s%s"
 
 #: qcsrc/common/notifications/all.inc:274
 #, c-format
 msgid "^BG%s%s^K1 was scored against by ^BG%s^K1's ^BG%s^K1 buff ^K1%s%s"
 msgstr ""
-"^BG%s%s^K1 wurde durch ^BG%s^K1s ^BG%s^K1 Bonus zu Punkten verarbeitet ^K1%s"
+"^BG%s%s^K1 wurde durch ^BG%s^K1s ^BG%s^K1-Bonus zu Punkten verarbeitet ^K1%s"
 "%s"
 
 #: qcsrc/common/notifications/all.inc:275
@@ -2366,12 +2366,12 @@ msgstr "^BG%s%s^K1 wurde in die Luft gejagt von ^BG%s^K1s Granate%s%s"
 #: qcsrc/common/notifications/all.inc:282
 #, c-format
 msgid "^BG%s%s^K1 got too close to a napalm explosion%s%s"
-msgstr "^BG%s%s^K1 trat einer Napalm-Explosion ein wenig zu nahe%s%s"
+msgstr "^BG%s%s^K1 trat einer Napalmexplosion ein wenig zu nahe%s%s"
 
 #: qcsrc/common/notifications/all.inc:282
 #, c-format
 msgid "^BG%s%s^K1 was burned to death by ^BG%s^K1's Napalm Nade%s%s"
-msgstr "^BG%s%s^K1 wurde von ^BG%s^K1s Napalm-Granate abgefackelt%s%s"
+msgstr "^BG%s%s^K1 wurde von ^BG%s^K1s Napalmgranate abgefackelt%s%s"
 
 #: qcsrc/common/notifications/all.inc:283
 #, c-format
@@ -2606,12 +2606,12 @@ msgstr "^BG%s^K1 meisterte die Kunst der Selbstsprengung%s%s"
 #, c-format
 msgid ""
 "^BG%s^K1 decided to take a look at the results of their napalm explosion%s%s"
-msgstr "^BG%s^K1 wollte sich so eine Napalm-Explosion mal genauer ansehen%s%s"
+msgstr "^BG%s^K1 wollte sich so eine Napalmexplosion mal genauer ansehen%s%s"
 
 #: qcsrc/common/notifications/all.inc:324
 #, c-format
 msgid "^BG%s^K1 was burned to death by their own Napalm Nade%s%s"
-msgstr "^BG%s^K1 wurde von der eigenen Napalm-Granate verbrannt%s%s"
+msgstr "^BG%s^K1 wurde von der eigenen Napalmgranate verbrannt%s%s"
 
 #: qcsrc/common/notifications/all.inc:326
 #, c-format
@@ -2626,7 +2626,7 @@ msgstr "^BG%s^K1 erfror durch die eigene Eisgranate%s%s"
 #: qcsrc/common/notifications/all.inc:327
 #, c-format
 msgid "^BG%s^K1's Healing Nade didn't quite heal them%s%s"
-msgstr "^BG%s^K1s Medizin-Granate war nicht sehr heilsam%s%s"
+msgstr "^BG%s^K1s Medizingranate war nicht sehr heilsam%s%s"
 
 #: qcsrc/common/notifications/all.inc:328
 #, c-format
@@ -2783,7 +2783,7 @@ msgstr "^BG%s^K1 konnte keinen Schutz vor der Raserrakete finden%s%s"
 #: qcsrc/common/notifications/all.inc:359
 #, c-format
 msgid "^BG%s^K1 was betrayed by ^BG%s^K1%s%s"
-msgstr "^BG%s^K1 wurde von ^BG%s^K1 betrogen%s%s"
+msgstr "^BG%s^K1 wurde von ^BG%s^K1 verraten%s%s"
 
 #: qcsrc/common/notifications/all.inc:361
 #, c-format
@@ -2793,12 +2793,12 @@ msgstr "^BG%s^BG%s^BG (%s %s alle %s Sekunden)"
 #: qcsrc/common/notifications/all.inc:363
 #, c-format
 msgid "^BG%s^K1 was frozen by ^BG%s"
-msgstr "^BG%s^K1 wurde von ^BG vereist%s"
+msgstr "^BG%s^K1 wurde von ^BG%s^K1 vereist"
 
 #: qcsrc/common/notifications/all.inc:364
 #, c-format
 msgid "^BG%s^K3 was revived by ^BG%s"
-msgstr "^BG%s^K3 wurde von ^BG wiederbelebt%s"
+msgstr "^BG%s^K3 wurde von ^BG%s^K3 wiederbelebt"
 
 #: qcsrc/common/notifications/all.inc:365
 #, c-format
@@ -3588,7 +3588,7 @@ msgstr "^BGDu hast die ^TC^TT^BG Flagge erobert!"
 
 #: qcsrc/common/notifications/all.inc:563
 msgid "^BGYou captured the flag!"
-msgstr "^BGDu hast die Flagge erobert"
+msgstr "^BGDu hast die Flagge erobert!"
 
 #: qcsrc/common/notifications/all.inc:564
 #, c-format
@@ -3676,12 +3676,12 @@ msgstr "^BGDer %sFeind (^BG%s%s)^BG hat die Flagge! Bringt sie zurück!"
 #: qcsrc/common/notifications/all.inc:581
 #, c-format
 msgid "^BGThe %senemy^BG got their flag! Retrieve it!"
-msgstr "^BGDer %sFeind^BG hat seine Flagge! Hole sie!"
+msgstr "^BGDer %sFeind^BG hat seine Flagge! Hol sie!"
 
 #: qcsrc/common/notifications/all.inc:582
 #, c-format
 msgid "^BGThe %senemy (^BG%s%s)^BG got their flag! Retrieve it!"
-msgstr "^BGDer %sFeind (^BG%s%s)^BG hat seine Flagge! Hole sie!"
+msgstr "^BGDer %sFeind (^BG%s%s)^BG hat seine Flagge! Hol sie!"
 
 #: qcsrc/common/notifications/all.inc:583
 #, c-format
@@ -3874,7 +3874,7 @@ msgstr "^K1Du has vergessen, den Pin wieder reinzustecken!"
 
 #: qcsrc/common/notifications/all.inc:645
 msgid "^K1Hanging around a napalm explosion is bad!"
-msgstr "^K1Bei einer Napalm-Explosion herumzuhängen ist schlecht!"
+msgstr "^K1Es ist schlecht, bei einer Napalmexplosion herumzuhängen!"
 
 #: qcsrc/common/notifications/all.inc:646
 msgid "^K1You felt a little chilly!"
@@ -3886,7 +3886,7 @@ msgstr "^K1Dir wurde ein wenig zu kalt!"
 
 #: qcsrc/common/notifications/all.inc:647
 msgid "^K1Your Healing Nade is a bit defective"
-msgstr "^K1Deine Medizin-Granate ist ein wenig defekt"
+msgstr "^K1Deine Medizingranate ist ein wenig defekt"
 
 #: qcsrc/common/notifications/all.inc:648
 msgid "^K1You are respawning for running out of ammo..."
@@ -3898,7 +3898,7 @@ msgstr "^K1Du wurdest getötet, weil du keine Munition mehr hast …"
 
 #: qcsrc/common/notifications/all.inc:649
 msgid "^K1You grew too old without taking your medicine"
-msgstr "^K1Du wurdest zu alt, und hast deine Medizin nicht genommen"
+msgstr "^K1Du wurdest zu alt, denn du hast deine Medizin nicht genommen"
 
 #: qcsrc/common/notifications/all.inc:649
 msgid "^K1You need to preserve your health"
@@ -4175,15 +4175,15 @@ msgstr "^BGDeine Waffe wurde verschlechtert, bis du etwas Munition findest!"
 
 #: qcsrc/common/notifications/all.inc:728
 msgid "^F4^COUNT^BG left to find some ammo!"
-msgstr "^F4^COUNT^BG verbleiben, um etwas Munition zu finden!"
+msgstr "^BGNoch ^F4^COUNT^BG, um etwas Munition zu finden!"
 
 #: qcsrc/common/notifications/all.inc:729
 msgid "^BGGet some ammo or you'll be dead in ^F4^COUNT^BG!"
-msgstr "^BGHole dir etwas Munition oder du stirbst in ^F4^COUNT^BG!"
+msgstr "^BGHol dir etwas Munition oder du stirbst in ^F4^COUNT^BG!"
 
 #: qcsrc/common/notifications/all.inc:729
 msgid "^BGGet some ammo! ^F4^COUNT^BG left!"
-msgstr "^BGHole dir etwas Munition! ^F4^COUNT^BG übrig!"
+msgstr "^BGHol dir etwas Munition! Noch ^F4^COUNT^BG!"
 
 #: qcsrc/common/notifications/all.inc:730
 #, c-format
@@ -4586,7 +4586,7 @@ msgstr "%d Punkte hintereinander! "
 #: qcsrc/common/notifications/all.qh:507
 #, c-format
 msgid "%d frag spree! "
-msgstr "%d Kills in Folge!"
+msgstr "%d Kills in Folge! "
 
 #: qcsrc/common/notifications/all.qh:520
 msgid "First blood! "
@@ -5837,7 +5837,7 @@ msgstr "Leg deinen Namen im Spiel fest"
 
 #: qcsrc/menu/xonotic/dialog_firstrun.qc:69
 msgid "Text language:"
-msgstr "Sprache:"
+msgstr "Textsprache:"
 
 #: qcsrc/menu/xonotic/dialog_firstrun.qc:78
 msgid "Allow player statistics to use your nickname at stats.xonotic.org?"
@@ -6310,7 +6310,7 @@ msgstr "Rein"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_score.qh:6
 msgid "Score Panel"
-msgstr "Punktetafel"
+msgstr "Punkte-Panel"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_timer.qc:16
 msgid "Timer:"
@@ -6856,7 +6856,7 @@ msgstr "Raketenflug"
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:67
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:217
 msgid "Invincible Projectiles"
-msgstr "Unzerstörbare Schüsse"
+msgstr "Unzerstörbare Projektile"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:71
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:293
@@ -9079,7 +9079,7 @@ msgstr "Aus"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "Idle limit:"
-msgstr "wenn inaktiv:"
+msgstr "Wenn inaktiv:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:122
 msgid "IDLFPS^Unlimited"
@@ -9215,7 +9215,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc:12
 msgid "full language changes will take effect starting from the next game"
-msgstr "volle Sprachänderungen finden erst nach dem Neustart des Spiels statt."
+msgstr "volle Sprachänderungen finden erst nach dem Neustart des Spiels statt"
 
 #: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc:16
 msgid "Disconnect now"
index b94867b3b3b3bf7c5756c811d5081bff67b57f2b..e76010a6d6ab47802ee43202a90bb7e4cea219ed 100644 (file)
@@ -27,7 +27,7 @@ msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2019-05-19 07:23+0200\n"
-"PO-Revision-Date: 2019-10-06 00:10+0000\n"
+"PO-Revision-Date: 2019-11-09 23:02+0000\n"
 "Last-Translator: Wuzzy <almikes@aol.com>\n"
 "Language-Team: German (http://www.transifex.com/team-xonotic/xonotic/"
 "language/de/)\n"
@@ -236,7 +236,7 @@ msgstr "^3Doppelklicke ^7ein Panel für Panel-spezifische Optionen."
 
 #: qcsrc/client/hud/panel/infomessages.qc:229
 msgid "^3CTRL ^7to disable collision testing, ^3SHIFT ^7and"
-msgstr "^3CTRL^7, um Kollisionstests zu deaktivieren, ^3SHIFT ^7und"
+msgstr "^3STRG^7, um Kollisionstests zu deaktivieren, ^3UMSCHALT ^7und"
 
 #: qcsrc/client/hud/panel/infomessages.qc:230
 msgid "^3ALT ^7+ ^3ARROW KEYS ^7for fine adjustments."
@@ -1833,7 +1833,7 @@ msgstr "Geschwindigkeit"
 
 #: qcsrc/common/mutators/mutator/buffs/all.inc:43
 msgid "Medic"
-msgstr "Medizin"
+msgstr "Sanitäter"
 
 #: qcsrc/common/mutators/mutator/buffs/all.inc:54
 msgid "Bash"
@@ -1955,7 +1955,7 @@ msgstr "Spawn-Granate"
 
 #: qcsrc/common/mutators/mutator/nades/nades.inc:50
 msgid "Heal grenade"
-msgstr "Heilgranate"
+msgstr "Medizingranate"
 
 #: qcsrc/common/mutators/mutator/nades/nades.inc:58
 msgid "Monster grenade"
@@ -2314,13 +2314,13 @@ msgstr "^F2Du wirst in der nächsten Runde zuschauen"
 #: qcsrc/common/notifications/all.inc:274
 #, c-format
 msgid "^BG%s%s^K1 was killed by ^BG%s^K1's ^BG%s^K1 buff ^K1%s%s"
-msgstr "^BG%s%s^K1 wurde durch ^BG%s^K1s ^BG%s^K1 Bonus getötet ^K1%s%s"
+msgstr "^BG%s%s^K1 wurde durch ^BG%s^K1s ^BG%s^K1-Bonus getötet ^K1%s%s"
 
 #: qcsrc/common/notifications/all.inc:274
 #, c-format
 msgid "^BG%s%s^K1 was scored against by ^BG%s^K1's ^BG%s^K1 buff ^K1%s%s"
 msgstr ""
-"^BG%s%s^K1 wurde durch ^BG%s^K1s ^BG%s^K1 Bonus zu Punkten verarbeitet ^K1%s"
+"^BG%s%s^K1 wurde durch ^BG%s^K1s ^BG%s^K1-Bonus zu Punkten verarbeitet ^K1%s"
 "%s"
 
 #: qcsrc/common/notifications/all.inc:275
@@ -2366,12 +2366,12 @@ msgstr "^BG%s%s^K1 wurde in die Luft gejagt von ^BG%s^K1s Granate%s%s"
 #: qcsrc/common/notifications/all.inc:282
 #, c-format
 msgid "^BG%s%s^K1 got too close to a napalm explosion%s%s"
-msgstr "^BG%s%s^K1 trat einer Napalm-Explosion ein wenig zu nahe%s%s"
+msgstr "^BG%s%s^K1 trat einer Napalmexplosion ein wenig zu nahe%s%s"
 
 #: qcsrc/common/notifications/all.inc:282
 #, c-format
 msgid "^BG%s%s^K1 was burned to death by ^BG%s^K1's Napalm Nade%s%s"
-msgstr "^BG%s%s^K1 wurde von ^BG%s^K1s Napalm-Granate abgefackelt%s%s"
+msgstr "^BG%s%s^K1 wurde von ^BG%s^K1s Napalmgranate abgefackelt%s%s"
 
 #: qcsrc/common/notifications/all.inc:283
 #, c-format
@@ -2606,12 +2606,12 @@ msgstr "^BG%s^K1 meisterte die Kunst der Selbstsprengung%s%s"
 #, c-format
 msgid ""
 "^BG%s^K1 decided to take a look at the results of their napalm explosion%s%s"
-msgstr "^BG%s^K1 wollte sich so eine Napalm-Explosion mal genauer ansehen%s%s"
+msgstr "^BG%s^K1 wollte sich so eine Napalmexplosion mal genauer ansehen%s%s"
 
 #: qcsrc/common/notifications/all.inc:324
 #, c-format
 msgid "^BG%s^K1 was burned to death by their own Napalm Nade%s%s"
-msgstr "^BG%s^K1 wurde von der eigenen Napalm-Granate verbrannt%s%s"
+msgstr "^BG%s^K1 wurde von der eigenen Napalmgranate verbrannt%s%s"
 
 #: qcsrc/common/notifications/all.inc:326
 #, c-format
@@ -2626,7 +2626,7 @@ msgstr "^BG%s^K1 erfror durch die eigene Eisgranate%s%s"
 #: qcsrc/common/notifications/all.inc:327
 #, c-format
 msgid "^BG%s^K1's Healing Nade didn't quite heal them%s%s"
-msgstr "^BG%s^K1s Medizin-Granate war nicht sehr heilsam%s%s"
+msgstr "^BG%s^K1s Medizingranate war nicht sehr heilsam%s%s"
 
 #: qcsrc/common/notifications/all.inc:328
 #, c-format
@@ -2783,7 +2783,7 @@ msgstr "^BG%s^K1 konnte keinen Schutz vor der Raserrakete finden%s%s"
 #: qcsrc/common/notifications/all.inc:359
 #, c-format
 msgid "^BG%s^K1 was betrayed by ^BG%s^K1%s%s"
-msgstr "^BG%s^K1 wurde von ^BG%s^K1 betrogen%s%s"
+msgstr "^BG%s^K1 wurde von ^BG%s^K1 verraten%s%s"
 
 #: qcsrc/common/notifications/all.inc:361
 #, c-format
@@ -2793,12 +2793,12 @@ msgstr "^BG%s^BG%s^BG (%s %s alle %s Sekunden)"
 #: qcsrc/common/notifications/all.inc:363
 #, c-format
 msgid "^BG%s^K1 was frozen by ^BG%s"
-msgstr "^BG%s^K1 wurde von ^BG vereist%s"
+msgstr "^BG%s^K1 wurde von ^BG%s^K1 vereist"
 
 #: qcsrc/common/notifications/all.inc:364
 #, c-format
 msgid "^BG%s^K3 was revived by ^BG%s"
-msgstr "^BG%s^K3 wurde von ^BG wiederbelebt%s"
+msgstr "^BG%s^K3 wurde von ^BG%s^K3 wiederbelebt"
 
 #: qcsrc/common/notifications/all.inc:365
 #, c-format
@@ -3589,7 +3589,7 @@ msgstr "^BGDu hast die ^TC^TT^BG Flagge erobert!"
 
 #: qcsrc/common/notifications/all.inc:563
 msgid "^BGYou captured the flag!"
-msgstr "^BGDu hast die Flagge erobert"
+msgstr "^BGDu hast die Flagge erobert!"
 
 #: qcsrc/common/notifications/all.inc:564
 #, c-format
@@ -3677,12 +3677,12 @@ msgstr "^BGDer %sFeind (^BG%s%s)^BG hat die Flagge! Bringt sie zurück!"
 #: qcsrc/common/notifications/all.inc:581
 #, c-format
 msgid "^BGThe %senemy^BG got their flag! Retrieve it!"
-msgstr "^BGDer %sFeind^BG hat seine Flagge! Hole sie!"
+msgstr "^BGDer %sFeind^BG hat seine Flagge! Hol sie!"
 
 #: qcsrc/common/notifications/all.inc:582
 #, c-format
 msgid "^BGThe %senemy (^BG%s%s)^BG got their flag! Retrieve it!"
-msgstr "^BGDer %sFeind (^BG%s%s)^BG hat seine Flagge! Hole sie!"
+msgstr "^BGDer %sFeind (^BG%s%s)^BG hat seine Flagge! Hol sie!"
 
 #: qcsrc/common/notifications/all.inc:583
 #, c-format
@@ -3875,7 +3875,7 @@ msgstr "^K1Du has vergessen, den Pin wieder reinzustecken!"
 
 #: qcsrc/common/notifications/all.inc:645
 msgid "^K1Hanging around a napalm explosion is bad!"
-msgstr "^K1Bei einer Napalm-Explosion herumzuhängen ist schlecht!"
+msgstr "^K1Es ist schlecht, bei einer Napalmexplosion herumzuhängen!"
 
 #: qcsrc/common/notifications/all.inc:646
 msgid "^K1You felt a little chilly!"
@@ -3887,7 +3887,7 @@ msgstr "^K1Dir wurde ein wenig zu kalt!"
 
 #: qcsrc/common/notifications/all.inc:647
 msgid "^K1Your Healing Nade is a bit defective"
-msgstr "^K1Deine Medizin-Granate ist ein wenig defekt"
+msgstr "^K1Deine Medizingranate ist ein wenig defekt"
 
 #: qcsrc/common/notifications/all.inc:648
 msgid "^K1You are respawning for running out of ammo..."
@@ -3899,7 +3899,7 @@ msgstr "^K1Du wurdest getötet, weil du keine Munition mehr hast …"
 
 #: qcsrc/common/notifications/all.inc:649
 msgid "^K1You grew too old without taking your medicine"
-msgstr "^K1Du wurdest zu alt, und hast deine Medizin nicht genommen"
+msgstr "^K1Du wurdest zu alt, denn du hast deine Medizin nicht genommen"
 
 #: qcsrc/common/notifications/all.inc:649
 msgid "^K1You need to preserve your health"
@@ -4176,15 +4176,15 @@ msgstr "^BGDeine Waffe wurde verschlechtert, bis du etwas Munition findest!"
 
 #: qcsrc/common/notifications/all.inc:728
 msgid "^F4^COUNT^BG left to find some ammo!"
-msgstr "^F4^COUNT^BG verbleiben, um etwas Munition zu finden!"
+msgstr "^BGNoch ^F4^COUNT^BG, um etwas Munition zu finden!"
 
 #: qcsrc/common/notifications/all.inc:729
 msgid "^BGGet some ammo or you'll be dead in ^F4^COUNT^BG!"
-msgstr "^BGHole dir etwas Munition oder du stirbst in ^F4^COUNT^BG!"
+msgstr "^BGHol dir etwas Munition oder du stirbst in ^F4^COUNT^BG!"
 
 #: qcsrc/common/notifications/all.inc:729
 msgid "^BGGet some ammo! ^F4^COUNT^BG left!"
-msgstr "^BGHole dir etwas Munition! ^F4^COUNT^BG übrig!"
+msgstr "^BGHol dir etwas Munition! Noch ^F4^COUNT^BG!"
 
 #: qcsrc/common/notifications/all.inc:730
 #, c-format
@@ -4587,7 +4587,7 @@ msgstr "%d Punkte hintereinander! "
 #: qcsrc/common/notifications/all.qh:507
 #, c-format
 msgid "%d frag spree! "
-msgstr "%d Kills in Folge!"
+msgstr "%d Kills in Folge! "
 
 #: qcsrc/common/notifications/all.qh:520
 msgid "First blood! "
@@ -5838,7 +5838,7 @@ msgstr "Leg deinen Namen im Spiel fest"
 
 #: qcsrc/menu/xonotic/dialog_firstrun.qc:69
 msgid "Text language:"
-msgstr "Sprache:"
+msgstr "Textsprache:"
 
 #: qcsrc/menu/xonotic/dialog_firstrun.qc:78
 msgid "Allow player statistics to use your nickname at stats.xonotic.org?"
@@ -6311,7 +6311,7 @@ msgstr "Rein"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_score.qh:6
 msgid "Score Panel"
-msgstr "Punktetafel"
+msgstr "Punkte-Panel"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_timer.qc:16
 msgid "Timer:"
@@ -6857,7 +6857,7 @@ msgstr "Raketenflug"
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:67
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:217
 msgid "Invincible Projectiles"
-msgstr "Unzerstörbare Schüsse"
+msgstr "Unzerstörbare Projektile"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:71
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:293
@@ -9080,7 +9080,7 @@ msgstr "Aus"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "Idle limit:"
-msgstr "wenn inaktiv:"
+msgstr "Wenn inaktiv:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:122
 msgid "IDLFPS^Unlimited"
@@ -9216,7 +9216,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc:12
 msgid "full language changes will take effect starting from the next game"
-msgstr "volle Sprachänderungen finden erst nach dem Neustart des Spiels statt."
+msgstr "volle Sprachänderungen finden erst nach dem Neustart des Spiels statt"
 
 #: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc:16
 msgid "Disconnect now"
index c32867dc4cf0b81fd6e3f8f46a498a6a25a06079..f7b0135c1fdb9afef381b5bd83c0abc7d6104886 100644 (file)
@@ -12,7 +12,7 @@
 # MasterWord, 2016
 # Mensious Mensious <ektoras@tutanota.com>, 2018-2019
 # Vindex <kon14.inside@gmail.com>, 2014
-# Γιάννης Ανθυμίδης, 2011-2012
+# Yannis Anthymidis, 2011-2012
 msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
index 3b406a3e5d5cc8d464cc18602c377a4d54c15bff..1d7275ed7db66a1c43990a94036611437bf591b9 100644 (file)
@@ -5,13 +5,14 @@
 # Translators:
 # Henry 'Exitium' Sanmark <henry.sanmark@gmail.com>, 2011
 # Jonas Sahlberg <fragthelion@gmail.com>, 2015
+# Oi Suomi On! <oisuomion@protonmail.com>, 2020
 msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2019-05-19 07:23+0200\n"
-"PO-Revision-Date: 2019-05-19 05:23+0000\n"
-"Last-Translator: divVerent <divVerent@xonotic.org>\n"
+"PO-Revision-Date: 2020-05-12 18:36+0000\n"
+"Last-Translator: Oi Suomi On! <oisuomion@protonmail.com>\n"
 "Language-Team: Finnish (http://www.transifex.com/team-xonotic/xonotic/"
 "language/fi/)\n"
 "Language: fi\n"
@@ -24,16 +25,18 @@ msgstr ""
 #, c-format
 msgid "^2Successfully exported to %s! (Note: It's saved in data/data/)"
 msgstr ""
+"^2Viety onnistuneesti kohteeseen %s! (Huomautus: tallennettu kansioon data/"
+"data/)"
 
 #: qcsrc/client/hud/hud_config.qc:247
 #, c-format
 msgid "^1Couldn't write to %s"
-msgstr ""
+msgstr "^1Ei voitu kirjoittaa kohteeseen %s"
 
 #: qcsrc/client/hud/panel/centerprint.qc:140
 #, c-format
 msgid "^3Countdown message at time %s, seconds left: ^COUNT"
-msgstr ""
+msgstr "^3Laskentaviesti ajassa %s, sekuntia jäljellä: ^COUNT"
 
 #: qcsrc/client/hud/panel/centerprint.qc:142
 #, c-format
@@ -41,184 +44,187 @@ msgid ""
 "^1Multiline message at time %s that\n"
 "^1lasts longer than normal"
 msgstr ""
+"^1Monirivinen viesti ajassa %s joka\n"
+"^1kestää pidempään kuin tavallisesti"
 
 #: qcsrc/client/hud/panel/centerprint.qc:144
 #, c-format
 msgid "Message at time %s"
-msgstr ""
+msgstr "Viesti ajassa %s"
 
 #: qcsrc/client/hud/panel/centerprint.qc:149
 msgid "Generic message"
-msgstr ""
+msgstr "Yleisluontoinen viesti"
 
 #: qcsrc/client/hud/panel/chat.qc:84
 msgid "^3Player^7: This is the chat area."
-msgstr ""
+msgstr "^3Pelaaja^7: Tämä on keskustelualue."
 
 #: qcsrc/client/hud/panel/engineinfo.qc:72
 #, c-format
 msgid "FPS: %.*f"
-msgstr ""
+msgstr "FPS-ruutunopeus: %.*f"
 
 #: qcsrc/client/hud/panel/infomessages.qc:89
 msgid "^1Observing"
-msgstr ""
+msgstr "^1Tarkkailee"
 
 #: qcsrc/client/hud/panel/infomessages.qc:91
 #, c-format
 msgid "^1Spectating: ^7%s"
-msgstr ""
+msgstr "^1Katselee: ^7%s"
 
 #: qcsrc/client/hud/panel/infomessages.qc:102
 #, c-format
 msgid "^1Press ^3%s^1 to spectate"
-msgstr ""
+msgstr "^1Paina ^3%s^1 katsellaksesi"
 
 #: qcsrc/client/hud/panel/infomessages.qc:102
 #: qcsrc/menu/xonotic/keybinder.qc:47
 msgid "primary fire"
-msgstr ""
+msgstr "ensisijainen tulitus"
 
 #: qcsrc/client/hud/panel/infomessages.qc:104
 #, c-format
 msgid "^1Press ^3%s^1 or ^3%s^1 for next or previous player"
 msgstr ""
+"^1Paina ^3%s^1 tai ^3%s^1 siirtyäksesi seuraavaan tai edelliseen pelaajaan"
 
 #: qcsrc/client/hud/panel/infomessages.qc:104
 #: qcsrc/client/hud/panel/infomessages.qc:108
 msgid "next weapon"
-msgstr ""
+msgstr "seuraava ase"
 
 #: qcsrc/client/hud/panel/infomessages.qc:104
 #: qcsrc/client/hud/panel/infomessages.qc:108
 msgid "previous weapon"
-msgstr ""
+msgstr "edellinen ase"
 
 #: qcsrc/client/hud/panel/infomessages.qc:108
 #, c-format
 msgid "^1Use ^3%s^1 or ^3%s^1 to change the speed"
-msgstr ""
+msgstr "^1Käytä ^3%s^1 tai ^3%s^1 muuttaaksesi nopeutta"
 
 #: qcsrc/client/hud/panel/infomessages.qc:110
 #, c-format
 msgid "^1Press ^3%s^1 to observe, ^3%s^1 to change camera mode"
-msgstr ""
+msgstr "^1Paina ^3%s^1 tarkkaillaksesi, ^3%s^1 vaihtaaksesi kameratilaa"
 
 #: qcsrc/client/hud/panel/infomessages.qc:110
 #: qcsrc/common/vehicles/cl_vehicles.qc:190
 msgid "drop weapon"
-msgstr ""
+msgstr "pudota ase"
 
 #: qcsrc/client/hud/panel/infomessages.qc:110
 #: qcsrc/menu/xonotic/keybinder.qc:48
 msgid "secondary fire"
-msgstr ""
+msgstr "toissijainen tulitus"
 
 #: qcsrc/client/hud/panel/infomessages.qc:113
 #, c-format
 msgid "^1Press ^3%s^1 for gamemode info"
-msgstr ""
+msgstr "^1Paina ^3%s^1 nähdäksesi pelitilatiedot"
 
 #: qcsrc/client/hud/panel/infomessages.qc:113
 #: qcsrc/menu/xonotic/keybinder.qc:105
 msgid "server info"
-msgstr ""
+msgstr "palvelimen tiedot"
 
 #: qcsrc/client/hud/panel/infomessages.qc:126
 msgid "^1Match has already begun"
-msgstr ""
+msgstr "^1Ottelu on jo alkanut"
 
 #: qcsrc/client/hud/panel/infomessages.qc:128
 msgid "^1You have no more lives left"
-msgstr ""
+msgstr "^1Sinulla ei ole elämiä enää jäljellä"
 
 #: qcsrc/client/hud/panel/infomessages.qc:130
 #: qcsrc/client/hud/panel/infomessages.qc:133
 #, c-format
 msgid "^1Press ^3%s^1 to join"
-msgstr ""
+msgstr "^1Paina ^3%s^1 liittyäksesi"
 
 #: qcsrc/client/hud/panel/infomessages.qc:130
 #: qcsrc/client/hud/panel/infomessages.qc:133
 msgid "jump"
-msgstr ""
+msgstr "hyppää"
 
 #: qcsrc/client/hud/panel/infomessages.qc:141
 #, c-format
 msgid "^1Game starts in ^3%d^1 seconds"
-msgstr ""
+msgstr "^1Peli alkaa ^3%d^1 sekunnin kuluttua"
 
 #: qcsrc/client/hud/panel/infomessages.qc:147
 msgid "^2Currently in ^1warmup^2 stage!"
-msgstr ""
+msgstr "^2Tällä hetkellä ^1lämmittelyssä^2 !"
 
 #: qcsrc/client/hud/panel/infomessages.qc:162
 #, c-format
 msgid "%sPress ^3%s%s to end warmup"
-msgstr ""
+msgstr "%sPaina ^3%s%s päättääksesi lämmittelyn"
 
 #: qcsrc/client/hud/panel/infomessages.qc:162
 #: qcsrc/client/hud/panel/infomessages.qc:164
 #: qcsrc/client/hud/panel/infomessages.qc:177
 #: qcsrc/menu/xonotic/keybinder.qc:101
 msgid "ready"
-msgstr ""
+msgstr "valmis"
 
 #: qcsrc/client/hud/panel/infomessages.qc:164
 #, c-format
 msgid "%sPress ^3%s%s once you are ready"
-msgstr ""
+msgstr "%sPaina ^3%s%s kun olet valmis"
 
 #: qcsrc/client/hud/panel/infomessages.qc:169
 msgid "^2Waiting for others to ready up to end warmup..."
-msgstr ""
+msgstr "^2Odotetaan muita saadakseen lämmittelynsä valmiiksi..."
 
 #: qcsrc/client/hud/panel/infomessages.qc:171
 msgid "^2Waiting for others to ready up..."
-msgstr ""
+msgstr "^2Odotetaan muita valmiiksi..."
 
 #: qcsrc/client/hud/panel/infomessages.qc:177
 #, c-format
 msgid "^2Press ^3%s^2 to end warmup"
-msgstr ""
+msgstr "^2Paina ^3%s^2 lämmittelyn lopettamiseksi"
 
 #: qcsrc/client/hud/panel/infomessages.qc:198
 msgid "Teamnumbers are unbalanced!"
-msgstr ""
+msgstr "Joukkuemäärät ovat epätasapainossa!"
 
 #: qcsrc/client/hud/panel/infomessages.qc:201
 #, c-format
 msgid " Press ^3%s%s to adjust"
-msgstr ""
+msgstr " Paina ^3%s%s säätääksesi"
 
 #: qcsrc/client/hud/panel/infomessages.qc:201
 #: qcsrc/menu/xonotic/keybinder.qc:117
 msgid "team menu"
-msgstr ""
+msgstr "joukkuevalikko"
 
 #: qcsrc/client/hud/panel/infomessages.qc:211
 msgid "^1Spectating this player:"
-msgstr ""
+msgstr "^1Seurataan tätä pelaajaa:"
 
 #: qcsrc/client/hud/panel/infomessages.qc:211
 msgid "^1Spectating you:"
-msgstr ""
+msgstr "^1Sinua seuraa:"
 
 #: qcsrc/client/hud/panel/infomessages.qc:227
 msgid "^7Press ^3ESC ^7to show HUD options."
-msgstr ""
+msgstr "^7Paina ^3ESC ^7nähdäksesi HUD-vaihtoehdot."
 
 #: qcsrc/client/hud/panel/infomessages.qc:228
 msgid "^3Doubleclick ^7a panel for panel-specific options."
-msgstr ""
+msgstr "^3Tuplanapsauta ^7a paneelia paneelikohtaisia valintoja varten."
 
 #: qcsrc/client/hud/panel/infomessages.qc:229
 msgid "^3CTRL ^7to disable collision testing, ^3SHIFT ^7and"
-msgstr ""
+msgstr "^3CTRL ^7kytkee pois yhteenottotestauksen, ^3SHIFT ^7ja"
 
 #: qcsrc/client/hud/panel/infomessages.qc:230
 msgid "^3ALT ^7+ ^3ARROW KEYS ^7for fine adjustments."
-msgstr ""
+msgstr "^3ALT ^7+ ^3NUOLINÄPPÄIMET ^7hienosäätöä varten."
 
 #: qcsrc/client/hud/panel/modicons.qc:576
 msgid "Personal best"
@@ -232,13 +238,13 @@ msgstr "Serverin Paras"
 #: qcsrc/client/hud/panel/score.qc:63
 #, c-format
 msgid "Player %d"
-msgstr ""
+msgstr "Pelaaja %d"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:591
 #: qcsrc/client/hud/panel/quickmenu.qc:593
 #, c-format
 msgid "Submenu%d"
-msgstr ""
+msgstr "Alivalikko%d"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:598
 #, c-format
@@ -252,281 +258,281 @@ msgstr "Jatka..."
 #: qcsrc/client/hud/panel/quickmenu.qc:781
 #: qcsrc/client/hud/panel/quickmenu.qc:788
 msgid "Chat"
-msgstr ""
+msgstr "Keskustelu"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:782
 msgid "QMCMD^Send public message to"
-msgstr ""
+msgstr "QMCMD^Lähetä julkinen viesti "
 
 #: qcsrc/client/hud/panel/quickmenu.qc:783
 msgid "QMCMD^:-) / nice one"
-msgstr ""
+msgstr "QMCMD^:-) / se oli hieno"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:783
 msgid "QMCMD^nice one"
-msgstr ""
+msgstr "QMCMD^se oli hieno"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:784
 msgid "QMCMD^good game"
-msgstr ""
+msgstr "QMCMD^hyvä peli"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:785
 msgid "QMCMD^hi / good luck"
-msgstr ""
+msgstr "QMCMD^moro / onnea matkaan"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:785
 msgid "QMCMD^hi / good luck and have fun"
-msgstr ""
+msgstr "QMCMD^moro / onnea matkaan ja pidähän hauskaa"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:787
 msgid "QMCMD^Send in English"
-msgstr ""
+msgstr "QMCMD^Lähetä Suomeksi"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:792
 #: qcsrc/client/hud/panel/quickmenu.qc:808
 msgid "QMCMD^Team chat"
-msgstr ""
+msgstr "QMCMD^joukkuekeskustelu"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:793
 msgid "QMCMD^quad soon"
-msgstr ""
+msgstr "QMCMD^kohta neloistila"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:794
 msgid "QMCMD^free item %x^7 (l:%y^7)"
-msgstr ""
+msgstr "QMCMD^vapauta esine %x^7 (l:%y^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:794
 msgid "QMCMD^free item, icon"
-msgstr ""
+msgstr "QMCMD^vapauta esine, kuvake"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:795
 msgid "QMCMD^took item (l:%l^7)"
-msgstr ""
+msgstr "QMCMD^otti esineen (l:%l^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:795
 msgid "QMCMD^took item, icon"
-msgstr ""
+msgstr "QMCMD^otti esineen, kuvake"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:796
 msgid "QMCMD^negative"
-msgstr ""
+msgstr "QMCMD^negatiivinen"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:797
 msgid "QMCMD^positive"
-msgstr ""
+msgstr "QMCMD^positiivinen"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:798
 msgid "QMCMD^need help (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
-msgstr ""
+msgstr "QMCMD^avuntarve (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:798
 msgid "QMCMD^need help, icon"
-msgstr ""
+msgstr "QMCMD^avuntarve, kuvake"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:799
 msgid "QMCMD^enemy seen (l:%y^7)"
-msgstr ""
+msgstr "QMCMD^vihollinen havaittu (l:%y^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:799
 msgid "QMCMD^enemy seen, icon"
-msgstr ""
+msgstr "QMCMD^vihollinen havaittu, kuvake"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:800
 msgid "QMCMD^flag seen (l:%y^7)"
-msgstr ""
+msgstr "QMCMD^lippu havaittu (l:%y^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:800
 msgid "QMCMD^flag seen, icon"
-msgstr ""
+msgstr "QMCMD^lippu havaittu, kuvake"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:801
 msgid "QMCMD^defending (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
-msgstr ""
+msgstr "QMCMD^puolustaa (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:801
 msgid "QMCMD^defending, icon"
-msgstr ""
+msgstr "QMCMD^puolustaa, kuvake"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:802
 msgid "QMCMD^roaming (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
-msgstr ""
+msgstr "QMCMD^kuljeskelee (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:802
 msgid "QMCMD^roaming, icon"
-msgstr ""
+msgstr "QMCMD^kuljeskelee, kuvake"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:803
 msgid "QMCMD^attacking (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
-msgstr ""
+msgstr "QMCMD^hyökkää (l:%l^7) (h:%h^7 a:%a^7 w:%w^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:803
 msgid "QMCMD^attacking, icon"
-msgstr ""
+msgstr "QMCMD^hyökkää, kuvake"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:804
 msgid "QMCMD^killed flagcarrier (l:%y^7)"
-msgstr ""
+msgstr "QMCMD^lipunkantaja tapettu (l:%y^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:804
 msgid "QMCMD^killed flagcarrier, icon"
-msgstr ""
+msgstr "QMCMD^lipunkantaja tapettu, kuvake"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:805
 #, c-format
 msgid "QMCMD^dropped flag (l:%d^7)"
-msgstr ""
+msgstr "QMCMD^lippu pudotettu (l:%d^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:805
 msgid "QMCMD^dropped flag, icon"
-msgstr ""
+msgstr "QMCMD^lippu pudotettu, kuvake"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:806
 msgid "QMCMD^drop weapon, icon"
-msgstr ""
+msgstr "QMCMD^pudota ase, kuvake"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:806
 msgid "QMCMD^dropped weapon %w^7 (l:%l^7)"
-msgstr ""
+msgstr "QMCMD^ase pudotettu %w^7 (l:%l^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:807
 msgid "QMCMD^drop flag/key, icon"
-msgstr ""
+msgstr "QMCMD^pudota lippu/avain, kuvake"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:807
 msgid "QMCMD^dropped flag/key %w^7 (l:%l^7)"
-msgstr ""
+msgstr "QMCMD^pudotettu lippu/avain %w^7 (l:%l^7)"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:811
 msgid "QMCMD^Send private message to"
-msgstr ""
+msgstr "QMCMD^Lähetä yksityisviesti"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:813
 #: qcsrc/client/hud/panel/quickmenu.qc:848
 msgid "QMCMD^Settings"
-msgstr ""
+msgstr "QMCMD^Asetukset"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:814
 #: qcsrc/client/hud/panel/quickmenu.qc:821
 msgid "QMCMD^View/HUD settings"
-msgstr ""
+msgstr "QMCMD^Katso/HUD-asetukset"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:815
 msgid "QMCMD^3rd person view"
-msgstr ""
+msgstr "QMCMD^näkymä 3:ssa persoonassa"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:816
 msgid "QMCMD^Player models like mine"
-msgstr ""
+msgstr "QMCMD^Pelaajamallit jotka vastaavat omaani"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:817
 msgid "QMCMD^Names above players"
-msgstr ""
+msgstr "QMCMD^Nimet pelaajien yläpuolella"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:818
 msgid "QMCMD^Crosshair per weapon"
-msgstr ""
+msgstr "QMCMD^Tähtäin tietyn aseen suhteen"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:819
 msgid "QMCMD^FPS"
-msgstr ""
+msgstr "QMCMD^FPS-ruutunopeus"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:820
 msgid "QMCMD^Net graph"
-msgstr ""
+msgstr "QMCMD^Nettomallinnus"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:823
 #: qcsrc/client/hud/panel/quickmenu.qc:826
 msgid "QMCMD^Sound settings"
-msgstr ""
+msgstr "QMCMD^Ääniasetukset"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:824
 msgid "QMCMD^Hit sound"
-msgstr ""
+msgstr "QMCMD^Osumaääni"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:825
 msgid "QMCMD^Chat sound"
-msgstr ""
+msgstr "QMCMD^Chat-keskustelun ääni"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:830
 #: qcsrc/client/hud/panel/quickmenu.qc:834
 msgid "QMCMD^Spectator camera"
-msgstr ""
+msgstr "QMCMD^Katselijakamera"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:831
 msgid "QMCMD^1st person"
-msgstr ""
+msgstr "QMCMD^Ens1persoona"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:832
 msgid "QMCMD^3rd person around player"
-msgstr ""
+msgstr "QMCMD^3:mas persoona pelaajan ympärillä"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:833
 msgid "QMCMD^3rd person behind"
-msgstr ""
+msgstr "QMCMD^3:mas persoona takaa"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:839
 #: qcsrc/client/hud/panel/quickmenu.qc:844
 msgid "QMCMD^Observer camera"
-msgstr ""
+msgstr "QMCMD^Tarkkailijakamera"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:840
 msgid "QMCMD^Increase speed"
-msgstr ""
+msgstr "QMCMD^Korota nopeutta"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:841
 msgid "QMCMD^Decrease speed"
-msgstr ""
+msgstr "QMCMD^Vähennä nopeutta"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:842
 msgid "QMCMD^Wall collision off"
-msgstr ""
+msgstr "QMCMD^Seinätörmäys pois"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:843
 msgid "QMCMD^Wall collision on"
-msgstr ""
+msgstr "QMCMD^Seinätörmäys päälle"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:847
 msgid "QMCMD^Fullscreen"
-msgstr ""
+msgstr "QMCMD^Kokoruutu"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:850
 #: qcsrc/client/hud/panel/quickmenu.qc:860
 msgid "QMCMD^Call a vote"
-msgstr ""
+msgstr "QMCMD^Pyydä äänestystä"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:851
 msgid "QMCMD^Restart the map"
-msgstr ""
+msgstr "QMCMD^Uudelleenkäynnistä kartta"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:852
 msgid "QMCMD^End match"
-msgstr ""
+msgstr "QMCMD^Lopeta ottelu"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:855
 msgid "QMCMD^Reduce match time"
-msgstr ""
+msgstr "QMCMD^Vähennä otteluaikaa"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:856
 msgid "QMCMD^Extend match time"
-msgstr ""
+msgstr "QMCMD^Lisää otteluaikaa"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:859
 msgid "QMCMD^Shuffle teams"
-msgstr ""
+msgstr "QMCMD^Sekoita joukkueet"
 
 #: qcsrc/client/hud/panel/racetimer.qc:54
 #, c-format
 msgid " (-%dL)"
-msgstr ""
+msgstr " (-%dL)"
 
 #: qcsrc/client/hud/panel/racetimer.qc:59
 #, c-format
 msgid " (+%dL)"
-msgstr ""
+msgstr " (+%dL)"
 
 #: qcsrc/client/hud/panel/racetimer.qc:78
 msgid "Start line"
-msgstr ""
+msgstr "Aloituslinja"
 
 #: qcsrc/client/hud/panel/racetimer.qc:80
 #: qcsrc/client/hud/panel/racetimer.qc:84
@@ -537,62 +543,62 @@ msgstr "Maali"
 #: qcsrc/client/hud/panel/racetimer.qc:151
 #, c-format
 msgid "Intermediate %d"
-msgstr ""
+msgstr "Välimuoto %d"
 
 #: qcsrc/client/hud/panel/racetimer.qc:154
 #: qcsrc/client/hud/panel/racetimer.qc:201
 #: qcsrc/client/hud/panel/racetimer.qc:262
 #, c-format
 msgid "PENALTY: %.1f (%s)"
-msgstr ""
+msgstr "RANGAISTUS: %.1f (%s)"
 
 #: qcsrc/client/hud/panel/racetimer.qc:154 qcsrc/client/main.qc:1129
 msgid "missing a checkpoint"
-msgstr ""
+msgstr "tarkastuspiste sivuutettu"
 
 #: qcsrc/client/hud/panel/radar.qc:373
 msgid "Click to select teleport destination"
-msgstr ""
+msgstr "Napsauta valitaksesi kaukosiirron määränpään"
 
 #: qcsrc/client/hud/panel/radar.qc:377
 msgid "Click to select spawn location"
-msgstr ""
+msgstr "Napsauta valitaksesi saapumismääränpään"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:87
 msgid "Number of ball carrier kills"
-msgstr ""
+msgstr "Pallonkantajatapot"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:87
 msgid "SCO^bckills"
-msgstr ""
+msgstr "SCO^pktapot"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:88
 msgid "SCO^bctime"
-msgstr ""
+msgstr "SCO^pkajat"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:88
 msgid "Total amount of time holding the ball in Keepaway"
-msgstr ""
+msgstr "Pallon hallussapidon yhteisaika Keepaway:ssa "
 
 #: qcsrc/client/hud/panel/scoreboard.qc:89
 msgid "How often a flag (CTF) or a key (KeyHunt) was captured"
-msgstr ""
+msgstr "Kuinka usein lippu (CTF) tai avain (KeyHunt) saatiin kaapattua"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:89
 msgid "SCO^caps"
-msgstr ""
+msgstr "SCO^kaappaukset"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:90
 msgid "SCO^captime"
-msgstr ""
+msgstr "SCO^kaappausaika"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:90
 msgid "Time of fastest capture (CTF)"
-msgstr ""
+msgstr "Nopeimman kaappauksen aika (CTF)"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:91
 msgid "Number of deaths"
-msgstr ""
+msgstr "Kuolemien määrä"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:91
 msgid "SCO^deaths"
@@ -600,121 +606,121 @@ msgstr "SCO^kuolemaa"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:92
 msgid "Number of keys destroyed by pushing them into void"
-msgstr ""
+msgstr "Tuhottujen avainten määrä työntämällä ne hukkaan"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:92
 msgid "SCO^destroyed"
-msgstr ""
+msgstr "SCO^tuhotut"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:93
 msgid "SCO^damage"
-msgstr ""
+msgstr "SCO^vaurio"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:93
 msgid "The total damage done"
-msgstr ""
+msgstr "Tehtyjen tuhojen yhteismäärä"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:94
 msgid "SCO^dmgtaken"
-msgstr ""
+msgstr "SCO^ttvastaanotot"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:94
 msgid "The total damage taken"
-msgstr ""
+msgstr "Kärsityt tuhot kokonaisuudessaan"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:95
 msgid "Number of flag drops"
-msgstr ""
+msgstr "Lippupudotusten määrä"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:95
 msgid "SCO^drops"
-msgstr ""
+msgstr "SCO^pudotukset"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:96
 msgid "Player ELO"
-msgstr ""
+msgstr "Pelaaja ELO"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:96
 msgid "SCO^elo"
-msgstr ""
+msgstr "SCO^elo"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:97
 msgid "SCO^fastest"
-msgstr ""
+msgstr "SCO^nopein"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:97
 msgid "Time of fastest lap (Race/CTS)"
-msgstr ""
+msgstr "Nopeimman kierroksen aika (kilpa/CTS)"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:98
 msgid "Number of faults committed"
-msgstr ""
+msgstr "Tehtyjen rikkomusten määrä"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:98
 msgid "SCO^faults"
-msgstr ""
+msgstr "SCO^rikkeet"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:99
 msgid "Number of flag carrier kills"
-msgstr ""
+msgstr "Lipunkantajien tappomäärä"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:99
 msgid "SCO^fckills"
-msgstr ""
+msgstr "SCO^lktapot"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:100
 msgid "FPS"
-msgstr ""
+msgstr "FPS-ruutunopeus"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:100
 msgid "SCO^fps"
-msgstr ""
+msgstr "SCO^fpsruutunopeus"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:101
 msgid "Number of kills minus suicides"
-msgstr ""
+msgstr "Tapot poislukien itsemurhat"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:101
 msgid "SCO^frags"
-msgstr ""
+msgstr "SCO^tapot"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:102
 msgid "Number of goals scored"
-msgstr ""
+msgstr "Tehdyt maalit"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:102
 msgid "SCO^goals"
-msgstr ""
+msgstr "SCO^maalit"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:103
 msgid "Number of keys carrier kills"
-msgstr ""
+msgstr "Avaimenkantajatapot"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:103
 msgid "SCO^kckills"
-msgstr ""
+msgstr "SCO^aktapot"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:104
 msgid "SCO^k/d"
-msgstr ""
+msgstr "SCO^t/k"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:104
 #: qcsrc/client/hud/panel/scoreboard.qc:105
 #: qcsrc/client/hud/panel/scoreboard.qc:106
 msgid "The kill-death ratio"
-msgstr ""
+msgstr "Suhdeluku tapot-kuolemat "
 
 #: qcsrc/client/hud/panel/scoreboard.qc:105
 msgid "SCO^kdr"
-msgstr ""
+msgstr "SCO^tks"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:106
 msgid "SCO^kdratio"
-msgstr ""
+msgstr "SCO^tksuhdeluku"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:107
 msgid "Number of kills"
-msgstr ""
+msgstr "Tapot"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:107
 msgid "SCO^kills"
@@ -722,7 +728,7 @@ msgstr "SCO^tappoa"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:108
 msgid "Number of laps finished (Race/CTS)"
-msgstr ""
+msgstr "Loppuunsaatettujen kierrosten lukumäärä (kilpa/CTS)"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:108
 msgid "SCO^laps"
@@ -730,24 +736,24 @@ msgstr "SCO^kierrosta"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:109
 msgid "Number of lives (LMS)"
-msgstr ""
+msgstr "Elämien määrä (LMS)"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:109
 msgid "SCO^lives"
-msgstr ""
+msgstr "SCO^elämät"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:110
 msgid "Number of times a key was lost"
-msgstr ""
+msgstr "Montako kertaa avain menetettiin"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:110
 msgid "SCO^losses"
-msgstr ""
+msgstr "SCO^menetykset"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:111
 #: qcsrc/client/hud/panel/scoreboard.qc:112
 msgid "Player name"
-msgstr ""
+msgstr "Pelaajan nimi"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:111
 msgid "SCO^name"
@@ -755,28 +761,29 @@ msgstr "SCO^nimi"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:112
 msgid "SCO^nick"
-msgstr ""
+msgstr "SCO^lempinimi"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:113
 msgid "Number of objectives destroyed"
-msgstr ""
+msgstr "Tavoitekohteita tuhottu"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:113
 msgid "SCO^objectives"
-msgstr ""
+msgstr "SCO^tavoitteet"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:114
 msgid ""
 "How often a flag (CTF) or a key (KeyHunt) or a ball (Keepaway) was picked up"
 msgstr ""
+"Monastiko lippu (CTF) tai avain (KeyHunt) tai pallo (Keepaway) poimittiin"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:114
 msgid "SCO^pickups"
-msgstr ""
+msgstr "SCO^poiminnat"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:115
 msgid "Ping time"
-msgstr ""
+msgstr "Ping-aika"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:115
 msgid "SCO^ping"
@@ -784,63 +791,63 @@ msgstr "Viive"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:116
 msgid "Packet loss"
-msgstr ""
+msgstr "Pakettirokotukset"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:116
 msgid "SCO^pl"
-msgstr ""
+msgstr "SCO^pr"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:117
 msgid "Number of players pushed into void"
-msgstr ""
+msgstr "Montako pelaajaa työnnettiin hukkaan"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:117
 msgid "SCO^pushes"
-msgstr ""
+msgstr "SCO^työnnöt"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:118
 msgid "Player rank"
-msgstr ""
+msgstr "Pelaajan taso"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:118
 msgid "SCO^rank"
-msgstr ""
+msgstr "SCO^taso"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:119
 msgid "Number of flag returns"
-msgstr ""
+msgstr "Lipunpalautusten määrä"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:119
 msgid "SCO^returns"
-msgstr ""
+msgstr "SCO^palautukset"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:120
 msgid "Number of revivals"
-msgstr ""
+msgstr "Virkoamisten määrä"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:120
 msgid "SCO^revivals"
-msgstr ""
+msgstr "SCO^virkoamiset"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:121
 msgid "Number of rounds won"
-msgstr ""
+msgstr "Voitetut kierrokset"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:121
 msgid "SCO^rounds won"
-msgstr ""
+msgstr "SCO^voitetut kierrokset"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:122
 msgid "SCO^score"
-msgstr ""
+msgstr "SCO^pistemäärä"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:122
 msgid "Total score"
-msgstr ""
+msgstr "Yhteispisteet"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:123
 msgid "Number of suicides"
-msgstr ""
+msgstr "Itsemurhat"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:123
 msgid "SCO^suicides"
@@ -848,82 +855,88 @@ msgstr "SCO^itsemurhia"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:124
 msgid "Number of kills minus deaths"
-msgstr ""
+msgstr "Tapot poislukien kuolemat"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:124
 msgid "SCO^sum"
-msgstr ""
+msgstr "SCO^määrä"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:125
 msgid "Number of domination points taken (Domination)"
-msgstr ""
+msgstr "Otetut dominointipisteet (Domination)"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:125
 msgid "SCO^takes"
-msgstr ""
+msgstr "SCO^otot"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:126
 msgid "Number of teamkills"
-msgstr ""
+msgstr "Joukkuetapot"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:126
 msgid "SCO^teamkills"
-msgstr ""
+msgstr "SCO^joukkuetapot"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:127
 msgid "Number of ticks (Domination)"
-msgstr ""
+msgstr "Tikkausten määrä (Domination)"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:127
 msgid "SCO^ticks"
-msgstr ""
+msgstr "SCO^tikkaukset"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:128
 msgid "SCO^time"
-msgstr ""
+msgstr "SCO^aika"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:128
 msgid "Total time raced (Race/CTS)"
-msgstr ""
+msgstr "Kilvan kokonaisaika (kilpa/CTS)"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:312
 msgid ""
 "You can modify the scoreboard using the ^2scoreboard_columns_set command."
-msgstr ""
+msgstr "Voit mukauttaa tulostaulua käyttäen ^2scoreboard_columns_set käskyä."
 
 #: qcsrc/client/hud/panel/scoreboard.qc:313
 msgid "Usage:"
-msgstr ""
+msgstr "Käyttö:"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:315
 msgid "^2scoreboard_columns_set ^3field1 field2 ..."
-msgstr ""
+msgstr "^2scoreboard_columns_set ^3field1 field2 ..."
 
 #: qcsrc/client/hud/panel/scoreboard.qc:316
 msgid ""
 "^2scoreboard_columns_set ^7without arguments reads the arguments from the "
 "cvar scoreboard_columns"
 msgstr ""
+"^2scoreboard_columns_set ^7ilman argumentteja otetaan argumentit cvar "
+"scoreboard_columns :sta"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:317
 msgid ""
 "  ^5Note: ^7scoreboard_columns_set without arguments is executed on every "
 "map start"
 msgstr ""
+"  ^5Huomautus: ^7scoreboard_columns_set ilman argumentteja ajetaan jokaisen "
+"kartan aloituksessa"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:318
 msgid ""
 "^2scoreboard_columns_set ^3expand_default ^7loads default layout and expands "
 "it into the cvar scoreboard_columns so you can edit it"
 msgstr ""
+"^2scoreboard_columns_set ^3expand_default ^7lataa vakioulkoasun ja laajentaa "
+"sen muotoon cvar scoreboard_columns jotta voit muokata sitä"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:319
 msgid "You can use a ^3|^7 to start the right-aligned fields."
-msgstr ""
+msgstr "Voit käyttää ^3|^7 aloittaaksesi oikealle tasatut kentät."
 
 #: qcsrc/client/hud/panel/scoreboard.qc:320
 msgid "The following field names are recognized (case insensitive):"
-msgstr ""
+msgstr "Seuraavat kenttänimet tunnistetaan (ei vaatimusta kirjainkoolle):"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:326
 msgid ""
@@ -932,28 +945,41 @@ 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 ""
+"Kenttää ennen voit laittaa + tai - merkin, jota seuraa pilkuilla eritelty "
+"lista\n"
+"pelimuodoista, sitten kenoviiva, saadaksesi kentän näkymään vain näissä\n"
+"tai kaikissa näissä pelimuodoissa. Voit myöskin määrittää 'kaikki' "
+"kenttänä \n"
+"näyttääksesi kaikki tarjolla olevat kentät sen hetkiselle pelimuodolle. "
 
 #: qcsrc/client/hud/panel/scoreboard.qc:332
 msgid ""
 "The special game type names 'teams' and 'noteams' can be used to\n"
 "include/exclude ALL teams/noteams game modes."
 msgstr ""
+"Erikoispelimuotojen nimiä 'teams' ja 'noteams' voidaan käyttää\n"
+"sisällyttääksesi/poislukien KAIKKI teams/noteams pelimuodot."
 
 #: qcsrc/client/hud/panel/scoreboard.qc:336
 msgid "Example: scoreboard_columns_set name ping pl | +ctf/field3 -dm/field4"
 msgstr ""
+"Esimerkki: scoreboard_columns_set nimi ping pl | +ctf/kenttä3 -dm/kenttä4"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:337
 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 ""
+"näyttää nimen, pingin ja pl:n asemoituna vasemmalle, ja kentät\n"
+"pystysuorapalkista oikealla asemoituna oikealle."
 
 #: qcsrc/client/hud/panel/scoreboard.qc:339
 msgid ""
 "'field3' will only be shown in CTF, and 'field4' will be shown in all\n"
 "other gamemodes except DM."
 msgstr ""
+"'kenttä3' näytetään vain CTF:ssä, ja 'kenttä4' näytetään kaikissa\n"
+"muissa pelimuodoissa poislukien muoto DM."
 
 #: qcsrc/client/hud/panel/scoreboard.qc:603
 #: qcsrc/client/hud/panel/scoreboard.qc:610
@@ -970,117 +996,117 @@ msgstr "N/A"
 #: qcsrc/client/hud/panel/scoreboard.qc:1188
 #, c-format
 msgid "Accuracy stats (average %d%%)"
-msgstr ""
+msgstr "Tarkkuustilastot (keskimäärin %d%%)"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1336
 msgid "Map stats:"
-msgstr ""
+msgstr "Kartan tilastot:"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1366
 msgid "Monsters killed:"
-msgstr ""
+msgstr "Hirviöitä tapettu:"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1373
 msgid "Secrets found:"
-msgstr ""
+msgstr "Salaisuuksia löydettiin:"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1395
 msgid "Capture time rankings"
-msgstr ""
+msgstr "Kaappausten aikatasot"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1395
 msgid "Rankings"
-msgstr ""
+msgstr "Rankkaustasot"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1613
 #, c-format
 msgid "^3%1.0f minutes"
-msgstr ""
+msgstr "^3%1.0f minuuttia"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1622
 #: qcsrc/client/hud/panel/scoreboard.qc:1629
 #, c-format
 msgid "^5%s %s"
-msgstr ""
+msgstr "^5%s %s"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1623
 #: qcsrc/client/hud/panel/scoreboard.qc:1630
 #: qcsrc/client/hud/panel/scoreboard.qc:1642
 #: qcsrc/client/hud/panel/scoreboard.qc:1649
 msgid "SCO^points"
-msgstr ""
+msgstr "SCO^pisteet"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1624
 #: qcsrc/client/hud/panel/scoreboard.qc:1631
 #: qcsrc/client/hud/panel/scoreboard.qc:1643
 #: qcsrc/client/hud/panel/scoreboard.qc:1650
 msgid "SCO^is beaten"
-msgstr ""
+msgstr "SCO^on päihitetty"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1641
 #: qcsrc/client/hud/panel/scoreboard.qc:1648
 #, c-format
 msgid "^2+%s %s"
-msgstr ""
+msgstr "^2+%s %s"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1659
 #, c-format
 msgid "^7Map: ^2%s"
-msgstr ""
+msgstr "^7Kartta: ^2%s"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1798
 #, c-format
 msgid "Speed award: %d%s ^7(%s^7)"
-msgstr ""
+msgstr "Nopeuspalkinto: %d%s ^7(%s^7)"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1802
 #, c-format
 msgid "All-time fastest: %d%s ^7(%s^7)"
-msgstr ""
+msgstr "Kaikkien aikojen nopein: %d%s ^7(%s^7)"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1818
 #, c-format
 msgid "Spectators"
-msgstr ""
+msgstr "Katselijat"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1845
 #, c-format
 msgid "^1Respawning in ^3%s^1..."
-msgstr ""
+msgstr "^1Virkoaminen tapahtuu ^3%s^1..."
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1855
 #, c-format
 msgid "You are dead, wait ^3%s^7 before respawning"
-msgstr ""
+msgstr "Olet kuollut, odota ^3%s^7 ennen uudelleenvirkoamista"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1864
 #, c-format
 msgid "You are dead, press ^2%s^7 to respawn"
-msgstr ""
+msgstr "Olet kuollut, paina ^2%s^7 virotaksesi uudelleen"
 
 #: qcsrc/client/hud/panel/timer.qc:67
 msgid "WARMUP"
-msgstr ""
+msgstr "LÄMMITTELY"
 
 #: qcsrc/client/hud/panel/vote.qc:27
 msgid "^1You must answer before entering hud configure mode"
-msgstr ""
+msgstr "^1Sinun tulee vastata ennen sisäänkäyntiä hud-asetus tilaan"
 
 #: qcsrc/client/hud/panel/vote.qc:30
 msgid "^2Name ^7instead of \"^1Anonymous player^7\" in stats"
-msgstr ""
+msgstr "^2Nimi ^7tämän sijasta \"^1Nimetön pelaaja^7\" tilastoissa"
 
 #: qcsrc/client/hud/panel/vote.qc:116
 msgid "A vote has been called for:"
-msgstr ""
+msgstr "Äänestys on tullut tulokseen:"
 
 #: qcsrc/client/hud/panel/vote.qc:118
 msgid "Allow servers to store and display your name?"
-msgstr ""
+msgstr "Salli palvelimien tallentaa ja näyttää nimesi?"
 
 #: qcsrc/client/hud/panel/vote.qc:122
 msgid "^1Configure the HUD"
-msgstr ""
+msgstr "^1Määrittele HUD"
 
 #: qcsrc/client/hud/panel/vote.qc:126 qcsrc/menu/xonotic/dialog_firstrun.qc:82
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qc:18
@@ -1106,15 +1132,15 @@ msgstr "Ei"
 
 #: qcsrc/client/hud/panel/weapons.qc:546
 msgid "Out of ammo"
-msgstr ""
+msgstr "Ammukset loppu"
 
 #: qcsrc/client/hud/panel/weapons.qc:550
 msgid "Don't have"
-msgstr ""
+msgstr "Ei ole"
 
 #: qcsrc/client/hud/panel/weapons.qc:554
 msgid "Unavailable"
-msgstr ""
+msgstr "Ei saatavissa"
 
 #: qcsrc/client/main.qc:1027
 msgid " qu/s"
@@ -1134,12 +1160,12 @@ msgstr "mph"
 
 #: qcsrc/client/main.qc:1035
 msgid " knots"
-msgstr ""
+msgstr "solmut"
 
 #: qcsrc/client/main.qc:1282
 #, c-format
 msgid "%s (not bound)"
-msgstr ""
+msgstr "%s (ei sidottu)"
 
 #: qcsrc/client/mapvoting.qc:52
 msgid " (1 vote)"
@@ -1152,11 +1178,11 @@ msgstr "(%d ääntä)"
 
 #: qcsrc/client/mapvoting.qc:274
 msgid "Don't care"
-msgstr ""
+msgstr "Aivan sama"
 
 #: qcsrc/client/mapvoting.qc:375
 msgid "Decide the gametype"
-msgstr ""
+msgstr "Valitse pelitila"
 
 #: qcsrc/client/mapvoting.qc:375
 msgid "Vote for a map"
@@ -1170,120 +1196,123 @@ msgstr "%d sekuntia jäljellä"
 #: qcsrc/client/mapvoting.qc:505
 msgid "mv_mapdownload: ^3You're not supposed to use this command on your own!"
 msgstr ""
+"mv_mapdownload: ^3Sinun ei ole tarkoitus käyttää tätä käskyä omin päin!"
 
 #: qcsrc/client/mapvoting.qc:515
 msgid "^1Error:^7 Couldn't find pak index."
-msgstr ""
+msgstr "^1Virhe:^7 Ei löytynyt: pak index."
 
 #: qcsrc/client/mapvoting.qc:524
 msgid "Requesting preview..."
-msgstr ""
+msgstr "Pyydetään esikatselua..."
 
 #: qcsrc/client/miscfunctions.qc:111
 msgid "Trying to remove a team which is not in the teamlist!"
-msgstr ""
+msgstr "Koetetaan poistaa joukkuetta joka ei ole joukkuelistassa!"
 
 #: qcsrc/client/view.qc:1518
 msgid "Nade timer"
-msgstr ""
+msgstr "Naattiajastin"
 
 #: qcsrc/client/view.qc:1523
 msgid "Capture progress"
-msgstr ""
+msgstr "Kaappauksen edistyminen"
 
 #: qcsrc/client/view.qc:1528
 msgid "Revival progress"
-msgstr ""
+msgstr "Elpymisen edistyminen"
 
 #: qcsrc/common/command/generic.qc:156
 msgid "error creating curl handle"
-msgstr ""
+msgstr "virhe luodessa: curl handle"
 
 #: qcsrc/common/command/generic.qc:412
 msgid "Notification restart command only works with cl_cmd and sv_cmd."
 msgstr ""
+"Ilmoituksen uudelleenkäynnistyskäsky toimii vain tämän kanssa cl_cmd and "
+"sv_cmd."
 
 #: qcsrc/common/gamemodes/gamemode/nexball/weapon.qh:7
 msgid "Ball Stealer"
-msgstr ""
+msgstr "Pallovaras"
 
 #: qcsrc/common/items/item/ammo.qh:66
 msgid "bullets"
-msgstr ""
+msgstr "luodit"
 
 #: qcsrc/common/items/item/ammo.qh:96
 msgid "cells"
-msgstr ""
+msgstr "kennot"
 
 #: qcsrc/common/items/item/ammo.qh:126
 msgid "plasma"
-msgstr ""
+msgstr "plasma"
 
 #: qcsrc/common/items/item/ammo.qh:156
 msgid "rockets"
-msgstr ""
+msgstr "raketit"
 
 #: qcsrc/common/items/item/ammo.qh:190
 msgid "shells"
-msgstr ""
+msgstr "ammukset"
 
 #: qcsrc/common/items/item/armor.qh:42
 msgid "Small armor"
-msgstr ""
+msgstr "Pieni panssari"
 
 #: qcsrc/common/items/item/armor.qh:80
 msgid "Medium armor"
-msgstr ""
+msgstr "Keskiluokan panssari"
 
 #: qcsrc/common/items/item/armor.qh:118 qcsrc/common/items/item/armor.qh:121
 msgid "Big armor"
-msgstr ""
+msgstr "Iso panssari"
 
 #: qcsrc/common/items/item/armor.qh:158 qcsrc/common/items/item/armor.qh:161
 msgid "Mega armor"
-msgstr ""
+msgstr "Mahtipanssari"
 
 #: qcsrc/common/items/item/health.qh:42
 msgid "Small health"
-msgstr ""
+msgstr "Pieni terveyspalautus"
 
 #: qcsrc/common/items/item/health.qh:80
 msgid "Medium health"
-msgstr ""
+msgstr "Keskiluokan terveyspalautus"
 
 #: qcsrc/common/items/item/health.qh:118 qcsrc/common/items/item/health.qh:121
 msgid "Big health"
-msgstr ""
+msgstr "Suuri terveyspalautus"
 
 #: qcsrc/common/items/item/health.qh:158 qcsrc/common/items/item/health.qh:161
 msgid "Mega health"
-msgstr ""
+msgstr "Mahtava terveyspalautus"
 
 #: 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:213
 msgid "Jetpack"
-msgstr ""
+msgstr "Lentopakkaus"
 
 #: qcsrc/common/items/item/jetpack.qh:71
 msgid "fuel"
-msgstr ""
+msgstr "polttoaine"
 
 #: qcsrc/common/items/item/jetpack.qh:96
 msgid "Fuel regenerator"
-msgstr ""
+msgstr "Polttoaineen uusiovalmistin"
 
 #: qcsrc/common/items/item/jetpack.qh:99
 msgid "Fuel regen"
-msgstr ""
+msgstr "Polttoaineen uusvalmistin"
 
 #: qcsrc/common/items/item/powerup.qh:43 qcsrc/common/items/item/powerup.qh:46
 msgid "Strength"
-msgstr ""
+msgstr "Voima"
 
 #: qcsrc/common/items/item/powerup.qh:79 qcsrc/common/items/item/powerup.qh:82
 msgid "Shield"
-msgstr ""
+msgstr "Suoja"
 
 #: qcsrc/common/mapinfo.qc:626
 #, no-c-format
@@ -1299,7 +1328,7 @@ msgstr "Tapporaja:"
 #: qcsrc/common/mapinfo.qh:72 qcsrc/common/mapinfo.qh:333
 #: qcsrc/common/mapinfo.qh:528
 msgid "The amount of frags needed before the match will end"
-msgstr ""
+msgstr "Tarvittava tappojen määrä ennen ottelun päättymistä"
 
 #: qcsrc/common/mapinfo.qh:114
 msgid "Deathmatch"
@@ -1307,7 +1336,7 @@ msgstr "Mättö (Deathmatch)"
 
 #: qcsrc/common/mapinfo.qh:114
 msgid "Score as many frags as you can"
-msgstr ""
+msgstr "Tee niin monta tappoa kuin pystyt"
 
 #: qcsrc/common/mapinfo.qh:127
 msgid "Last Man Standing"
@@ -1315,7 +1344,7 @@ msgstr "Viimeiseen mieheen (Last Man Standing)"
 
 #: qcsrc/common/mapinfo.qh:127
 msgid "Survive and kill until the enemies have no lives left"
-msgstr ""
+msgstr "Selviydy ja tapa kunnes vihollisilla ei ole enää elämiä jäljellä"
 
 #: qcsrc/common/mapinfo.qh:136
 msgid "Lives:"
@@ -1327,7 +1356,7 @@ msgstr "Kilpailu (RACE)"
 
 #: qcsrc/common/mapinfo.qh:148
 msgid "Race against other players to the finish line"
-msgstr ""
+msgstr "Kisaa toisia pelaajia vastaan kohti maaliviivaa"
 
 #: qcsrc/common/mapinfo.qh:175
 msgid "Laps:"
@@ -1339,7 +1368,7 @@ msgstr "Kilpailu CTS (RACE CTS)"
 
 #: qcsrc/common/mapinfo.qh:188
 msgid "Race for fastest time."
-msgstr ""
+msgstr "Kisaa saavuttaaksesi nopeimman ajan."
 
 #: qcsrc/common/mapinfo.qh:205 qcsrc/common/mapinfo.qh:256
 #: qcsrc/common/mapinfo.qh:372 qcsrc/common/mapinfo.qh:415
@@ -1350,7 +1379,7 @@ msgstr "Pisteraja:"
 
 #: qcsrc/common/mapinfo.qh:218
 msgid "Help your team score the most frags against the enemy team"
-msgstr ""
+msgstr "Auta joukkuettasi tekemään eniten tappoja vihollisjoukkuetta vastaan"
 
 #: qcsrc/common/mapinfo.qh:218
 msgid "Team Deathmatch"
@@ -1359,7 +1388,7 @@ msgstr "Joukkuemättö (Team Deatchmatch)"
 #: qcsrc/common/mapinfo.qh:256 qcsrc/common/mapinfo.qh:372
 #: qcsrc/common/mapinfo.qh:415
 msgid "The amount of points needed before the match will end"
-msgstr ""
+msgstr "Tarvittava pistemäärä ennen kuin ottelu loppuu"
 
 #: qcsrc/common/mapinfo.qh:270
 msgid "Capture the Flag"
@@ -1370,6 +1399,8 @@ msgid ""
 "Find and bring the enemy flag to your base to capture it, defend your base "
 "from the other team"
 msgstr ""
+"Löydä ja toimita vihollisen lippu tukikohtaasi kaapataksesi sen, puolusta "
+"tukikohtaasi toiselta joukkueelta"
 
 #: qcsrc/common/mapinfo.qh:288
 msgid "Capture limit:"
@@ -1377,7 +1408,7 @@ msgstr "Lipunryöstöraja"
 
 #: qcsrc/common/mapinfo.qh:288
 msgid "The amount of captures needed before the match will end"
-msgstr ""
+msgstr "Tarvittava kaappausten määrä ennen kuin ottelu loppuu"
 
 #: qcsrc/common/mapinfo.qh:305
 msgid "Clan Arena"
@@ -1385,11 +1416,11 @@ msgstr "Klaaniareena (Clan Arena)"
 
 #: qcsrc/common/mapinfo.qh:305
 msgid "Kill all enemy teammates to win the round"
-msgstr ""
+msgstr "Tapa kaikki vihollisjoukkueen jäsenet voittaaksesi kierroksen"
 
 #: qcsrc/common/mapinfo.qh:349
 msgid "Capture and defend all the control points to win"
-msgstr ""
+msgstr "Valtaa kaikki hallintapisteet ja puolusta niitä voittaaksesi"
 
 #: qcsrc/common/mapinfo.qh:349
 msgid "Domination"
@@ -1397,7 +1428,7 @@ msgstr "Hallinta (Domination)"
 
 #: qcsrc/common/mapinfo.qh:387
 msgid "Gather all the keys to win the round"
-msgstr ""
+msgstr "Kerää kaikki avaimet voittaaksesi kierroksen"
 
 #: qcsrc/common/mapinfo.qh:387
 msgid "Key Hunt"
@@ -1412,10 +1443,12 @@ msgid ""
 "Destroy obstacles to find and destroy the enemy power core before time runs "
 "out"
 msgstr ""
+"Tuhoa esteet löytääksesi ja tuhotaksesi vihollisen ytimen ennen kuin aika "
+"loppuu"
 
 #: qcsrc/common/mapinfo.qh:451
 msgid "Capture control points to reach and destroy the enemy generator"
-msgstr ""
+msgstr "Valtaa hallintapisteet päästäksesi vihollisen generaattorille"
 
 #: qcsrc/common/mapinfo.qh:451
 msgid "Onslaught"
@@ -1427,7 +1460,7 @@ msgstr "Nexpallo (Nexball)"
 
 #: qcsrc/common/mapinfo.qh:473
 msgid "Shoot and kick the ball into the enemies goal, keep your goal clean"
-msgstr ""
+msgstr "Ammu ja potkaise pallo vihollisen maaliin, pidä oma maalisi puhtaana"
 
 #: qcsrc/common/mapinfo.qh:487
 msgid "Goals:"
@@ -1435,7 +1468,7 @@ msgstr "Maalit:"
 
 #: qcsrc/common/mapinfo.qh:487
 msgid "The amount of goals needed before the match will end"
-msgstr ""
+msgstr "Tarvittava maalimäärä ennen kuin ottelu loppuu"
 
 #: qcsrc/common/mapinfo.qh:500
 msgid "Freeze Tag"
@@ -1446,10 +1479,13 @@ msgid ""
 "Kill enemies to freeze them, stand next to frozen teammates to revive them; "
 "freeze all enemies to win"
 msgstr ""
+"Tapa viholliset heidät jäädyttääksesi, seiso jäädytettyjen "
+"joukkuekavereidesi vieressä elvyttääksesi heidät; jäädytä kaikki viholliset "
+"voittaaksesi"
 
 #: qcsrc/common/mapinfo.qh:544
 msgid "Hold the ball to get points for kills"
-msgstr ""
+msgstr "Pidä palloa saadaksesi tappopisteitä"
 
 #: qcsrc/common/mapinfo.qh:544
 msgid "Keepaway"
@@ -1457,23 +1493,24 @@ msgstr "Pakomatka (Keepaway)"
 
 #: qcsrc/common/mapinfo.qh:559
 msgid "Invasion"
-msgstr ""
+msgstr "Tunkeutuminen"
 
 #: qcsrc/common/mapinfo.qh:559
 msgid "Survive against waves of monsters"
-msgstr ""
+msgstr "Selviydy hirviöaaltoja vastaan"
 
 #: qcsrc/common/mapinfo.qh:589
 msgid "Duel"
-msgstr ""
+msgstr "Kaksintaistelu"
 
 #: qcsrc/common/mapinfo.qh:589
 msgid "Fight in a one versus one arena battle to decide the winner"
 msgstr ""
+"Taistele areenalla yksi-vastaan-yksi kamppailu voittajan selvittämiseksi"
 
 #: qcsrc/common/minigames/cl_minigames.qc:383
 msgid "It's your turn"
-msgstr ""
+msgstr "Sinun vuorosi"
 
 #: qcsrc/common/minigames/cl_minigames_hud.qc:346
 #: qcsrc/menu/xonotic/dialog_quit.qh:6
@@ -1482,15 +1519,15 @@ msgstr "Lopeta"
 
 #: qcsrc/common/minigames/cl_minigames_hud.qc:351
 msgid "Invite"
-msgstr ""
+msgstr "Kutsu"
 
 #: qcsrc/common/minigames/cl_minigames_hud.qc:390
 msgid "Current Game"
-msgstr ""
+msgstr "Tämänhetkinen peli"
 
 #: qcsrc/common/minigames/cl_minigames_hud.qc:415
 msgid "Exit Menu"
-msgstr ""
+msgstr "Poistu"
 
 #: qcsrc/common/minigames/cl_minigames_hud.qc:427
 #: qcsrc/menu/xonotic/dialog_multiplayer.qc:16
@@ -1503,57 +1540,57 @@ msgstr "Liity"
 
 #: qcsrc/common/minigames/cl_minigames_hud.qc:506
 msgid "Minigames"
-msgstr ""
+msgstr "Pienpelit"
 
 #: qcsrc/common/minigames/cl_minigames_hud.qc:567
 msgid "Minigame message"
-msgstr ""
+msgstr "Pienpeliviesti"
 
 #: qcsrc/common/minigames/minigame/bd.qc:2
 msgid "Bulldozer"
-msgstr ""
+msgstr "Jyrä"
 
 #: 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 ""
+msgstr "Peli on ohi!"
 
 #: qcsrc/common/minigames/minigame/bd.qc:1095
 msgid "Well done! Click 'Next Level' to continue"
-msgstr ""
+msgstr "Hienosti meni! Napsauta 'Seuraava Taso' jatkaaksesi"
 
 #: qcsrc/common/minigames/minigame/bd.qc:1162
 msgid "Better luck next time!"
-msgstr ""
+msgstr "Paremmin ensi kerralla!"
 
 #: qcsrc/common/minigames/minigame/bd.qc:1167
 msgid "Tubular! Press \"Next Level\" to continue!"
-msgstr ""
+msgstr "Se meni putkeen! Paina \"Seuraava Taso\" jatkaaksesi!"
 
 #: qcsrc/common/minigames/minigame/bd.qc:1169
 msgid "Wicked! Press \"Next Level\" to continue!"
-msgstr ""
+msgstr "Päheetä! Paina \"Seuraava taso\" jatkaaksesi!"
 
 #: qcsrc/common/minigames/minigame/bd.qc:1173
 msgid "Press the space bar to change your currently selected tile"
-msgstr ""
+msgstr "Paina välilyöntiä vaihtaaksesi valitsemasi murikan"
 
 #: qcsrc/common/minigames/minigame/bd.qc:1176
 msgid "Push the boulders onto the targets"
-msgstr ""
+msgstr "Työnnä lohkareet kohteita kohti"
 
 #: qcsrc/common/minigames/minigame/bd.qc:1398
 msgid "Next Level"
-msgstr ""
+msgstr "Seuraava Taso"
 
 #: qcsrc/common/minigames/minigame/bd.qc:1399
 msgid "Restart"
-msgstr ""
+msgstr "Aloita uudelleen"
 
 #: qcsrc/common/minigames/minigame/bd.qc:1400
 msgid "Editor"
-msgstr ""
+msgstr "Muokkain"
 
 #: qcsrc/common/minigames/minigame/bd.qc:1401
 #: qcsrc/menu/xonotic/dialog_settings_input_userbind.qc:37
@@ -1562,7 +1599,7 @@ msgstr "Tallenna"
 
 #: qcsrc/common/minigames/minigame/c4.qc:2
 msgid "Connect Four"
-msgstr ""
+msgstr "Neljän suora"
 
 #: qcsrc/common/minigames/minigame/c4.qc:311
 #: qcsrc/common/minigames/minigame/c4.qc:317
@@ -1572,205 +1609,209 @@ msgstr ""
 #: qcsrc/common/minigames/minigame/pp.qc:368
 #, c-format
 msgid "%s^7 won the game!"
-msgstr ""
+msgstr "%s^7 voitti pelin!"
 
 #: qcsrc/common/minigames/minigame/c4.qc:373
 #: qcsrc/common/minigames/minigame/pp.qc:438
 #: qcsrc/common/minigames/minigame/ttt.qc:319
 msgid "Draw"
-msgstr ""
+msgstr "Tasapeli"
 
 #: qcsrc/common/minigames/minigame/c4.qc:378
 #: qcsrc/common/minigames/minigame/nmm.qc:606
 #: qcsrc/common/minigames/minigame/pp.qc:443
 #: qcsrc/common/minigames/minigame/ttt.qc:324
 msgid "You lost the game!"
-msgstr ""
+msgstr "Hävisit pelin!"
 
 #: qcsrc/common/minigames/minigame/c4.qc:379
 #: qcsrc/common/minigames/minigame/nmm.qc:607
 #: qcsrc/common/minigames/minigame/pp.qc:444
 #: qcsrc/common/minigames/minigame/ttt.qc:325
 msgid "You win!"
-msgstr ""
+msgstr "Voitto on sinun!"
 
 #: qcsrc/common/minigames/minigame/c4.qc:383
 #: qcsrc/common/minigames/minigame/nmm.qc:611
 #: qcsrc/common/minigames/minigame/pp.qc:455
 #: qcsrc/common/minigames/minigame/ttt.qc:336
 msgid "Wait for your opponent to make their move"
-msgstr ""
+msgstr "Odota että vastustajasi toteuttaa liikkeensä"
 
 #: qcsrc/common/minigames/minigame/c4.qc:386
 #: qcsrc/common/minigames/minigame/nmm.qc:613
 #: qcsrc/common/minigames/minigame/pp.qc:458
 #: qcsrc/common/minigames/minigame/ttt.qc:339
 msgid "Click on the game board to place your piece"
-msgstr ""
+msgstr "Napsauta pelilaudalla asettaaksesi nappulasi"
 
 #: qcsrc/common/minigames/minigame/nmm.qc:7
 msgid "Nine Men's Morris"
-msgstr ""
+msgstr "Mylly"
 
 #: 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 ""
+"Voit valita nappuloistasi yhden siirtääksesi sen yhteen ympäröivistä "
+"paikoista"
 
 #: qcsrc/common/minigames/minigame/nmm.qc:617
 msgid "You can select one of your pieces to move it anywhere on the board"
 msgstr ""
+"Voit valita yhden nappuloistasi siirtääksesi sen laudalla mihin tahansa "
 
 #: qcsrc/common/minigames/minigame/nmm.qc:619
 msgid "You can take one of the opponent's pieces"
-msgstr ""
+msgstr "Voit syödä yhden vastustajasi nappuloista"
 
 #: qcsrc/common/minigames/minigame/pong.qc:2
 msgid "Pong"
-msgstr ""
+msgstr "Pong-mailapeli"
 
 #: qcsrc/common/minigames/minigame/pong.qc:589
 #: qcsrc/common/minigames/minigame/ttt.qc:299
 msgid "AI"
-msgstr ""
+msgstr "AI-tekoäly"
 
 #: qcsrc/common/minigames/minigame/pong.qc:606
 msgid "Press ^1Start Match^7 to start the match with the current players"
 msgstr ""
+"Paina ^1Aloita Ottelu^7 aloittaaksesi ottelun tämänhetkisillä pelaajilla"
 
 #: qcsrc/common/minigames/minigame/pong.qc:674
 msgid "Start Match"
-msgstr ""
+msgstr "Aloita Ottelu"
 
 #: qcsrc/common/minigames/minigame/pong.qc:675
 msgid "Add AI player"
-msgstr ""
+msgstr "Lisää AI-tekoälypelaajia"
 
 #: qcsrc/common/minigames/minigame/pong.qc:676
 msgid "Remove AI player"
-msgstr ""
+msgstr "Poista AI-tekoälypelaaja"
 
 #: qcsrc/common/minigames/minigame/pp.qc:2
 msgid "Push-Pull"
-msgstr ""
+msgstr "Työnnä-Vedä"
 
 #: qcsrc/common/minigames/minigame/pp.qc:443
 #: qcsrc/common/minigames/minigame/ttt.qc:324
 msgid "Select \"^1Next Match^7\" on the menu for a rematch!"
-msgstr ""
+msgstr "Valitse valikossa \"^1Seuraava Ottelu^7\" uusintaottelua varten!"
 
 #: qcsrc/common/minigames/minigame/pp.qc:444
 #: qcsrc/common/minigames/minigame/pp.qc:450
 #: qcsrc/common/minigames/minigame/ttt.qc:325
 #: qcsrc/common/minigames/minigame/ttt.qc:331
 msgid "Select \"^1Next Match^7\" on the menu to start a new match!"
-msgstr ""
+msgstr "Valitse valikossa \"^1Seuraava Ottelu^7\" aloittaaksesi uuden ottelun!"
 
 #: qcsrc/common/minigames/minigame/pp.qc:451
 #: qcsrc/common/minigames/minigame/ttt.qc:332
 msgid "Wait for your opponent to confirm the rematch"
-msgstr ""
+msgstr "Odota vastustajasi vahvistusta uusintaottelulle"
 
 #: qcsrc/common/minigames/minigame/pp.qc:581
 #: qcsrc/common/minigames/minigame/ttt.qc:664
 msgid "Next Match"
-msgstr ""
+msgstr "Seuraava Ottelu"
 
 #: qcsrc/common/minigames/minigame/ps.qc:2
 msgid "Peg Solitaire"
-msgstr ""
+msgstr "Lautapasianssi"
 
 #: qcsrc/common/minigames/minigame/ps.qc:414
 msgid "All pieces cleared!"
-msgstr ""
+msgstr "Kaikki nappulat poisputsattu!"
 
 #: qcsrc/common/minigames/minigame/ps.qc:416
 msgid "Remaining pieces:"
-msgstr ""
+msgstr "Jäljelläolevat nappulat:"
 
 #: qcsrc/common/minigames/minigame/ps.qc:481
 #, c-format
 msgid "Pieces left: %s"
-msgstr ""
+msgstr "Nappuloita jäljellä: %s"
 
 #: qcsrc/common/minigames/minigame/ps.qc:491
 msgid "No more valid moves"
-msgstr ""
+msgstr "Ei enempää kelvollisia siirtoja"
 
 #: qcsrc/common/minigames/minigame/ps.qc:494
 msgid "Well done, you win!"
-msgstr ""
+msgstr "Hienosti meni, voitto on sinun!"
 
 #: qcsrc/common/minigames/minigame/ps.qc:497
 msgid "Jump a piece over another to capture it"
-msgstr ""
+msgstr "Pompsauta nappula toisen päälle kaapataksesi sen"
 
 #: qcsrc/common/minigames/minigame/ttt.qc:2
 msgid "Tic Tac Toe"
-msgstr ""
+msgstr "Ristinolla"
 
 #: qcsrc/common/minigames/minigame/ttt.qc:665
 msgid "Single Player"
-msgstr ""
+msgstr "Yksinpeli"
 
 #: qcsrc/common/monsters/monster/mage.qh:17
 #: qcsrc/menu/xonotic/dialog_monstertools.qc:18
 msgid "Mage"
-msgstr ""
+msgstr "Velho"
 
 #: qcsrc/common/monsters/monster/mage.qh:29
 msgid "Mage spike"
-msgstr ""
+msgstr "Velhontähkä"
 
 #: qcsrc/common/monsters/monster/shambler.qh:17
 #: qcsrc/menu/xonotic/dialog_monstertools.qc:17
 msgid "Shambler"
-msgstr ""
+msgstr "Värisyttäjä"
 
 #: qcsrc/common/monsters/monster/spider.qh:17
 #: qcsrc/menu/xonotic/dialog_monstertools.qc:16
 msgid "Spider"
-msgstr ""
+msgstr "Hämähäkki"
 
 #: qcsrc/common/monsters/monster/spider.qh:28
 msgid "Spider attack"
-msgstr ""
+msgstr "Hämähäkin hyökkäys"
 
 #: qcsrc/common/monsters/monster/wyvern.qh:17
 #: qcsrc/menu/xonotic/dialog_monstertools.qc:19
 msgid "Wyvern"
-msgstr ""
+msgstr "Lohikäärme"
 
 #: qcsrc/common/monsters/monster/wyvern.qh:28
 msgid "Wyvern attack"
-msgstr ""
+msgstr "Lohikäärmeen hyökkäys"
 
 #: qcsrc/common/monsters/monster/zombie.qh:17
 #: qcsrc/menu/xonotic/dialog_monstertools.qc:15
 msgid "Zombie"
-msgstr ""
+msgstr "Zombie"
 
 #: qcsrc/common/mutators/mutator/buffs/all.inc:15
 msgid "Ammo"
-msgstr ""
+msgstr "Ammukset"
 
 #: qcsrc/common/mutators/mutator/buffs/all.inc:24
 msgid "Resistance"
-msgstr ""
+msgstr "Vastarinta"
 
 #: qcsrc/common/mutators/mutator/buffs/all.inc:33
 #: qcsrc/common/mutators/mutator/instagib/items.qh:126
 #: qcsrc/common/mutators/mutator/instagib/items.qh:129
 msgid "Speed"
-msgstr ""
+msgstr "Nopeus"
 
 #: qcsrc/common/mutators/mutator/buffs/all.inc:43
 msgid "Medic"
-msgstr ""
+msgstr "Lääkintämies"
 
 #: qcsrc/common/mutators/mutator/buffs/all.inc:54
 msgid "Bash"
-msgstr ""
+msgstr "Murjaisu"
 
 #: qcsrc/common/mutators/mutator/buffs/all.inc:62
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:83
@@ -1780,67 +1821,67 @@ msgstr "Vampyyri"
 
 #: qcsrc/common/mutators/mutator/buffs/all.inc:70
 msgid "Disability"
-msgstr ""
+msgstr "Vammaisuus"
 
 #: qcsrc/common/mutators/mutator/buffs/all.inc:78
 msgid "Vengeance"
-msgstr ""
+msgstr "Kosto"
 
 #: qcsrc/common/mutators/mutator/buffs/all.inc:86
 msgid "Jump"
-msgstr ""
+msgstr "Hyppy"
 
 #: qcsrc/common/mutators/mutator/buffs/all.inc:95
 msgid "Invisible"
-msgstr ""
+msgstr "Näkymätön"
 
 #: qcsrc/common/mutators/mutator/buffs/all.inc:104
 msgid "Inferno"
-msgstr ""
+msgstr "Pätsi"
 
 #: qcsrc/common/mutators/mutator/buffs/all.inc:112
 msgid "Swapper"
-msgstr ""
+msgstr "Vaihdokki"
 
 #: qcsrc/common/mutators/mutator/buffs/all.inc:120
 msgid "Magnet"
-msgstr ""
+msgstr "Magneetti"
 
 #: qcsrc/common/mutators/mutator/buffs/all.inc:128
 msgid "Luck"
-msgstr ""
+msgstr "Lykästys"
 
 #: qcsrc/common/mutators/mutator/buffs/all.inc:136
 msgid "Flight"
-msgstr ""
+msgstr "Lento"
 
 #: qcsrc/common/mutators/mutator/buffs/buffs.qh:7
 msgid "Buff"
-msgstr ""
+msgstr "Puhvi"
 
 #: qcsrc/common/mutators/mutator/damagetext/ui_damagetext.qc:8
 msgid "Damage text"
-msgstr ""
+msgstr "Vahinkoteksti"
 
 #: qcsrc/common/mutators/mutator/damagetext/ui_damagetext.qc:18
 msgid "Draw damage numbers"
-msgstr ""
+msgstr "Piirrä vahinkonumerot"
 
 #: qcsrc/common/mutators/mutator/damagetext/ui_damagetext.qc:20
 msgid "Font size minimum:"
-msgstr ""
+msgstr "Pienin kirjasinkoko:"
 
 #: qcsrc/common/mutators/mutator/damagetext/ui_damagetext.qc:25
 msgid "Font size maximum:"
-msgstr ""
+msgstr "Suurin kirjasinkoko:"
 
 #: qcsrc/common/mutators/mutator/damagetext/ui_damagetext.qc:30
 msgid "Accumulate range:"
-msgstr ""
+msgstr "Kerääntymän kantama:"
 
 #: qcsrc/common/mutators/mutator/damagetext/ui_damagetext.qc:38
 msgid "Lifetime:"
-msgstr ""
+msgstr "Elinaika:"
 
 #: qcsrc/common/mutators/mutator/damagetext/ui_damagetext.qc:43
 #: qcsrc/common/mutators/mutator/damagetext/ui_damagetext.qc:53
@@ -1854,164 +1895,164 @@ msgstr "Väri:"
 
 #: qcsrc/common/mutators/mutator/damagetext/ui_damagetext.qc:50
 msgid "Draw damage numbers for friendly fire"
-msgstr ""
+msgstr "Piirrä vahinkonumerot koskien vahinkolaukauksia"
 
 #: qcsrc/common/mutators/mutator/instagib/items.qh:33
 msgid "Vaporizer ammo"
-msgstr ""
+msgstr "Höyrystimen ammukset"
 
 #: qcsrc/common/mutators/mutator/instagib/items.qh:59
 #: qcsrc/common/mutators/mutator/instagib/items.qh:62
 msgid "Extra life"
-msgstr ""
+msgstr "Lisäelämä"
 
 #: qcsrc/common/mutators/mutator/instagib/items.qh:91
 #: qcsrc/common/mutators/mutator/instagib/items.qh:94
 msgid "Invisibility"
-msgstr ""
+msgstr "Näkymättömyys"
 
 #: qcsrc/common/mutators/mutator/nades/nades.inc:18
 msgid "Napalm grenade"
-msgstr ""
+msgstr "Napalmikranaatti"
 
 #: qcsrc/common/mutators/mutator/nades/nades.inc:26
 msgid "Ice grenade"
-msgstr ""
+msgstr "Jääkranaatti"
 
 #: qcsrc/common/mutators/mutator/nades/nades.inc:34
 msgid "Translocate grenade"
-msgstr ""
+msgstr "Erikohdistuskranaatti"
 
 #: qcsrc/common/mutators/mutator/nades/nades.inc:42
 msgid "Spawn grenade"
-msgstr ""
+msgstr "Uudelleensyntykranaatti"
 
 #: qcsrc/common/mutators/mutator/nades/nades.inc:50
 msgid "Heal grenade"
-msgstr ""
+msgstr "Toipumiskranaatti"
 
 #: qcsrc/common/mutators/mutator/nades/nades.inc:58
 msgid "Monster grenade"
-msgstr ""
+msgstr "Hirviökranaatti"
 
 #: qcsrc/common/mutators/mutator/nades/nades.inc:66
 msgid "Entrap grenade"
-msgstr ""
+msgstr "Ansakranaatti"
 
 #: qcsrc/common/mutators/mutator/nades/nades.inc:74
 msgid "Veil grenade"
-msgstr ""
+msgstr "Huntukranaatti"
 
 #: qcsrc/common/mutators/mutator/nades/nades.qh:34
 msgid "Grenade"
-msgstr ""
+msgstr "Kranaatti"
 
 #: qcsrc/common/mutators/mutator/overkill/okhmg.qh:20
 msgid "Overkill Heavy Machine Gun"
-msgstr ""
+msgstr "Ylimalkaallinen raskaskonepistooli"
 
 #: qcsrc/common/mutators/mutator/overkill/okmachinegun.qh:18
 msgid "Overkill MachineGun"
-msgstr ""
+msgstr "Ylimalkaallinen konepistooli"
 
 #: qcsrc/common/mutators/mutator/overkill/oknex.qh:19
 msgid "Overkill Nex"
-msgstr ""
+msgstr "Ylimalkaallinen Nex"
 
 #: qcsrc/common/mutators/mutator/overkill/okrpc.qh:20
 msgid "Overkill Rocket Propelled Chainsaw"
-msgstr ""
+msgstr "Ylimalkaallinen rakettikäyttöinen moottorisaha"
 
 #: qcsrc/common/mutators/mutator/overkill/okshotgun.qh:18
 msgid "Overkill Shotgun"
-msgstr ""
+msgstr "Ylimalkaallinen haulikko"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:3
 msgid "Waypoint"
-msgstr ""
+msgstr "Välietappi"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:4
 msgid "Help me!"
-msgstr ""
+msgstr "Auta minua!"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:5
 msgid "Here"
-msgstr ""
+msgstr "Tässä"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:6
 msgid "DANGER"
-msgstr ""
+msgstr "VAARA"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:8
 msgid "Frozen!"
-msgstr ""
+msgstr "Jäässä!"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:10
 msgid "Item"
-msgstr ""
+msgstr "Esine"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:12
 msgid "Checkpoint"
-msgstr ""
+msgstr "Jatkopiste"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:13
 #: qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc:240
 msgid "Finish"
-msgstr ""
+msgstr "Loppu"
 
 #: 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 ""
+msgstr "Alku"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:17
 msgid "Defend"
-msgstr ""
+msgstr "Puolusta"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:18
 msgid "Destroy"
-msgstr ""
+msgstr "Tuhoa"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:19
 msgid "Push"
-msgstr ""
+msgstr "Työnnä"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:21
 msgid "Flag carrier"
-msgstr ""
+msgstr "Lipunkantaja"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:22
 msgid "Enemy carrier"
-msgstr ""
+msgstr "Viholliskantaja"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:23
 msgid "Dropped flag"
-msgstr ""
+msgstr "Pudotettu lippu"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:24
 msgid "White base"
-msgstr ""
+msgstr "Valkoinen tukikohta"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:25
 msgid "Red base"
-msgstr ""
+msgstr "Punainen tukikohta"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:26
 msgid "Blue base"
-msgstr ""
+msgstr "Sininen tukikohta"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:27
 msgid "Yellow base"
-msgstr ""
+msgstr "Keltainen tukikohta"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:28
 msgid "Pink base"
-msgstr ""
+msgstr "Vaaleanpunainen tukikohta"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:29
 msgid "Return flag here"
-msgstr ""
+msgstr "Palauta lippu tänne"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:31
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:32
@@ -2022,11 +2063,11 @@ msgstr ""
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:52
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:53
 msgid "Control point"
-msgstr ""
+msgstr "Hallintapiste"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:37
 msgid "Dropped key"
-msgstr ""
+msgstr "Pudotettu avain"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:38
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:40
@@ -2034,54 +2075,54 @@ msgstr ""
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:42
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:43
 msgid "Key carrier"
-msgstr ""
+msgstr "Avaimenkantaja"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:39
 msgid "Run here"
-msgstr ""
+msgstr "Juokse tänne"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:45
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:48
 msgid "Ball"
-msgstr ""
+msgstr "Pallo"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:46
 msgid "Ball carrier"
-msgstr ""
+msgstr "Pallonkantaja"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:49
 msgid "Goal"
-msgstr ""
+msgstr "Maali"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:54
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:55
 msgid "Generator"
-msgstr ""
+msgstr "Generaattori"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:57
 msgid "Weapon"
-msgstr ""
+msgstr "Ase"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:59
 msgid "Monster"
-msgstr ""
+msgstr "Hirviö"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:61
 msgid "Vehicle"
-msgstr ""
+msgstr "Ajoneuvo"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:62
 msgid "Intruder!"
-msgstr ""
+msgstr "Tunkeutuja!"
 
 #: qcsrc/common/mutators/mutator/waypoints/all.inc:64
 msgid "Tagged"
-msgstr ""
+msgstr "Korvamerkitty"
 
 #: qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc:695
 #, c-format
 msgid "%s needing help!"
-msgstr ""
+msgstr "%s avuntarpeessa!"
 
 #: qcsrc/common/net_notice.qc:90
 msgid "^1Server notices:"
@@ -2090,11 +2131,12 @@ msgstr "^1Palvelimen ilmoitukset:"
 #: qcsrc/common/notifications/all.inc:239
 msgid "^F4NOTE: ^BGSpectator chat is not sent to players during the match"
 msgstr ""
+"^F4HUOMAUTUS: ^BGKatselijakeskustelua ei lähetetä pelaajille ottelun aikana"
 
 #: qcsrc/common/notifications/all.inc:241
 #, c-format
 msgid "^BG%s^BG captured the ^TC^TT^BG flag"
-msgstr ""
+msgstr "^BG%s^BG kaappasi ^TC^TT^BG lipun"
 
 #: qcsrc/common/notifications/all.inc:242
 #, c-format
@@ -2102,16 +2144,18 @@ 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 ""
+"^BG%s^BG kaappasi ^TC^TT^BG lipun ^F1%s^BG sekunnissa, rikkoen ^BG%s^BG's "
+"edellisen ennätyksen ^F2%s^BG sekuntia"
 
 #: qcsrc/common/notifications/all.inc:243
 #, c-format
 msgid "^BG%s^BG captured the flag"
-msgstr ""
+msgstr "^BG%s^BG kaappasi lipun"
 
 #: qcsrc/common/notifications/all.inc:244
 #, c-format
 msgid "^BG%s^BG captured the ^TC^TT^BG flag in ^F1%s^BG seconds"
-msgstr ""
+msgstr "^BG%s^BG kaappasi ^TC^TT^BG lipun ^F1%s^BG sekunnissa"
 
 #: qcsrc/common/notifications/all.inc:245
 #, c-format
@@ -2119,40 +2163,43 @@ 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 ""
+"^BG%s^BG kaappasi ^TC^TT^BG lipun ^F2%s^BG sekunnissa, onnistumatta "
+"rikkomaan ^BG%s^BG's edellistä ennätystä ^F1%s^BG sekuntia"
 
 #: qcsrc/common/notifications/all.inc:246
 msgid "^BGThe ^TC^TT^BG flag was returned to base by its owner"
-msgstr ""
+msgstr "^BGThe ^TC^TT^BG lippu palautettiin tukikohtaan omistajansa toimesta"
 
 #: qcsrc/common/notifications/all.inc:247
 msgid "^BGThe flag was returned by its owner"
-msgstr ""
+msgstr "^BGLippu palautettiin omistajansa toimesta"
 
 #: qcsrc/common/notifications/all.inc:248
 msgid "^BGThe ^TC^TT^BG flag was destroyed and returned to base"
-msgstr ""
+msgstr "^BGLippu ^TC^TT^BG tuhottiin ja palautettiin tukikohtaan"
 
 #: qcsrc/common/notifications/all.inc:249
 msgid "^BGThe flag was destroyed and returned to base"
-msgstr ""
+msgstr "^BGLippu tuhottiin ja palautettiin tukikohtaan"
 
 #: qcsrc/common/notifications/all.inc:250
 msgid "^BGThe ^TC^TT^BG flag was dropped in the base and returned itself"
-msgstr ""
+msgstr "^BGLippu ^TC^TT^BG pudotettiin tukikohtaan palauttaen itse itsensä"
 
 #: qcsrc/common/notifications/all.inc:251
 msgid "^BGThe flag was dropped in the base and returned itself"
-msgstr ""
+msgstr "^BGLippu pudotettiin tukikohtaan palauttaen itsensä"
 
 #: qcsrc/common/notifications/all.inc:252
 msgid ""
 "^BGThe ^TC^TT^BG flag fell somewhere it couldn't be reached and returned to "
 "base"
 msgstr ""
+"^BGLippu ^TC^TT^BG putosi johonkin saavuttamattomiin tukikohtapalautukselle"
 
 #: qcsrc/common/notifications/all.inc:253
 msgid "^BGThe flag fell somewhere it couldn't be reached and returned to base"
-msgstr ""
+msgstr "^BGLippu putosi johonkin saavuttamattomiin tukikohtapalautukselle"
 
 #: qcsrc/common/notifications/all.inc:254
 #, c-format
@@ -2160,825 +2207,844 @@ msgid ""
 "^BGThe ^TC^TT^BG flag became impatient after ^F1%.2f^BG seconds and returned "
 "itself"
 msgstr ""
+"^BGLippu ^TC^TT^BG muuttui malttamattomaksi ^F1%.2f^BG sekunnin jälkeen "
+"palauttaen itsensä"
 
 #: qcsrc/common/notifications/all.inc:255
 #, c-format
 msgid ""
 "^BGThe flag became impatient after ^F1%.2f^BG seconds and returned itself"
 msgstr ""
+"^BGLippu muuttui malttamattomaksi ^F1%.2f^BG sekunnin jälkeen palauttaen "
+"itsensä"
 
 #: qcsrc/common/notifications/all.inc:256
 msgid "^BGThe ^TC^TT^BG flag has returned to the base"
-msgstr ""
+msgstr "^BGLippu ^TC^TT^BG palautui tukikohtaan"
 
 #: qcsrc/common/notifications/all.inc:257
 msgid "^BGThe flag has returned to the base"
-msgstr ""
+msgstr "^BGLippu palautui tukikohtaan"
 
 #: qcsrc/common/notifications/all.inc:258
 #, c-format
 msgid "^BG%s^BG lost the ^TC^TT^BG flag"
-msgstr ""
+msgstr "^BG%s^BG menetti ^TC^TT^BG lipun"
 
 #: qcsrc/common/notifications/all.inc:259
 #, c-format
 msgid "^BG%s^BG lost the flag"
-msgstr ""
+msgstr "^BG%s^BG menetti lipun"
 
 #: qcsrc/common/notifications/all.inc:260
 #, c-format
 msgid "^BG%s^BG got the ^TC^TT^BG flag"
-msgstr ""
+msgstr "^BG%s^BG sai ^TC^TT^BG lipun"
 
 #: qcsrc/common/notifications/all.inc:261
 #, c-format
 msgid "^BG%s^BG got the flag"
-msgstr ""
+msgstr "^BG%s^BG sai lipun"
 
 #: qcsrc/common/notifications/all.inc:262
 #: qcsrc/common/notifications/all.inc:263
 #, c-format
 msgid "^BG%s^BG returned the ^TC^TT^BG flag"
-msgstr ""
+msgstr "^BG%s^BG palautti ^TC^TT^BG lipun"
 
 #: qcsrc/common/notifications/all.inc:265
 #: qcsrc/common/notifications/all.inc:557
 #, c-format
 msgid "^F2Throwing coin... Result: %s^F2!"
-msgstr ""
+msgstr "^F2Kolikonheitto... Tulos: %s^F2!"
 
 #: qcsrc/common/notifications/all.inc:267
 msgid "^BGYou don't have any fuel for the ^F1Jetpack"
-msgstr ""
+msgstr "^BGSinulla ei ole polttoainetta ^F1Lentopakkaukseen"
 
 #: qcsrc/common/notifications/all.inc:269
 msgid "^F2You lack a UID, superspec options will not be saved/restored"
-msgstr ""
+msgstr "^F2Sinulta uupuu UID, superspes valintoja ei tallenneta/palauteta"
 
 #: qcsrc/common/notifications/all.inc:271
 msgid "^F1Round already started, you will join the game in the next round"
-msgstr ""
+msgstr "^F1Kierros on jo alkanut, pääset mukaan ensi kierrokselle"
 
 #: qcsrc/common/notifications/all.inc:272
 msgid "^F2You will spectate in the next round"
-msgstr ""
+msgstr "^F2Seuraava kierros menee sinun osaltasi katsellessa"
 
 #: qcsrc/common/notifications/all.inc:274
 #, c-format
 msgid "^BG%s%s^K1 was killed by ^BG%s^K1's ^BG%s^K1 buff ^K1%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 tapettiin ^BG%s^K1's ^BG%s^K1 puhvilla ^K1%s%s"
 
 #: qcsrc/common/notifications/all.inc:274
 #, c-format
 msgid "^BG%s%s^K1 was scored against by ^BG%s^K1's ^BG%s^K1 buff ^K1%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 otettiin pisteitä pois ^BG%s^K1's ^BG%s^K1 puhvilla ^K1%s%s"
 
 #: qcsrc/common/notifications/all.inc:275
 #, c-format
 msgid "^BG%s%s^K1 was unfairly eliminated by ^BG%s^K1%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 lopetettiin epärehellisesti ja syyllinen oli ^BG%s^K1%s%s"
 
 #: qcsrc/common/notifications/all.inc:276
 #, c-format
 msgid "^BG%s%s^K1 was drowned by ^BG%s^K1%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 hukutettiin syyllisen ollen ^BG%s^K1%s%s"
 
 #: qcsrc/common/notifications/all.inc:277
 #, c-format
 msgid "^BG%s%s^K1 was grounded by ^BG%s^K1%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 palautettiin maanpinnalle syyllisen ollen ^BG%s^K1%s%s"
 
 #: qcsrc/common/notifications/all.inc:278
 #, c-format
 msgid "^BG%s%s^K1 felt a little hot from ^BG%s^K1's fire^K1%s%s"
 msgstr ""
+"^BG%s%s^K1 tunsi mitä se on kun tekee poppaa ^BG%s^K1's tulen polttaessa^K1%s"
+"%s"
 
 #: qcsrc/common/notifications/all.inc:278
 #, c-format
 msgid "^BG%s%s^K1 was burnt up into a crisp by ^BG%s^K1%s%s"
 msgstr ""
+"^BG%s%s^K1 poltettiin täydeksi paistiksi syyllisen ollessa ^BG%s^K1%s%s"
 
 #: qcsrc/common/notifications/all.inc:279
 #, c-format
 msgid "^BG%s%s^K1 was cooked by ^BG%s^K1%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 päätyi murkinaksi kokin ollessa ^BG%s^K1%s%s"
 
 #: qcsrc/common/notifications/all.inc:280
 #, c-format
 msgid "^BG%s%s^K1 was pushed in front of a monster by ^BG%s^K1%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 työnnettiin hirviön eteen ja tekijä oli ^BG%s^K1%s%s"
 
 #: qcsrc/common/notifications/all.inc:281
 #, c-format
 msgid "^BG%s%s^K1 was blown up by ^BG%s^K1's Nade%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 posautettiin taivaan tuuliin ^BG%s^K1's Naatilla%s%s"
 
 #: qcsrc/common/notifications/all.inc:282
 #, c-format
 msgid "^BG%s%s^K1 got too close to a napalm explosion%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 erehtyi liian lähelle napalmiräjähdystä%s%s"
 
 #: qcsrc/common/notifications/all.inc:282
 #, c-format
 msgid "^BG%s%s^K1 was burned to death by ^BG%s^K1's Napalm Nade%s%s"
 msgstr ""
+"^BG%s%s^K1 poltettiin kuoliaaksi ^BG%s^K1's Napalminaatin toimesta %s%s"
 
 #: qcsrc/common/notifications/all.inc:283
 #, c-format
 msgid "^BG%s%s^K1 was blown up by ^BG%s^K1's Ice Nade%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 posautettiin ^BG%s^K1's Jäänaatin toimesta %s%s"
 
 #: qcsrc/common/notifications/all.inc:284
 #, c-format
 msgid "^BG%s%s^K1 was frozen to death by ^BG%s^K1's Ice Nade%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 jäätyi pakastelihaksi ^BG%s^K1's Jäänaatin toimesta%s%s"
 
 #: qcsrc/common/notifications/all.inc:285
 #, c-format
 msgid "^BG%s%s^K1 has not been healed by ^BG%s^K1's Healing Nade%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 ei tervehtynyt ^BG%s^K1's Terveysnaatista %s%s"
 
 #: qcsrc/common/notifications/all.inc:286
 #, c-format
 msgid "^BG%s%s^K1 was shot into space by ^BG%s^K1%s%s"
 msgstr ""
+"^BG%s%s^K1 ammuttiin planeettaa kiertävälle radalle syyllisen ollen ^BG"
+"%s^K1%s%s"
 
 #: qcsrc/common/notifications/all.inc:287
 #, c-format
 msgid "^BG%s%s^K1 was slimed by ^BG%s^K1%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 limakyllästettiin ja tekijä oli ^BG%s^K1%s%s"
 
 #: qcsrc/common/notifications/all.inc:288
 #, c-format
 msgid "^BG%s%s^K1 was preserved by ^BG%s^K1%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 säilöttiin säilöjän ollen ^BG%s^K1%s%s"
 
 #: qcsrc/common/notifications/all.inc:289
 #, c-format
 msgid "^BG%s%s^K1 tried to occupy ^BG%s^K1's teleport destination space%s%s"
 msgstr ""
+"^BG%s%s^K1 yritti koijailla ^BG%s^K1's etäsiirtomääränpään tonteilla%s%s"
 
 #: qcsrc/common/notifications/all.inc:289
 #, c-format
 msgid "^BG%s%s^K1 was telefragged by ^BG%s^K1%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 etäsurmattiin syyllisen ollen ^BG%s^K1%s%s"
 
 #: qcsrc/common/notifications/all.inc:290
 #, c-format
 msgid "^BG%s%s^K1 died in an accident with ^BG%s^K1%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 menehtyi onnettomuudessa ja kanssansa oli ^BG%s^K1%s%s"
 
 #: qcsrc/common/notifications/all.inc:291
 #, c-format
 msgid ""
 "^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Bumblebee exploded%s%s"
 msgstr ""
+"^BG%s%s^K1 otti osumaa töräyksestä kun ^BG%s^K1'n Bumblebee räjähti%s%s"
 
 #: qcsrc/common/notifications/all.inc:292
 #, c-format
 msgid "^BG%s%s^K1 saw the pretty lights of ^BG%s^K1's Bumblebee gun%s%s"
 msgstr ""
+"^BG%s%s^K1 koki kauniit valot joita ^BG%s^K1'n Bumblebee-ase tuottaa%s%s"
 
 #: qcsrc/common/notifications/all.inc:293
 #, c-format
 msgid "^BG%s%s^K1 was crushed by ^BG%s^K1%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 tuli rusennetuksi syypään ollen ^BG%s^K1%s%s"
 
 #: qcsrc/common/notifications/all.inc:294
 #, c-format
 msgid "^BG%s%s^K1 was cluster bombed by ^BG%s^K1's Raptor%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 sai maistaa sirpalepommia ^BG%s^K1'n Raptorin toimesta%s%s"
 
 #: qcsrc/common/notifications/all.inc:295
 #, c-format
 msgid "^BG%s%s^K1 couldn't resist ^BG%s^K1's purple blobs%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 ei voinut vastustaa ^BG%s^K1'n purppurakimpaleita%s%s"
 
 #: qcsrc/common/notifications/all.inc:296
 #, c-format
 msgid "^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Raptor exploded%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 otti osumaa töräyksestä kun ^BG%s^K1'n Raptor räjähti%s%s"
 
 #: qcsrc/common/notifications/all.inc:297
 #, c-format
 msgid ""
 "^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Spiderbot exploded%s%s"
 msgstr ""
+"^BG%s%s^K1 otti osumaa töräyksestä kun ^BG%s^K1'n Hämisbotti räjähti%s%s"
 
 #: qcsrc/common/notifications/all.inc:298
 #, c-format
 msgid "^BG%s%s^K1 got shredded by ^BG%s^K1's Spiderbot%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 silppuuntui ^BG%s^K1'n Hämisbotin toimesta%s%s"
 
 #: qcsrc/common/notifications/all.inc:299
 #, c-format
 msgid "^BG%s%s^K1 was blasted to bits by ^BG%s^K1's Spiderbot%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 posautettiin päreiksi ^BG%s^K1'n Hämisbotin toimesta%s%s"
 
 #: qcsrc/common/notifications/all.inc:300
 #, c-format
 msgid "^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Racer exploded%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 otti osumaa töräyksestä kun ^BG%s^K1'n Kilpuri räjähti%s%s"
 
 #: qcsrc/common/notifications/all.inc:301
 #, c-format
 msgid "^BG%s%s^K1 was bolted down by ^BG%s^K1's Racer%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 iskettiin alas ^BG%s^K1'n Kilpurin toimesta%s%s"
 
 #: qcsrc/common/notifications/all.inc:302
 #, c-format
 msgid "^BG%s%s^K1 couldn't find shelter from ^BG%s^K1's Racer%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 ei löytänyt suojaa ^BG%s^K1'n Kilpurilta%s%s"
 
 #: qcsrc/common/notifications/all.inc:303
 #, c-format
 msgid "^BG%s%s^K1 was thrown into a world of hurt by ^BG%s^K1%s%s"
 msgstr ""
+"^BG%s%s^K1 linkaistiin tuskien taipaleelle syyllisen ollen ^BG%s^K1%s%s"
 
 #: qcsrc/common/notifications/all.inc:305
 #, c-format
 msgid "^BG%s^K1 was moved into the %s%s"
-msgstr ""
+msgstr "^BG%s^K1 siirrettiin tänne %s%s"
 
 #: qcsrc/common/notifications/all.inc:306
 #, c-format
 msgid "^BG%s^K1 became enemies with the Lord of Teamplay%s%s"
-msgstr ""
+msgstr "^BG%s^K1 tuli viholliseksi Joukkuepelin Isännän kanssa %s%s"
 
 #: qcsrc/common/notifications/all.inc:307
 #, c-format
 msgid "^BG%s^K1 thought they found a nice camping ground%s%s"
-msgstr ""
+msgstr "^BG%s^K1 luulivat löytäneensä lokoisan retkeilyalueen%s%s"
 
 #: qcsrc/common/notifications/all.inc:308
 #, c-format
 msgid "^BG%s^K1 unfairly eliminated themself%s%s"
-msgstr ""
+msgstr "^BG%s^K1 lopettivat itsensä epäreilusti%s%s"
 
 #: qcsrc/common/notifications/all.inc:310
 #, c-format
 msgid "^BG%s^K1 couldn't catch their breath%s%s"
-msgstr ""
+msgstr "^BG%s^K1 eivät saaneet henkeä%s%s"
 
 #: qcsrc/common/notifications/all.inc:310
 #, c-format
 msgid "^BG%s^K1 was in the water for too long%s%s"
-msgstr ""
+msgstr "^BG%s^K1 oli vedessä liian pitkään%s%s"
 
 #: qcsrc/common/notifications/all.inc:311
 #, c-format
 msgid "^BG%s^K1 hit the ground with a bit too much force%s%s"
-msgstr ""
+msgstr "^BG%s^K1 kohtasi maankamaran hiukan liiallisella voimalla%s%s"
 
 #: qcsrc/common/notifications/all.inc:311
 #, c-format
 msgid "^BG%s^K1 hit the ground with a crunch%s%s"
-msgstr ""
+msgstr "^BG%s^K1 kohtasi maankamaran kanssa niin että narskui%s%s"
 
 #: qcsrc/common/notifications/all.inc:312
 #, c-format
 msgid "^BG%s^K1 became a bit too crispy%s%s"
-msgstr ""
+msgstr "^BG%s^K1 muuttui hiukan liian rapeaksi%s%s"
 
 #: qcsrc/common/notifications/all.inc:312
 #, c-format
 msgid "^BG%s^K1 felt a little hot%s%s"
-msgstr ""
+msgstr "^BG%s^K1 tunsi pientä kuumotusta%s%s"
 
 #: qcsrc/common/notifications/all.inc:313
 #, c-format
 msgid "^BG%s^K1 died%s%s"
-msgstr ""
+msgstr "^BG%s^K1 delasi%s%s"
 
 #: qcsrc/common/notifications/all.inc:314
 #, c-format
 msgid "^BG%s^K1 found a hot place%s%s"
-msgstr ""
+msgstr "^BG%s^K1 ja kuumat paikat%s%s"
 
 #: qcsrc/common/notifications/all.inc:314
 #, c-format
 msgid "^BG%s^K1 turned into hot slag%s%s"
-msgstr ""
+msgstr "^BG%s^K1 muuntui kuumaksi kuonaksi%s%s"
 
 #: qcsrc/common/notifications/all.inc:315
 #, c-format
 msgid "^BG%s^K1 was exploded by a Mage%s%s"
-msgstr ""
+msgstr "^BG%s^K1 joutui Velhon räjäyttämäksi%s%s"
 
 #: qcsrc/common/notifications/all.inc:316
 #, c-format
 msgid "^BG%s^K1's innards became outwards by a Shambler%s%s"
-msgstr ""
+msgstr "^BG%s^K1'n sisimmät tulivat ulos Värisyttäjän toimesta%s%s"
 
 #: qcsrc/common/notifications/all.inc:317
 #, c-format
 msgid "^BG%s^K1 was smashed by a Shambler%s%s"
-msgstr ""
+msgstr "^BG%s^K1 murskattiin Värisyttäjän toimesta%s%s"
 
 #: qcsrc/common/notifications/all.inc:318
 #, c-format
 msgid "^BG%s^K1 was zapped to death by a Shambler%s%s"
-msgstr ""
+msgstr "^BG%s^K1 sai kuolettavan sähköiskun Värisyttäjän toimesta%s%s"
 
 #: qcsrc/common/notifications/all.inc:319
 #, c-format
 msgid "^BG%s^K1 was bitten by a Spider%s%s"
-msgstr ""
+msgstr "^BG%s^K1 purtiin Hämähäkin toimesta%s%s"
 
 #: qcsrc/common/notifications/all.inc:320
 #, c-format
 msgid "^BG%s^K1 was fireballed by a Wyvern%s%s"
-msgstr ""
+msgstr "^BG%s^K1 sai Lohikäärmeen tulipallon kohtalokseen%s%s"
 
 #: qcsrc/common/notifications/all.inc:321
 #, c-format
 msgid "^BG%s^K1 joins the Zombies%s%s"
-msgstr ""
+msgstr "^BG%s^K1 liittyi eläviin kuolleisiin%s%s"
 
 #: qcsrc/common/notifications/all.inc:322
 #, c-format
 msgid "^BG%s^K1 was given kung fu lessons by a Zombie%s%s"
-msgstr ""
+msgstr "^BG%s^K1 sai kung fu -oppia Zombielta%s%s"
 
 #: qcsrc/common/notifications/all.inc:323
 #: qcsrc/common/notifications/all.inc:325
 #, c-format
 msgid "^BG%s^K1 mastered the art of self-nading%s%s"
 msgstr ""
+"^BG%s^K1 saavutti mestarillisuuden itsenaatittamisen jalossa taidossa%s%s"
 
 #: qcsrc/common/notifications/all.inc:324
 #, c-format
 msgid ""
 "^BG%s^K1 decided to take a look at the results of their napalm explosion%s%s"
-msgstr ""
+msgstr "^BG%s^K1 päätti katsoa napalmiräjäytyksensä tulokset%s%s"
 
 #: qcsrc/common/notifications/all.inc:324
 #, c-format
 msgid "^BG%s^K1 was burned to death by their own Napalm Nade%s%s"
-msgstr ""
+msgstr "^BG%s^K1 paloi poroksi omien Napalminaattiensa ansiosta%s%s"
 
 #: qcsrc/common/notifications/all.inc:326
 #, c-format
 msgid "^BG%s^K1 felt a little chilly%s%s"
-msgstr ""
+msgstr "^BG%s^K1 tunsi pientä kylmetystä%s%s"
 
 #: qcsrc/common/notifications/all.inc:326
 #, c-format
 msgid "^BG%s^K1 was frozen to death by their own Ice Nade%s%s"
-msgstr ""
+msgstr "^BG%s^K1 jäätyi kuoliaaksi omien Jäänaattiensa takia%s%s"
 
 #: qcsrc/common/notifications/all.inc:327
 #, c-format
 msgid "^BG%s^K1's Healing Nade didn't quite heal them%s%s"
-msgstr ""
+msgstr "^BG%s^K1'n Terveysnaatti ei heitä aivan tervehdyttänyt%s%s"
 
 #: qcsrc/common/notifications/all.inc:328
 #, c-format
 msgid "^BG%s^K1 died%s%s. What's the point of living without ammo?"
-msgstr ""
+msgstr "^BG%s^K1 kuoli%s%s. Onko elämällä jokin tarkoitus ilman ammuksia?"
 
 #: qcsrc/common/notifications/all.inc:328
 #, c-format
 msgid "^BG%s^K1 ran out of ammo%s%s"
-msgstr ""
+msgstr "^BG%s^K1 huomasi ammustensa loppuneen%s%s"
 
 #: qcsrc/common/notifications/all.inc:329
 #, c-format
 msgid "^BG%s^K1 rotted away%s%s"
-msgstr ""
+msgstr "^BG%s^K1 mätäni pois%s%s"
 
 #: qcsrc/common/notifications/all.inc:330
 #, c-format
 msgid "^BG%s^K1 became a shooting star%s%s"
-msgstr ""
+msgstr "^BG%s^K1 muuttui tähdenlennoksi%s%s"
 
 #: qcsrc/common/notifications/all.inc:331
 #, c-format
 msgid "^BG%s^K1 was slimed%s%s"
-msgstr ""
+msgstr "^BG%s^K1 kuorrutettiin limalla%s%s"
 
 #: qcsrc/common/notifications/all.inc:332
 #, c-format
 msgid "^BG%s^K1 couldn't take it anymore%s%s"
-msgstr ""
+msgstr "^BG%s^K1 sai tarpeekseen%s%s"
 
 #: qcsrc/common/notifications/all.inc:333
 #, c-format
 msgid "^BG%s^K1 is now preserved for centuries to come%s%s"
-msgstr ""
+msgstr "^BG%s^K1 on nyt säilötty tuleville sukupolville%s%s"
 
 #: qcsrc/common/notifications/all.inc:334
 #, c-format
 msgid "^BG%s^K1 switched to the %s%s"
-msgstr ""
+msgstr "^BG%s^K1 vaihtoi tähän %s%s"
 
 #: qcsrc/common/notifications/all.inc:335
 #, c-format
 msgid "^BG%s^K1 died in an accident%s%s"
-msgstr ""
+msgstr "^BG%s^K1 menehtyi onnettomuudessa%s%s"
 
 #: qcsrc/common/notifications/all.inc:336
 #, c-format
 msgid "^BG%s^K1 ran into a turret%s%s"
-msgstr ""
+msgstr "^BG%s^K1 porhalsi tykkitorniin%s%s"
 
 #: qcsrc/common/notifications/all.inc:337
 #, c-format
 msgid "^BG%s^K1 was blasted away by an eWheel turret%s%s"
-msgstr ""
+msgstr "^BG%s^K1 töräytettiin taivaan tuuliin eWheel-tykkitornin toimesta%s%s"
 
 #: qcsrc/common/notifications/all.inc:338
 #, c-format
 msgid "^BG%s^K1 got caught up in the FLAC turret fire%s%s"
-msgstr ""
+msgstr "^BG%s^K1 otti osumaa FLAC-tykkitornin tulesta%s%s"
 
 #: qcsrc/common/notifications/all.inc:339
 #, c-format
 msgid "^BG%s^K1 was blasted away by a Hellion turret%s%s"
-msgstr ""
+msgstr "^BG%s^K1 töräytettiin taivaan tuuliin Hellion-tykkitornin toimesta%s%s"
 
 #: qcsrc/common/notifications/all.inc:340
 #, c-format
 msgid "^BG%s^K1 could not hide from the Hunter turret%s%s"
-msgstr ""
+msgstr "^BG%s^K1 ei kyennyt piiloutumaan Hunter-tykkitornilta%s%s"
 
 #: qcsrc/common/notifications/all.inc:341
 #, c-format
 msgid "^BG%s^K1 was riddled full of holes by a Machinegun turret%s%s"
-msgstr ""
+msgstr "^BG%s^K1 ammuttiin seulaksi Machinegun-tykkitornin toimesta%s%s"
 
 #: qcsrc/common/notifications/all.inc:342
 #, c-format
 msgid "^BG%s^K1 got turned into smoldering gibs by an MLRS turret%s%s"
-msgstr ""
+msgstr "^BG%s^K1 muuntui kyteviksi viipaleiksi MLRS-tykkitornin toimesta%s%s"
 
 #: qcsrc/common/notifications/all.inc:343
 #, c-format
 msgid "^BG%s^K1 was phased out by a turret%s%s"
-msgstr ""
+msgstr "^BG%s^K1 poistettiin tykkitornin toimesta%s%s"
 
 #: qcsrc/common/notifications/all.inc:344
 #, c-format
 msgid "^BG%s^K1 got served some superheated plasma from a turret%s%s"
-msgstr ""
+msgstr "^BG%s^K1 sai tykkitornin tarjoamaa äärikuumennettua plasmaa %s%s"
 
 #: qcsrc/common/notifications/all.inc:345
 #, c-format
 msgid "^BG%s^K1 was electrocuted by a Tesla turret%s%s"
-msgstr ""
+msgstr "^BG%s^K1 sai shokkihoitoa Tesla-tykkitornilta%s%s"
 
 #: qcsrc/common/notifications/all.inc:346
 #, c-format
 msgid "^BG%s^K1 got served a lead enrichment by a Walker turret%s%s"
-msgstr ""
+msgstr "^BG%s^K1 sai tuta lyijyn arvon Walker-tykkitornin toimesta%s%s"
 
 #: qcsrc/common/notifications/all.inc:347
 #, c-format
 msgid "^BG%s^K1 was impaled by a Walker turret%s%s"
-msgstr ""
+msgstr "^BG%s^K1 seivästettiin Walker-tykkitornin toimesta%s%s"
 
 #: qcsrc/common/notifications/all.inc:348
 #, c-format
 msgid "^BG%s^K1 was blasted away by a Walker turret%s%s"
-msgstr ""
+msgstr "^BG%s^K1 posautettiin taivaan tuuliin Walker-tykkitornin toimesta%s%s"
 
 #: qcsrc/common/notifications/all.inc:349
 #, c-format
 msgid "^BG%s^K1 got caught in the blast of a Bumblebee explosion%s%s"
-msgstr ""
+msgstr "^BG%s^K1 otti osumaa Bumblebee:n töräyksestä%s%s"
 
 #: qcsrc/common/notifications/all.inc:350
 #, c-format
 msgid "^BG%s^K1 was crushed by a vehicle%s%s"
-msgstr ""
+msgstr "^BG%s^K1 ajautui ajoneuvon murskaamaksi%s%s"
 
 #: qcsrc/common/notifications/all.inc:351
 #, c-format
 msgid "^BG%s^K1 was caught in a Raptor cluster bomb%s%s"
-msgstr ""
+msgstr "^BG%s^K1 otti osumaa Raptor-sirpalepommista%s%s"
 
 #: qcsrc/common/notifications/all.inc:352
 #, c-format
 msgid "^BG%s^K1 got caught in the blast of a Raptor explosion%s%s"
-msgstr ""
+msgstr "^BG%s^K1 otti osumaa Raptor:in töräyksestä%s%s"
 
 #: qcsrc/common/notifications/all.inc:353
 #, c-format
 msgid "^BG%s^K1 got caught in the blast of a Spiderbot explosion%s%s"
-msgstr ""
+msgstr "^BG%s^K1 otti osumaa Hämisbot:in räjähdyksen töräyksestä%s%s"
 
 #: qcsrc/common/notifications/all.inc:354
 #, c-format
 msgid "^BG%s^K1 was blasted to bits by a Spiderbot rocket%s%s"
-msgstr ""
+msgstr "^BG%s^K1 posautettiin palasiksi Hämisbot:in raketin toimesta%s%s"
 
 #: qcsrc/common/notifications/all.inc:355
 #, c-format
 msgid "^BG%s^K1 got caught in the blast of a Racer explosion%s%s"
-msgstr ""
+msgstr "^BG%s^K1 otti osumaa Kilpurin räjähdyksestä%s%s"
 
 #: qcsrc/common/notifications/all.inc:356
 #, c-format
 msgid "^BG%s^K1 couldn't find shelter from a Racer rocket%s%s"
-msgstr ""
+msgstr "^BG%s^K1 ei löytänyt suojaa Kilpurin raketin edessä%s%s"
 
 #: qcsrc/common/notifications/all.inc:359
 #, c-format
 msgid "^BG%s^K1 was betrayed by ^BG%s^K1%s%s"
-msgstr ""
+msgstr "^BG%s^K1 petettiin ja syyllinen on ^BG%s^K1%s%s"
 
 #: qcsrc/common/notifications/all.inc:361
 #, c-format
 msgid "^BG%s^BG%s^BG (%s %s every %s seconds)"
-msgstr ""
+msgstr "^BG%s^BG%s^BG (%s %s joka %s sekunti)"
 
 #: qcsrc/common/notifications/all.inc:363
 #, c-format
 msgid "^BG%s^K1 was frozen by ^BG%s"
-msgstr ""
+msgstr "^BG%s^K1 jäädytettiin ja pakkasukkona toimi ^BG%s"
 
 #: qcsrc/common/notifications/all.inc:364
 #, c-format
 msgid "^BG%s^K3 was revived by ^BG%s"
-msgstr ""
+msgstr "^BG%s^K3 elvytettiin ja auttaja oli ^BG%s"
 
 #: qcsrc/common/notifications/all.inc:365
 #, c-format
 msgid "^BG%s^K3 was revived by falling"
-msgstr ""
+msgstr "^BG%s^K3 elvytettiin kaatumalla"
 
 #: qcsrc/common/notifications/all.inc:366
 #, c-format
 msgid "^BG%s^K3 was revived by their Nade explosion"
-msgstr ""
+msgstr "^BG%s^K3 elvytettiin heidän Naattiräjähdyksellään"
 
 #: qcsrc/common/notifications/all.inc:367
 #, c-format
 msgid "^BG%s^K3 was automatically revived after %s second(s)"
-msgstr ""
+msgstr "^BG%s^K3 elvytettiin automaattisesti %s sekunnin (sekuntien) kuluttua"
 
 #: qcsrc/common/notifications/all.inc:368
 #, c-format
 msgid "^BG%s^K1 froze themself"
-msgstr ""
+msgstr "^BG%s^K1 jäädyttivät itsensä"
 
 #: qcsrc/common/notifications/all.inc:370
 #: qcsrc/common/notifications/all.inc:688
 msgid "^TC^TT^BG team wins the round"
-msgstr ""
+msgstr "^TC^TT^BG joukkue voitti kierroksen"
 
 #: qcsrc/common/notifications/all.inc:371
 #: qcsrc/common/notifications/all.inc:689
 #, c-format
 msgid "^BG%s^BG wins the round"
-msgstr ""
+msgstr "^BG%s^BG voitti kierroksen"
 
 #: qcsrc/common/notifications/all.inc:372
 #: qcsrc/common/notifications/all.inc:552
 msgid "^BGRound tied"
-msgstr ""
+msgstr "^BGKierros päättyi tasapeliin"
 
 #: qcsrc/common/notifications/all.inc:373
 #: qcsrc/common/notifications/all.inc:553
 msgid "^BGRound over, there's no winner"
-msgstr ""
+msgstr "^BGKierros ohi, ei voittajaa"
 
 #: qcsrc/common/notifications/all.inc:375
 #, c-format
 msgid "^BGGodmode saved you %s units of damage, cheater!"
-msgstr ""
+msgstr "^BGJumaltila pelasti sinut %s yksikköä vahinkoa, huiputtaja!"
 
 #: qcsrc/common/notifications/all.inc:377
 #, c-format
 msgid "^BG%s^BG got the %s^BG buff!"
-msgstr ""
+msgstr "^BG%s^BG sai %s^BG puhvin!"
 
 #: qcsrc/common/notifications/all.inc:378
 #, c-format
 msgid "^BG%s^BG lost the %s^BG buff!"
-msgstr ""
+msgstr "^BG%s^BG menetti %s^BG puhvin!"
 
 #: qcsrc/common/notifications/all.inc:379
 #: qcsrc/common/notifications/all.inc:696
 #, c-format
 msgid "^BGYou dropped the %s^BG buff!"
-msgstr ""
+msgstr "^BGSinä pudotit %s^BG puhvin!"
 
 #: qcsrc/common/notifications/all.inc:380
 #: qcsrc/common/notifications/all.inc:697
 #, c-format
 msgid "^BGYou got the %s^BG buff!"
-msgstr ""
+msgstr "^BGSinulla on %s^BG puhvi!"
 
 #: qcsrc/common/notifications/all.inc:382
 #: qcsrc/common/notifications/all.inc:700
 #, c-format
 msgid "^BGYou do not have the ^F1%s"
-msgstr ""
+msgstr "^BGSinulla ei ole ^F1%s"
 
 #: qcsrc/common/notifications/all.inc:383
 #: qcsrc/common/notifications/all.inc:701
 #, c-format
 msgid "^BGYou dropped the ^F1%s^BG%s"
-msgstr ""
+msgstr "^BGSinä pudotit ^F1%s^BG%s"
 
 #: qcsrc/common/notifications/all.inc:384
 #: qcsrc/common/notifications/all.inc:702
 #, c-format
 msgid "^BGYou got the ^F1%s"
-msgstr ""
+msgstr "^BGSinulla on ^F1%s"
 
 #: qcsrc/common/notifications/all.inc:385
 #: qcsrc/common/notifications/all.inc:703
 #, c-format
 msgid "^BGYou don't have enough ammo for the ^F1%s"
-msgstr ""
+msgstr "^BGSinulla ei ole tarpeeksi ammuksia tähän ^F1%s"
 
 #: qcsrc/common/notifications/all.inc:386
 #: qcsrc/common/notifications/all.inc:704
 #, c-format
 msgid "^F1%s %s^BG is unable to fire, but its ^F1%s^BG can"
 msgstr ""
+"^F1%s %s^BG on kykenemätön tulittamaan, mutta sen ^F1%s^BG kykenee siihen"
 
 #: qcsrc/common/notifications/all.inc:387
 #: qcsrc/common/notifications/all.inc:705
 #, c-format
 msgid "^F1%s^BG is ^F4not available^BG on this map"
-msgstr ""
+msgstr "^F1%s^BG ei ^F4ole saatavissa^BG tässä kartassa"
 
 #: qcsrc/common/notifications/all.inc:389
 #, c-format
 msgid "^BG%s^BG is connecting..."
-msgstr ""
+msgstr "^BG%s^BG yhdistää..."
 
 #: qcsrc/common/notifications/all.inc:390
 #, c-format
 msgid "^BG%s^F3 connected"
-msgstr ""
+msgstr "^BG%s^F3 yhdistetty"
 
 #: qcsrc/common/notifications/all.inc:391
 #, c-format
 msgid "^BG%s^F3 is now playing"
-msgstr ""
+msgstr "^BG%s^F3 on nyt pelaamassa"
 
 #: qcsrc/common/notifications/all.inc:392
 #, c-format
 msgid "^BG%s^F3 is now playing on the ^TC^TT team"
-msgstr ""
+msgstr "^BG%s^F3 pelaa nyt ^TC^TT joukkueessa"
 
 #: qcsrc/common/notifications/all.inc:394
 #: qcsrc/common/notifications/all.inc:710
 #, c-format
 msgid "^BG%s^BG has dropped the ball!"
-msgstr ""
+msgstr "^BG%s^BG on pudottanut pallon!"
 
 #: qcsrc/common/notifications/all.inc:395
 #: qcsrc/common/notifications/all.inc:711
 #, c-format
 msgid "^BG%s^BG has picked up the ball!"
-msgstr ""
+msgstr "^BG%s^BG on poiminut pallon!"
 
 #: qcsrc/common/notifications/all.inc:397
 #, c-format
 msgid "^BG%s^BG captured the keys for the ^TC^TT team"
-msgstr ""
+msgstr "^BG%s^BG kaappasi avaimet ^TC^TT joukkueelle"
 
 #: qcsrc/common/notifications/all.inc:398
 #, c-format
 msgid "^BG%s^BG dropped the ^TC^TT Key"
-msgstr ""
+msgstr "^BG%s^BG pudotti ^TC^TT Avaimen"
 
 #: qcsrc/common/notifications/all.inc:399
 #, c-format
 msgid "^BG%s^BG lost the ^TC^TT Key"
-msgstr ""
+msgstr "^BG%s^BG menetti ^TC^TT Avaimen"
 
 #: qcsrc/common/notifications/all.inc:400
 #, c-format
 msgid "^BG%s^BG pushed %s^BG causing the ^TC^TT Key ^BGdestruction"
-msgstr ""
+msgstr "^BG%s^BG työnsi %s^BG aiheuttaen ^TC^TT Avaimen ^BGtuhoutumisen"
 
 #: qcsrc/common/notifications/all.inc:401
 #, c-format
 msgid "^BG%s^BG destroyed the ^TC^TT Key"
-msgstr ""
+msgstr "^BG%s^BG tuhosi ^TC^TT Avaimen"
 
 #: qcsrc/common/notifications/all.inc:402
 #, c-format
 msgid "^BG%s^BG picked up the ^TC^TT Key"
-msgstr ""
+msgstr "^BG%s^BG poimi ^TC^TT Avaimen"
 
 #: qcsrc/common/notifications/all.inc:404
 #, c-format
 msgid "^BG%s^F3 forfeited"
-msgstr ""
+msgstr "^BG%s^F3 luovutti"
 
 #: qcsrc/common/notifications/all.inc:405
 #, c-format
 msgid "^BG%s^F3 has no more lives left"
-msgstr ""
+msgstr "^BG%s^F3 on menettänyt kaikki elämänsä"
 
 #: qcsrc/common/notifications/all.inc:407
 msgid "^BGMonsters are currently disabled"
-msgstr ""
+msgstr "^BGHirviöt ovat tällä hetkellä otettu pelistä pois"
 
 #: qcsrc/common/notifications/all.inc:409
 msgid "^BGThe ^TC^TT^BG team held the ball for too long"
-msgstr ""
+msgstr "^BGJoukkue ^TC^TT^BG piti palloa hallussa liian pitkään "
 
 #: qcsrc/common/notifications/all.inc:411
 #, c-format
 msgid "^BG%s^BG captured %s^BG control point"
-msgstr ""
+msgstr "^BG%s^BG kaappasi %s^BG hallintapisteen"
 
 #: qcsrc/common/notifications/all.inc:412
 #, c-format
 msgid "^TC^TT^BG team %s^BG control point has been destroyed by %s"
-msgstr ""
+msgstr "^TC^TT^BG joukkueen %s^BG hallintapiste on tuhottu täten %s"
 
 #: qcsrc/common/notifications/all.inc:413
 msgid "^TC^TT^BG generator has been destroyed"
-msgstr ""
+msgstr "^TC^TT^BG generaattori on tuhottu"
 
 #: qcsrc/common/notifications/all.inc:414
 msgid "^TC^TT^BG generator spontaneously combusted due to overtime!"
-msgstr ""
+msgstr "^TC^TT^BG generaattori syttyi oma-aloitteisesti yliajan johdosta!"
 
 #: qcsrc/common/notifications/all.inc:416
 #, c-format
 msgid "^BG%s^K1 picked up Invisibility"
-msgstr ""
+msgstr "^BG%s^K1 poimi Näkymättömyyden"
 
 #: qcsrc/common/notifications/all.inc:417
 #, c-format
 msgid "^BG%s^K1 picked up Shield"
-msgstr ""
+msgstr "^BG%s^K1 poimi Suojan"
 
 #: qcsrc/common/notifications/all.inc:418
 #, c-format
 msgid "^BG%s^K1 picked up Speed"
-msgstr ""
+msgstr "^BG%s^K1 keräsi Nopeutta"
 
 #: qcsrc/common/notifications/all.inc:419
 #, c-format
 msgid "^BG%s^K1 picked up Strength"
-msgstr ""
+msgstr "^BG%s^K1 keräsi Vahvennusta"
 
 #: qcsrc/common/notifications/all.inc:421
 #, c-format
 msgid "^BG%s^F3 disconnected"
-msgstr ""
+msgstr "^BG%s^F3 yhteys katkesi"
 
 #: qcsrc/common/notifications/all.inc:422
 #, c-format
 msgid "^BG%s^F3 was kicked for idling"
-msgstr ""
+msgstr "^BG%s^F3 potkaistiin joutilaisuuden takia"
 
 #: qcsrc/common/notifications/all.inc:423
 msgid ""
 "^F2You were kicked from the server because you are a spectator and "
 "spectators aren't allowed at the moment."
 msgstr ""
+"^F2Sinut potkaistiin palvelimelta koska olet katsoja ja katsojat eivät ole "
+"sallittuja tällä hetkellä."
 
 #: qcsrc/common/notifications/all.inc:424
 #, c-format
 msgid "^BG%s^F3 was kicked for excessive teamkilling"
-msgstr ""
+msgstr "^BG%s^F3 potkaistiin jatkuvien oman joukkueen jäsenten tappamisesta"
 
 #: qcsrc/common/notifications/all.inc:425
 #, c-format
 msgid "^BG%s^F3 is now spectating"
-msgstr ""
+msgstr "^BG%s^F3 katselee "
 
 #: qcsrc/common/notifications/all.inc:427
 #, c-format
 msgid "^BG%s^BG has abandoned the race"
-msgstr ""
+msgstr "^BG%s^BG hylkäsi kilvan"
 
 #: qcsrc/common/notifications/all.inc:428
 #, c-format
 msgid "^BG%s^BG couldn't break their %s%s^BG place record of %s%s %s"
-msgstr ""
+msgstr "^BG%s^BG eivät kyenneet rikkomaan %s%s^BG sijoitusennätystä %s%s %s"
 
 #: qcsrc/common/notifications/all.inc:429
 #, c-format
 msgid "^BG%s^BG couldn't break the %s%s^BG place record of %s%s %s"
-msgstr ""
+msgstr "^BG%s^BG ei kyennyt rikkomaan %s%s^BG sijoitusennätystään %s%s%s"
 
 #: qcsrc/common/notifications/all.inc:430
 #, c-format
 msgid "^BG%s^BG has finished the race"
-msgstr ""
+msgstr "^BG%s^BG sai kisan päätökseen"
 
 #: qcsrc/common/notifications/all.inc:431
 #, c-format
 msgid "^BG%s^BG broke %s^BG's %s%s^BG place record with %s%s %s"
-msgstr ""
+msgstr "^BG%s^BG rikkoi %s^BG's %s%s^BG sijoitusennätyksen ajassa %s%s %s"
 
 #: qcsrc/common/notifications/all.inc:432
 #, c-format
 msgid "^BG%s^BG improved their %s%s^BG place record with %s%s %s"
-msgstr ""
+msgstr "^BG%s^BG paransivat %s%s^BG sijoitusennätystään %s%s %s"
 
 #: qcsrc/common/notifications/all.inc:433
 #, c-format
@@ -2986,6 +3052,8 @@ msgid ""
 "^BG%s^BG scored a new record with ^F2%s^BG, but unfortunately lacks a UID "
 "and will be lost."
 msgstr ""
+"^BG%s^BG laittoi tiskiin uuden ennätyksen ^F2%s^BG, mutta valitettavasti UID "
+"uupuu joten se hukataan."
 
 #: qcsrc/common/notifications/all.inc:434
 #, c-format
@@ -2993,11 +3061,13 @@ msgid ""
 "^BG%s^BG scored a new record with ^F2%s^BG, but is anonymous and will be "
 "lost."
 msgstr ""
+"^BG%s^BG laittoi tiskiin uuden ennätyksen ^F2%s^BG, mutta ollen anonyymi, se "
+"hukataan."
 
 #: qcsrc/common/notifications/all.inc:435
 #, c-format
 msgid "^BG%s^BG set the %s%s^BG place record with %s%s"
-msgstr ""
+msgstr "^BG%s^BG pisti %s%s^BG sijoitusennätyksen %s%s"
 
 #: qcsrc/common/notifications/all.inc:437
 #, c-format
@@ -3005,10 +3075,12 @@ msgid ""
 "^F4You have been invited by ^BG%s^F4 to join their game of ^F2%s^F4 "
 "(^F1%s^F4)"
 msgstr ""
+"^F4Sinut kutsuttiin ^BG%s^F4 :n toimesta liittymään peliinsä  ^F2%s^F4 "
+"(^F1%s^F4)"
 
 #: qcsrc/common/notifications/all.inc:439
 msgid "^TC^TT ^BGteam scores!"
-msgstr ""
+msgstr "^TC^TT ^BGjoukkue maalaa!"
 
 #: qcsrc/common/notifications/all.inc:441
 #, c-format
@@ -3016,19 +3088,21 @@ 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 ""
+"^F2Sinun täytyy alkaa pelaamaan ajan %ssisällä, muutoin sinut potkaistaan "
+"ulos koska katseleminen ei ole sallittua tällä kertaa!"
 
 #: qcsrc/common/notifications/all.inc:443
 #, c-format
 msgid "^BG%s^K1 picked up a Superweapon"
-msgstr ""
+msgstr "^BG%s^K1 poimi Mahtiaseen"
 
 #: qcsrc/common/notifications/all.inc:445
 msgid "^BGYou cannot change to a larger team"
-msgstr ""
+msgstr "^BGEt voi vaihtaa isompaan joukkueeseen"
 
 #: qcsrc/common/notifications/all.inc:446
 msgid "^BGYou are not allowed to change teams"
-msgstr ""
+msgstr "^BGJoukkueiden vaihtaminen ei ole sallittua"
 
 #: qcsrc/common/notifications/all.inc:448
 #, c-format
@@ -3036,12 +3110,16 @@ msgid ""
 "^F4NOTE: ^BGThe server is running ^F1Xonotic %s (beta)^BG, you have "
 "^F2Xonotic %s"
 msgstr ""
+"^F4NOTE: ^BGPalvelin ajaa ^F1Xonotic:in %s (beta-versiota)^BG, sinulla on "
+"^F2Xonotic %s"
 
 #: qcsrc/common/notifications/all.inc:449
 #, c-format
 msgid ""
 "^F4NOTE: ^BGThe server is running ^F1Xonotic %s^BG, you have ^F2Xonotic %s"
 msgstr ""
+"^F4NOTE: ^BGPalvelin ajaa ^F1Xonotic:in versiota %s^BG, sinulla on "
+"^F2Xonotic %s"
 
 #: qcsrc/common/notifications/all.inc:450
 #, c-format
@@ -3049,221 +3127,236 @@ msgid ""
 "^F4NOTE: ^F1Xonotic %s^BG is out, and you still have ^F2Xonotic %s^BG - get "
 "the update from ^F3http://www.xonotic.org/^BG!"
 msgstr ""
+"^F4HUOMAUTUS: ^F1Xonotic %s^BG on julkaistu, ja sinulla on edelleen "
+"^F2Xonotic %s^BG - hae päivitys osoitteesta ^F3http://www.xonotic.org/^BG!"
 
 #: qcsrc/common/notifications/all.inc:452
 #, c-format
 msgid "^F3SVQC Build information: ^F4%s"
-msgstr ""
+msgstr "^F3SVQC Kokooman tiedot: ^F4%s"
 
 #: qcsrc/common/notifications/all.inc:454
 #, c-format
 msgid ""
 "^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Accordeon%s%s"
 msgstr ""
+"^BG%s%s^K1 kuoli syyn ollen ^BG%s^K1 on mahtava soittamaan @!#%%'n Haitaria%s"
+"%s"
 
 #: qcsrc/common/notifications/all.inc:455
 #, c-format
 msgid "^BG%s^K1 hurt their own ears with the @!#%%'n Accordeon%s%s"
-msgstr ""
+msgstr "^BG%s^K1 koki korvien vihlontaa @!#%% Haitarin takia%s%s"
 
 #: qcsrc/common/notifications/all.inc:456
 #, c-format
 msgid "^BG%s%s^K1 was electrocuted by ^BG%s^K1's Arc%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 sai shokkihoitoa ^BG%s^K1'n Arc:in toimesta%s%s"
 
 #: qcsrc/common/notifications/all.inc:457
 #, c-format
 msgid "^BG%s%s^K1 was blasted by ^BG%s^K1's Arc bolts%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 joutui läjäytetyksi ^BG%s^K1'n Arc-salamoista%s%s"
 
 #: qcsrc/common/notifications/all.inc:458
 #, c-format
 msgid "^BG%s%s^K1 was shot to death by ^BG%s^K1's Blaster%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 ammuttiin kuoliaaksi ^BG%s^K1'n Läjäyttimellä%s%s"
 
 #: qcsrc/common/notifications/all.inc:459
 #, c-format
 msgid "^BG%s^K1 shot themself to hell with their Blaster%s%s"
-msgstr ""
+msgstr "^BG%s^K1 ampuivat itsensä hornan tuuttiin Läjäyttimillään%s%s"
 
 #: qcsrc/common/notifications/all.inc:460
 #, c-format
 msgid "^BG%s%s^K1 felt the strong pull of ^BG%s^K1's Crylink%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 sai tuntea vahvaa vetoa ^BG%s^K1'n Crylink:in toimesta%s%s"
 
 #: qcsrc/common/notifications/all.inc:461
 #, c-format
 msgid "^BG%s^K1 felt the strong pull of their Crylink%s%s"
-msgstr ""
+msgstr "^BG%s^K1 saivat tuntea vahvaa vetoa Crylink:eistään%s%s"
 
 #: qcsrc/common/notifications/all.inc:462
 #, c-format
 msgid "^BG%s%s^K1 ate ^BG%s^K1's rocket%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 söi ^BG%s^K1'n raketin%s%s"
 
 #: qcsrc/common/notifications/all.inc:463
 #, c-format
 msgid "^BG%s%s^K1 got too close to ^BG%s^K1's rocket%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 erehtyi liian lähelle ^BG%s^K1'n rakettia%s%s"
 
 #: qcsrc/common/notifications/all.inc:464
 #, c-format
 msgid "^BG%s^K1 blew themself up with their Devastator%s%s"
-msgstr ""
+msgstr "^BG%s^K1 räjäyttivät itsensä ilmavoimiin Devastator:illaan%s%s"
 
 #: qcsrc/common/notifications/all.inc:465
 #, c-format
 msgid "^BG%s%s^K1 was blasted by ^BG%s^K1's Electro bolt%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 päätyi läjäytetyksi ^BG%s^K1'n Sähkösalaman voimasta%s%s"
 
 #: qcsrc/common/notifications/all.inc:466
 #, c-format
 msgid "^BG%s%s^K1 felt the electrifying air of ^BG%s^K1's Electro combo%s%s"
 msgstr ""
+"^BG%s%s^K1 tunsi sähköä ilmassa ^BG%s^K1'n Sähköyhdistelmän voimasta%s%s"
 
 #: qcsrc/common/notifications/all.inc:467
 #, c-format
 msgid "^BG%s%s^K1 got too close to ^BG%s^K1's Electro orb%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 erehtyi liian lähelle ^BG%s^K1'n Sähköpalloa%s%s"
 
 #: qcsrc/common/notifications/all.inc:468
 #, c-format
 msgid "^BG%s^K1 played with Electro bolts%s%s"
-msgstr ""
+msgstr "^BG%s^K1 leikki Sähkösalamoilla%s%s"
 
 #: qcsrc/common/notifications/all.inc:469
 #, c-format
 msgid "^BG%s^K1 could not remember where they put their Electro orb%s%s"
-msgstr ""
+msgstr "^BG%s^K1 unohtivat mihin olivat Sähköpallonsa laittaneet%s%s"
 
 #: qcsrc/common/notifications/all.inc:470
 #, c-format
 msgid "^BG%s%s^K1 got too close to ^BG%s^K1's fireball%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 erehtyi liian lähelle ^BG%s^K1'n tulipalloa%s%s"
 
 #: qcsrc/common/notifications/all.inc:471
 #, c-format
 msgid "^BG%s%s^K1 got burnt by ^BG%s^K1's firemine%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 paloi poroksi ^BG%s^K1'n tulimiinaan käveltyään%s%s"
 
 #: qcsrc/common/notifications/all.inc:472
 #, c-format
 msgid "^BG%s^K1 should have used a smaller gun%s%s"
-msgstr ""
+msgstr "^BG%s^K1 huomasi että olisi pitänyt käyttää pienempää pyssyä%s%s"
 
 #: qcsrc/common/notifications/all.inc:473
 #, c-format
 msgid "^BG%s^K1 forgot about their firemine%s%s"
-msgstr ""
+msgstr "^BG%s^K1 unohtivat tulimiinansa olemassaolon%s%s"
 
 #: qcsrc/common/notifications/all.inc:474
 #, c-format
 msgid "^BG%s%s^K1 was pummeled by a burst of ^BG%s^K1's Hagar rockets%s%s"
 msgstr ""
+"^BG%s%s^K1 tuli nuijituksi tärskäyksellä ^BG%s^K1'n Hagar-raketteja%s%s"
 
 #: qcsrc/common/notifications/all.inc:475
 #, c-format
 msgid "^BG%s%s^K1 was pummeled by ^BG%s^K1's Hagar rockets%s%s"
 msgstr ""
+"^BG%s%s^K1 tuli nuijituksi tärskäyksellä ^BG%s^K1'n Hagar-raketteja%s%s"
 
 #: qcsrc/common/notifications/all.inc:476
 #, c-format
 msgid "^BG%s^K1 played with tiny Hagar rockets%s%s"
-msgstr ""
+msgstr "^BG%s^K1 leikitteli pienenpienillä Hagar-raketeilla%s%s"
 
 #: qcsrc/common/notifications/all.inc:477
 #, c-format
 msgid "^BG%s%s^K1 was cut down with ^BG%s^K1's HLAC%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 päätyi viillokiksi ^BG%s^K1'n HLAC:ien tehosta%s%s"
 
 #: qcsrc/common/notifications/all.inc:478
 #, c-format
 msgid "^BG%s^K1 got a little jumpy with their HLAC%s%s"
-msgstr ""
+msgstr "^BG%s^K1 äityivät hiukan säikyiksi HLAC:iensa kanssa%s%s"
 
 #: qcsrc/common/notifications/all.inc:479
 #, c-format
 msgid "^BG%s%s^K1 was caught in ^BG%s^K1's Hook gravity bomb%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 otti osumaa ^BG%s^K1'n Hook-painovoimapommista%s%s"
 
 #: qcsrc/common/notifications/all.inc:480
 #, c-format
 msgid ""
 "^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Klein Bottle%s%s"
 msgstr ""
+"^BG%s%s^K1 kuoli ^BG%s^K1'n huikean pelaamisen johdosta @!#%%'n Klein-"
+"pullolla%s%s"
 
 #: qcsrc/common/notifications/all.inc:481
 #, c-format
 msgid "^BG%s^K1 hurt their own ears with the @!#%%'n Klein Bottle%s%s"
-msgstr ""
+msgstr "^BG%s^K1 hajottivat omat korvansa @!#%%'n Klein-pullolla%s%s"
 
 #: qcsrc/common/notifications/all.inc:482
 #, c-format
 msgid "^BG%s%s^K1 was sniped by ^BG%s^K1's Machine Gun%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 laitettiin nippuun ^BG%s^K1'n Konekiväärillä %s%s"
 
 #: qcsrc/common/notifications/all.inc:483
 #, c-format
 msgid "^BG%s%s^K1 was riddled full of holes by ^BG%s^K1's Machine Gun%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 koristeltiin reikiä täyteen ^BG%s^K1'n Konekiväärillä%s%s"
 
 #: qcsrc/common/notifications/all.inc:484
 #: qcsrc/common/notifications/all.inc:794
 #, c-format
 msgid "^BGYou cannot place more than ^F2%s^BG mines at a time"
-msgstr ""
+msgstr "^BGEt voi asettaa enempää kuin ^F2%s^BG miinaa kerrallaan"
 
 #: qcsrc/common/notifications/all.inc:485
 #, c-format
 msgid "^BG%s%s^K1 got too close to ^BG%s^K1's mine%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 erehtyi liian lähelle ^BG%s^K1'n miinaa%s%s"
 
 #: qcsrc/common/notifications/all.inc:486
 #, c-format
 msgid "^BG%s^K1 forgot about their mine%s%s"
-msgstr ""
+msgstr "^BG%s^K1 unohtivat miinojensa olemassaolon%s%s"
 
 #: qcsrc/common/notifications/all.inc:487
 #, c-format
 msgid "^BG%s%s^K1 got too close to ^BG%s^K1's Mortar grenade%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 erehtyi liian lähelle ^BG%s^K1'n Mörssärikranaattia%s%s"
 
 #: qcsrc/common/notifications/all.inc:488
 #, c-format
 msgid "^BG%s%s^K1 ate ^BG%s^K1's Mortar grenade%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 hotkaisi ^BG%s^K1'n Mörssärikranaatin%s%s"
 
 #: qcsrc/common/notifications/all.inc:489
 #, c-format
 msgid "^BG%s^K1 didn't see their own Mortar grenade%s%s"
-msgstr ""
+msgstr "^BG%s^K1 eivät huomanneet omaa Mörssärikranaattiaan%s%s"
 
 #: qcsrc/common/notifications/all.inc:490
 #, c-format
 msgid "^BG%s^K1 blew themself up with their own Mortar%s%s"
-msgstr ""
+msgstr "^BG%s^K1 räjäyttivät itsensä omalla Mörssärillään%s%s"
 
 #: qcsrc/common/notifications/all.inc:491
 #, c-format
 msgid "^BG%s%s^K1 was sniped by ^BG%s^K1's Overkill Heavy Machine Gun%s%s"
 msgstr ""
+"^BG%s%s^K1 niputettiin ^BG%s^K1'n Ylimalkaallisen Raskaalla Konekiväärillä%s"
+"%s"
 
 #: qcsrc/common/notifications/all.inc:492
 #, c-format
 msgid ""
 "^BG%s%s^K1 was torn to bits by ^BG%s^K1's Overkill Heavy Machine Gun%s%s"
 msgstr ""
+"^BG%s%s^K1 revittiin palasiksi ^BG%s^K1'n Ylimalkaallisella "
+"raskaskonekiväärillä%s%s"
 
 #: qcsrc/common/notifications/all.inc:493
 #, c-format
 msgid ""
 "^BG%s%s^K1 was riddled full of holes by ^BG%s^K1's Overkill Machine Gun%s%s"
 msgstr ""
+"^BG%s%s^K1 ropisi täyteen reikiä ^BG%s^K1'n Ylimalkaallisella konekiväärillä"
+"%s%s"
 
 #: qcsrc/common/notifications/all.inc:494
 #, c-format
 msgid "^BG%s%s^K1 has been vaporized by ^BG%s^K1's Overkill Nex%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 höyrytettiin ^BG%s^K1'n Ylimalkaallisella Nex:illä%s%s"
 
 #: qcsrc/common/notifications/all.inc:495
 #, c-format
@@ -3271,146 +3364,158 @@ msgid ""
 "^BG%s%s^K1 was sawn in half by ^BG%s^K1's Overkill Rocket Propelled Chainsaw"
 "%s%s"
 msgstr ""
+"^BG%s%s^K1 sahattiin kahtia ^BG%s^K1'n Ylimalkaallisella rakettikäyttöisellä "
+"moottorisahalla%s%s"
 
 #: qcsrc/common/notifications/all.inc:496
 #, c-format
 msgid ""
 "^BG%s%s^K1 almost dodged ^BG%s^K1's Overkill Rocket Propelled Chainsaw%s%s"
 msgstr ""
+"^BG%s%s^K1 sai lähes väistettyä ^BG%s^K1'n Ylimalkaallisen rakettikäyttöisen "
+"mootorisahan toiminnassaan%s%s"
 
 #: qcsrc/common/notifications/all.inc:497
 #, c-format
 msgid ""
 "^BG%s^K1 was sawn in half by their own Overkill Rocket Propelled Chainsaw%s%s"
 msgstr ""
+"^BG%s^K1 sahasi itsensä kahtia omalla Ylimalkaallisella rakettikäyttöisellä "
+"moottorisahallaan%s%s"
 
 #: qcsrc/common/notifications/all.inc:498
 #, c-format
 msgid ""
 "^BG%s^K1 blew themself up with their Overkill Rocket Propelled Chainsaw%s%s"
 msgstr ""
+"^BG%s^K1 räjäyttivät itsensä omalla Ylimalkaallisella rakettikäyttöisellä "
+"moottorisahallaan%s%s"
 
 #: qcsrc/common/notifications/all.inc:500
 #, c-format
 msgid "^BG%s%s^K1 was gunned down by ^BG%s^K1's Overkill Shotgun%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 ammuttiin ^BG%s^K1'n Ylimalkaallisella haulikolla%s%s"
 
 #: qcsrc/common/notifications/all.inc:501
 #, c-format
 msgid "^BG%s%s^K1 was sniped with a Rifle by ^BG%s^K1%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 niputettiin kiväärillä syyllisen ollen ^BG%s^K1%s%s"
 
 #: qcsrc/common/notifications/all.inc:502
 #, c-format
 msgid "^BG%s%s^K1 died in ^BG%s^K1's Rifle bullet hail%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 kuoli ^BG%s^K1'n Kiväärin luoti-ilmiössä%s%s"
 
 #: qcsrc/common/notifications/all.inc:503
 #, c-format
 msgid "^BG%s%s^K1 failed to hide from ^BG%s^K1's Rifle bullet hail%s%s"
 msgstr ""
+"^BG%s%s^K1 ei onnistunut piiloutumisyrityksessään ^BG%s^K1'n Kiväärin luoti-"
+"ilmiön edessä%s%s"
 
 #: qcsrc/common/notifications/all.inc:504
 #, c-format
 msgid "^BG%s%s^K1 failed to hide from ^BG%s^K1's Rifle%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 ei onnistunut välttämään ^BG%s^K1'n Kiväärin toimintaa%s%s"
 
 #: qcsrc/common/notifications/all.inc:505
 #, c-format
 msgid "^BG%s%s^K1 was pummeled by ^BG%s^K1's Seeker rockets%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 nuijittiin ^BG%s^K1'n Hakeutuvilla raketeilla%s%s"
 
 #: qcsrc/common/notifications/all.inc:506
 #, c-format
 msgid "^BG%s%s^K1 was tagged by ^BG%s^K1's Seeker%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 korvamerkittiin ^BG%s^K1's Hakeutuvalla ammuksella%s%s"
 
 #: qcsrc/common/notifications/all.inc:507
 #, c-format
 msgid "^BG%s^K1 played with tiny Seeker rockets%s%s"
-msgstr ""
+msgstr "^BG%s^K1 leikitteli pienenpienillä Hakeutuvilla raketeilla%s%s"
 
 #: qcsrc/common/notifications/all.inc:508
 #, c-format
 msgid "^BG%s%s^K1 was gunned down by ^BG%s^K1's Shockwave%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 päätyi kanveesiin ^BG%s^K1'n Shokkihoidon tiimoilta%s%s"
 
 #: qcsrc/common/notifications/all.inc:509
 #, c-format
 msgid "^BG%s%s^K1 slapped ^BG%s^K1 around a bit with a large Shockwave%s%s"
 msgstr ""
+"^BG%s%s^K1 tunsi tukkansa pölisevän ^BG%s^K1 ison Paineaallon tiimoilta%s%s"
 
 #: qcsrc/common/notifications/all.inc:510
 #, c-format
 msgid "^BG%s%s^K1 was gunned down by ^BG%s^K1's Shotgun%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 ammuttiin ^BG%s^K1'n Haulikolla%s%s"
 
 #: qcsrc/common/notifications/all.inc:511
 #, c-format
 msgid "^BG%s%s^K1 slapped ^BG%s^K1 around a bit with a large Shotgun%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 sai kuin avarista ^BG%s^K1 ison Haulikon tiimoilta%s%s"
 
 #: qcsrc/common/notifications/all.inc:512
 #, c-format
 msgid "^BG%s^K1 is now thinking with portals%s%s"
-msgstr ""
+msgstr "^BG%s^K1 ajattelee tällä hetkellä uusia ulottuvuuksia%s%s"
 
 #: qcsrc/common/notifications/all.inc:513
 #, c-format
 msgid "^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Tuba%s%s"
 msgstr ""
+"^BG%s%s^K1 sai tarpeekseen ^BG%s^K1'n upeasta @!#%%'n Tuubakonsertosta%s%s"
 
 #: qcsrc/common/notifications/all.inc:514
 #, c-format
 msgid "^BG%s^K1 hurt their own ears with the @!#%%'n Tuba%s%s"
-msgstr ""
+msgstr "^BG%s^K1 ja korvansa kovilla @!#%%'n Tuubasta%s%s"
 
 #: qcsrc/common/notifications/all.inc:515
 #, c-format
 msgid "^BG%s%s^K1 has been sublimated by ^BG%s^K1's Vaporizer%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 härmistyi by ^BG%s^K1'n Höyryttimestä%s%s"
 
 #: qcsrc/common/notifications/all.inc:516
 #, c-format
 msgid "^BG%s%s^K1 has been vaporized by ^BG%s^K1's Vortex%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 pöllytettiin ^BG%s^K1'n Pyörremyrskyllä%s%s"
 
 #: qcsrc/common/notifications/all.inc:541
 msgid "^F4You are now alone!"
-msgstr ""
+msgstr "^F4Olet nyt yksin!"
 
 #: qcsrc/common/notifications/all.inc:543
 msgid "^BGYou are attacking!"
-msgstr ""
+msgstr "^BGSinä hyökkäät!"
 
 #: qcsrc/common/notifications/all.inc:544
 msgid "^BGYou are defending!"
-msgstr ""
+msgstr "^BGSinä puolustat!"
 
 #: qcsrc/common/notifications/all.inc:545
 #, c-format
 msgid "^BGObjective destroyed in ^F4%s^BG!"
-msgstr ""
+msgstr "^BGKohde tuhottu ^F4%s^BG!"
 
 #: qcsrc/common/notifications/all.inc:547
 msgid "^F4Begin!"
-msgstr ""
+msgstr "^F4Alkaa!"
 
 #: qcsrc/common/notifications/all.inc:548
 msgid "^F4Game starts in ^COUNT"
-msgstr ""
+msgstr "^F4Peli alkaa ^COUNT"
 
 #: qcsrc/common/notifications/all.inc:549
 msgid "^F4Round starts in ^COUNT"
-msgstr ""
+msgstr "^F4Kierros alkaa ^COUNT"
 
 #: qcsrc/common/notifications/all.inc:550
 msgid "^F4Round cannot start"
-msgstr ""
+msgstr "^F4Kierros ei voi alkaa"
 
 #: qcsrc/common/notifications/all.inc:555
 msgid "^F2Don't camp!"
-msgstr ""
+msgstr "^F2Älähän kämppää!"
 
 #: qcsrc/common/notifications/all.inc:559
 msgid ""
@@ -3418,10 +3523,13 @@ msgid ""
 "^BGFeel free to ^F2try to capture^BG the flag again\n"
 "^BGif you think you will succeed."
 msgstr ""
+"^BGSinut on vapautettu.\n"
+"^BGNyt voit ^F2yrittää kaapata^BG lipun jälleen\n"
+"^BGmikäli uskot sen onnistuvan."
 
 #: qcsrc/common/notifications/all.inc:560
 msgid "^BGThis flag is currently inactive"
-msgstr ""
+msgstr "^BGTämä lippu ei ole toiminnassa mukana tällä hetkellä"
 
 #: qcsrc/common/notifications/all.inc:561
 msgid ""
@@ -3429,216 +3537,221 @@ msgid ""
 "^BGfor ^F2too many unsuccessful attempts^BG to capture.\n"
 "^BGMake some defensive scores before trying again."
 msgstr ""
+"^BGOlet nyt ^F1suojakerrotettu^BG lipulta (lipuilta)\n"
+"^BGfor ^F2liian monta epäonnistunutta yritystä^BG kaappauksissa.\n"
+"^BGHanki puolustuspisteitä ennen kuin yrität uudelleen."
 
 #: qcsrc/common/notifications/all.inc:562
 msgid "^BGYou captured the ^TC^TT^BG flag!"
-msgstr ""
+msgstr "^BGSinä kaappasit ^TC^TT^BG lipun!"
 
 #: qcsrc/common/notifications/all.inc:563
 msgid "^BGYou captured the flag!"
-msgstr ""
+msgstr "^BGSinä kaappasit lipun!"
 
 #: qcsrc/common/notifications/all.inc:564
 #, c-format
 msgid "^BGToo many flag throws! Throwing disabled for %s."
-msgstr ""
+msgstr "^BGLiian monta lipun heittoa! Heittäminen evätty %s."
 
 #: qcsrc/common/notifications/all.inc:565
 #, c-format
 msgid "^BG%s^BG passed the ^TC^TT^BG flag to %s"
-msgstr ""
+msgstr "^BG%s^BG antoi ^TC^TT^BG lipun eteenpäin -  %s"
 
 #: qcsrc/common/notifications/all.inc:566
 #, c-format
 msgid "^BG%s^BG passed the flag to %s"
-msgstr ""
+msgstr "^BG%s^BG antoi lipun eteenpäin - %s"
 
 #: qcsrc/common/notifications/all.inc:567
 #, c-format
 msgid "^BGYou received the ^TC^TT^BG flag from %s"
-msgstr ""
+msgstr "^BGSinä sait ^TC^TT^BG lipun %s:lta"
 
 #: qcsrc/common/notifications/all.inc:568
 #, c-format
 msgid "^BGYou received the flag from %s"
-msgstr ""
+msgstr "^BGSinä sait lipun %s :lta"
 
 #: qcsrc/common/notifications/all.inc:569
 #, c-format
 msgid "^BGPress ^F2%s^BG to receive the flag from %s^BG"
-msgstr ""
+msgstr "^BGPaina ^F2%s^BG ottaaksesi lipun vastaan %s^BG :lta"
 
 #: qcsrc/common/notifications/all.inc:570
 #, c-format
 msgid "^BGRequesting %s^BG to pass you the flag"
-msgstr ""
+msgstr "^BGPyydetään %s^BG :ta antamaan lippu sinulle"
 
 #: qcsrc/common/notifications/all.inc:571
 #, c-format
 msgid "^BGYou passed the ^TC^TT^BG flag to %s"
-msgstr ""
+msgstr "^BGSinä annoit ^TC^TT^BG lipun %s :lle"
 
 #: qcsrc/common/notifications/all.inc:572
 #, c-format
 msgid "^BGYou passed the flag to %s"
-msgstr ""
+msgstr "^BGSinä annoit lipun %s :lle"
 
 #: qcsrc/common/notifications/all.inc:573
 msgid "^BGYou got the ^TC^TT^BG flag!"
-msgstr ""
+msgstr "^BGSinulla on ^TC^TT^BG lippu!"
 
 #: qcsrc/common/notifications/all.inc:574
 msgid "^BGYou got the flag!"
-msgstr ""
+msgstr "^BGSinulla on lippu!"
 
 #: qcsrc/common/notifications/all.inc:575
 #, c-format
 msgid "^BGYou got your %steam^BG's flag, return it!"
-msgstr ""
+msgstr "^BGSinulla on %sjoukkueesi^BG's lippu, palauta se!"
 
 #: qcsrc/common/notifications/all.inc:576
 #, c-format
 msgid "^BGYou got the %senemy^BG's flag, return it!"
-msgstr ""
+msgstr "^BGSinulla on %svihollisen^BG's lippu, palauta se!"
 
 #: qcsrc/common/notifications/all.inc:577
 #, c-format
 msgid "^BGThe %senemy^BG got your flag! Retrieve it!"
-msgstr ""
+msgstr "^BGVihollisella %senemy^BG on lippusi! Nouda se!"
 
 #: qcsrc/common/notifications/all.inc:578
 #, c-format
 msgid "^BGThe %senemy (^BG%s%s)^BG got your flag! Retrieve it!"
-msgstr ""
+msgstr "^BGVihollinen %ssai (^BG%s%s)^BG lippusi! Nouda se!"
 
 #: qcsrc/common/notifications/all.inc:579
 #, c-format
 msgid "^BGThe %senemy^BG got the flag! Retrieve it!"
-msgstr ""
+msgstr "^BGVihollinen %ssai^BG lipun! Nouda se!"
 
 #: qcsrc/common/notifications/all.inc:580
 #, c-format
 msgid "^BGThe %senemy (^BG%s%s)^BG got the flag! Retrieve it!"
-msgstr ""
+msgstr "^BGVihollinen %ssai (^BG%s%s)^BG lipun! Nouda se!"
 
 #: qcsrc/common/notifications/all.inc:581
 #, c-format
 msgid "^BGThe %senemy^BG got their flag! Retrieve it!"
-msgstr ""
+msgstr "^BGVihollinen %ssai^BG lippunsa! Nouda se!"
 
 #: qcsrc/common/notifications/all.inc:582
 #, c-format
 msgid "^BGThe %senemy (^BG%s%s)^BG got their flag! Retrieve it!"
-msgstr ""
+msgstr "^BGVihollinen %ssai (^BG%s%s)^BG lippunsa! Nouda se!"
 
 #: qcsrc/common/notifications/all.inc:583
 #, c-format
 msgid "^BGYour %steam mate^BG got the ^TC^TT^BG flag! Protect them!"
-msgstr ""
+msgstr "^BGSinun %sjoukkuekaverisi^BG sai ^TC^TT^BG lipun! Suojelua!"
 
 #: qcsrc/common/notifications/all.inc:584
 #, c-format
 msgid "^BGYour %steam mate (^BG%s%s)^BG got the ^TC^TT^BG flag! Protect them!"
-msgstr ""
+msgstr "^BGSinun %sjoukkuekaverisi (^BG%s%s)^BG sai ^TC^TT^BG lipun! Suojelua!"
 
 #: qcsrc/common/notifications/all.inc:585
 #, c-format
 msgid "^BGYour %steam mate^BG got the flag! Protect them!"
-msgstr ""
+msgstr "^BGSinun %sjoukkuekaverisi^BG sai lipun! Suojelua!"
 
 #: qcsrc/common/notifications/all.inc:586
 #, c-format
 msgid "^BGYour %steam mate (^BG%s%s)^BG got the flag! Protect them!"
-msgstr ""
+msgstr "^BGSinun %sjoukkuekaverisi (^BG%s%s)^BG sai lipun! Suojelua!"
 
 #: qcsrc/common/notifications/all.inc:587
 msgid "^BGEnemies can now see you on radar!"
-msgstr ""
+msgstr "^BGNäyt nyt vihollisten tutkassa!"
 
 #: qcsrc/common/notifications/all.inc:588
 msgid "^BGYou returned the ^TC^TT^BG flag!"
-msgstr ""
+msgstr "^BGSinä palautit ^TC^TT^BG lipun!"
 
 #: qcsrc/common/notifications/all.inc:589
 msgid "^BGStalemate! Enemies can now see you on radar!"
-msgstr ""
+msgstr "^BGPattitilanne! Näyt nyt vihollisten tutkassa!"
 
 #: qcsrc/common/notifications/all.inc:590
 msgid "^BGStalemate! Flag carriers can now be seen by enemies on radar!"
 msgstr ""
+"^BGPattitilanne! Lipunkantajat ovat nyt vihollisten nähtävissä tutkassa!"
 
 #: qcsrc/common/notifications/all.inc:594
 #, c-format
 msgid "^K3%sYou fragged ^BG%s"
-msgstr ""
+msgstr "^K3%sFrägäsit: ^BG%s"
 
 #: qcsrc/common/notifications/all.inc:595
 #: qcsrc/common/notifications/all.inc:604
 #: qcsrc/common/notifications/all.inc:613
 #, c-format
 msgid "^K3%sYou scored against ^BG%s"
-msgstr ""
+msgstr "^K3%sTeit pisteitä ^BG%s:n kustannuksella"
 
 #: qcsrc/common/notifications/all.inc:596
 #, c-format
 msgid "^K1%sYou were fragged by ^BG%s"
-msgstr ""
+msgstr "^K1%sSinut frägättiin ^BG%s:n toimesta"
 
 #: qcsrc/common/notifications/all.inc:597
 #: qcsrc/common/notifications/all.inc:606
 #: qcsrc/common/notifications/all.inc:615
 #, c-format
 msgid "^K1%sYou were scored against by ^BG%s"
-msgstr ""
+msgstr "^K1%sKustannuksellasi tehtiin pisteitä tekijän ollen ^BG%s"
 
 #: qcsrc/common/notifications/all.inc:603
 #, c-format
 msgid "^K3%sYou burned ^BG%s"
-msgstr ""
+msgstr "^K3%sSinä paloit ^BG%s"
 
 #: qcsrc/common/notifications/all.inc:605
 #, c-format
 msgid "^K1%sYou were burned by ^BG%s"
-msgstr ""
+msgstr "^K1%sTulit poltetuksi ^BG%s:n toimesta"
 
 #: qcsrc/common/notifications/all.inc:612
 #, c-format
 msgid "^K3%sYou froze ^BG%s"
-msgstr ""
+msgstr "^K3%sJäädyit ^BG%s"
 
 #: qcsrc/common/notifications/all.inc:614
 #, c-format
 msgid "^K1%sYou were frozen by ^BG%s"
-msgstr ""
+msgstr "^K1%sSinut jäädytettiin ^BG%s :n toimesta"
 
 #: qcsrc/common/notifications/all.inc:621
 #, c-format
 msgid "^K1%sYou typefragged ^BG%s"
-msgstr ""
+msgstr "^K1%sSinä kirjoittelunaikaisfrägäsit ^BG%s"
 
 #: qcsrc/common/notifications/all.inc:622
 #, c-format
 msgid "^K1%sYou scored against ^BG%s^K1 while they were typing"
 msgstr ""
+"^K1%sOtitte hyödyn irti ^BG%s^K1 :n kustannuksella heidän kirjoitellessaan"
 
 #: qcsrc/common/notifications/all.inc:623
 #, c-format
 msgid "^K1%sYou were typefragged by ^BG%s"
-msgstr ""
+msgstr "^K1%sSinut kirjoittelunaikaisfrägättiin ^BG%s:n toimesta"
 
 #: qcsrc/common/notifications/all.inc:624
 #, c-format
 msgid "^K1%sYou were scored against by ^BG%s^K1 while typing"
-msgstr ""
+msgstr "^K1%sSinusta revittiin hyöty irti ^BG%s^K1 kirjoitellessasi"
 
 #: qcsrc/common/notifications/all.inc:630
 #, c-format
 msgid "^BGPress ^F2%s^BG again to toss the nade!"
-msgstr ""
+msgstr "^BGPaina ^F2%s^BG uudestaan viskataksesi naatin!"
 
 #: qcsrc/common/notifications/all.inc:631
 msgid "^F2You got a ^K1BONUS GRENADE^F2!"
-msgstr ""
+msgstr "^F2Sinä sait ^K1LISÄETU-KRANAATIN^F2!"
 
 #: qcsrc/common/notifications/all.inc:633
 #, c-format
@@ -3646,342 +3759,358 @@ msgid ""
 "^BGYou have been moved into a different team\n"
 "You are now on: %s"
 msgstr ""
+"^BGSinut siirrettiin eri joukkueeseen\n"
+"Olet nyt joukkueessa: %s"
 
 #: qcsrc/common/notifications/all.inc:634
 msgid "^K1Don't go against your team mates!"
-msgstr ""
+msgstr "^K1Älä käy joukkuekavereitasi vastaan!"
 
 #: qcsrc/common/notifications/all.inc:634
 msgid "^K1Don't shoot your team mates!"
-msgstr ""
+msgstr "^K1Älä joukkuekavereitasi ammu!"
 
 #: qcsrc/common/notifications/all.inc:635
 msgid "^K1Die camper!"
-msgstr ""
+msgstr "^K1Kuole senkin kämpperi!"
 
 #: qcsrc/common/notifications/all.inc:635
 msgid "^K1Reconsider your tactics, camper!"
-msgstr ""
+msgstr "^K1Kelaapa suunnitelmasi uusiksi, kämpperi!"
 
 #: qcsrc/common/notifications/all.inc:636
 msgid "^K1You unfairly eliminated yourself!"
-msgstr ""
+msgstr "^K1Sinä hyvin epärehellisesti poistit itsesi!"
 
 #: qcsrc/common/notifications/all.inc:637
 #, c-format
 msgid "^K1You were %s"
-msgstr ""
+msgstr "^K1Sinulle kävi nyt näin %s"
 
 #: qcsrc/common/notifications/all.inc:638
 msgid "^K1You couldn't catch your breath!"
-msgstr ""
+msgstr "^K1Et saanut henkeä!"
 
 #: qcsrc/common/notifications/all.inc:639
 msgid "^K1You hit the ground with a crunch!"
-msgstr ""
+msgstr "^K1Kohtasit maankamaran kanssa että raksui vain!"
 
 #: qcsrc/common/notifications/all.inc:640
 msgid "^K1You felt a little too hot!"
-msgstr ""
+msgstr "^K1Meni vähän liian kuumaksi!"
 
 #: qcsrc/common/notifications/all.inc:640
 msgid "^K1You got a little bit too crispy!"
-msgstr ""
+msgstr "^K1Nyt oli hiukan liian rapeaa!"
 
 #: qcsrc/common/notifications/all.inc:641
 msgid "^K1You killed your own dumb self!"
-msgstr ""
+msgstr "^K1Latvakakkonen tappoi itsensä!"
 
 #: qcsrc/common/notifications/all.inc:641
 msgid "^K1You need to be more careful!"
-msgstr ""
+msgstr "^K1Olisit piirunverran huolellisempi!"
 
 #: qcsrc/common/notifications/all.inc:642
 msgid "^K1You couldn't stand the heat!"
-msgstr ""
+msgstr "^K1Et kestänyt löylyä!"
 
 #: qcsrc/common/notifications/all.inc:643
 msgid "^K1You need to watch out for monsters!"
-msgstr ""
+msgstr "^K1Sinun pitää varoa hirviöitä!"
 
 #: qcsrc/common/notifications/all.inc:643
 msgid "^K1You were killed by a monster!"
-msgstr ""
+msgstr "^K1Hirviö tappoi sinut!"
 
 #: qcsrc/common/notifications/all.inc:644
 msgid "^K1Tastes like chicken!"
-msgstr ""
+msgstr "^K1Maistuu ihan kotkotilta!"
 
 #: qcsrc/common/notifications/all.inc:644
 msgid "^K1You forgot to put the pin back in!"
-msgstr ""
+msgstr "^K1Taisi unohtua laittaa tappi takaisin!"
 
 #: qcsrc/common/notifications/all.inc:645
 msgid "^K1Hanging around a napalm explosion is bad!"
-msgstr ""
+msgstr "^K1Sen siitä saa kun velttoilee napalmiräjähdysalueella!"
 
 #: qcsrc/common/notifications/all.inc:646
 msgid "^K1You felt a little chilly!"
-msgstr ""
+msgstr "^K1Nyt tuli holotna!"
 
 #: qcsrc/common/notifications/all.inc:646
 msgid "^K1You got a little bit too cold!"
-msgstr ""
+msgstr "^K1Nyt vilustuit!"
 
 #: qcsrc/common/notifications/all.inc:647
 msgid "^K1Your Healing Nade is a bit defective"
-msgstr ""
+msgstr "^K1Terveysnaattisi vaikuttaa jokseenkin kotikutoiselta"
 
 #: qcsrc/common/notifications/all.inc:648
 msgid "^K1You are respawning for running out of ammo..."
-msgstr ""
+msgstr "^K1Jälleensyntymä ammusten loppumisen takia..."
 
 #: qcsrc/common/notifications/all.inc:648
 msgid "^K1You were killed for running out of ammo..."
-msgstr ""
+msgstr "^K1Ei ammuksia jäljellä joten sinut tapettiin..."
 
 #: qcsrc/common/notifications/all.inc:649
 msgid "^K1You grew too old without taking your medicine"
-msgstr ""
+msgstr "^K1Nytpä äityivät aivot vanhoiksi ilman lääkitystäsi"
 
 #: qcsrc/common/notifications/all.inc:649
 msgid "^K1You need to preserve your health"
-msgstr ""
+msgstr "^K1Sinun täytyy ajatella terveyttäsi"
 
 #: qcsrc/common/notifications/all.inc:650
 msgid "^K1You became a shooting star!"
-msgstr ""
+msgstr "^K1Sinusta tuli tähdenlento!"
 
 #: qcsrc/common/notifications/all.inc:651
 msgid "^K1You melted away in slime!"
-msgstr ""
+msgstr "^K1Kohtaloksesi koitui sulaminen limassa!"
 
 #: qcsrc/common/notifications/all.inc:652
 msgid "^K1You committed suicide!"
-msgstr ""
+msgstr "^K1Otit itse itseltäsi nirrin pois!"
 
 #: qcsrc/common/notifications/all.inc:652
 msgid "^K1You ended it all!"
-msgstr ""
+msgstr "^K1Lopetit kaiken!"
 
 #: qcsrc/common/notifications/all.inc:653
 msgid "^K1You got stuck in a swamp!"
-msgstr ""
+msgstr "^K1Lauloit itsesi suohon!"
 
 #: qcsrc/common/notifications/all.inc:654
 #, c-format
 msgid "^BGYou are now on: %s"
-msgstr ""
+msgstr "^BGOlet nyt: %s :ssa"
 
 #: qcsrc/common/notifications/all.inc:655
 msgid "^K1You died in an accident!"
-msgstr ""
+msgstr "^K1Kuolit onnettomuudessa!"
 
 #: qcsrc/common/notifications/all.inc:656
 msgid "^K1You had an unfortunate run in with a turret!"
-msgstr ""
+msgstr "^K1Treffit tykkitornin kanssa eivät päättyneet hyvin!"
 
 #: qcsrc/common/notifications/all.inc:656
 msgid "^K1You were fragged by a turret!"
-msgstr ""
+msgstr "^K1Tykkitorni vei sinut!"
 
 #: qcsrc/common/notifications/all.inc:657
 msgid "^K1You had an unfortunate run in with an eWheel turret!"
-msgstr ""
+msgstr "^K1Ikävämmänpuoleinen kohtaaminen eWheel-tykkitornin kanssa!"
 
 #: qcsrc/common/notifications/all.inc:657
 msgid "^K1You were fragged by an eWheel turret!"
-msgstr ""
+msgstr "^K1Sinut frägäsi eWheel-tykkitorni!"
 
 #: qcsrc/common/notifications/all.inc:658
 msgid "^K1You had an unfortunate run in with a Walker turret!"
-msgstr ""
+msgstr "^K1Ikävämmänpuoleinen kohtaaminen Walker-tykkitornin kanssa! "
 
 #: qcsrc/common/notifications/all.inc:658
 msgid "^K1You were fragged by a Walker turret!"
-msgstr ""
+msgstr "^K1Sinut frägäsi Walker-tykkitorni! "
 
 #: qcsrc/common/notifications/all.inc:659
 msgid "^K1You got caught in the blast of a Bumblebee explosion!"
-msgstr ""
+msgstr "^K1Otit osumaa Bumblebee:n töräyksestä!"
 
 #: qcsrc/common/notifications/all.inc:660
 msgid "^K1You were crushed by a vehicle!"
-msgstr ""
+msgstr "^K1Ajauduit ajoneuvon murskaamaksi!"
 
 #: qcsrc/common/notifications/all.inc:661
 msgid "^K1You were caught in a Raptor cluster bomb!"
-msgstr ""
+msgstr "^K1YOtit osumaa Raptor-sirpalepommista!"
 
 #: qcsrc/common/notifications/all.inc:662
 msgid "^K1You got caught in the blast of a Raptor explosion!"
-msgstr ""
+msgstr "^K1YOtit osumaa Raptor:in töräyksestä!"
 
 #: qcsrc/common/notifications/all.inc:663
 msgid "^K1You got caught in the blast of a Spiderbot explosion!"
-msgstr ""
+msgstr "^K1Otit osumaa Hämisbot:in räjähdyksen töräyksestä!"
 
 #: qcsrc/common/notifications/all.inc:664
 msgid "^K1You were blasted to bits by a Spiderbot rocket!"
-msgstr ""
+msgstr "^K1Sinut posautettiin palasiksi Hämisbot:in raketin toimesta!"
 
 #: qcsrc/common/notifications/all.inc:665
 msgid "^K1You got caught in the blast of a Racer explosion!"
-msgstr ""
+msgstr "^K1Otit osumaa Kilpurin räjähdyksen töräyksestä! "
 
 #: qcsrc/common/notifications/all.inc:666
 msgid "^K1You couldn't find shelter from a Racer rocket!"
-msgstr ""
+msgstr "^K1Et löytänyt suojaa Kilpurin raketilta!"
 
 #: qcsrc/common/notifications/all.inc:667
 msgid "^K1Watch your step!"
-msgstr ""
+msgstr "^K1Katso mihin astut!"
 
 #: qcsrc/common/notifications/all.inc:669
 #, c-format
 msgid "^K1Moron! You fragged ^BG%s^K1, a team mate!"
-msgstr ""
+msgstr "^K1Vatipää! Frägäsit ^BG%s^K1, joukkuekaverin!"
 
 #: qcsrc/common/notifications/all.inc:669
 #, c-format
 msgid "^K1Moron! You went against ^BG%s^K1, a team mate!"
-msgstr ""
+msgstr "^K1Vatipää! Kävit ^BG%s^K1, joukkuekaveria vastaan!"
 
 #: qcsrc/common/notifications/all.inc:670
 #, c-format
 msgid "^K1You were fragged by ^BG%s^K1, a team mate"
-msgstr ""
+msgstr "^K1Sinut frägättiin ^BG%s^K1, joukkuekaverin toimesta"
 
 #: qcsrc/common/notifications/all.inc:670
 #, c-format
 msgid "^K1You were scored against by ^BG%s^K1, a team mate"
-msgstr ""
+msgstr "^K1Sinua kohtaan tehtiin vääryyttä ^BG%s^K1, joukkuekaverin toimesta"
 
 #: qcsrc/common/notifications/all.inc:672
 msgid ""
 "^K1Stop idling!\n"
 "^BGDisconnecting in ^COUNT..."
 msgstr ""
+"^K1Lopeta se mitääntekemättömyys!\n"
+"^BGYhteys katkaistaan ^COUNT..."
 
 #: qcsrc/common/notifications/all.inc:674
 #, c-format
 msgid "^BGYou need %s^BG!"
-msgstr ""
+msgstr "^BGSinä tarvitset %s^BG!"
 
 #: qcsrc/common/notifications/all.inc:675
 #, c-format
 msgid "^BGYou also need %s^BG!"
-msgstr ""
+msgstr "^BGSen lisäksi tarvitset %s^BG!"
 
 #: qcsrc/common/notifications/all.inc:676
 msgid "^BGDoor unlocked!"
-msgstr ""
+msgstr "^BGOvi avattu!"
 
 #: qcsrc/common/notifications/all.inc:678
 msgid "^F2You picked up some extra lives"
-msgstr ""
+msgstr "^F2Poimit lisäelämiä"
 
 #: qcsrc/common/notifications/all.inc:680
 #, c-format
 msgid "^K3You revived ^BG%s"
-msgstr ""
+msgstr "^K3Sinä elvytit ^BG%s"
 
 #: qcsrc/common/notifications/all.inc:681
 msgid "^K3You revived yourself"
-msgstr ""
+msgstr "^K3Elvytit itsesi"
 
 #: qcsrc/common/notifications/all.inc:682
 #, c-format
 msgid "^K3You were revived by ^BG%s"
-msgstr ""
+msgstr "^K3Sinut elvytettiin ^BG%s :n toimesta"
 
 #: qcsrc/common/notifications/all.inc:683
 #, c-format
 msgid "^K3You were automatically revived after %s second(s)"
-msgstr ""
+msgstr "^K3Sinut elvytettiin automaattisesti %s sekunnissa()"
 
 #: qcsrc/common/notifications/all.inc:685
 msgid "^BGThe generator is under attack!"
-msgstr ""
+msgstr "^BGGeneraattori hyökkäyksen alaisena!"
 
 #: qcsrc/common/notifications/all.inc:687
 msgid "^TC^TT^BG team loses the round"
-msgstr ""
+msgstr "^TC^TT^BG joukkue häviää kierroksen"
 
 #: qcsrc/common/notifications/all.inc:691
 msgid "^K1You froze yourself"
-msgstr ""
+msgstr "^K1Jäädytit itsesi"
 
 #: qcsrc/common/notifications/all.inc:692
 msgid "^K1Round already started, you spawn as frozen"
-msgstr ""
+msgstr "^K1Kierros on jo alkanut, ilmestyt jäätyneenä"
 
 #: qcsrc/common/notifications/all.inc:694
 #, c-format
 msgid "^K1A %s has arrived!"
-msgstr ""
+msgstr "^K1A %s on saapunut!"
 
 #: qcsrc/common/notifications/all.inc:698
 msgid "^BGYou got the ^F1Fuel regenerator"
-msgstr ""
+msgstr "^BGSinulla on ^F1Polttoaineen uusiotuotin"
 
 #: qcsrc/common/notifications/all.inc:699
 msgid "^BGYou got the ^F1Jetpack"
-msgstr ""
+msgstr "^BGSinulla on ^F1Lentopakkaus"
 
 #: qcsrc/common/notifications/all.inc:707
 msgid ""
 "^K1No spawnpoints available!\n"
 "Hope your team can fix it..."
 msgstr ""
+"^K1Ei uudelleensyntypisteitä!\n"
+"Toivottavasti joukkueesi korjaa tämän asian..."
 
 #: qcsrc/common/notifications/all.inc:708
 msgid ""
 "^K1You may not join the game at this time.\n"
 "The player limit reached maximum capacity."
 msgstr ""
+"^K1Et voi liittyä peliin juuri nyt.\n"
+"Pelaajamäärä on saavuttanut lakipisteensä."
 
 #: qcsrc/common/notifications/all.inc:712
 msgid "^BGYou picked up the ball"
-msgstr ""
+msgstr "^BGPoimit pallon matkaan"
 
 #: qcsrc/common/notifications/all.inc:713
 msgid "^BGKilling people while you don't have the ball gives no points!"
-msgstr ""
+msgstr "^BGIhmisten tappaminen ilman palloa ei kerrytä pisteitä!"
 
 #: qcsrc/common/notifications/all.inc:715
 msgid ""
 "^BGAll keys are in your team's hands!\n"
 "Help the key carriers to meet!"
 msgstr ""
+"^BGKaikki avaimet ovat joukkueesi hallussa!\n"
+"Avusta avaintenkantajia tapaamaan toisensa!"
 
 #: qcsrc/common/notifications/all.inc:716
 msgid ""
 "^BGAll keys are in ^TC^TT team^BG's hands!\n"
 "Interfere ^F4NOW^BG!"
 msgstr ""
+"^BGKaikki avaimet ovat ^TC^TT joukkueen^BG hallussa!\n"
+"Puutu tilanteeseen ^F4NOW^BG!"
 
 #: qcsrc/common/notifications/all.inc:717
 msgid ""
 "^BGAll keys are in your team's hands!\n"
 "Meet the other key carriers ^F4NOW^BG!"
 msgstr ""
+"^BGKaikki avaimet ovat sinun joukkueesi hallussa!\n"
+"Järjestä tapaaminen muiden avaintenkantajien kanssa ^F4NOW^BG!"
 
 #: qcsrc/common/notifications/all.inc:718
 msgid "^F4Round will start in ^COUNT"
-msgstr ""
+msgstr "^F4Kierros alkaa ^COUNT"
 
 #: qcsrc/common/notifications/all.inc:719
 msgid "^BGScanning frequency range..."
-msgstr ""
+msgstr "^BGLäpikäydään taajuusaluetta..."
 
 #: qcsrc/common/notifications/all.inc:720
 msgid "^BGYou are starting with the ^TC^TT Key"
-msgstr ""
+msgstr "^BGAloitat ^TC^TT Avaimella"
 
 #: qcsrc/common/notifications/all.inc:722
 msgid "^BGYou have no lives left, you must wait until the next match"
 msgstr ""
+"^BGSinulla ei ole enää elämiä jäljellä, sinun täytyy odottaa seuraavaa "
+"ottelua"
 
 #: qcsrc/common/notifications/all.inc:724
 #, c-format
@@ -3989,32 +4118,34 @@ msgid ""
 "^BGWaiting for players to join...\n"
 "Need active players for: %s"
 msgstr ""
+"^BGPelaajia odotetaan liittyväksi...\n"
+"Aktiivisia tarvitaan: %s"
 
 #: qcsrc/common/notifications/all.inc:725
 #, c-format
 msgid "^BGWaiting for %s player(s) to join..."
-msgstr ""
+msgstr "^BGOdotetaan %s pelaajaa (pelaajia) liittymään..."
 
 #: qcsrc/common/notifications/all.inc:727
 msgid "^BGYour weapon has been downgraded until you find some ammo!"
-msgstr ""
+msgstr "^BGAseesi alasluokattiin kunnes löydät ammuksia!"
 
 #: qcsrc/common/notifications/all.inc:728
 msgid "^F4^COUNT^BG left to find some ammo!"
-msgstr ""
+msgstr "^F4^COUNT^BG jäljellä löytää ammuksia!"
 
 #: qcsrc/common/notifications/all.inc:729
 msgid "^BGGet some ammo or you'll be dead in ^F4^COUNT^BG!"
-msgstr ""
+msgstr "^BGHanki ammuksia tai olet kuollut tuotapikaa ^F4^COUNT^BG!"
 
 #: qcsrc/common/notifications/all.inc:729
 msgid "^BGGet some ammo! ^F4^COUNT^BG left!"
-msgstr ""
+msgstr "^BGHanki niitä ammuksia! ^F4^COUNT^BG jäljellä!"
 
 #: qcsrc/common/notifications/all.inc:730
 #, c-format
 msgid "^F2Extra lives remaining: ^K1%s"
-msgstr ""
+msgstr "^F2Lisäelämiä jäljellä: ^K1%s"
 
 #: qcsrc/common/notifications/all.inc:734
 #, c-format
@@ -4022,63 +4153,73 @@ msgid ""
 "^F2^COUNT^BG until weapon change...\n"
 "Next weapon: ^F1%s"
 msgstr ""
+"^F2^COUNT^BG jäljellä seuraavaan asevaihtoon...\n"
+"Seuraava ase: ^F1%s"
 
 #: qcsrc/common/notifications/all.inc:735
 #, c-format
 msgid "^F2Active weapon: ^F1%s"
-msgstr ""
+msgstr "^F2Aktiivinen ase: ^F1%s"
 
 #: qcsrc/common/notifications/all.inc:737
 #, c-format
 msgid "^BGYou captured %s^BG control point"
-msgstr ""
+msgstr "^BGKaappasit haltuusi %s^BG hallintapisteen"
 
 #: qcsrc/common/notifications/all.inc:738
 #, c-format
 msgid "^TC^TT^BG team captured %s^BG control point"
-msgstr ""
+msgstr "^TC^TT^BG joukkue kaappasi %s^BG hallintapisteen"
 
 #: qcsrc/common/notifications/all.inc:739
 msgid "^BGThis control point currently cannot be captured"
-msgstr ""
+msgstr "^BGTätä hallintapistettä ei nykyisellään voi kaapata haltuun"
 
 #: qcsrc/common/notifications/all.inc:740
 msgid ""
 "^BGThe enemy generator cannot be destroyed yet\n"
 "^F2Capture some control points to unshield it"
 msgstr ""
+"^BGVihollisgeneraattoria ei vielä voi tuhota\n"
+"^F2Kaappaa hallintapisteitä haltuusi riisuaksesi sen suojaukset"
 
 #: qcsrc/common/notifications/all.inc:741
 msgid "^BGThe ^TCenemy^BG generator is no longer shielded!"
-msgstr ""
+msgstr "^BGNyt ^TCvihollisten^BG generaattori on riisuttu suojauksistaan!"
 
 #: qcsrc/common/notifications/all.inc:742
 msgid ""
 "^K1Your generator is NOT shielded!\n"
 "^BGRe-capture control points to shield it!"
 msgstr ""
+"^K1Generaattorisi EI OLE suojattu!\n"
+"^BGKaappaa hallintapisteet takaisin suojataksesi sen!"
 
 #: qcsrc/common/notifications/all.inc:743
 #, c-format
 msgid "^BGPress ^F2%s^BG to teleport"
-msgstr ""
+msgstr "^BGPaina ^F2%s^BG etäsiirtyäksesi"
 
 #: qcsrc/common/notifications/all.inc:744
 #, c-format
 msgid "^BGTeleporting disabled for %s"
-msgstr ""
+msgstr "^BGEtäsiirto on kytketty pois %s :lle"
 
 #: qcsrc/common/notifications/all.inc:746
 msgid ""
 "^F2Now playing ^F4OVERTIME^F2!\n"
 "Keep fragging until we have a winner!"
 msgstr ""
+"^F2Nyt pelataan ^F4JATKOAIKAA^F2!\n"
+"Jatka frägäämistä kunnes voittaja selviää!"
 
 #: qcsrc/common/notifications/all.inc:746
 msgid ""
 "^F2Now playing ^F4OVERTIME^F2!\n"
 "Keep scoring until we have a winner!"
 msgstr ""
+"^F2Nyt pelataan ^F4JATKOAIKAA^F2!\n"
+"Jatka pisteiden takomista kunnes voittaja selviää!"
 
 #: qcsrc/common/notifications/all.inc:747
 msgid ""
@@ -4088,6 +4229,11 @@ msgid ""
 "The more control points your team holds,\n"
 "the faster the enemy generator decays"
 msgstr ""
+"^F2Nyt pelataan ^F4JATKOAIKAA^F2!\n"
+"\n"
+"Generaattorit hiipuvat.\n"
+"Mitä enemmän hallintapisteitä joukkueesi pitää hallussa,\n"
+"sitä nopeammin vastustajan generaattorit hiipuvat"
 
 #: qcsrc/common/notifications/all.inc:748
 #, c-format
@@ -4095,277 +4241,286 @@ msgid ""
 "^F2Now playing ^F4OVERTIME^F2!\n"
 "^BGAdded ^F4%s^BG to the game!"
 msgstr ""
+"^F2Nyt pelataan ^F4JATKOAIKAA^F2!\n"
+"^BGLisätty ^F4%s^BG peliin!"
 
 #: qcsrc/common/notifications/all.inc:750
 msgid "^K1In^BG-portal created"
-msgstr ""
+msgstr "^K1Sisäänkäynti^BG-portaali on luotu"
 
 #: qcsrc/common/notifications/all.inc:751
 msgid "^F3Out^BG-portal created"
-msgstr ""
+msgstr "^F3Uloskäynti^BG-portaali luotu"
 
 #: qcsrc/common/notifications/all.inc:752
 msgid "^F1Portal creation failed"
-msgstr ""
+msgstr "^F1Portaalin luominen epäonnistui"
 
 #: qcsrc/common/notifications/all.inc:754
 msgid "^F2Strength infuses your weapons with devastating power"
-msgstr ""
+msgstr "^F2Voima sytyttää aseesi tuhoisalla vahvuudella"
 
 #: qcsrc/common/notifications/all.inc:755
 msgid "^F2Strength has worn off"
-msgstr ""
+msgstr "^F2Voima ehtyi pois"
 
 #: qcsrc/common/notifications/all.inc:757
 msgid "^F2Shield surrounds you"
-msgstr ""
+msgstr "^F2Sinua ympäröi suojus"
 
 #: qcsrc/common/notifications/all.inc:758
 msgid "^F2Shield has worn off"
-msgstr ""
+msgstr "^F2Suoja ehtyi pois"
 
 #: qcsrc/common/notifications/all.inc:760
 msgid "^F2You are on speed"
-msgstr ""
+msgstr "^F2Olet vauhdissa"
 
 #: qcsrc/common/notifications/all.inc:761
 msgid "^F2Speed has worn off"
-msgstr ""
+msgstr "^F2Vauhti ehtyi pois"
 
 #: qcsrc/common/notifications/all.inc:763
 msgid "^F2You are invisible"
-msgstr ""
+msgstr "^F2Olet näkymätön"
 
 #: qcsrc/common/notifications/all.inc:764
 msgid "^F2Invisibility has worn off"
-msgstr ""
+msgstr "^F2Näkymättömyys ehtyi pois"
 
 #: qcsrc/common/notifications/all.inc:766
 msgid "^F2The race is over, finish your lap!"
-msgstr ""
+msgstr "^F2Kilpa on ohi, päätä kierroksesi päätökseen!"
 
 #: qcsrc/common/notifications/all.inc:768
 msgid "^BGSecondary fire inflicts no damage!"
-msgstr ""
+msgstr "^BGToissijainen tulitus ei aiheuta vahinkoa!"
 
 #: qcsrc/common/notifications/all.inc:770
 msgid "^BGSequence completed!"
-msgstr ""
+msgstr "^BGOsio saatettu päätökseen!"
 
 #: qcsrc/common/notifications/all.inc:771
 msgid "^BGThere are more to go..."
-msgstr ""
+msgstr "^BGEdessä on lisää..."
 
 #: qcsrc/common/notifications/all.inc:772
 #, c-format
 msgid "^BGOnly %s^BG more to go..."
-msgstr ""
+msgstr "^BGAinoastaan %s^BG jäljellä..."
 
 #: qcsrc/common/notifications/all.inc:774
 msgid "^F2Superweapons have broken down"
-msgstr ""
+msgstr "^F2Mahtiaseet ovat menneet rikki"
 
 #: qcsrc/common/notifications/all.inc:775
 msgid "^F2Superweapons have been lost"
-msgstr ""
+msgstr "^F2Mahtiaseet menetetty"
 
 #: qcsrc/common/notifications/all.inc:776
 msgid "^F2You now have a superweapon"
-msgstr ""
+msgstr "^F2Sinulla on nyt hallussasi mahtiase"
 
 #: qcsrc/common/notifications/all.inc:778
 msgid "^K1Changing to ^TC^TT^K1 in ^COUNT"
-msgstr ""
+msgstr "^K1Vaihdetaan ^TC^TT^K1 ajassa ^COUNT"
 
 #: qcsrc/common/notifications/all.inc:779
 msgid "^K1Changing team in ^COUNT"
-msgstr ""
+msgstr "^K1Vaihdetaan joukkuetta ajassa ^COUNT"
 
 #: qcsrc/common/notifications/all.inc:780
 msgid "^K1Spectating in ^COUNT"
-msgstr ""
+msgstr "^K1Katselu alkaa ^COUNT"
 
 #: qcsrc/common/notifications/all.inc:781
 msgid "^K1Suicide in ^COUNT"
-msgstr ""
+msgstr "^K1Itsemurha ajassa ^COUNT"
 
 #: qcsrc/common/notifications/all.inc:783
 msgid "^F4Timeout begins in ^COUNT"
-msgstr ""
+msgstr "^F4Aikalisä alkaa ^COUNT"
 
 #: qcsrc/common/notifications/all.inc:784
 msgid "^F4Timeout ends in ^COUNT"
-msgstr ""
+msgstr "^F4Aikalisä päättyy ajassa ^COUNT"
 
 #: qcsrc/common/notifications/all.inc:786
 msgid "^K1Cannot join given minigame session!"
-msgstr ""
+msgstr "^K1Annettuun pienpeli-istuntoon ei voitu liittyä!"
 
 #: qcsrc/common/notifications/all.inc:788
 #, c-format
 msgid "^BGPress ^F2%s^BG to enter/exit the vehicle"
-msgstr ""
+msgstr "^BGPaina ^F2%s^BG käydäksesi sisään/poistuaksesi ajoneuvosta"
 
 #: qcsrc/common/notifications/all.inc:789
 #, c-format
 msgid "^BGPress ^F2%s^BG to enter the vehicle gunner"
-msgstr ""
+msgstr "^BGPaina ^F2%s^BG käydäksesi sisälle ajoneuvon ampumisosaan"
 
 #: qcsrc/common/notifications/all.inc:790
 #, c-format
 msgid "^BGPress ^F2%s^BG to steal this vehicle"
-msgstr ""
+msgstr "^BGPaina ^F2%s^BG varastaaksesi ajoneuvon"
 
 #: qcsrc/common/notifications/all.inc:791
 msgid ""
 "^F2The enemy is stealing one of your vehicles!\n"
 "^F4Stop them!"
 msgstr ""
+"^F2Vihulainen varastaa yhtä ajoneuvoistasi!\n"
+"^F4Pysäytä heidät!"
 
 #: qcsrc/common/notifications/all.inc:792
 msgid "^F2Intruder detected, disabling shields!"
-msgstr ""
+msgstr "^F2Havaittu tunkeilija, kytketään suojat pois!"
 
 #: qcsrc/common/notifications/all.qh:194
 msgid "Notification dump command only works with cl_cmd and sv_cmd."
-msgstr ""
+msgstr "Ilmoitusten heivauskäsky toimii vain: cl_cmd ja sv_cmd."
 
 #: qcsrc/common/notifications/all.qh:404 qcsrc/common/notifications/all.qh:405
 #, c-format
 msgid " (near %s)"
-msgstr ""
+msgstr " (lähellä %s)"
 
 #: qcsrc/common/notifications/all.qh:412 qcsrc/common/notifications/all.qh:413
 msgid "primary"
-msgstr ""
+msgstr "ensisijainen"
 
 #: qcsrc/common/notifications/all.qh:412 qcsrc/common/notifications/all.qh:413
 msgid "secondary"
-msgstr ""
+msgstr "toissijainen"
 
 #: qcsrc/common/notifications/all.qh:415
 msgid "point"
-msgstr ""
+msgstr "piste"
 
 #: qcsrc/common/notifications/all.qh:415
 msgid "points"
-msgstr ""
+msgstr "pisteet"
 
 #: qcsrc/common/notifications/all.qh:424
 msgid "drop flag"
-msgstr ""
+msgstr "pudota lippu"
 
 #: qcsrc/common/notifications/all.qh:425
 msgid "throw nade"
-msgstr ""
+msgstr "heitä naatti"
 
 #: qcsrc/common/notifications/all.qh:450
 #, c-format
 msgid "%s^K1 made a TRIPLE FRAG! %s^BG"
-msgstr ""
+msgstr "%s^K1 toteutti KOLMOISFRÄGIN! %s^BG"
 
 #: qcsrc/common/notifications/all.qh:450
 #, c-format
 msgid "%s^K1 made a TRIPLE SCORE! %s^BG"
-msgstr ""
+msgstr "%s^K1 teki KOLMOISPISTEET! %s^BG"
 
 #: qcsrc/common/notifications/all.qh:450
 msgid "TRIPLE FRAG! "
-msgstr ""
+msgstr "KOLMOISFRÄGI!"
 
 #: qcsrc/common/notifications/all.qh:451
 #, c-format
 msgid "%s^K1 made FIVE SCORES IN A ROW! %s^BG"
-msgstr ""
+msgstr "%s^K1 toteutti VIISI PISTEISIIN OIKEUTTAVAA TEKOA PUTKEEN! %s^BG"
 
 #: qcsrc/common/notifications/all.qh:451
 #, c-format
 msgid "%s^K1 unlocked RAGE! %s^BG"
-msgstr ""
+msgstr "%s^K1 avattu ominaisuus: RAIVO! %s^BG"
 
 #: qcsrc/common/notifications/all.qh:451
 msgid "RAGE! "
-msgstr ""
+msgstr "RAIVO!"
 
 #: qcsrc/common/notifications/all.qh:452
 #, c-format
 msgid "%s^K1 made TEN SCORES IN A ROW! %s^BG"
-msgstr ""
+msgstr "%s^K1 toteutti KYMMENEN PISTEISIIN OIKEUTTAVAA TEKOA PUTKEEN!  %s^BG"
 
 #: qcsrc/common/notifications/all.qh:452
 #, c-format
 msgid "%s^K1 started a MASSACRE! %s^BG"
-msgstr ""
+msgstr "%s^K1 aloitti TEURASTUKSEN! %s^BG"
 
 #: qcsrc/common/notifications/all.qh:452
 msgid "MASSACRE! "
-msgstr ""
+msgstr "TEURASTUS!"
 
 #: qcsrc/common/notifications/all.qh:453
 #, c-format
 msgid "%s^K1 executed MAYHEM! %s^BG"
-msgstr ""
+msgstr "%s^K1 laittoi alulle SEKASORRON! %s^BG"
 
 #: qcsrc/common/notifications/all.qh:453
 #, c-format
 msgid "%s^K1 made FIFTEEN SCORES IN A ROW! %s^BG"
 msgstr ""
+"%s^K1 toteutti VIISITOISTA PISTEISIIN OIKEUTTAVAA TEKOA PUTKEEN!  %s^BG"
 
 #: qcsrc/common/notifications/all.qh:453
 msgid "MAYHEM! "
-msgstr ""
+msgstr "SEKASORTO!"
 
 #: qcsrc/common/notifications/all.qh:454
 #, c-format
 msgid "%s^K1 is a BERSERKER! %s^BG"
-msgstr ""
+msgstr "%s^K1 on RAIVOHULLU! %s^BG"
 
 #: qcsrc/common/notifications/all.qh:454
 #, c-format
 msgid "%s^K1 made TWENTY SCORES IN A ROW! %s^BG"
 msgstr ""
+"%s^K1 toteutti KAKSIKYMMENTÄ PISTEISIIN OIKEUTTAVAA TEKOA PUTKEEN!  %s^BG"
 
 #: qcsrc/common/notifications/all.qh:454
 msgid "BERSERKER! "
-msgstr ""
+msgstr "RAIVOHULLU!"
 
 #: qcsrc/common/notifications/all.qh:455
 #, c-format
 msgid "%s^K1 inflicts CARNAGE! %s^BG"
-msgstr ""
+msgstr "%s^K1 aloitti VERILÖYLYN! %s^BG"
 
 #: qcsrc/common/notifications/all.qh:455
 #, c-format
 msgid "%s^K1 made TWENTY FIVE SCORES IN A ROW! %s^BG"
 msgstr ""
+"%s^K1 toteutti KAKSIKYMMENTÄ JA VIISI PISTEISIIN OIKEUTTAVAA TEKOA "
+"PUTKEEN! ! %s^BG"
 
 #: qcsrc/common/notifications/all.qh:455
 msgid "CARNAGE! "
-msgstr ""
+msgstr "VERILÖYLY!"
 
 #: qcsrc/common/notifications/all.qh:456
 #, c-format
 msgid "%s^K1 made THIRTY SCORES IN A ROW! %s^BG"
 msgstr ""
+"%s^K1 toteutti KOLMEKYMMENTÄ PISTEISIIN OIKEUTTAVAA TEKOA PUTKEEN!! %s^BG"
 
 #: qcsrc/common/notifications/all.qh:456
 #, c-format
 msgid "%s^K1 unleashes ARMAGEDDON! %s^BG"
-msgstr ""
+msgstr "%s^K1 päästi valloilleen MAAILMANLOPUN MEININGIN! %s^BG"
 
 #: qcsrc/common/notifications/all.qh:456
 msgid "ARMAGEDDON! "
-msgstr ""
+msgstr "MAAILMANLOPUN MEININKI!"
 
 #: qcsrc/common/notifications/all.qh:463
 #, c-format
 msgid "%s(^F1Bot^BG)"
-msgstr ""
+msgstr "%s(^F1Bot^BG)"
 
 #: qcsrc/common/notifications/all.qh:465
 #, c-format
 msgid "%s(Ping ^F1%d^BG)"
-msgstr ""
+msgstr "%s(Ping ^F1%d^BG)"
 
 #: qcsrc/common/notifications/all.qh:472
 #, c-format
@@ -4373,6 +4528,8 @@ msgid ""
 "\n"
 "(Health ^1%d^BG / Armor ^2%d^BG)%s"
 msgstr ""
+"\n"
+"(Terveys ^1%d^BG / Suojaus ^2%d^BG)%s"
 
 #: qcsrc/common/notifications/all.qh:474
 #, c-format
@@ -4380,410 +4537,412 @@ msgid ""
 "\n"
 "(^F4Dead^BG)%s"
 msgstr ""
+"\n"
+"(^F4Kuollut^BG)%s"
 
 #: qcsrc/common/notifications/all.qh:495 qcsrc/common/notifications/all.qh:508
 #, c-format
 msgid "%d score spree! "
-msgstr ""
+msgstr "%d pisteputki! "
 
 #: qcsrc/common/notifications/all.qh:507
 #, c-format
 msgid "%d frag spree! "
-msgstr ""
+msgstr "%d frägiputki! "
 
 #: qcsrc/common/notifications/all.qh:520
 msgid "First blood! "
-msgstr ""
+msgstr "Ensiveri vuodatettu!"
 
 #: qcsrc/common/notifications/all.qh:520
 msgid "First score! "
-msgstr ""
+msgstr "Ensipisteet!"
 
 #: qcsrc/common/notifications/all.qh:524
 msgid "First casualty! "
-msgstr ""
+msgstr "Ensikärsijä!"
 
 #: qcsrc/common/notifications/all.qh:524
 msgid "First victim! "
-msgstr ""
+msgstr "Ensiuhri!"
 
 #: qcsrc/common/notifications/all.qh:565
 #, c-format
 msgid "%s^K1 has %d frags in a row! %s^BG"
-msgstr ""
+msgstr "%s^K1 pisti %d frägiä putkeen! %s^BG"
 
 #: qcsrc/common/notifications/all.qh:566
 #, c-format
 msgid "%s^K1 made %d scores in a row! %s^BG"
-msgstr ""
+msgstr "%s^K1 laittoi %d kirjausta putkeen! %s^BG"
 
 #: qcsrc/common/notifications/all.qh:584
 #, c-format
 msgid "%s^K1 drew first blood! %s^BG"
-msgstr ""
+msgstr "%s^K1 vuodatutti ensiveret! %s^BG"
 
 #: qcsrc/common/notifications/all.qh:585
 #, c-format
 msgid "%s^K1 got the first score! %s^BG"
-msgstr ""
+msgstr "%s^K1 saavutti ensipisteet! %s^BG"
 
 #: qcsrc/common/notifications/all.qh:601
 #, c-format
 msgid ", ending their %d frag spree"
-msgstr ""
+msgstr ", päättää %d frägiputkensa"
 
 #: qcsrc/common/notifications/all.qh:602
 #, c-format
 msgid ", ending their %d score spree"
-msgstr ""
+msgstr ", päättää %d pisteputkensa"
 
 #: qcsrc/common/notifications/all.qh:616
 #, c-format
 msgid ", losing their %d frag spree"
-msgstr ""
+msgstr ", menettää %d frägiputkensa"
 
 #: qcsrc/common/notifications/all.qh:617
 #, c-format
 msgid ", losing their %d score spree"
-msgstr ""
+msgstr ", menettää %d pisteputkensa"
 
 #: qcsrc/common/notifications/all.qh:642
 #, c-format
 msgid " with %d %s"
-msgstr ""
+msgstr "täten %d %s"
 
 #: qcsrc/common/teams.qh:31
 msgid "TEAM^Red"
-msgstr ""
+msgstr "JOUKKUE^Punainen"
 
 #: qcsrc/common/teams.qh:32
 msgid "TEAM^Blue"
-msgstr ""
+msgstr "JOUKKUE^Sininen"
 
 #: qcsrc/common/teams.qh:33
 msgid "TEAM^Yellow"
-msgstr ""
+msgstr "JOUKKUE^Keltainen"
 
 #: qcsrc/common/teams.qh:34
 msgid "TEAM^Pink"
-msgstr ""
+msgstr "JOUKKUE^Vaaleanpunainen"
 
 #: qcsrc/common/teams.qh:35
 msgid "Team"
-msgstr ""
+msgstr "Joukkue"
 
 #: qcsrc/common/teams.qh:36
 msgid "Neutral"
-msgstr ""
+msgstr "Puolueeton"
 
 #: qcsrc/common/teams.qh:39
 msgid "KEY^Red"
-msgstr ""
+msgstr "AVAIN^Punainen"
 
 #: qcsrc/common/teams.qh:40
 msgid "KEY^Blue"
-msgstr ""
+msgstr "AVAIN^Sininen"
 
 #: qcsrc/common/teams.qh:41
 msgid "KEY^Yellow"
-msgstr ""
+msgstr "AVAIN^Keltainen"
 
 #: qcsrc/common/teams.qh:42
 msgid "KEY^Pink"
-msgstr ""
+msgstr "AVAIN^Vaaleanpunainen"
 
 #: qcsrc/common/teams.qh:43
 msgid "FLAG^Red"
-msgstr ""
+msgstr "LIPPU^Punainen"
 
 #: qcsrc/common/teams.qh:44
 msgid "FLAG^Blue"
-msgstr ""
+msgstr "LIPPU^Sininen"
 
 #: qcsrc/common/teams.qh:45
 msgid "FLAG^Yellow"
-msgstr ""
+msgstr "LIPPU^Keltainen"
 
 #: qcsrc/common/teams.qh:46
 msgid "FLAG^Pink"
-msgstr ""
+msgstr "LIPPU^Vaaleanpunainen"
 
 #: qcsrc/common/teams.qh:47
 msgid "GENERATOR^Red"
-msgstr ""
+msgstr "GENERAATTORI^Punainen"
 
 #: qcsrc/common/teams.qh:48
 msgid "GENERATOR^Blue"
-msgstr ""
+msgstr "GENERAATTORI^Sininen"
 
 #: qcsrc/common/teams.qh:49
 msgid "GENERATOR^Yellow"
-msgstr ""
+msgstr "GENERAATTORI^Keltainen"
 
 #: qcsrc/common/teams.qh:50
 msgid "GENERATOR^Pink"
-msgstr ""
+msgstr "GENERAATTORI^Vaaleanpunainen"
 
 #: qcsrc/common/turrets/all.qh:96
 msgid "Turrets dump command only works with sv_cmd."
-msgstr ""
+msgstr "Tykkitornien heivaamiskäsky toimii vain tämän kautta: sv_cmd."
 
 #: qcsrc/common/turrets/cl_turrets.qc:125
 #, c-format
 msgid "%s under attack!"
-msgstr ""
+msgstr "%s hyökkäyksen alaisena!"
 
 #: qcsrc/common/turrets/turret.qh:11
 msgid "Turret"
-msgstr ""
+msgstr "Tykkitorni"
 
 #: qcsrc/common/turrets/turret/ewheel.qh:15
 msgid "eWheel Turret"
-msgstr ""
+msgstr "eWheel-tykkitorni"
 
 #: qcsrc/common/turrets/turret/ewheel_weapon.qh:7
 msgid "eWheel"
-msgstr ""
+msgstr "e-Wheel"
 
 #: qcsrc/common/turrets/turret/flac.qh:13
 msgid "FLAC Cannon"
-msgstr ""
+msgstr "FLAC-tykki"
 
 #: qcsrc/common/turrets/turret/flac_weapon.qh:9
 msgid "FLAC"
-msgstr ""
+msgstr "FLAC"
 
 #: qcsrc/common/turrets/turret/fusionreactor.qh:11
 msgid "Fusion Reactor"
-msgstr ""
+msgstr "Fuusioreaktori"
 
 #: qcsrc/common/turrets/turret/hellion.qh:13
 msgid "Hellion Missile Turret"
-msgstr ""
+msgstr "Hellion-ohjustykkitorni"
 
 #: qcsrc/common/turrets/turret/hellion_weapon.qh:7
 msgid "Hellion"
-msgstr ""
+msgstr "Hellion"
 
 #: qcsrc/common/turrets/turret/hk.qh:15
 msgid "Hunter-Killer Turret"
-msgstr ""
+msgstr "Hunter-Killer-tykkitorni"
 
 #: qcsrc/common/turrets/turret/hk_weapon.qh:7
 msgid "Hunter-Killer"
-msgstr ""
+msgstr "Hunter-Killer"
 
 #: qcsrc/common/turrets/turret/machinegun.qh:13
 msgid "Machinegun Turret"
-msgstr ""
+msgstr "Machinegun -koneaseellinen tykkitorni"
 
 #: qcsrc/common/turrets/turret/machinegun_weapon.qh:7
 msgid "Machinegun"
-msgstr ""
+msgstr "Machinegun-konease"
 
 #: qcsrc/common/turrets/turret/mlrs.qh:13
 msgid "MLRS Turret"
-msgstr ""
+msgstr "MLRS-tykkitorni"
 
 #: qcsrc/common/turrets/turret/mlrs_weapon.qh:7
 msgid "MLRS"
-msgstr ""
+msgstr "MLRS"
 
 #: qcsrc/common/turrets/turret/phaser.qh:13
 msgid "Phaser Cannon"
-msgstr ""
+msgstr "Vaiheistykki"
 
 #: qcsrc/common/turrets/turret/phaser_weapon.qh:7
 msgid "Phaser"
-msgstr ""
+msgstr "Vaiheistykki"
 
 #: qcsrc/common/turrets/turret/plasma.qh:13
 msgid "Plasma Cannon"
-msgstr ""
+msgstr "Plasmatykki"
 
 #: qcsrc/common/turrets/turret/plasma_dual.qh:8
 msgid "Dual plasma"
-msgstr ""
+msgstr "Kaksoisplasma"
 
 #: qcsrc/common/turrets/turret/plasma_dual.qh:20
 msgid "Dual Plasma Cannon"
-msgstr ""
+msgstr "Kaksoisplasmatykki"
 
 #: qcsrc/common/turrets/turret/plasma_weapon.qh:7
 msgid "Plasma"
-msgstr ""
+msgstr "Plasma"
 
 #: qcsrc/common/turrets/turret/tesla.qh:13
 #: qcsrc/common/turrets/turret/tesla_weapon.qh:7
 msgid "Tesla Coil"
-msgstr ""
+msgstr "Tesla-käämi"
 
 #: qcsrc/common/turrets/turret/walker.qh:15
 msgid "Walker Turret"
-msgstr ""
+msgstr "Walker-tykkitorni"
 
 #: qcsrc/common/turrets/turret/walker_weapon.qh:7
 msgid "Walker"
-msgstr ""
+msgstr "Walker"
 
 #: qcsrc/common/util.qc:1403
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:173
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:183
 msgid "Male"
-msgstr ""
+msgstr "Miespuolinen"
 
 #: qcsrc/common/util.qc:1404
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:172
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:182
 msgid "Female"
-msgstr ""
+msgstr "Naispuolinen"
 
 #: qcsrc/common/util.qc:1405
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:171
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:184
 msgid "Undisclosed"
-msgstr ""
+msgstr "Epäselvä"
 
 #: qcsrc/common/util.qc:1452
 msgid "<KEY NOT FOUND>"
-msgstr ""
+msgstr "<KEY NOT FOUND>"
 
 #: qcsrc/common/util.qc:1453
 msgid "<UNKNOWN KEYNUM>"
-msgstr ""
+msgstr "<UNKNOWN KEYNUM>"
 
 #: qcsrc/common/util.qc:1458
 msgid "TAB"
-msgstr ""
+msgstr "TAB"
 
 #: qcsrc/common/util.qc:1459 qcsrc/common/util.qc:1530
 #, c-format
 msgid "ENTER"
-msgstr ""
+msgstr "ENTER"
 
 #: qcsrc/common/util.qc:1460
 msgid "ESCAPE"
-msgstr ""
+msgstr "ESCAPE"
 
 #: qcsrc/common/util.qc:1461
 msgid "SPACE"
-msgstr ""
+msgstr "VÄLILYÖNTI"
 
 #: qcsrc/common/util.qc:1463
 msgid "BACKSPACE"
-msgstr ""
+msgstr "BACKSPACE-taakseaskellusnäppäin"
 
 #: qcsrc/common/util.qc:1464 qcsrc/common/util.qc:1521
 #, c-format
 msgid "UPARROW"
-msgstr ""
+msgstr "NUOLI YLÖSPÄIN"
 
 #: qcsrc/common/util.qc:1465 qcsrc/common/util.qc:1516
 #, c-format
 msgid "DOWNARROW"
-msgstr ""
+msgstr "NUOLI ALASPÄIN"
 
 #: qcsrc/common/util.qc:1466 qcsrc/common/util.qc:1518
 #, c-format
 msgid "LEFTARROW"
-msgstr ""
+msgstr "NUOLI VASEMMALLE"
 
 #: qcsrc/common/util.qc:1467 qcsrc/common/util.qc:1519
 #, c-format
 msgid "RIGHTARROW"
-msgstr ""
+msgstr "NUOLI OIKEALLE"
 
 #: qcsrc/common/util.qc:1469
 msgid "ALT"
-msgstr ""
+msgstr "ALT"
 
 #: qcsrc/common/util.qc:1470
 msgid "CTRL"
-msgstr ""
+msgstr "CTRL"
 
 #: qcsrc/common/util.qc:1471
 msgid "SHIFT"
-msgstr ""
+msgstr "SHIFT-vaihtonäppäin"
 
 #: qcsrc/common/util.qc:1473 qcsrc/common/util.qc:1514
 #, c-format
 msgid "INS"
-msgstr ""
+msgstr "INS"
 
 #: qcsrc/common/util.qc:1474 qcsrc/common/util.qc:1524
 #, c-format
 msgid "DEL"
-msgstr ""
+msgstr "DEL"
 
 #: qcsrc/common/util.qc:1475 qcsrc/common/util.qc:1517
 #, c-format
 msgid "PGDN"
-msgstr ""
+msgstr "PGDN"
 
 #: qcsrc/common/util.qc:1476 qcsrc/common/util.qc:1522
 #, c-format
 msgid "PGUP"
-msgstr ""
+msgstr "PGUP"
 
 #: qcsrc/common/util.qc:1477 qcsrc/common/util.qc:1520
 #, c-format
 msgid "HOME"
-msgstr ""
+msgstr "HOME"
 
 #: qcsrc/common/util.qc:1478 qcsrc/common/util.qc:1515
 #, c-format
 msgid "END"
-msgstr ""
+msgstr "END"
 
 #: qcsrc/common/util.qc:1480
 msgid "PAUSE"
-msgstr ""
+msgstr "PAUSE"
 
 #: qcsrc/common/util.qc:1482
 msgid "NUMLOCK"
-msgstr ""
+msgstr "NUMLOCK"
 
 #: qcsrc/common/util.qc:1483
 msgid "CAPSLOCK"
-msgstr ""
+msgstr "CAPSLOCK"
 
 #: qcsrc/common/util.qc:1484
 msgid "SCROLLOCK"
-msgstr ""
+msgstr "SCROLLOCK"
 
 #: qcsrc/common/util.qc:1486
 msgid "SEMICOLON"
-msgstr ""
+msgstr "PUOLIPISTE"
 
 #: qcsrc/common/util.qc:1487
 msgid "TILDE"
-msgstr ""
+msgstr "TILDE-aaltoviiva"
 
 #: qcsrc/common/util.qc:1488
 msgid "BACKQUOTE"
-msgstr ""
+msgstr "BACKQUOTE-taaksepäinlainaus"
 
 #: qcsrc/common/util.qc:1489
 msgid "QUOTE"
-msgstr ""
+msgstr "QUOTE-lainausmerkki"
 
 #: qcsrc/common/util.qc:1490
 msgid "APOSTROPHE"
-msgstr ""
+msgstr "HEITTOMERKKI"
 
 #: qcsrc/common/util.qc:1491
 msgid "BACKSLASH"
-msgstr ""
+msgstr "KENOVIIVA"
 
 #: qcsrc/common/util.qc:1499
 #, c-format
 msgid "F%d"
-msgstr ""
+msgstr "F%d"
 
 #: qcsrc/common/util.qc:1509
 #, c-format
 msgid "KP_%d"
-msgstr ""
+msgstr "KP_%d"
 
 #: qcsrc/common/util.qc:1514 qcsrc/common/util.qc:1515
 #: qcsrc/common/util.qc:1516 qcsrc/common/util.qc:1517
@@ -4796,74 +4955,74 @@ msgstr ""
 #: qcsrc/common/util.qc:1530 qcsrc/common/util.qc:1531
 #, c-format
 msgid "KP_%s"
-msgstr ""
+msgstr "KP_%s"
 
 #: qcsrc/common/util.qc:1523
 #, c-format
 msgid "PERIOD"
-msgstr ""
+msgstr "PISTE"
 
 #: qcsrc/common/util.qc:1525
 #, c-format
 msgid "DIVIDE"
-msgstr ""
+msgstr "JAKOMERKKI"
 
 #: qcsrc/common/util.qc:1526
 #, c-format
 msgid "SLASH"
-msgstr ""
+msgstr "KENOVIIVA ETEEN"
 
 #: qcsrc/common/util.qc:1527
 #, c-format
 msgid "MULTIPLY"
-msgstr ""
+msgstr "KERTOMERKKI"
 
 #: qcsrc/common/util.qc:1528
 #, c-format
 msgid "MINUS"
-msgstr ""
+msgstr "MIINUS"
 
 #: qcsrc/common/util.qc:1529
 #, c-format
 msgid "PLUS"
-msgstr ""
+msgstr "PLUS"
 
 #: qcsrc/common/util.qc:1531
 #, c-format
 msgid "EQUALS"
-msgstr ""
+msgstr "YHTÄKUIN"
 
 #: qcsrc/common/util.qc:1536
 msgid "PRINTSCREEN"
-msgstr ""
+msgstr "PRINTSCREEN-näppäin"
 
 #: qcsrc/common/util.qc:1539
 #, c-format
 msgid "MOUSE%d"
-msgstr ""
+msgstr "HIIRI%d"
 
 #: qcsrc/common/util.qc:1541
 msgid "MWHEELUP"
-msgstr ""
+msgstr "HIIRIRULLA YLÖS"
 
 #: qcsrc/common/util.qc:1542
 msgid "MWHEELDOWN"
-msgstr ""
+msgstr "HIIRIRULLA ALAS"
 
 #: qcsrc/common/util.qc:1545
 #, c-format
 msgid "JOY%d"
-msgstr ""
+msgstr "SAUVA%d"
 
 #: qcsrc/common/util.qc:1548
 #, c-format
 msgid "AUX%d"
-msgstr ""
+msgstr "AUX%d"
 
 #: qcsrc/common/util.qc:1555
 #, c-format
 msgid "DPAD_UP"
-msgstr ""
+msgstr "D-PADI_YLÖS"
 
 #: qcsrc/common/util.qc:1555 qcsrc/common/util.qc:1556
 #: qcsrc/common/util.qc:1557 qcsrc/common/util.qc:1558
@@ -4877,190 +5036,190 @@ msgstr ""
 #: qcsrc/common/util.qc:1573 qcsrc/common/util.qc:1574
 #, c-format
 msgid "X360_%s"
-msgstr ""
+msgstr "X360_%s"
 
 #: qcsrc/common/util.qc:1556
 #, c-format
 msgid "DPAD_DOWN"
-msgstr ""
+msgstr "D-PADI_ALAS"
 
 #: qcsrc/common/util.qc:1557
 #, c-format
 msgid "DPAD_LEFT"
-msgstr ""
+msgstr "D-PADI_VASEN"
 
 #: qcsrc/common/util.qc:1558
 #, c-format
 msgid "DPAD_RIGHT"
-msgstr ""
+msgstr "D-PADI_OIKEA"
 
 #: qcsrc/common/util.qc:1559
 #, c-format
 msgid "START"
-msgstr ""
+msgstr "START-nappi"
 
 #: qcsrc/common/util.qc:1560
 #, c-format
 msgid "BACK"
-msgstr ""
+msgstr "BACK-takaisinnappi"
 
 #: qcsrc/common/util.qc:1561
 #, c-format
 msgid "LEFT_THUMB"
-msgstr ""
+msgstr "VASEN_PEUKALO"
 
 #: qcsrc/common/util.qc:1562
 #, c-format
 msgid "RIGHT_THUMB"
-msgstr ""
+msgstr "OIKEA_PEUKALO"
 
 #: qcsrc/common/util.qc:1563
 #, c-format
 msgid "LEFT_SHOULDER"
-msgstr ""
+msgstr "VASEN_OLKAPÄÄ"
 
 #: qcsrc/common/util.qc:1564
 #, c-format
 msgid "RIGHT_SHOULDER"
-msgstr ""
+msgstr "OIKEA_OLKAPÄÄ"
 
 #: qcsrc/common/util.qc:1565
 #, c-format
 msgid "LEFT_TRIGGER"
-msgstr ""
+msgstr "VASEN_LIIPAISIN"
 
 #: qcsrc/common/util.qc:1566
 #, c-format
 msgid "RIGHT_TRIGGER"
-msgstr ""
+msgstr "OIKEA_LIIPAISIN"
 
 #: qcsrc/common/util.qc:1567
 #, c-format
 msgid "LEFT_THUMB_UP"
-msgstr ""
+msgstr "VASEN_PEUKALO_YLÖS"
 
 #: qcsrc/common/util.qc:1568
 #, c-format
 msgid "LEFT_THUMB_DOWN"
-msgstr ""
+msgstr "VASEN_PEUKALO_ALAS"
 
 #: qcsrc/common/util.qc:1569
 #, c-format
 msgid "LEFT_THUMB_LEFT"
-msgstr ""
+msgstr "VASEN_PEUKALO_VASEN"
 
 #: qcsrc/common/util.qc:1570
 #, c-format
 msgid "LEFT_THUMB_RIGHT"
-msgstr ""
+msgstr "VASEN_PEUKALO_OIKEA"
 
 #: qcsrc/common/util.qc:1571
 #, c-format
 msgid "RIGHT_THUMB_UP"
-msgstr ""
+msgstr "OIKEA_PEUKALO_YLÖS"
 
 #: qcsrc/common/util.qc:1572
 #, c-format
 msgid "RIGHT_THUMB_DOWN"
-msgstr ""
+msgstr "OIKEA_PEUKALO_ALAS"
 
 #: qcsrc/common/util.qc:1573
 #, c-format
 msgid "RIGHT_THUMB_LEFT"
-msgstr ""
+msgstr "OIKEA_PEUKALO_VASEN"
 
 #: qcsrc/common/util.qc:1574
 #, c-format
 msgid "RIGHT_THUMB_RIGHT"
-msgstr ""
+msgstr "OIKEA_PEUKALO_OIKEA"
 
 #: qcsrc/common/util.qc:1584 qcsrc/common/util.qc:1585
 #: qcsrc/common/util.qc:1586 qcsrc/common/util.qc:1587
 #, c-format
 msgid "JOY_%s"
-msgstr ""
+msgstr "Sauvaohjain_%s"
 
 #: qcsrc/common/util.qc:1584
 #, c-format
 msgid "UP"
-msgstr ""
+msgstr "YLÖS"
 
 #: qcsrc/common/util.qc:1585
 #, c-format
 msgid "DOWN"
-msgstr ""
+msgstr "ALAS"
 
 #: qcsrc/common/util.qc:1586
 #, c-format
 msgid "LEFT"
-msgstr ""
+msgstr "VASEN"
 
 #: qcsrc/common/util.qc:1587
 #, c-format
 msgid "RIGHT"
-msgstr ""
+msgstr "OIKEA"
 
 #: qcsrc/common/util.qc:1593
 #, c-format
 msgid "MIDINOTE%d"
-msgstr ""
+msgstr "MIDIHUOMAUTUS%d"
 
 #: qcsrc/common/vehicles/cl_vehicles.qc:190
 #, c-format
 msgid "Press %s"
-msgstr ""
+msgstr "Paina %s"
 
 #: qcsrc/common/vehicles/vehicle/bumblebee.qc:947
 msgid "No right gunner!"
-msgstr ""
+msgstr "Ei oikean ammuntaa!"
 
 #: qcsrc/common/vehicles/vehicle/bumblebee.qc:953
 msgid "No left gunner!"
-msgstr ""
+msgstr "Ei vasemman ammuntaa!"
 
 #: qcsrc/common/vehicles/vehicle/bumblebee.qh:19
 msgid "Bumblebee"
-msgstr ""
+msgstr "Bumblebee"
 
 #: qcsrc/common/vehicles/vehicle/racer.qh:19
 msgid "Racer"
-msgstr ""
+msgstr "Kilpuri"
 
 #: qcsrc/common/vehicles/vehicle/racer_weapon.qh:9
 msgid "Racer cannon"
-msgstr ""
+msgstr "Kilpuritykki"
 
 #: qcsrc/common/vehicles/vehicle/raptor.qh:19
 msgid "Raptor"
-msgstr ""
+msgstr "Raptor"
 
 #: qcsrc/common/vehicles/vehicle/raptor_weapons.qh:9
 msgid "Raptor cannon"
-msgstr ""
+msgstr "Raptor-tykki"
 
 #: qcsrc/common/vehicles/vehicle/raptor_weapons.qh:17
 msgid "Raptor bomb"
-msgstr ""
+msgstr "Raptor-pommi"
 
 #: qcsrc/common/vehicles/vehicle/raptor_weapons.qh:25
 msgid "Raptor flare"
-msgstr ""
+msgstr "Raptor-soihtu"
 
 #: qcsrc/common/vehicles/vehicle/spiderbot.qh:19
 msgid "Spiderbot"
-msgstr ""
+msgstr "Hämisbotti"
 
 #: qcsrc/common/weapons/all.qh:77
 msgid "Weapons dump command only works with sv_cmd."
-msgstr ""
+msgstr "Aseiden heivauskäsky toimii vain täten: sv_cmd."
 
 #: qcsrc/common/weapons/weapon/arc.qh:18
 msgid "Arc"
-msgstr ""
+msgstr "Arc"
 
 #: qcsrc/common/weapons/weapon/blaster.qh:18
 msgid "Blaster"
-msgstr ""
+msgstr "Läjäytin"
 
 #: qcsrc/common/weapons/weapon/crylink.qh:18
 msgid "Crylink"
@@ -5068,7 +5227,7 @@ msgstr "Crylink"
 
 #: qcsrc/common/weapons/weapon/devastator.qh:18
 msgid "Devastator"
-msgstr ""
+msgstr "Hävittäjä"
 
 #: qcsrc/common/weapons/weapon/electro.qh:18
 msgid "Electro"
@@ -5092,7 +5251,7 @@ msgstr "Grabbling Hook"
 
 #: qcsrc/common/weapons/weapon/machinegun.qh:18
 msgid "MachineGun"
-msgstr ""
+msgstr "MachineGun-konease"
 
 #: qcsrc/common/weapons/weapon/minelayer.qh:18
 msgid "Mine Layer"
@@ -5116,7 +5275,7 @@ msgstr "T.A.G. Seeker"
 
 #: qcsrc/common/weapons/weapon/shockwave.qh:18
 msgid "Shockwave"
-msgstr ""
+msgstr "Shockwave-paineaalto"
 
 #: qcsrc/common/weapons/weapon/shotgun.qh:18
 msgid "Shotgun"
@@ -5129,196 +5288,196 @@ msgstr "@!#%'n tuuba"
 
 #: qcsrc/common/weapons/weapon/vaporizer.qh:19
 msgid "Vaporizer"
-msgstr ""
+msgstr "Höyrystäjä"
 
 #: qcsrc/common/weapons/weapon/vortex.qh:19
 msgid "Vortex"
-msgstr ""
+msgstr "Pyörremyrsky"
 
 #: qcsrc/lib/counting.qh:9
 #, c-format
 msgid "CI_DEC^%s years"
-msgstr ""
+msgstr "CI_DEC^%s vuotta"
 
 #: qcsrc/lib/counting.qh:12
 #, c-format
 msgid "CI_ZER^%d years"
-msgstr ""
+msgstr "CI_ZER^%d vuotta"
 
 #: qcsrc/lib/counting.qh:13
 #, c-format
 msgid "CI_FIR^%d year"
-msgstr ""
+msgstr "CI_FIR^%d vuosi"
 
 #: qcsrc/lib/counting.qh:14
 #, c-format
 msgid "CI_SEC^%d years"
-msgstr ""
+msgstr "CI_SEC^%d vuotta"
 
 #: qcsrc/lib/counting.qh:15
 #, c-format
 msgid "CI_THI^%d years"
-msgstr ""
+msgstr "CI_THI^%d vuotta"
 
 #: qcsrc/lib/counting.qh:16
 #, c-format
 msgid "CI_MUL^%d years"
-msgstr ""
+msgstr "CI_MUL^%d vuotta"
 
 #: qcsrc/lib/counting.qh:18
 #, c-format
 msgid "CI_DEC^%s weeks"
-msgstr ""
+msgstr "CI_DEC^%s viikkoa"
 
 #: qcsrc/lib/counting.qh:21
 #, c-format
 msgid "CI_ZER^%d weeks"
-msgstr ""
+msgstr "CI_ZER^%d viikkoa"
 
 #: qcsrc/lib/counting.qh:22
 #, c-format
 msgid "CI_FIR^%d week"
-msgstr ""
+msgstr "CI_FIR^%d viikko"
 
 #: qcsrc/lib/counting.qh:23
 #, c-format
 msgid "CI_SEC^%d weeks"
-msgstr ""
+msgstr "CI_SEC^%d viikkoa"
 
 #: qcsrc/lib/counting.qh:24
 #, c-format
 msgid "CI_THI^%d weeks"
-msgstr ""
+msgstr "CI_THI^%d viikkoa"
 
 #: qcsrc/lib/counting.qh:25
 #, c-format
 msgid "CI_MUL^%d weeks"
-msgstr ""
+msgstr "CI_MUL^%d viikkoa"
 
 #: qcsrc/lib/counting.qh:27
 #, c-format
 msgid "CI_DEC^%s days"
-msgstr ""
+msgstr "CI_DEC^%s päivää"
 
 #: qcsrc/lib/counting.qh:30
 #, c-format
 msgid "CI_ZER^%d days"
-msgstr ""
+msgstr "CI_ZER^%d päivää"
 
 #: qcsrc/lib/counting.qh:31
 #, c-format
 msgid "CI_FIR^%d day"
-msgstr ""
+msgstr "CI_FIR^%d päivä"
 
 #: qcsrc/lib/counting.qh:32
 #, c-format
 msgid "CI_SEC^%d days"
-msgstr ""
+msgstr "CI_SEC^%d päivää"
 
 #: qcsrc/lib/counting.qh:33
 #, c-format
 msgid "CI_THI^%d days"
-msgstr ""
+msgstr "CI_THI^%d päivää"
 
 #: qcsrc/lib/counting.qh:34
 #, c-format
 msgid "CI_MUL^%d days"
-msgstr ""
+msgstr "CI_MUL^%d päivää"
 
 #: qcsrc/lib/counting.qh:36
 #, c-format
 msgid "CI_DEC^%s hours"
-msgstr ""
+msgstr "CI_DEC^%s tuntia"
 
 #: qcsrc/lib/counting.qh:39
 #, c-format
 msgid "CI_ZER^%d hours"
-msgstr ""
+msgstr "CI_ZER^%d tuntia"
 
 #: qcsrc/lib/counting.qh:40
 #, c-format
 msgid "CI_FIR^%d hour"
-msgstr ""
+msgstr "CI_FIR^%d tunti"
 
 #: qcsrc/lib/counting.qh:41
 #, c-format
 msgid "CI_SEC^%d hours"
-msgstr ""
+msgstr "CI_SEC^%d tuntia"
 
 #: qcsrc/lib/counting.qh:42
 #, c-format
 msgid "CI_THI^%d hours"
-msgstr ""
+msgstr "CI_THI^%d tuntia"
 
 #: qcsrc/lib/counting.qh:43
 #, c-format
 msgid "CI_MUL^%d hours"
-msgstr ""
+msgstr "CI_MUL^%d tuntia"
 
 #: qcsrc/lib/counting.qh:46
 #, c-format
 msgid "CI_DEC^%s minutes"
-msgstr ""
+msgstr "CI_DEC^%s minuuttia"
 
 #: qcsrc/lib/counting.qh:49
 #, c-format
 msgid "CI_ZER^%d minutes"
-msgstr ""
+msgstr "CI_ZER^%d minuuttia"
 
 #: qcsrc/lib/counting.qh:50
 #, c-format
 msgid "CI_FIR^%d minute"
-msgstr ""
+msgstr "CI_FIR^%d minuutti"
 
 #: qcsrc/lib/counting.qh:51
 #, c-format
 msgid "CI_SEC^%d minutes"
-msgstr ""
+msgstr "CI_SEC^%d minuuttia"
 
 #: qcsrc/lib/counting.qh:52
 #, c-format
 msgid "CI_THI^%d minutes"
-msgstr ""
+msgstr "CI_THI^%d minuuttia"
 
 #: qcsrc/lib/counting.qh:53
 #, c-format
 msgid "CI_MUL^%d minutes"
-msgstr ""
+msgstr "CI_MUL^%d minuuttia"
 
 #: qcsrc/lib/counting.qh:55
 #, c-format
 msgid "CI_DEC^%s seconds"
-msgstr ""
+msgstr "CI_DEC^%s sekuntia"
 
 #: qcsrc/lib/counting.qh:58
 #, c-format
 msgid "CI_ZER^%d seconds"
-msgstr ""
+msgstr "CI_ZER^%d sekuntia"
 
 #: qcsrc/lib/counting.qh:59
 #, c-format
 msgid "CI_FIR^%d second"
-msgstr ""
+msgstr "CI_FIR^%d sekunti"
 
 #: qcsrc/lib/counting.qh:60
 #, c-format
 msgid "CI_SEC^%d seconds"
-msgstr ""
+msgstr "CI_SEC^%d seconds"
 
 #: qcsrc/lib/counting.qh:61
 #, c-format
 msgid "CI_THI^%d seconds"
-msgstr ""
+msgstr "CI_THI^%d sekuntia"
 
 #: qcsrc/lib/counting.qh:62
 #, c-format
 msgid "CI_MUL^%d seconds"
-msgstr ""
+msgstr "CI_MUL^%d sekuntia"
 
 #: qcsrc/lib/counting.qh:79
 #, c-format
 msgid "%dst"
-msgstr ""
+msgstr "%dst"
 
 #: qcsrc/lib/counting.qh:80
 #, c-format
@@ -5337,7 +5496,7 @@ msgstr "%dth"
 
 #: qcsrc/lib/oo.qh:330
 msgid "No description"
-msgstr ""
+msgstr "Ei kuvausta"
 
 #: qcsrc/lib/spawnfunc.qh:240
 #, c-format
@@ -5345,40 +5504,43 @@ msgid ""
 "Entity field %s.%s (%s) is not whitelisted. If you believe this is an error, "
 "please file an issue."
 msgstr ""
+"Oliokenttä %s.%s (%s) ei ole valkoluetteloitu. Mikäli uskot tämän olevan "
+"virhe, ole hyvä ja ilmoita siitä."
 
 #: qcsrc/lib/string.qh:81
 #, c-format
 msgid "%d days, %02d:%02d:%02d"
-msgstr ""
+msgstr "%d päivää, %02d:%02d:%02d"
 
 #: qcsrc/lib/string.qh:82
 #, c-format
 msgid "%02d:%02d:%02d"
-msgstr ""
+msgstr "%02d:%02d:%02d"
 
 #: qcsrc/menu/command/menu_cmd.qc:48
 msgid "Usage: menu_cmd command..., where possible commands are:"
-msgstr ""
+msgstr "Käyttö: menu_cmd command..., johon mahdollisest käskyt ovat:"
 
 #: qcsrc/menu/command/menu_cmd.qc:49
 msgid "  sync - reloads all cvars on the current menu page"
-msgstr ""
+msgstr "  sync - uudelleenlataa kaiken nykyisellä valikkosivulla"
 
 #: qcsrc/menu/command/menu_cmd.qc:50
 msgid "  directmenu ITEM - select a menu item as main item"
-msgstr ""
+msgstr "  directmenu ITEM - valitse valikkokohde pääkohteeksi"
 
 #: qcsrc/menu/command/menu_cmd.qc:51
 msgid "  dumptree - dump the state of the menu as a tree to the console"
-msgstr ""
+msgstr "  dumptree - heivaa valikon tila päätteeseen puu-oksarakenteisena"
 
 #: qcsrc/menu/command/menu_cmd.qc:81
 msgid "Available options:"
-msgstr ""
+msgstr "Mahdolliset vaihtoehdot:"
 
 #: qcsrc/menu/command/menu_cmd.qc:130
 msgid "Invalid command. For a list of supported commands, try menu_cmd help."
 msgstr ""
+"Epäkelpo käsky. Tuettuja käskyjä katsellaksesi, kokeile: menu_cmd help."
 
 #: qcsrc/menu/item/listbox.qc:413
 #, c-format
@@ -5399,183 +5561,183 @@ msgstr "Taso %d: %s"
 
 #: qcsrc/menu/xonotic/credits.qc:4
 msgid "Core Team"
-msgstr ""
+msgstr "Ydinjoukkue"
 
 #: qcsrc/menu/xonotic/credits.qc:16
 msgid "Extended Team"
-msgstr ""
+msgstr "Laajennettu joukkue"
 
 #: qcsrc/menu/xonotic/credits.qc:48
 msgid "Website"
-msgstr ""
+msgstr "Verkkosivu"
 
 #: qcsrc/menu/xonotic/credits.qc:53
 msgid "Stats"
-msgstr ""
+msgstr "Tilastot"
 
 #: qcsrc/menu/xonotic/credits.qc:57
 msgid "Art"
-msgstr ""
+msgstr "Taide"
 
 #: qcsrc/menu/xonotic/credits.qc:65
 msgid "Animation"
-msgstr ""
+msgstr "Animaatio"
 
 #: qcsrc/menu/xonotic/credits.qc:69
 msgid "Level Design"
-msgstr ""
+msgstr "Kenttäsuunnittelu"
 
 #: qcsrc/menu/xonotic/credits.qc:92
 msgid "Music / Sound FX"
-msgstr ""
+msgstr "Musiikki / ääniefektit"
 
 #: qcsrc/menu/xonotic/credits.qc:108
 msgid "Game Code"
-msgstr ""
+msgstr "Pelin ohjelmakoodi"
 
 #: qcsrc/menu/xonotic/credits.qc:116
 msgid "Marketing / PR"
-msgstr ""
+msgstr "Markkinointi / PR"
 
 #: qcsrc/menu/xonotic/credits.qc:122
 msgid "Legal"
-msgstr ""
+msgstr "Lakisääteiset asiat"
 
 #: qcsrc/menu/xonotic/credits.qc:127
 msgid "Game Engine"
-msgstr ""
+msgstr "Pelimoottori"
 
 #: qcsrc/menu/xonotic/credits.qc:131
 msgid "Engine Additions"
-msgstr ""
+msgstr "Moottorin lisät"
 
 #: qcsrc/menu/xonotic/credits.qc:136
 msgid "Compiler"
-msgstr ""
+msgstr "Koonti"
 
 #: qcsrc/menu/xonotic/credits.qc:142
 msgid "Other Active Contributors"
-msgstr ""
+msgstr "Muita aktiivisia panoksensa antajia"
 
 #: qcsrc/menu/xonotic/credits.qc:149
 msgid "Translators"
-msgstr ""
+msgstr "Kääntäjät"
 
 #: qcsrc/menu/xonotic/credits.qc:151
 msgid "Asturian"
-msgstr ""
+msgstr "Asturian-kieli"
 
 #: qcsrc/menu/xonotic/credits.qc:156
 msgid "Belarusian"
-msgstr ""
+msgstr "Valko-venäjä"
 
 #: qcsrc/menu/xonotic/credits.qc:159
 msgid "Bulgarian"
-msgstr ""
+msgstr "Bulgaria"
 
 #: qcsrc/menu/xonotic/credits.qc:166
 msgid "Chinese (China)"
-msgstr ""
+msgstr "Kiina (Kiinassa)"
 
 #: qcsrc/menu/xonotic/credits.qc:172
 msgid "Chinese (Taiwan)"
-msgstr ""
+msgstr "Kiina (Taiwan)"
 
 #: qcsrc/menu/xonotic/credits.qc:177
 msgid "Cornish"
-msgstr ""
+msgstr "Korni"
 
 #: qcsrc/menu/xonotic/credits.qc:180
 msgid "Czech"
-msgstr ""
+msgstr "Tsekki"
 
 #: qcsrc/menu/xonotic/credits.qc:185
 msgid "Dutch"
-msgstr ""
+msgstr "Hollanti"
 
 #: qcsrc/menu/xonotic/credits.qc:192
 msgid "English (Australia)"
-msgstr ""
+msgstr "Englanti (Australiassa)"
 
 #: qcsrc/menu/xonotic/credits.qc:197
 msgid "Finnish"
-msgstr ""
+msgstr "Suomi"
 
 #: qcsrc/menu/xonotic/credits.qc:202
 msgid "French"
-msgstr ""
+msgstr "Ranska"
 
 #: qcsrc/menu/xonotic/credits.qc:210
 msgid "German"
-msgstr ""
+msgstr "Saksa"
 
 #: qcsrc/menu/xonotic/credits.qc:221
 msgid "Greek"
-msgstr ""
+msgstr "Kreikka"
 
 #: qcsrc/menu/xonotic/credits.qc:227
 msgid "Hungarian"
-msgstr ""
+msgstr "Unkari"
 
 #: qcsrc/menu/xonotic/credits.qc:231
 msgid "Irish"
-msgstr ""
+msgstr "Iiri"
 
 #: qcsrc/menu/xonotic/credits.qc:234
 msgid "Italian"
-msgstr ""
+msgstr "Italia"
 
 #: qcsrc/menu/xonotic/credits.qc:240
 msgid "Kazakh"
-msgstr ""
+msgstr "Kasakki"
 
 #: qcsrc/menu/xonotic/credits.qc:243
 msgid "Korean"
-msgstr ""
+msgstr "Korea"
 
 #: qcsrc/menu/xonotic/credits.qc:247
 msgid "Polish"
-msgstr ""
+msgstr "Puola"
 
 #: qcsrc/menu/xonotic/credits.qc:255
 msgid "Portuguese"
-msgstr ""
+msgstr "Portugali"
 
 #: qcsrc/menu/xonotic/credits.qc:261
 msgid "Romanian"
-msgstr ""
+msgstr "Romania"
 
 #: qcsrc/menu/xonotic/credits.qc:268
 msgid "Russian"
-msgstr ""
+msgstr "Venäjä"
 
 #: qcsrc/menu/xonotic/credits.qc:279
 msgid "Scottish Gaelic"
-msgstr ""
+msgstr "Skottilainen keltti"
 
 #: qcsrc/menu/xonotic/credits.qc:282
 msgid "Serbian"
-msgstr ""
+msgstr "Serbia"
 
 #: qcsrc/menu/xonotic/credits.qc:288
 msgid "Spanish"
-msgstr ""
+msgstr "Espanja"
 
 #: qcsrc/menu/xonotic/credits.qc:299
 msgid "Swedish"
-msgstr ""
+msgstr "Ruotsi"
 
 #: qcsrc/menu/xonotic/credits.qc:303
 msgid "Ukrainian"
-msgstr ""
+msgstr "Ukraina"
 
 #: qcsrc/menu/xonotic/credits.qc:310
 msgid "Past Contributors"
-msgstr ""
+msgstr "Aikaisemmat panoksensa antajat"
 
 #: qcsrc/menu/xonotic/cvarlist.qc:73
 msgid "forced to be saved to config.cfg"
-msgstr ""
+msgstr "pakoitettu tallennettavaksi tiedostoon config.cfg"
 
 #: qcsrc/menu/xonotic/cvarlist.qc:79 qcsrc/menu/xonotic/cvarlist.qc:89
 msgid "will not be saved"
@@ -5612,7 +5774,7 @@ msgstr "Tekijät"
 
 #: qcsrc/menu/xonotic/dialog_credits.qh:8
 msgid "The Xonotic credits"
-msgstr ""
+msgstr "Xonotic:in tunnustusmaininnat"
 
 #: qcsrc/menu/xonotic/dialog_firstrun.qc:39
 msgid ""
@@ -5632,7 +5794,7 @@ msgstr "Nimi:"
 #: qcsrc/menu/xonotic/dialog_firstrun.qc:53
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:64
 msgid "Name under which you will appear in the game"
-msgstr ""
+msgstr "Näkyvä nimi jota tulet käyttämään pelissä"
 
 #: qcsrc/menu/xonotic/dialog_firstrun.qc:69
 msgid "Text language:"
@@ -5644,7 +5806,7 @@ msgstr "Salli pelinimesi käyttö pelaajatilastosivulla stats.xonotic.org?"
 
 #: qcsrc/menu/xonotic/dialog_firstrun.qc:84
 msgid "Undecided"
-msgstr ""
+msgstr "Ei päätetty"
 
 #: qcsrc/menu/xonotic/dialog_firstrun.qc:88
 msgid "Save settings"
@@ -5665,12 +5827,12 @@ msgstr "Näytä vain nykyinen ammustyyppi"
 #: qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc:24
 #: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:46
 msgid "Noncurrent alpha:"
-msgstr ""
+msgstr "Ei-ajanmukainen alpha-versio:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc:28
 #: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:50
 msgid "Noncurrent scale:"
-msgstr ""
+msgstr "Ei-ajanmukaisuuden skaala:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_ammo.qc:32
 #: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:24
@@ -5734,7 +5896,7 @@ msgstr "Fontin skaalaus:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_centerprint.qh:6
 msgid "Centerprint Panel"
-msgstr ""
+msgstr "Keskeiskirjoituksen palkki"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_chat.qc:17
 msgid "Chat entries:"
@@ -5770,7 +5932,7 @@ msgstr "Pelimoottorin tietopaneeli"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:17
 msgid "Combine health and armor"
-msgstr ""
+msgstr "Yhdistä terveys ja suojapanssari"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_healtharmor.qc:19
 #: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:28
@@ -5838,35 +6000,35 @@ msgstr "Pois päältä"
 #: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:17
 #: qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qc:15
 msgid "Enable spectating"
-msgstr ""
+msgstr "Kytke päälle sivustakatselu"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:18
 msgid "Enable even playing in warmup"
-msgstr ""
+msgstr "Salli jopa lämmittelykierrosta pelatessa"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:29
 msgid "Reduced"
-msgstr ""
+msgstr "Alennettu"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:32
 msgid "Text/icon ratio:"
-msgstr ""
+msgstr "Teksti/kuvake-suhde:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:35
 msgid "Hide spawned items"
-msgstr ""
+msgstr "Piilota ilmestyneet esineet"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:37
 msgid "Hide big armor and health"
-msgstr ""
+msgstr "Piilota suuri suojapanssari ja terveysmääre"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc:39
 msgid "Dynamic size"
-msgstr ""
+msgstr "Dynaaminen koko"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qh:6
 msgid "Items Time Panel"
-msgstr ""
+msgstr "Esineiden aikapalkki"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_modicons.qh:6
 msgid "Mod Icons Panel"
@@ -5899,15 +6061,15 @@ msgstr "Ilmoituspaneeli"
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:16
 #: qcsrc/menu/xonotic/util.qc:766
 msgid "Enable"
-msgstr ""
+msgstr "Ota käyttöön"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:17
 msgid "Enable even observing"
-msgstr ""
+msgstr "Salli jopa katselijana"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:18
 msgid "Enable only in Race/CTS"
-msgstr ""
+msgstr "Otakäyttöön vain Kilvassa/CTS:ssä"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:24
 msgid "Status bar"
@@ -5994,7 +6156,7 @@ msgstr "Tehonlisäyspaneeli"
 #: qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qc:16
 #: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:17
 msgid "Always enable"
-msgstr ""
+msgstr "Aina päällä"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_pressedkeys.qc:23
 msgid "Forced aspect:"
@@ -6006,7 +6168,7 @@ msgstr "Painettujen näppäinten paneeli"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_quickmenu.qh:6
 msgid "Quick Menu Panel"
-msgstr ""
+msgstr "Pikavalikkopalkki"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_racetimer.qh:6
 msgid "Race Timer Panel"
@@ -6014,7 +6176,7 @@ msgstr "Kilpajuoksun ajanoton paneeli"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:16
 msgid "Enable in team games"
-msgstr ""
+msgstr "Salli joukkuepeleissä"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:23
 msgid "Radar:"
@@ -6192,7 +6354,7 @@ msgstr "Näppäin"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:60
 msgid "Weapon ID scale:"
-msgstr ""
+msgstr "Aseen ID-tunnisteen skaalaus:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:66
 msgid "Show Accuracy"
@@ -6216,7 +6378,7 @@ msgstr "Asepaneeli"
 
 #: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:19
 msgid "HUD skins"
-msgstr ""
+msgstr "HUD-päällysteskinit"
 
 #: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:22
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:173
@@ -6232,7 +6394,7 @@ msgstr "Suodatin:"
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:49
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc:42
 msgid "Refresh"
-msgstr ""
+msgstr "Virkistys"
 
 #: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:33
 #: qcsrc/menu/xonotic/dialog_settings_user.qc:30
@@ -6241,7 +6403,7 @@ msgstr "Aseta ulkoasu:"
 
 #: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:37
 msgid "Save current skin"
-msgstr ""
+msgstr "Tallenna nykyinen päällysteskini"
 
 #: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:46
 msgid "Panel background defaults:"
@@ -6322,7 +6484,7 @@ msgstr "Paneelin näkymän asetukset"
 
 #: qcsrc/menu/xonotic/dialog_monstertools.qc:13
 msgid "Monster:"
-msgstr ""
+msgstr "Hirviö:"
 
 #: qcsrc/menu/xonotic/dialog_monstertools.qc:22
 #: qcsrc/menu/xonotic/dialog_sandboxtools.qc:20
@@ -6336,27 +6498,27 @@ msgstr "Poista"
 
 #: qcsrc/menu/xonotic/dialog_monstertools.qc:25
 msgid "Move target:"
-msgstr ""
+msgstr "Siirrä kohde:"
 
 #: qcsrc/menu/xonotic/dialog_monstertools.qc:26
 msgid "Follow"
-msgstr ""
+msgstr "Seuraa"
 
 #: qcsrc/menu/xonotic/dialog_monstertools.qc:27
 msgid "Wander"
-msgstr ""
+msgstr "Vaella"
 
 #: qcsrc/menu/xonotic/dialog_monstertools.qc:28
 msgid "Spawnpoint"
-msgstr ""
+msgstr "Syntymispiste"
 
 #: qcsrc/menu/xonotic/dialog_monstertools.qc:29
 msgid "No moving"
-msgstr ""
+msgstr "Ei liikkettä"
 
 #: qcsrc/menu/xonotic/dialog_monstertools.qc:31
 msgid "Colors:"
-msgstr ""
+msgstr "Värit:"
 
 #: qcsrc/menu/xonotic/dialog_monstertools.qc:33
 #: qcsrc/menu/xonotic/dialog_sandboxtools.qc:39
@@ -6365,7 +6527,7 @@ msgstr "Aseta iho:"
 
 #: qcsrc/menu/xonotic/dialog_monstertools.qh:6
 msgid "Monster Tools"
-msgstr ""
+msgstr "Hirviötyökalut"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer.qc:14
 msgid "Servers"
@@ -6373,19 +6535,19 @@ msgstr "Palvelimet"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer.qc:15
 msgid "Find servers to play on"
-msgstr ""
+msgstr "Etsi palvelimia joissa pelata"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer.qc:17
 msgid "Host your own game"
-msgstr ""
+msgstr "Isännöi oma pelisi"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer.qc:18
 msgid "Media"
-msgstr ""
+msgstr "Media"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer.qc:19
 msgid "Profile"
-msgstr ""
+msgstr "Henkilökuva"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer.qh:6
 msgid "Multiplayer"
@@ -6396,6 +6558,8 @@ msgid ""
 "Play online, against your friends in LAN, view demos or change player "
 "settings"
 msgstr ""
+"Pelaa internet-verkossa, ystäviäsi vastaan LAN-lähiverkossa, katsele demoja "
+"tai muuta pelaaja-asetuksia"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:38
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:111
@@ -6408,11 +6572,11 @@ msgstr "Perusasetus"
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:40
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Unlimited"
-msgstr ""
+msgstr "Rajoittamaton"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:74
 msgid "Gametype"
-msgstr ""
+msgstr "Pelimuoto"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:79
 msgid "Time limit:"
@@ -6420,16 +6584,16 @@ msgstr "Aikaraja"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
 msgid "Timelimit in minutes that when hit, will end the match"
-msgstr ""
+msgstr "Aikaraja minuuteissa jonka täytyttyä, päättää ottelun"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
 #, c-format
 msgid "%d minutes"
-msgstr ""
+msgstr "%d minuuttia"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
 msgid "TIMLIM^Default"
-msgstr ""
+msgstr "TIMLIM^Vakio"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:84
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:159
@@ -6438,7 +6602,7 @@ msgstr "1 minuutti"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:101
 msgid "TIMLIM^Infinite"
-msgstr ""
+msgstr "TIMLIM^Rajaton"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:109
 msgid "Teams:"
@@ -6446,15 +6610,15 @@ msgstr "Joukkueet:"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:112
 msgid "2 teams"
-msgstr ""
+msgstr "2 joukkuetta"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:113
 msgid "3 teams"
-msgstr ""
+msgstr "3 joukkuetta"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:114
 msgid "4 teams"
-msgstr ""
+msgstr "4 joukkuetta"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:117
 msgid "Player slots:"
@@ -6465,6 +6629,8 @@ msgid ""
 "The maximum amount of players or bots that can be connected to your server "
 "at once"
 msgstr ""
+"Pelaajien tai bottien enimmäismäärä jotka voivat yhdistää palvelimeesi "
+"kerralla"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:121
 msgid "Number of bots:"
@@ -6472,7 +6638,7 @@ msgstr "Bottien lukumäärä:"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:123
 msgid "Amount of bots on your server"
-msgstr ""
+msgstr "Bottien lukumäärä palvelimellasi"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:125
 msgid "Bot skill:"
@@ -6480,7 +6646,7 @@ msgstr "Bottien taitotaso:"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:128
 msgid "Specify how experienced the bots will be"
-msgstr ""
+msgstr "Määritä kuinka kokeneita haluat bottien olevan"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:129
 msgid "Botlike"
@@ -6532,49 +6698,51 @@ msgstr "Muokkaukset..."
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:156
 msgid "Mutators and weapon arenas"
-msgstr ""
+msgstr "Mutaattorit ja ase-areenat"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:165
 msgid "Maplist"
-msgstr ""
+msgstr "Karttaluettelo"
 
 #: 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 ""
+"Napsauta tässä tai Ctrl-F toimittaaksesi avainsanan kaventaaksesi "
+"karttaluetteloa. Ctrl-Delete tyhjentää; paina Enter kun kaikki valmista."
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:184
 msgid "Add shown"
-msgstr ""
+msgstr "Lisää näkyvät"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:185
 msgid "Add the maps shown in the list to your selection"
-msgstr ""
+msgstr "Lisää kartat jotka näkyvät "
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:188
 msgid "Remove shown"
-msgstr ""
+msgstr "Poista näkyvistä"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:189
 msgid "Remove the maps shown in the list from your selection"
-msgstr ""
+msgstr "Poista karttoja jotka näkyvät "
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:194
 msgid "Add all"
-msgstr ""
+msgstr "Lisää kaikki"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:195
 msgid "Add every available map to your selection"
-msgstr ""
+msgstr "Lisää kaikki tarjollaolevat kartat valintaasi"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:198
 msgid "Remove all"
-msgstr ""
+msgstr "Poista kaikki"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:199
 msgid "Remove all the maps from your selection"
-msgstr ""
+msgstr "Poista kaikki kartat valinnastasi"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:206
 msgid "Start Multiplayer!"
@@ -6626,7 +6794,7 @@ msgstr "Väistely"
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:59
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:278
 msgid "InstaGib"
-msgstr ""
+msgstr "InstaGib-hetitappo"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:61
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:221
@@ -6674,7 +6842,7 @@ msgstr "Jalat irti maasta"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:81
 msgid "Melee only"
-msgstr ""
+msgstr "Vain lähiaseet"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:85
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:229
@@ -6694,11 +6862,11 @@ msgstr "Verenvuodatus"
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:93
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:174
 msgid "Buffs"
-msgstr ""
+msgstr "Puhvit"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:95
 msgid "Overkill"
-msgstr ""
+msgstr "Ylimalkaalliset"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:97
 msgid "No powerups"
@@ -6715,7 +6883,7 @@ msgstr "Räjähtävä kosketus"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:103
 msgid "Wall jumping"
-msgstr ""
+msgstr "Seinähyppely"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:105
 msgid "MUT^None"
@@ -6727,28 +6895,33 @@ msgstr "Pelityylin muokkaukset:"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:164
 msgid "Enable dodging"
-msgstr ""
+msgstr "Ota käyttöön väistäminen"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:171
 msgid "All players are almost invisible"
-msgstr ""
+msgstr "Kaikki pelaajat ovat lähes näkymättömiä"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:179
 msgid "Only possible to inflict damage on your enemy while they're airborne"
 msgstr ""
+"Ainoa mahdollisuus aiheuttaa vahinkoa vihollisillesi on silloin kun he ovat "
+"ilmassa"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:183
 msgid "Damage done to your enemy gets added to your own health"
-msgstr ""
+msgstr "Vihollisellesi aiheutettu vahinko siirtyy lisänä omaan terveyteesi "
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:188
 msgid ""
 "Amount of health below which your player gets stunned because of blood loss"
 msgstr ""
+"Terveysmääre missä kohtaa pelaajasi menee taintumatilaan verenhukan takia"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:197
 msgid "Make things fall to the ground slower, lower value means lower gravity"
 msgstr ""
+"Laita esineet putoamaan maahan hitaammin, matalampi arvo tarkoittaa "
+"vähäisempää vetovoimaa"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:206
 msgid "Weapon & item mutators:"
@@ -6760,19 +6933,19 @@ msgstr "Köysi"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:210
 msgid "Players spawn with the grappling hook"
-msgstr ""
+msgstr "Pelaajat syntyvät heittokoukun kera"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:214
 msgid "Players spawn with the jetpack"
-msgstr ""
+msgstr "Pelaajat syntyvät lentopakkauksen kera"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:230
 msgid "Players will drop all weapons they possessed when they are killed"
-msgstr ""
+msgstr "Pelaajat pudottavat kaikki omaamansa aseet tapetuksi tullessaan "
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:235
 msgid "Weapons stay after they are picked up"
-msgstr ""
+msgstr "Aseet säilyvät poimimisen jälkeen"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:240
 msgid "Regular (no arena)"
@@ -6783,6 +6956,8 @@ msgid ""
 "Players will be given a set of weapons at spawn as well as unlimited ammo, "
 "without weapon pickups"
 msgstr ""
+"Pelaajille annetaan asevalikoima syntyessä kuten myös rajattomat ammukset, "
+"ilman asepoimintaa"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:243
 msgid "Weapon arenas:"
@@ -6790,7 +6965,7 @@ msgstr "Tietyn aseen taistelukenttä"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:246
 msgid "Custom weapons"
-msgstr ""
+msgstr "Mukautetut aseet"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:268
 msgid "Most weapons"
@@ -6811,6 +6986,11 @@ msgid ""
 "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 ""
+"Pelaajille annetaan vain yksi ase, joka voi tappaa vastustajan välittömästi "
+"yhdellä laukauksella. Mikäli pelaajalta loppuvat ammukset, saa hän 10 "
+"sekuntia aikaa löytääkseen niitä tai jos hän siinä epäonnistuu, kuolo "
+"korjaa. Toissijainen tulitus ei aiheuta ollenkaan vahinkoa mutta on kätevä "
+"temppuhyppyjen toteuttamiseen."
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:284
 msgid ""
@@ -6818,14 +6998,17 @@ msgid ""
 "weapon. After some time, a countdown will start, after which everyone will "
 "switch to another weapon."
 msgstr ""
+"Xonotic ilman esineitä - poiminnallisten esineiden sijasta, kaikki pelaavat "
+"samalla aseella. Kotvan kuluttua, lähtölaskenta alkaa, ja jonka päätyttyä "
+"jokainen vaihtaa toiseen aseeseen."
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:288
 msgid "with blaster"
-msgstr ""
+msgstr "läjäyttimellä"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:289
 msgid "Always carry the blaster as an additional weapon in Nix"
-msgstr ""
+msgstr "Läjäytin aina kannossa lisäaseen ominaisuudessa Nix:issä"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qh:9
 msgid "Mutators"
@@ -6833,7 +7016,7 @@ msgstr "Muokatut pelitilat"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:39
 msgid "SRVS^Categories"
-msgstr ""
+msgstr "SRVS^Osa-alueet"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:42
 msgid "SRVS^Empty"
@@ -6841,7 +7024,7 @@ msgstr "SRVS^Tyhjä"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:43
 msgid "Show empty servers"
-msgstr ""
+msgstr "Näytä tyhjät palvelimet"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:47
 msgid "SRVS^Full"
@@ -6849,7 +7032,7 @@ msgstr "SRVS^Täynnä"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:48
 msgid "Show full servers that have no slots available"
-msgstr ""
+msgstr "Näytä täydet palvelimet joissa ei ole pelaajapaikkoja jäljellä"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:52
 msgid "Pause"
@@ -6859,10 +7042,12 @@ msgstr "Keskeytä"
 msgid ""
 "Pause updating the server list to prevent servers from \"jumping around\""
 msgstr ""
+"Tauota palvelinluettelon päivittäminen estääksesi palvelimien \"sinne-tänne "
+"hyppelyn\""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:54
 msgid "Reload the server list"
-msgstr ""
+msgstr "Lataa palvelinluettelo uudestaan"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:68
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:184
@@ -6875,17 +7060,17 @@ msgstr "Tietoa..."
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:80
 msgid "Show more information about the currently highlighted server"
-msgstr ""
+msgstr "Näytä lisätietoja tämänhetkisestä korostetusta palvelimesta"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:85
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qh:6
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qh:6
 msgid "Disconnect"
-msgstr ""
+msgstr "Katkaise yhteys"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:86
 msgid "Disconnect from the server"
-msgstr ""
+msgstr "Katkaise yhteys palvelimeen"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join.qc:88
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:264
@@ -6895,7 +7080,7 @@ msgstr "Liity!"
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:114
 #: qcsrc/menu/xonotic/serverlist.qc:1044
 msgid "MOD^Default"
-msgstr ""
+msgstr "MOD^Vakio"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:121
 #, c-format
@@ -6948,7 +7133,7 @@ msgstr "Vaadittu (salaus onnistuu)"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:161
 msgid "Use the `crypto_aeslevel` cvar to change your preferences"
-msgstr ""
+msgstr "Käytä `crypto_aeslevel` cvar muuttaaksesi asetuksia"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.qc:178
 msgid "Hostname:"
@@ -7009,15 +7194,15 @@ msgstr "Demot"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:26
 msgid "Screenshots"
-msgstr ""
+msgstr "Kuvakaappaukset"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media.qc:27
 msgid "Music Player"
-msgstr ""
+msgstr "Musiikkisoitin"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:48
 msgid "Auto record demos"
-msgstr ""
+msgstr "Demojen automaattitallennus"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:57
 msgid "Timedemo"
@@ -7026,6 +7211,8 @@ msgstr "Aikademo"
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:58
 msgid "Benchmark how fast your computer can run the highlighted demo"
 msgstr ""
+"Toteuta mittapuu joka ilmentää kuinka nopeasti tietokoneesi pystyy ajamaan "
+"kyseistä demoa"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo.qc:62
 msgid "DEMO^Play"
@@ -7033,92 +7220,92 @@ msgstr "Pelaa"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_startconfirm.qc:13
 msgid "Playing a demo will disconnect you from the current match."
-msgstr ""
+msgstr "Demon pelaaminen katkaisee yhteytesi nykyiseen otteluun."
 
 #: 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 ""
+msgstr "Haluatko todella katkaista yhteyden nyt?"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_demo_timeconfirm.qc:13
 msgid "Timing a demo will disconnect you from the current match."
-msgstr ""
+msgstr "Demon ajastus katkaisee yhteyden tämänhetkiseen otteluun."
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:37
 msgid "MUSICPL^Add"
-msgstr ""
+msgstr "MUSICPL^Lisää"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:40
 msgid "MUSICPL^Add all"
-msgstr ""
+msgstr "MUSICPL^Lisää kaikki"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:44
 msgid "Set as menu track"
-msgstr ""
+msgstr "Aseta valikon musiikkiraidaksi"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:48
 msgid "Reset default menu track"
-msgstr ""
+msgstr "Nollaa vakiollinen valikon musiikkiraita"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:54
 msgid "Playlist:"
-msgstr ""
+msgstr "Soittolista:"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:55
 msgid "Random order"
-msgstr ""
+msgstr "Satunnainen järjestys"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:60
 msgid "MUSICPL^Stop"
-msgstr ""
+msgstr "MUSICPL^Pysäytä"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:63
 msgid "MUSICPL^Play"
-msgstr ""
+msgstr "MUSICPL^Soita"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:66
 msgid "MUSICPL^Pause"
-msgstr ""
+msgstr "MUSICPL^Tauko"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:69
 msgid "MUSICPL^Prev"
-msgstr ""
+msgstr "MUSICPL^Edell"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:72
 msgid "MUSICPL^Next"
-msgstr ""
+msgstr "MUSICPL^Seur"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:76
 msgid "MUSICPL^Remove"
-msgstr ""
+msgstr "MUSICPL^Poista"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_musicplayer.qc:79
 msgid "MUSICPL^Remove all"
-msgstr ""
+msgstr "MUSICPL^Poista kaikki"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc:41
 msgid "Auto screenshot scoreboard"
-msgstr ""
+msgstr "Automaattinen kuvakaappaus tulostaulusta"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot.qc:61
 msgid "Open in the viewer"
-msgstr ""
+msgstr "Avaa kuvankatseluohjelmassa"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc:137
 msgid "Reset"
-msgstr ""
+msgstr "Nollaa"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc:142
 msgid "Previous"
-msgstr ""
+msgstr "Edellinen"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc:145
 msgid "Next"
-msgstr ""
+msgstr "Seuraava"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_media_screenshot_viewer.qc:150
 msgid "Slide show"
-msgstr ""
+msgstr "Kuvasarja"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:38
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:21
@@ -7131,23 +7318,23 @@ msgstr "Ota heti käyttöön"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:52
 msgid "Name"
-msgstr ""
+msgstr "Nimi"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:81
 msgid "Model"
-msgstr ""
+msgstr "Malli"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:100
 msgid "Glowing color"
-msgstr ""
+msgstr "Hehkuva väri"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:110
 msgid "Detail color"
-msgstr ""
+msgstr "Yksityiskohtaväri"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:125
 msgid "Statistics"
-msgstr ""
+msgstr "Tilastot"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:129
 msgid "Allow player statistics to track your client"
@@ -7159,19 +7346,19 @@ msgstr "Salli pelaajatilastojen käyttävän pelinimeäsi"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:149
 msgid "Country"
-msgstr ""
+msgstr "Maa"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:153
 msgid "Select language..."
-msgstr ""
+msgstr "Valitse kieli..."
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:169
 msgid "Gender:"
-msgstr ""
+msgstr "Sukupuoli:"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:176
 msgid "Gender"
-msgstr ""
+msgstr "Sukupuoli"
 
 #: qcsrc/menu/xonotic/dialog_quit.qc:11
 msgid "Are you sure you want to quit?"
@@ -7179,15 +7366,15 @@ msgstr "Haluatko aivan varmasti lopettaa pelin?"
 
 #: qcsrc/menu/xonotic/dialog_quit.qc:15
 msgid "Back to work..."
-msgstr ""
+msgstr "Takaisin sorvin ääreen..."
 
 #: qcsrc/menu/xonotic/dialog_quit.qc:17
 msgid "I got some more fragging to do!"
-msgstr ""
+msgstr "Minulla on vielä hiukan lisää frägättävää!"
 
 #: qcsrc/menu/xonotic/dialog_quit.qh:7
 msgid "Quit the game"
-msgstr ""
+msgstr "Lopeta peli"
 
 #: qcsrc/menu/xonotic/dialog_sandboxtools.qc:15
 msgid "Model:"
@@ -7327,7 +7514,7 @@ msgstr "Ääni"
 
 #: qcsrc/menu/xonotic/dialog_settings.qc:22
 msgid "Game"
-msgstr ""
+msgstr "Peli"
 
 #: qcsrc/menu/xonotic/dialog_settings.qc:23
 msgid "Input"
@@ -7348,7 +7535,7 @@ msgstr "Asetukset"
 
 #: qcsrc/menu/xonotic/dialog_settings.qh:7
 msgid "Change the game settings"
-msgstr ""
+msgstr "Muuta peliasetuksia"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:29
 msgid "Master:"
@@ -7404,7 +7591,7 @@ msgstr "Taajuus:"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:107
 msgid "Sound output frequency"
-msgstr ""
+msgstr "Äänen ulostulotaajuus"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:108
 msgid "8 kHz"
@@ -7444,7 +7631,7 @@ msgstr "Kanavat:"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:121
 msgid "Number of channels for the sound output"
-msgstr ""
+msgstr "Ääniulostulon kanavien määrä"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:122
 msgid "Mono"
@@ -7480,11 +7667,11 @@ msgstr "7.1"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:134
 msgid "Swap stereo output channels"
-msgstr ""
+msgstr "Vaihda stereo-ulostulokanavat keskenään"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:135
 msgid "Swap left/right channels"
-msgstr ""
+msgstr "Vaihda kanavat vasen/oikea"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:138
 msgid "Headphone friendly mode"
@@ -7495,6 +7682,8 @@ msgid ""
 "Enable spatialization (blend the right and left channel slightly to decrease "
 "stereo separation a bit for headphones)"
 msgstr ""
+"Kytke spatialisaatio (sekoittaa inansa oikeaa ja vasempaa kanavaa "
+"vähentääkseen stereo erottelua hiukan kuulokkeita ajatellen) "
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:143
 msgid "Hit indication sound"
@@ -7502,7 +7691,7 @@ msgstr "Osumailmaisimen ääni"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:144
 msgid "Play a hit indicator sound when your shot hits an enemy"
-msgstr ""
+msgstr "Toista osumaa merkitsevä ääni laukauksesi osuessa viholliseen"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:147
 msgid "Chat message sound"
@@ -7514,15 +7703,15 @@ msgstr "Valikon äänet"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:150
 msgid "Play sounds when clicking menu items"
-msgstr ""
+msgstr "Toista ääniä kun napsauttelet valikon kohteita"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:151
 msgid "Focus sounds"
-msgstr ""
+msgstr "Kohdista äänet"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:152
 msgid "Play sounds when hovering over menu items too"
-msgstr ""
+msgstr "Toista äänet myöskin vain leijaillessa valikon kohteiden yllä"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:156
 msgid "Time announcer:"
@@ -7542,25 +7731,25 @@ msgstr "WRN^Molemmat"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:164
 msgid "Automatic taunts:"
-msgstr ""
+msgstr "Automaattiset herjaukset:"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:166
 msgid "Automatically taunt enemies after fragging them"
-msgstr ""
+msgstr "Herjaa vihulaisia automaattisesti sinun heidät frägättyäsi "
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:168
 msgid "Sometimes"
-msgstr ""
+msgstr "Aika-ajoin"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:169
 msgid "Often"
-msgstr ""
+msgstr "Usein"
 
 #: 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 ""
+msgstr "Aina"
 
 #: qcsrc/menu/xonotic/dialog_settings_audio.qc:176
 msgid "Debug info about sounds"
@@ -7568,11 +7757,11 @@ msgstr "Äänten debug info"
 
 #: qcsrc/menu/xonotic/dialog_settings_bindings_reset.qc:11
 msgid "Are you sure you want to reset all key bindings?"
-msgstr ""
+msgstr "Oletko varma että haluat nollata kaikki näppäinsidonnat?"
 
 #: qcsrc/menu/xonotic/dialog_settings_bindings_reset.qh:6
 msgid "Reset key bindings"
-msgstr ""
+msgstr "Nollaa näppäinsidonnat"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:41
 msgid "Quality preset:"
@@ -7612,7 +7801,7 @@ msgstr "Geometriset yksityiskohdat:"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:67
 msgid "Change the smoothness of the curves on the map"
-msgstr ""
+msgstr "Muuta mutkien sileyttä kartassa"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:68
 msgid "DET^Lowest"
@@ -7644,23 +7833,23 @@ msgstr "Pelaajahahmon yksityiskohtaisuus"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:79
 msgid "PDET^Low"
-msgstr ""
+msgstr "PDET^Matala"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:80
 msgid "PDET^Medium"
-msgstr ""
+msgstr "PDET^Keskisuhteinen"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:81
 msgid "PDET^Normal"
-msgstr ""
+msgstr "PDET^Tavanomainen"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:82
 msgid "PDET^Good"
-msgstr ""
+msgstr "PDET^Hyvä"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:83
 msgid "PDET^Best"
-msgstr ""
+msgstr "PDET^Paras"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:87
 msgid "Texture resolution:"
@@ -7709,6 +7898,9 @@ msgid ""
 "Disable textures completely for very slow hardware. This gives a huge "
 "performance boost, but looks very ugly."
 msgstr ""
+"Ota tekstuurit kokonaan päältä pois erittäin hitaan laitteiston ollessa "
+"käytössä. Tämä tuottaa valtavan parannuksen suorituskykyyn, mutta kaikki "
+"näyttää erittäin rumalta."
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:135
 msgid "Use lightmaps"
@@ -7719,6 +7911,8 @@ msgid ""
 "Use high resolution lightmaps, which will look pretty but use up some extra "
 "video memory"
 msgstr ""
+"Käytä korkean erottelutarkkuuden valokarttoja; näyttää sievältä mutta syöden "
+"hiukan lisää videomuistia."
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:138
 msgid "Deluxe mapping"
@@ -7726,7 +7920,7 @@ msgstr "Pikselikohtainen valaistus"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:139
 msgid "Use per-pixel lighting effects"
-msgstr ""
+msgstr "Käytä pikselikohtaisia valoefektejä"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:141
 msgid "Gloss"
@@ -7734,7 +7928,7 @@ msgstr "Kiilto"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:142
 msgid "Enable the use of glossmaps on textures supporting it"
-msgstr ""
+msgstr "Ota käyttöön tuetut hohtokartat tekstuureissa"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:145
 msgid "Offset mapping"
@@ -7745,6 +7939,9 @@ msgid ""
 "Offset mapping effect that will make textures with bumpmaps appear like they "
 "\"pop out\" of the flat 2D surface"
 msgstr ""
+"Poikkeamatyyppinen kartoitusefekti joka laittaa tekstuurit bumpmappausten "
+"kanssa näyttämään siltä kuin ne \"pompsahtaisivat ulos\" lättänästä 2D "
+"pinnasta"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:148
 msgid "Relief mapping"
@@ -7754,6 +7951,8 @@ msgstr "Tehokas tekstuurien kuhmujen korostus"
 msgid ""
 "Higher quality offset mapping, which also has a huge impact on performance"
 msgstr ""
+"Korkeampilaatuinen poikkeamatyyppinen kartoitus jolla on myös suuri vaikutus "
+"suorituskykyyn"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:152
 msgid "Reflections:"
@@ -7764,10 +7963,12 @@ msgid ""
 "Reflection and refraction quality, has a huge impact on performance on maps "
 "with reflecting surfaces"
 msgstr ""
+"Heijastusten- ja taittumien laatu; omaa suuren vaikutuksen suorituskykyn "
+"kartoissa joissa on heijastavia pintoja"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:156
 msgid "Resolution of reflections/refractions"
-msgstr ""
+msgstr "Heijastusten/taittumien erottelumääre"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:157
 msgid "Blurred"
@@ -7787,7 +7988,7 @@ msgstr "Siirtokuvat"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:164
 msgid "Enable decals (bullet holes and blood)"
-msgstr ""
+msgstr "Ota käyttöön tapahtumajäljet (luodinreijät ja verijäljet)"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:165
 msgid "Decals on models"
@@ -7800,7 +8001,7 @@ msgstr "Etäisyys:"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:172
 msgid "Decals further away than this will not be drawn"
-msgstr ""
+msgstr "Tapahtumajälkiä tätä kauempana ei piirretä "
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:176
 msgid "Time:"
@@ -7808,7 +8009,7 @@ msgstr "Kesto:"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:179
 msgid "Time in seconds before decals fade away"
-msgstr ""
+msgstr "Aika sekunneissa milloin tapahtumajäljet haihtuvat"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:183
 msgid "Damage effects:"
@@ -7816,15 +8017,15 @@ msgstr "Vahinkoefektit:"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:185
 msgid "DMGFX^Disabled"
-msgstr ""
+msgstr "DMGFX^Poispäältä"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:186
 msgid "Skeletal"
-msgstr ""
+msgstr "Luurankomainen"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:187
 msgid "DMGFX^All"
-msgstr ""
+msgstr "DMGFX^Kaikki"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:191
 msgid "No dynamic lighting"
@@ -7832,7 +8033,7 @@ msgstr "Ei dynaamista valaistusta"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:192
 msgid "Enable corona flares around certain lights"
-msgstr ""
+msgstr "Ota käyttöön pyöröheijastukset tiettyjen valojen ympärille"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:194
 msgid "Fake corona lighting"
@@ -7843,6 +8044,8 @@ msgid ""
 "Enable faster but uglier dynamic lights by rendering bright coronas instead "
 "of real dynamic lights"
 msgstr ""
+"Ota käyttöön nopeammat mutta karummat dynaamiset valot renderöimällä "
+"kirkkaat pyörövalotukset oikeiden dynaamisten valojen sijaan"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:198
 msgid "Realtime dynamic lighting"
@@ -7851,6 +8054,8 @@ msgstr "Reaaliaikainen dynaaminen valaitus"
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:199
 msgid "Enable rendering of dynamic lights such as explosions and rocket lights"
 msgstr ""
+"Ota käyttöön dynaamisten valojen renderöinti kuten räjähdykset ja rakettien "
+"valot"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:201
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:207
@@ -7859,7 +8064,7 @@ msgstr "Varjot"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:202
 msgid "Enable rendering of shadows from dynamic lights"
-msgstr ""
+msgstr "Ota käyttöön varjojen renderöinti dynaamisista valoista"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:205
 msgid "Realtime world lighting"
@@ -7870,10 +8075,13 @@ msgid ""
 "Enable rendering of full realtime world lighting on maps that support it. "
 "Note that this might have a big impact on performance."
 msgstr ""
+"Ota käyttöön kaikenkattava oikea-aikainen maailmavalaistus kartoissa jotka "
+"sitä tukevat. Huomaa että tämä vaikuttaa huomattavasti suorituskykyyn."
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:208
 msgid "Enable rendering of shadows from realtime world lights"
 msgstr ""
+"Ota käyttöön varjojen renderöinti oikea-aikaisista maailmavalotuksista "
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:212
 msgid "Use normal maps"
@@ -7881,7 +8089,7 @@ msgstr "Käytä tekstuurien suunnattua varjostamista"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:213
 msgid "Enable use of directional shading on textures"
-msgstr ""
+msgstr "Ota käyttöön suunnittainen tekstuurien vivahteikkuus"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:215
 msgid "Soft shadows"
@@ -7889,11 +8097,11 @@ msgstr "Pehmeät varjot"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:219
 msgid "Fade corona according to visibility"
-msgstr ""
+msgstr "Himmennä pyörövaloheijastusta näkyvyyteen nähden"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:220
 msgid "Fade coronas according to visibility"
-msgstr ""
+msgstr "Himmennä pyörövaloheijastuksia näkyvyyteen nähden"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:224
 msgid "Bloom"
@@ -7904,6 +8112,8 @@ msgid ""
 "Enable bloom effect, which brightens the neighboring pixels of very bright "
 "pixels. Has a big impact on performance."
 msgstr ""
+"Ota käyttöön bloom-tehoste, joka kirkastaa myös vierekkäiset pikselit hyvin "
+"kirkkaista pikseleistä. Suuri vaikutus suorituskykyyn."
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:226
 msgid "Extra postprocessing effects"
@@ -7914,10 +8124,12 @@ msgid ""
 "Enables special postprocessing effects for when damaged or under water or "
 "using a powerup"
 msgstr ""
+"Ottaa käyttöön erityiset jälkikäsittelyefektit kun otetaan vastaan vahinkoa, "
+"ollaan veden alla tai kun käytetään pikavoimistuksia"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:232
 msgid "Motion blur strength - 0.4 recommended"
-msgstr ""
+msgstr "Liikkeen utuisuuden voimakkuus - 0.4 on suositeltava"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:233
 msgid "Motion blur:"
@@ -7925,19 +8137,20 @@ msgstr "Liikesumeus:"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:239
 msgid "Particles"
-msgstr ""
+msgstr "Hiukkaset"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:240
 msgid "Spawnpoint effects"
-msgstr ""
+msgstr "Syntypiste-efektit"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:241
 msgid "Particles effects at all spawn points and whenever a player spawns"
 msgstr ""
+"Hiukkasefektit kaikilla syntymispisteillä ja aina kun pelaaja ilmestyy/syntyy"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:246
 msgid "Quality:"
-msgstr ""
+msgstr "Laatu:"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:249
 #: qcsrc/menu/xonotic/slider_particles.qc:13
@@ -7945,10 +8158,12 @@ msgid ""
 "Multiplier for amount of particles. Less means less particles, which in turn "
 "gives for better performance"
 msgstr ""
+"Hiukkasten määrän kerroin. Vähemmän tietää lukumääräisesti vähempää määrää "
+"hiukkasia, joka puolestaan johtaa parempaan suorituskykyyn"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:256
 msgid "Particles further away than this will not be drawn"
-msgstr ""
+msgstr "Tätä kauempana siintäviä hiukkasia ei piirretä"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:31
 msgid "No crosshair"
@@ -7964,12 +8179,13 @@ msgid ""
 "Set a different crosshair for each weapon, good if you play without weapon "
 "models"
 msgstr ""
+"Aseta eri tähtäin jokaiselle aseelle; on hyväksi jos pelaat ilman asemalleja"
 
 #: 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 ""
+msgstr "Koko:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:64
 msgid "By health"
@@ -8001,6 +8217,9 @@ msgid ""
 "when there's an obstacle between your gun and the target; Enemies: also "
 "enlarge the crosshair when you would hit an enemy"
 msgstr ""
+"Ei mitään: älä tee muutoksia tähtäimeen. TosiTähtäys: sumenna tähtäintä kun "
+"aseen ja kohteen välissä on este. Viholliset: isonna tähtäintä silloin kun "
+"voisit ampua osuman"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:129
 msgid "HTTST^Disabled"
@@ -8020,45 +8239,47 @@ msgstr "Sumenna tähtäin jos aseen ja kohteen välissä on este"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:140
 msgid "Enlarge crosshair if targeting an enemy"
-msgstr ""
+msgstr "Suurenna tähtäintä mikäli tähtäät vihollista kohti"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:143
 msgid "Animate crosshair when hitting an enemy"
-msgstr ""
+msgstr "Elollista tähtäin kun ammut osuman viholliseen"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qc:146
 msgid "Animate crosshair when picking up an item"
-msgstr ""
+msgstr "Elollista tähtäin poimiessasi esineen"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_crosshair.qh:7
 msgid "Crosshair"
-msgstr ""
+msgstr "Tähtäin"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:43
 msgid "Scoreboard"
-msgstr ""
+msgstr "Tulostaulu"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:48
 msgid "Fading speed:"
-msgstr ""
+msgstr "Haihtumisen nopeus:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:51
 msgid "Enable rows / columns highlighting"
-msgstr ""
+msgstr "Ota käyttöön rivien / pystysarakkaiden korostus"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:53
 msgid "Show accuracy underneath scoreboard"
-msgstr ""
+msgstr "Näytä tulostaulun alaosassa osumatarkkuus"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:55
 msgid "Show team sizes:"
-msgstr ""
+msgstr "Näytä joukkueiden koot:"
 
 #: 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 ""
+"Joukkuekoon sijainti: Pois= älä näytä. Vasen= tulostaulun vasemmassa "
+"laidassa sekä siirrä joukkuepisteet oikealle. Oikea= tulostaulun oikea laita "
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:64
 msgid "Waypoints"
@@ -8066,20 +8287,20 @@ msgstr "Välietapit"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:66
 msgid "Display waypoint markers for objectives on the map"
-msgstr ""
+msgstr "Näytä välietappien maamerkit kartan kohteille "
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:67
 msgid "Show various gametype specific waypoints"
-msgstr ""
+msgstr "Näytä useita pelimuoto-ominaisia välietappeja"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:73
 msgid "Control transparency of the waypoints"
-msgstr ""
+msgstr "Hallinnoi välietappien läpinäkyvyyttä"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:77
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:130
 msgid "Fontsize:"
-msgstr ""
+msgstr "Kirjasinkoko:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:83
 msgid "Edge offset:"
@@ -8087,15 +8308,15 @@ msgstr "Tönäisy reunasta:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:91
 msgid "Fade when near the crosshair"
-msgstr ""
+msgstr "Hämärrä kun lähellä tähtäintä"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:95
 msgid "Display names instead of icons"
-msgstr ""
+msgstr "Näytä nimet kuvakkeiden sijasta"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:100
 msgid "Damage"
-msgstr ""
+msgstr "Vahinko"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:102
 msgid "Overlay:"
@@ -8111,7 +8332,7 @@ msgstr "Sisääntulon häivennyksen kesto"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:118
 msgid "Player Names"
-msgstr ""
+msgstr "Pelaajanimet"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:120
 msgid "Show names above players"
@@ -8119,16 +8340,16 @@ msgstr "Näytä pelaajanimet hahmojen yläpuolella"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:136
 msgid "Max distance:"
-msgstr ""
+msgstr "Enimmäisetäisyys:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:142
 msgid "Decolorize:"
-msgstr ""
+msgstr "Väripoisto:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:146
 #: qcsrc/menu/xonotic/keybinder.qc:114
 msgid "Teamplay"
-msgstr ""
+msgstr "Joukkuepeli"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:154
 msgid "Only when near crosshair"
@@ -8140,19 +8361,19 @@ msgstr "Näytä elämän ja panssarin arvot"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:163
 msgid "Damage overlay:"
-msgstr ""
+msgstr "Päällys joka osoittaa vahingot:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:166
 msgid "Dynamic HUD"
-msgstr ""
+msgstr "Dynaaminen HUD"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:167
 msgid "HUD moves around following player's movement"
-msgstr ""
+msgstr "HUD liikkuu ympärillä seuraten pelaajan liikkeitä"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:169
 msgid "Shake the HUD when hurt"
-msgstr ""
+msgstr "Väristä HUD:ia kun sattuu"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qc:173
 #: qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qh:6
@@ -8161,7 +8382,7 @@ msgstr "Muokkaa näkymää"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hud.qh:7
 msgid "HUD"
-msgstr ""
+msgstr "HUD"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qc:21
 msgid "In order for the HUD editor to show, you must first be in game."
@@ -8174,153 +8395,153 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:24
 msgid "Frag Information"
-msgstr ""
+msgstr "Frägitieto"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:26
 msgid "Display information about killing sprees"
-msgstr ""
+msgstr "Näytä tiedot tappoputkista"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:29
 msgid "Only display sprees if they are achievements"
-msgstr ""
+msgstr "Näytä putket vain jos niitä saavutetaan"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:34
 msgid "Show spree information in centerprints"
-msgstr ""
+msgstr "Näytä putkitiedot keskeiskirjoituksessa"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:38
 msgid "Show spree information in death messages"
-msgstr ""
+msgstr "Näytä putkitiedot kuoloviesteissä"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:43
 msgid "Sprees in info messages:"
-msgstr ""
+msgstr "Putkitiedot tiedotusviesteissä:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:46
 msgid "SPREES^Disabled"
-msgstr ""
+msgstr "SPREES^Pois"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:47
 msgid "Target"
-msgstr ""
+msgstr "Kohde"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:48
 msgid "Attacker"
-msgstr ""
+msgstr "Hyökkääjä"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:49
 msgid "SPREES^Both"
-msgstr ""
+msgstr "SPREES^Molemmat"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:55
 msgid "Print on a seperate line"
-msgstr ""
+msgstr "Tulosta eri riveille"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:58
 msgid "Add extra frag information to centerprint when available"
-msgstr ""
+msgstr "Laita lisäfrägitiedot keskikirjoitukseen kun niitä on saatavilla"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:62
 msgid "Add frag location to death messages when available"
-msgstr ""
+msgstr "Lisää frägin sijaintitieto kuoloviesteihin kun niitä on saatavilla"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:65
 msgid "Gamemode Settings"
-msgstr ""
+msgstr "Pelimuotoasetukset"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:67
 msgid "Display capture times in Capture The Flag"
-msgstr ""
+msgstr "Näytä kaappausajat Lipunryöstössä"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:71
 msgid "Display name of flag stealer in Capture The Flag"
-msgstr ""
+msgstr "Näytä lipunvarastajan nimi Lipunryöstössä"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:76
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:92
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:133
 msgid "Other"
-msgstr ""
+msgstr "Muuta"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:78
 msgid "Display console messages in the top left corner"
-msgstr ""
+msgstr "Näytä pääteviestejä vasemmassa yläkulmassa"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:80
 msgid "Display all info messages in the chatbox"
-msgstr ""
+msgstr "Näytä kaikki tiedotusviestit keskustelulaatikossa"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:82
 msgid "Display player statuses in the chatbox"
-msgstr ""
+msgstr "Näytä pelaajatilat keskustelulaatikossa"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:86
 msgid "Powerup notifications"
-msgstr ""
+msgstr "Pikavoimistusten ilmoitukset"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:89
 msgid "Weapon centerprint notifications"
-msgstr ""
+msgstr "Aseiden ilmoitukset keskikirjoituksessa"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:92
 msgid "Weapon info message notifications"
-msgstr ""
+msgstr "Asetietoviestien ilmoitukset"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:96
 msgid "Announcers"
-msgstr ""
+msgstr "Julkistajat"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:98
 msgid "Respawn countdown sounds"
-msgstr ""
+msgstr "Uudelleensyntymislaskennan äänet"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:101
 msgid "Killstreak sounds"
-msgstr ""
+msgstr "Tapposarjan äänet"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qc:104
 msgid "Achievement sounds"
-msgstr ""
+msgstr "Saavutusäänet"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_messages.qh:7
 msgid "Messages"
-msgstr ""
+msgstr "Viestit"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:30
 msgid "Items"
-msgstr ""
+msgstr "Esineet"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:32
 msgid "Use simple 2D images instead of item models"
-msgstr ""
+msgstr "Käytä yksinkertaisia 2D-kuvia esinemallien sijasta"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:34
 msgid "Unavailable alpha:"
-msgstr ""
+msgstr "Ei saatavissa alpha:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:37
 msgid "Unavailable color:"
-msgstr ""
+msgstr "Ei paikalla -väri:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:39
 msgid "GHOITEMS^Black"
-msgstr ""
+msgstr "GHOITEMS^Musta"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:40
 msgid "GHOITEMS^Dark"
-msgstr ""
+msgstr "GHOITEMS^Tumma"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:41
 msgid "GHOITEMS^Tinted"
-msgstr ""
+msgstr "GHOITEMS^Sävytetty"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:42
 msgid "GHOITEMS^Normal"
-msgstr ""
+msgstr "GHOITEMS^Tavanomainen"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:43
 msgid "GHOITEMS^Blue"
-msgstr ""
+msgstr "GHOITEMS^Sininen"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:49
 #: qcsrc/menu/xonotic/serverlist.qc:751
@@ -8337,7 +8558,7 @@ msgstr "Pakota pelaajat samanvärisiksi"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:56
 msgid "In non teamplay modes only"
-msgstr ""
+msgstr "Vain ei-joukkuepelimuodoissa"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qc:60
 msgid "Body fading:"
@@ -8365,11 +8586,11 @@ msgstr "GIBS^Runsaasti"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qh:7
 msgid "Models"
-msgstr ""
+msgstr "Mallit"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_model.qh:8
 msgid "Customize how players and items are displayed in game"
-msgstr ""
+msgstr "Mukauta miten pelaajat ja esineet näytetään pelissä"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:26
 msgid "1st person perspective"
@@ -8377,7 +8598,7 @@ msgstr "Ensimmäisen persoonan näkymä"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:30
 msgid "Slide to third person upon death"
-msgstr ""
+msgstr "Liu'uta kolmanteen persoonaan kuollessa"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:34
 msgid "Smooth the view when landing from a jump"
@@ -8417,23 +8638,25 @@ msgstr "Näkökenttä:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:72
 msgid "Field of vision in degrees"
-msgstr ""
+msgstr "Näkökenttä asteissa"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:76
 msgid "ZOOM^Zoom factor:"
-msgstr ""
+msgstr "ZOOM^Zoomauksen kerroin:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:78
 msgid "How big the zoom factor is when the zoom button is pressed"
-msgstr ""
+msgstr "Kuinka iso zoomauksen kerroin on zoomaus-nappia painettaessa"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:81
 msgid "ZOOM^Zoom speed:"
-msgstr ""
+msgstr "ZOOM^Zoom-nopeus:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:83
 msgid "How fast the view will be zoomed, disable to zoom instantly"
 msgstr ""
+"Kuinka nopeasti näkymä zoomataan, ota pois käytöstä jotta zoom tapahtuu "
+"välittömästi"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:92
 msgid "ZOOM^Instant"
@@ -8441,46 +8664,48 @@ msgstr "ZOOM^Heti"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:96
 msgid "ZOOM^Zoom sensitivity:"
-msgstr ""
+msgstr "ZOOM^Zoom-herkkyys:"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:98
 msgid ""
 "How zoom changes sensitivity, from 0 (lower sensitivity) to 1 (no "
 "sensitivity change)"
 msgstr ""
+"Kuinka zoom kohdistaa herkkyyden kannalta, alkaen 0:sta (matalampi "
+"herkkyystaso) määreeseen 1 (ei muutosta herkkyydensäätöön)"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:101
 msgid "Velocity zoom"
-msgstr ""
+msgstr "Kiertonopeus-zoom"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:102
 msgid "Forward movement only"
-msgstr ""
+msgstr "Vain eteenpäinliike"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:106
 msgid "VZOOM^Factor"
-msgstr ""
+msgstr "VZOOM^Kerroin"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:113
 msgid "Display reticle 2D overlay while zooming"
-msgstr ""
+msgstr "Näytä 2D-päällisristikko zoomatessa"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:116
 msgid "Release zoom when you die or respawn"
-msgstr ""
+msgstr "Vapauta zoom kuollessa tai uudelleensynnyt"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qc:120
 msgid "Release zoom when you switch weapons"
-msgstr ""
+msgstr "Vapauta zoom vaihtaessasi aseita"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_view.qh:7
 #: qcsrc/menu/xonotic/keybinder.qc:85
 msgid "View"
-msgstr ""
+msgstr "Näkymä"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:34
 msgid "Weapon Priority List (* = mutator weapon)"
-msgstr ""
+msgstr "Aseiden ensisijaisuusluettelo (* = mutaattori-ase)"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:40
 msgid "Up"
@@ -8498,10 +8723,12 @@ msgstr "Käytä prioriteettiä aseiden vaihdossa"
 msgid ""
 "Make use of the list above when cycling through weapons with the mouse wheel"
 msgstr ""
+"Käytä hyväksi ylläolevaa luetteloa kun kierrät läpi asevalikoimaasi hiiren "
+"rullalla"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:53
 msgid "Cycle through only usable weapon selections"
-msgstr ""
+msgstr "Läpikäy vain käytettäviä aseita"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:57
 msgid "Auto switch weapons on pickup"
@@ -8512,10 +8739,12 @@ msgid ""
 "Automatically switch to newly picked up weapons if they are better than what "
 "you are carrying"
 msgstr ""
+"Vaihda automaattisesti tuoreeltaan poimittu ase jos se on parempi kuin mitä "
+"sillä hetkellä kannat"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:61
 msgid "Release attack buttons when you switch weapons"
-msgstr ""
+msgstr "Vapauta hyökkäysnappi vaihtaessasi aseita"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:64
 msgid "Draw 1st person weapon model"
@@ -8523,13 +8752,13 @@ msgstr "Piirrä ensimmäisen persoonan asemalli"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:65
 msgid "Draw the weapon model"
-msgstr ""
+msgstr "Piirrä asemalli"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:69
 #: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:72
 #: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:75
 msgid "Position of the weapon model; requires reconnect"
-msgstr ""
+msgstr "Asemallin sijainti; vaatii yhteyden uudelleenmuodostamisen"
 
 #: qcsrc/menu/xonotic/dialog_settings_game_weapons.qc:80
 msgid "Gun model swaying"
@@ -8542,11 +8771,11 @@ msgstr "Aseen heilunta"
 #: qcsrc/menu/xonotic/dialog_settings_game_weapons.qh:7
 #: qcsrc/menu/xonotic/keybinder.qc:51
 msgid "Weapons"
-msgstr ""
+msgstr "Aseet"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:34
 msgid "Key Bindings"
-msgstr ""
+msgstr "Näppäinsidonnat"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:38
 msgid "Change key..."
@@ -8562,11 +8791,11 @@ msgstr "Tyhjennä"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:53
 msgid "Reset all"
-msgstr ""
+msgstr "Nollaa kaikki"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:58
 msgid "Mouse"
-msgstr ""
+msgstr "Hiiri"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:60
 msgid "Sensitivity:"
@@ -8574,7 +8803,7 @@ msgstr "Herkkyys:"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:62
 msgid "Mouse speed multiplier"
-msgstr ""
+msgstr "Hiiren nopeuden moninkertaistaja"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:64
 msgid "Smooth aiming"
@@ -8583,6 +8812,7 @@ msgstr "Tähtäyksen pehmennys"
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:65
 msgid "Smoothes the mouse movement, but makes aiming slightly less responsive"
 msgstr ""
+"Pehmentää hiiriliikkeitä, mutta tekee tähtäämisen hiukan vähemmän herkäksi"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:67
 msgid "Invert aiming"
@@ -8590,11 +8820,11 @@ msgstr "Käännä hiiren suunta"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:68
 msgid "Invert mouse movement on the Y-axis"
-msgstr ""
+msgstr "Käännä hiiriliikkeet Y-akselilla"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:70
 msgid "Use system mouse positioning"
-msgstr ""
+msgstr "Käytä järjestelmän hiirenkohdistusta"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:75
 msgid "Enable built in mouse acceleration"
@@ -8608,7 +8838,7 @@ msgstr "Laita käyttöjärjestelmän hiiren kiihtyvyys pois päältä"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:80
 msgid "Make use of DGA mouse input"
-msgstr ""
+msgstr "Käytä DGA-sisääntuloa hiirelle"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:94
 msgid "Pressing \"enter console\" key also closes it"
@@ -8616,7 +8846,7 @@ msgstr "\"avaa komentorivi\" myös sulkee komentorivin"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:95
 msgid "Allow the console toggling bind to also close the console"
-msgstr ""
+msgstr "Salli päätteen esiintulon nappisidontaa myöskin päätteen sulkemiseen"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:97
 msgid "Automatically repeat jumping if holding jump"
@@ -8624,19 +8854,19 @@ msgstr "Hyppää automaattisesti uudestaan pitämällä hyppynappi painettuna"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:100
 msgid "Jetpack on jump:"
-msgstr ""
+msgstr "Lentopakkaus hypätessä:"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:102
 msgid "JPJUMP^Disabled"
-msgstr ""
+msgstr "JPJUMP^Pois"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:103
 msgid "Air only"
-msgstr ""
+msgstr "Vain ilmassa"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:104
 msgid "JPJUMP^All"
-msgstr ""
+msgstr "JPJUMP^Kaikki"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:110
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:115
@@ -8663,21 +8893,21 @@ msgstr "Käyttäjän määrittelemä näppäinasetus"
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:11
 #, c-format
 msgid "%d fps"
-msgstr ""
+msgstr "%d fps-ruudunpäivitys"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:12
 #, c-format
 msgid "%d KB/s"
-msgstr ""
+msgstr "%d Kt/s"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:13
 #, c-format
 msgid "%d MB/s"
-msgstr ""
+msgstr "%d Mt/s"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:27
 msgid "Network"
-msgstr ""
+msgstr "Verkko"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
 msgid "Client UDP port:"
@@ -8686,14 +8916,16 @@ msgstr "Asiakkaan UDP portti"
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
 msgid "Force client to use chosen port unless it is set to 0"
 msgstr ""
+"Pakota asiakasohjelma käyttämään valittua porttia ellei se ole asetettu "
+"muotoon 0"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
 msgid "Bandwidth:"
-msgstr ""
+msgstr "Kaistanleveys:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
 msgid "Specify your network speed"
-msgstr ""
+msgstr "Määritä verkkoyhteytesi nopeus"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
 msgid "56k"
@@ -8721,11 +8953,11 @@ msgstr "Vastaanottopaketit /s:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
 msgid "How many input packets to send to the server each second"
-msgstr ""
+msgstr "Montako sisääntulopakettia lähettää palvelimelle jokainen sekunti"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
 msgid "Server queries/s:"
-msgstr ""
+msgstr "Palvelinkyselyt/s:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:52
 msgid "Downloads:"
@@ -8733,11 +8965,11 @@ msgstr "Lataukset:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:54
 msgid "Maximum number of concurrent HTTP/FTP downloads"
-msgstr ""
+msgstr "Rinnakkaisten HTTP/FTP latausten enimmäismäärä"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:56
 msgid "Download speed:"
-msgstr ""
+msgstr "Latausnopeus:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:69
 msgid "Local latency:"
@@ -8749,7 +8981,7 @@ msgstr "Näytä verkkograafi"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:74
 msgid "Show a graph of packet sizes and other information"
-msgstr ""
+msgstr "Näytä pakettikokojen- ja muiden tietojen kuvaus"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:76
 msgid "Client-side movement prediction"
@@ -8761,11 +8993,11 @@ msgstr "Liikkeen virhekompensaatio"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:82
 msgid "Use encryption (AES) when available"
-msgstr ""
+msgstr "Käytä salausta (AES) kun se on saatavissa"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
 msgid "Framerate"
-msgstr ""
+msgstr "Ruudunpäivitysnopeus"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
 msgid "Maximum:"
@@ -8801,7 +9033,7 @@ msgstr "Näytä ruudunpäivitysnopeus (FPS)"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:130
 msgid "Show your rendered frames per second"
-msgstr ""
+msgstr "Näytä renderöityjen ruutujen nopeus /sekunnissa"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:135
 msgid "Menu tooltips:"
@@ -8812,6 +9044,8 @@ msgid ""
 "Menu tooltips: disabled, standard or advanced (also shows cvar or console "
 "command bound to the menu item)"
 msgstr ""
+"Valikon vihjeet: pois, vakiollinen tai edistynyt (näyttää myös cvar:in tai "
+"päätekäskyn joka on sidonnainen valikon kohteeseen)"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:138
 msgid "TLTIP^Disabled"
@@ -8827,11 +9061,13 @@ msgstr "TLTIP^Kehittynyt"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:143
 msgid "Show current date and time"
-msgstr ""
+msgstr "Näytä tämänhetkinen päivämäärä ja kellonaika"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:144
 msgid "Show current date and time of day, useful on screenshots"
 msgstr ""
+"Näytä tämänhetkinen päivämäärä ja kellonaika, käytännöllinen "
+"kuvakaappauksissa"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:147
 msgid "Enable developer mode"
@@ -8844,11 +9080,13 @@ msgstr "Edistyneet asetukset..."
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:152
 msgid "Advanced settings where you can tweak every single variable of the game"
 msgstr ""
+"Edistyneet -valikko on paikka jonka kautta voit säätää pelien jokaista osa-"
+"aluetta ja muuttujaa"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:157
 #: qcsrc/menu/xonotic/dialog_settings_misc_reset.qh:6
 msgid "Factory reset"
-msgstr ""
+msgstr "Nollaus tehdasasetuksiin"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc:31
 msgid "Cvar filter:"
@@ -8856,7 +9094,7 @@ msgstr "Cvar suodatin"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc:38
 msgid "Modified cvars only"
-msgstr ""
+msgstr "Vain mukautetut cvar:it"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc:45
 msgid "Setting:"
@@ -8880,19 +9118,19 @@ msgstr "Edistyneet asetukset"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc_reset.qc:11
 msgid "Are you sure you want to reset all settings?"
-msgstr ""
+msgstr "Oletko varma että haluat nollata kaikki asetukset?"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc_reset.qc:13
 msgid "This will create a backup config in your data directory"
-msgstr ""
+msgstr "Tämä luo varmuuskopion asetuksista data-kansioosi"
 
 #: qcsrc/menu/xonotic/dialog_settings_user.qc:25
 msgid "Menu Skins"
-msgstr ""
+msgstr "Valikon päällysteet"
 
 #: qcsrc/menu/xonotic/dialog_settings_user.qc:64
 msgid "Text Language"
-msgstr ""
+msgstr "Tekstin kieli"
 
 #: qcsrc/menu/xonotic/dialog_settings_user.qc:69
 msgid "Set language"
@@ -8905,26 +9143,30 @@ msgstr "Ota ylimitoitettu raakuus ja karski kieli pois käytöstä"
 #: qcsrc/menu/xonotic/dialog_settings_user.qc:75
 msgid "Replace blood and gibs with content that does not have any gore effects"
 msgstr ""
+"Korvaa veri ja viillokit sisällöllä joka ei sisällä mitään hurmeosastoa"
 
 #: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc:10
 msgid "While connected language changes will be applied only to the menu,"
 msgstr ""
+"Kun kieli jolla yhteys on muodostettu muutetaan, se vaikuttaa vain valikkoon"
 
 #: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc:12
 msgid "full language changes will take effect starting from the next game"
 msgstr ""
+"kielimuutos astuu voimaan kokonaisuudessaan vasta kun käynnistät seuraavan "
+"pelin"
 
 #: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc:16
 msgid "Disconnect now"
-msgstr ""
+msgstr "Katkaise yhteys nyt"
 
 #: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qc:17
 msgid "Switch language"
-msgstr ""
+msgstr "Vaihda kieli"
 
 #: qcsrc/menu/xonotic/dialog_settings_user_languagewarning.qh:6
 msgid "Warning"
-msgstr ""
+msgstr "Varoitus"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:33
 msgid "Resolution:"
@@ -8977,6 +9219,7 @@ msgstr "Värisävy:"
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:53
 msgid "How many bits per pixel (BPP) to render at, 32 is recommended"
 msgstr ""
+"Montako tavua pikseliä kohden (BPP) renderöitäväksi; 32 on suositeltava määrä"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:54
 msgid "16bit"
@@ -8999,6 +9242,8 @@ msgid ""
 "Enable vertical synchronization to prevent tearing, will cap your fps to the "
 "screen refresh rate"
 msgstr ""
+"Ota käyttöön pystysuuntainen yhdenmukaistus välttääksesi ruuturevintää, "
+"rajaa ruudunpäivitystä virkistystaajuuteen nähden"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:67
 msgid "Flip view horizontally"
@@ -9006,7 +9251,7 @@ msgstr "Käännä näkymä horisontaalisesti"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:68
 msgid "Poor man's left handed mode"
-msgstr ""
+msgstr "Köyhänmiehen vasenkäsi -tila"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:71
 msgid "Anisotropy:"
@@ -9014,7 +9259,7 @@ msgstr "Anisotropia:"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:73
 msgid "Anisotropic filtering quality"
-msgstr ""
+msgstr "Anisotrooppisen suodatuksen laatu"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:74
 msgid "ANISO^Disabled"
@@ -9047,6 +9292,8 @@ msgid ""
 "Enable antialiasing, which smooths the edges of 3D geometry. Note that it "
 "might decrease performance by quite a lot"
 msgstr ""
+"Kytke päälle anti-aliasing, joka pehmentää 3D-geometrisiä reunoja. Huomaa, "
+"että tämä saattaa alentaa suorituskykyä melkoisesti"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:85
 msgid "AA^Disabled"
@@ -9065,6 +9312,8 @@ msgid ""
 "Eliminate overdraw by rendering a depth-only version of the scene before the "
 "normal rendering starts"
 msgstr ""
+"Poista ylipiirräntä renderöimällä vain-syvyys version kohtauksesta ennen "
+"kuin tavanomainen renderöinti alkaa"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:100
 msgid "DF^Disabled"
@@ -9097,6 +9346,8 @@ msgid ""
 "Make use of Vertex Buffer Objects to store static geometry in video memory "
 "for faster rendering"
 msgstr ""
+"Ota käyttöön Vertex Buffer Objects varastoidaksesi staattista geometriaa "
+"videomuistiin nopeampaa renderöintiä varten"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:113
 msgid "Vertices"
@@ -9112,7 +9363,7 @@ msgstr "Kirkkaus:"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:121
 msgid "Brightness of black"
-msgstr ""
+msgstr "Mustan kirkkaus"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:123
 msgid "Contrast:"
@@ -9120,7 +9371,7 @@ msgstr "Kontrasti:"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "Brightness of white"
-msgstr ""
+msgstr "Valkoisen kirkkaus"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:127
 msgid "Gamma:"
@@ -9131,6 +9382,8 @@ msgid ""
 "Inverse gamma correction value, a brightness effect that does not affect "
 "white or black"
 msgstr ""
+"Käännä gamma-kirkkauden korjausmääre, kirkkausefekti joka ei vaikuta "
+"valkoiseen tai mustaan"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:133
 msgid "Contrast boost:"
@@ -9138,7 +9391,7 @@ msgstr "Kontrastin lisäys:"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:136
 msgid "By how much to multiply the contrast in dark areas"
-msgstr ""
+msgstr "Monellako kontrasti kerrotaan tummilla alueilla"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:139
 msgid "Saturation:"
@@ -9149,6 +9402,8 @@ msgid ""
 "Saturation adjustment (0 = grayscale, 1 = normal, 2 = oversaturated), "
 "requires GLSL color control"
 msgstr ""
+"Kylläisyyden säätö (0 = harmaasävy, 1 = tavallinen, 2 = ylikylläinen), "
+"vaatii GLSL-värihallinnan"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:146
 msgid "LIT^Ambient:"
@@ -9159,6 +9414,8 @@ msgid ""
 "Ambient lighting, if set too high it tends to make light on maps look dull "
 "and flat"
 msgstr ""
+"Ympäröivä valaistus; mikäli asetettu liian korkeaksi, se tapaa tehdä kartan "
+"valot tylsiksi ja tasapaksuiksi"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:150
 msgid "Intensity:"
@@ -9166,7 +9423,7 @@ msgstr "Intensiivisyys:"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:152
 msgid "Global rendering brightness"
-msgstr ""
+msgstr "Yleismaailmallisen renderöinnin kirkkaus"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:155
 msgid "Wait for GPU to finish each frame"
@@ -9177,6 +9434,9 @@ 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 ""
+"Laita suoritin odottamaan näytönohjainta viimeistelläkseen jokaisen "
+"kehyksen; voi auttaa joissakin oudoissa sisääntulo tai videon "
+"laahaamisongelmissa joillakin kokoonpanoilla"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:158
 msgid "Use OpenGL 2.0 shaders (GLSL)"
@@ -9191,6 +9451,8 @@ msgid ""
 "Enable use of GLSL to apply gamma correction, note that it might decrease "
 "performance by a lot"
 msgstr ""
+"Ota käyttöön GLSL toteuttaaksesi gamma-kirkkauskorjauksen, huomaa että tämä "
+"saattaa alentaa suorituskykyä huomattavasti"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:168
 msgid "Psycho coloring (easter egg)"
@@ -9235,6 +9497,8 @@ msgstr "Yksinpeli"
 #: qcsrc/menu/xonotic/dialog_singleplayer.qh:7
 msgid "Play the singleplayer campaign or instant action matches against bots"
 msgstr ""
+"Pelaa yksinpeli-kampanja tai välitön toiminnantäyteinen ottelu botteja "
+"vastaan"
 
 #: qcsrc/menu/xonotic/dialog_singleplayer_winner.qh:7
 msgid "Winner"
@@ -9246,7 +9510,7 @@ msgstr "liity 'parhaimpaan' joukkueeseen"
 
 #: qcsrc/menu/xonotic/dialog_teamselect.qc:33
 msgid "Autoselect team (recommended)"
-msgstr ""
+msgstr "Joukkueen automaattivalinta (suositeltava)"
 
 #: qcsrc/menu/xonotic/dialog_teamselect.qc:37
 msgid "red"
@@ -9274,179 +9538,179 @@ msgstr "Joukkueen valinta"
 
 #: qcsrc/menu/xonotic/dialog_uid2name.qc:10
 msgid "Allow player statistics to use your nickname?"
-msgstr ""
+msgstr "Salli pelaajatilastojen käyttää lempinimeäsi?"
 
 #: qcsrc/menu/xonotic/dialog_uid2name.qc:12
 msgid "Answering \"No\" you will appear as \"Anonymous player\""
-msgstr ""
+msgstr "Vastaamalla \"Ei\" näyt muodossa \"Nimetön pelaaja\""
 
 #: qcsrc/menu/xonotic/gametypelist.qc:87
 msgid "teamplay"
-msgstr ""
+msgstr "joukkuepeli"
 
 #: qcsrc/menu/xonotic/gametypelist.qc:89
 msgid "free for all"
-msgstr ""
+msgstr "kaikille vapaa"
 
 #: qcsrc/menu/xonotic/keybinder.qc:35
 msgid "Moving"
-msgstr ""
+msgstr "Liikkeet"
 
 #: qcsrc/menu/xonotic/keybinder.qc:36
 msgid "forward"
-msgstr ""
+msgstr "eteenpäin"
 
 #: qcsrc/menu/xonotic/keybinder.qc:37
 msgid "backpedal"
-msgstr ""
+msgstr "taakse"
 
 #: qcsrc/menu/xonotic/keybinder.qc:38
 msgid "strafe left"
-msgstr ""
+msgstr "askella vasemmalle"
 
 #: qcsrc/menu/xonotic/keybinder.qc:39
 msgid "strafe right"
-msgstr ""
+msgstr "askella oikealle"
 
 #: qcsrc/menu/xonotic/keybinder.qc:40
 msgid "jump / swim"
-msgstr ""
+msgstr "hyppää / ui"
 
 #: qcsrc/menu/xonotic/keybinder.qc:41
 msgid "crouch / sink"
-msgstr ""
+msgstr "kyykisty / uppoa"
 
 #: qcsrc/menu/xonotic/keybinder.qc:42
 msgid "off-hand hook"
-msgstr ""
+msgstr "toisenkäden koukku"
 
 #: qcsrc/menu/xonotic/keybinder.qc:43
 msgid "jetpack"
-msgstr ""
+msgstr "lentopakkaus"
 
 #: qcsrc/menu/xonotic/keybinder.qc:46
 msgid "Attacking"
-msgstr ""
+msgstr "Hyökkääminen"
 
 #: qcsrc/menu/xonotic/keybinder.qc:52
 msgid "WEAPON^previous"
-msgstr ""
+msgstr "ASE^edellinen"
 
 #: qcsrc/menu/xonotic/keybinder.qc:53
 msgid "WEAPON^next"
-msgstr ""
+msgstr "ASE^seuraava"
 
 #: qcsrc/menu/xonotic/keybinder.qc:54
 msgid "WEAPON^previously used"
-msgstr ""
+msgstr "ASE^aiemmin käytetty"
 
 #: qcsrc/menu/xonotic/keybinder.qc:55
 msgid "WEAPON^best"
-msgstr ""
+msgstr "ASE^paras"
 
 #: qcsrc/menu/xonotic/keybinder.qc:56
 msgid "reload"
-msgstr ""
+msgstr "lataa uudelleen"
 
 #: qcsrc/menu/xonotic/keybinder.qc:57
 msgid "drop weapon / throw nade"
-msgstr ""
+msgstr "pudota ase / heitä naatti"
 
 #: qcsrc/menu/xonotic/keybinder.qc:86
 msgid "hold zoom"
-msgstr ""
+msgstr "pidä zoom paikallaan"
 
 #: qcsrc/menu/xonotic/keybinder.qc:87
 msgid "toggle zoom"
-msgstr ""
+msgstr "zoom-kytkin"
 
 #: qcsrc/menu/xonotic/keybinder.qc:88
 msgid "show scores"
-msgstr ""
+msgstr "näytä pisteet"
 
 #: qcsrc/menu/xonotic/keybinder.qc:89
 msgid "screen shot"
-msgstr ""
+msgstr "kuvakaappaus"
 
 #: qcsrc/menu/xonotic/keybinder.qc:90
 msgid "maximize radar"
-msgstr ""
+msgstr "suurenna tutka"
 
 #: qcsrc/menu/xonotic/keybinder.qc:91
 msgid "3rd person view"
-msgstr ""
+msgstr "näkymä 3:ssa persoonassa"
 
 #: qcsrc/menu/xonotic/keybinder.qc:92
 msgid "enter spectator mode"
-msgstr ""
+msgstr "käynnistä katsojatila"
 
 #: qcsrc/menu/xonotic/keybinder.qc:95
 msgid "Communicate"
-msgstr ""
+msgstr "Keskustele"
 
 #: qcsrc/menu/xonotic/keybinder.qc:96
 msgid "public chat"
-msgstr ""
+msgstr "julkinen chat-keskustelu"
 
 #: qcsrc/menu/xonotic/keybinder.qc:97 qcsrc/menu/xonotic/keybinder.qc:115
 msgid "team chat"
-msgstr ""
+msgstr "joukkue-chat-keskustelu"
 
 #: qcsrc/menu/xonotic/keybinder.qc:98
 msgid "show chat history"
-msgstr ""
+msgstr "näytä keskusteluhistoria"
 
 #: qcsrc/menu/xonotic/keybinder.qc:99
 msgid "vote YES"
-msgstr ""
+msgstr "äänestä KYLLÄ"
 
 #: qcsrc/menu/xonotic/keybinder.qc:100
 msgid "vote NO"
-msgstr ""
+msgstr "äänestä EI"
 
 #: qcsrc/menu/xonotic/keybinder.qc:104
 msgid "Client"
-msgstr ""
+msgstr "Asiakasohjelma"
 
 #: qcsrc/menu/xonotic/keybinder.qc:108
 msgid "enter console"
-msgstr ""
+msgstr "käynnistä pääte"
 
 #: qcsrc/menu/xonotic/keybinder.qc:110
 msgid "disconnect"
-msgstr ""
+msgstr "katkaise yhteys"
 
 #: qcsrc/menu/xonotic/keybinder.qc:111
 msgid "quit"
-msgstr ""
+msgstr "lopeta"
 
 #: qcsrc/menu/xonotic/keybinder.qc:116
 msgid "auto-join team"
-msgstr ""
+msgstr "liity joukkueeseen automaattisesti"
 
 #: qcsrc/menu/xonotic/keybinder.qc:118
 msgid "drop key / drop flag"
-msgstr ""
+msgstr "pudota avain / puodta lippu"
 
 #: qcsrc/menu/xonotic/keybinder.qc:122
 msgid "respawn"
-msgstr ""
+msgstr "uudelleensynty"
 
 #: qcsrc/menu/xonotic/keybinder.qc:123
 msgid "quick menu"
-msgstr ""
+msgstr "pikavalikko"
 
 #: qcsrc/menu/xonotic/keybinder.qc:124
 msgid "sandbox menu"
-msgstr ""
+msgstr "rajattu hiekkalaatikkovalikko"
 
 #: qcsrc/menu/xonotic/keybinder.qc:125
 msgid "drag object"
-msgstr ""
+msgstr "raahaa kohde"
 
 #: qcsrc/menu/xonotic/keybinder.qc:128
 msgid "User defined"
-msgstr ""
+msgstr "Käyttäjän määrittämä"
 
 #: qcsrc/menu/xonotic/mainwindow.qc:65 qcsrc/menu/xonotic/mainwindow.qc:68
 msgid "Do not press this button again!"
@@ -9456,6 +9720,8 @@ msgstr "Älä paina enää näppäintä!"
 msgid ""
 "Huh? Can't play this (m is NULL). Refiltering so this won't happen again."
 msgstr ""
+"Täh? Tätä ei voi pelata (m on NULL-tyhjiö). Uudelleensuodatetaan jotta näin "
+"ei tapahtuisi enää."
 
 #: qcsrc/menu/xonotic/maplist.qc:296
 #, c-format
@@ -9467,6 +9733,8 @@ msgid ""
 "Huh? Can't play this (invalid game type). Refiltering so this won't happen "
 "again."
 msgstr ""
+"Täh? Tätä ei voi pelata (epäkelpo pelityyppi). Uudelleensuodatetaan jotta "
+"näin ei tapahtuisi enää."
 
 #: qcsrc/menu/xonotic/playerlist.qc:102 qcsrc/menu/xonotic/playerlist.qc:112
 msgid "spectator"
@@ -9478,13 +9746,15 @@ msgstr "<mallia ei löytynyt>"
 
 #: qcsrc/menu/xonotic/serverlist.qc:267
 msgid "Favorite"
-msgstr ""
+msgstr "Lemppari"
 
 #: qcsrc/menu/xonotic/serverlist.qc:268
 msgid ""
 "Bookmark the currently highlighted server so that it's faster to find in the "
 "future"
 msgstr ""
+"Laita kirjanmerkiksi tämänhetkinen korostettu palvelin jotta se on nopeampi "
+"löytää tulevassa"
 
 #: qcsrc/menu/xonotic/serverlist.qc:747
 msgid "Ping"
@@ -9492,7 +9762,7 @@ msgstr "Viive"
 
 #: qcsrc/menu/xonotic/serverlist.qc:748
 msgid "Hostname"
-msgstr ""
+msgstr "Palvelinnimi"
 
 #: qcsrc/menu/xonotic/serverlist.qc:749
 msgid "Map"
@@ -9505,74 +9775,74 @@ msgstr "Tyyppi"
 #: qcsrc/menu/xonotic/serverlist.qc:1043
 #, c-format
 msgid "AES level %d"
-msgstr ""
+msgstr "AES taso %d"
 
 #: qcsrc/menu/xonotic/serverlist.qc:1043
 msgid "ENC^none"
-msgstr ""
+msgstr "ENC^ei mikään"
 
 #: qcsrc/menu/xonotic/serverlist.qc:1043
 msgid "encryption:"
-msgstr ""
+msgstr "salaus:"
 
 #: qcsrc/menu/xonotic/serverlist.qc:1044
 #, c-format
 msgid "mod: %s"
-msgstr ""
+msgstr "modi: %s"
 
 #: qcsrc/menu/xonotic/serverlist.qc:1046
 #, c-format
 msgid "modified settings"
-msgstr ""
+msgstr "mukautetut asetukset"
 
 #: qcsrc/menu/xonotic/serverlist.qc:1046
 #, c-format
 msgid "official settings"
-msgstr ""
+msgstr "viralliset asetukset"
 
 #: qcsrc/menu/xonotic/serverlist.qc:1048
 msgid "stats disabled"
-msgstr ""
+msgstr "tilastot pois päältä"
 
 #: qcsrc/menu/xonotic/serverlist.qc:1048
 msgid "stats enabled"
-msgstr ""
+msgstr "tilastot päällä"
 
 #: qcsrc/menu/xonotic/serverlist.qh:152
 msgid "SLCAT^Favorites"
-msgstr ""
+msgstr "SLCAT^Lempparit"
 
 #: qcsrc/menu/xonotic/serverlist.qh:153
 msgid "SLCAT^Recommended"
-msgstr ""
+msgstr "SLCAT^Suositellut"
 
 #: qcsrc/menu/xonotic/serverlist.qh:154
 msgid "SLCAT^Normal Servers"
-msgstr ""
+msgstr "SLCAT^Tavalliset palvelimet"
 
 #: qcsrc/menu/xonotic/serverlist.qh:155
 msgid "SLCAT^Servers"
-msgstr ""
+msgstr "SLCAT^Palvelimet"
 
 #: qcsrc/menu/xonotic/serverlist.qh:156
 msgid "SLCAT^Competitive Mode"
-msgstr ""
+msgstr "SLCAT^Kilpailullinen tila"
 
 #: qcsrc/menu/xonotic/serverlist.qh:157
 msgid "SLCAT^Modified Servers"
-msgstr ""
+msgstr "SLCAT^Mukautetut palvelimet"
 
 #: qcsrc/menu/xonotic/serverlist.qh:158
 msgid "SLCAT^Overkill"
-msgstr ""
+msgstr "SLCAT^Ylimalkaalliset"
 
 #: qcsrc/menu/xonotic/serverlist.qh:159
 msgid "SLCAT^InstaGib"
-msgstr ""
+msgstr "SLCAT^InstaGib-hetitappo"
 
 #: qcsrc/menu/xonotic/serverlist.qh:160
 msgid "SLCAT^Defrag Mode"
-msgstr ""
+msgstr "SLCAT^Epäfrägitila"
 
 #: qcsrc/menu/xonotic/skinlist.qc:70
 msgid "<TITLE>"
@@ -9597,165 +9867,167 @@ msgstr "%s dB"
 
 #: qcsrc/menu/xonotic/slider_particles.qc:14
 msgid "PART^OMG"
-msgstr ""
+msgstr "PART^OMG"
 
 #: qcsrc/menu/xonotic/slider_particles.qc:15
 msgid "PART^Low"
-msgstr ""
+msgstr "PART^Matala"
 
 #: qcsrc/menu/xonotic/slider_particles.qc:16
 msgid "PART^Medium"
-msgstr ""
+msgstr "PART^Keskisuhta"
 
 #: qcsrc/menu/xonotic/slider_particles.qc:17
 #: qcsrc/menu/xonotic/slider_sbfadetime.qc:14
 msgid "PART^Normal"
-msgstr ""
+msgstr "PART^Tavallinen"
 
 #: qcsrc/menu/xonotic/slider_particles.qc:18
 msgid "PART^High"
-msgstr ""
+msgstr "PART^Korkea"
 
 #: qcsrc/menu/xonotic/slider_particles.qc:19
 msgid "PART^Ultra"
-msgstr ""
+msgstr "PART^Mahtava"
 
 #: qcsrc/menu/xonotic/slider_particles.qc:20
 msgid "PART^Ultimate"
-msgstr ""
+msgstr "PART^Jumalainen"
 
 #: 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 ""
+"Muuta päällysteiden terävyyttä. Alennus vähentää tehokkaasti muistikäyttöä, "
+"mutta saa päällysteet näyttämään hyvin sumuisilta."
 
 #: qcsrc/menu/xonotic/slider_resolution.qc:115
 msgid "Screen resolution"
-msgstr ""
+msgstr "Näytön tarkkuus"
 
 #: qcsrc/menu/xonotic/slider_sbfadetime.qc:13
 msgid "PART^Slow"
-msgstr ""
+msgstr "PART^Hidas"
 
 #: qcsrc/menu/xonotic/slider_sbfadetime.qc:15
 msgid "PART^Fast"
-msgstr ""
+msgstr "PART^Nopea"
 
 #: qcsrc/menu/xonotic/slider_sbfadetime.qc:16
 msgid "PART^Instant"
-msgstr ""
+msgstr "PART^Välitön"
 
 #: qcsrc/menu/xonotic/statslist.qc:29
 msgid "January"
-msgstr ""
+msgstr "Tammikuu"
 
 #: qcsrc/menu/xonotic/statslist.qc:30
 msgid "February"
-msgstr ""
+msgstr "Helmikuu"
 
 #: qcsrc/menu/xonotic/statslist.qc:31
 msgid "March"
-msgstr ""
+msgstr "Maaliskuu"
 
 #: qcsrc/menu/xonotic/statslist.qc:32
 msgid "April"
-msgstr ""
+msgstr "Huhtikuu"
 
 #: qcsrc/menu/xonotic/statslist.qc:33
 msgid "May"
-msgstr ""
+msgstr "Toukokuu"
 
 #: qcsrc/menu/xonotic/statslist.qc:34
 msgid "June"
-msgstr ""
+msgstr "Kesäkuu"
 
 #: qcsrc/menu/xonotic/statslist.qc:35
 msgid "July"
-msgstr ""
+msgstr "Heinäkuu"
 
 #: qcsrc/menu/xonotic/statslist.qc:36
 msgid "August"
-msgstr ""
+msgstr "Elokuu"
 
 #: qcsrc/menu/xonotic/statslist.qc:37
 msgid "September"
-msgstr ""
+msgstr "Syyskuu"
 
 #: qcsrc/menu/xonotic/statslist.qc:38
 msgid "October"
-msgstr ""
+msgstr "Lokakuu"
 
 #: qcsrc/menu/xonotic/statslist.qc:39
 msgid "November"
-msgstr ""
+msgstr "Marraskuu"
 
 #: qcsrc/menu/xonotic/statslist.qc:40
 msgid "December"
-msgstr ""
+msgstr "Joulukuu"
 
 #: qcsrc/menu/xonotic/statslist.qc:96
 msgid "Joined:"
-msgstr ""
+msgstr "Liittyi:"
 
 #: qcsrc/menu/xonotic/statslist.qc:103
 msgid "Last match:"
-msgstr ""
+msgstr "Viimeisin ottelu:"
 
 #: qcsrc/menu/xonotic/statslist.qc:110
 msgid "Time played:"
-msgstr ""
+msgstr "Peliaika:"
 
 #: qcsrc/menu/xonotic/statslist.qc:117 qcsrc/menu/xonotic/statslist.qc:230
 msgid "Favorite map:"
-msgstr ""
+msgstr "Lempikartta:"
 
 #: qcsrc/menu/xonotic/statslist.qc:149 qcsrc/menu/xonotic/statslist.qc:201
 #: qcsrc/menu/xonotic/statslist.qc:244
 #, c-format
 msgid "Matches:"
-msgstr ""
+msgstr "Ottelut:"
 
 #: qcsrc/menu/xonotic/statslist.qc:154
 #, c-format
 msgid "Wins/Losses:"
-msgstr ""
+msgstr "Voitot/Tappiot"
 
 #: qcsrc/menu/xonotic/statslist.qc:155
 #, c-format
 msgid "Win percentage:"
-msgstr ""
+msgstr "Voittoprosentti:"
 
 #: qcsrc/menu/xonotic/statslist.qc:166
 #, c-format
 msgid "Kills/Deaths:"
-msgstr ""
+msgstr "Tapot/Kuolemat"
 
 #: qcsrc/menu/xonotic/statslist.qc:172
 #, c-format
 msgid "Kill ratio:"
-msgstr ""
+msgstr "Tapposuhde:"
 
 #: qcsrc/menu/xonotic/statslist.qc:207
 msgid "ELO:"
-msgstr ""
+msgstr "ELO:"
 
 #: qcsrc/menu/xonotic/statslist.qc:214
 msgid "Rank:"
-msgstr ""
+msgstr "Rankkaustaso:"
 
 #: qcsrc/menu/xonotic/statslist.qc:221
 msgid "Percentile:"
-msgstr ""
+msgstr "Prosenttipiste:"
 
 #: qcsrc/menu/xonotic/statslist.qc:246
 #, c-format
 msgid "%d (unranked)"
-msgstr ""
+msgstr "%d (ei rankattu)"
 
 #: qcsrc/menu/xonotic/util.qc:417
 msgid "Update can be downloaded at:"
-msgstr ""
+msgstr "Päivitys ladattavissa osoitteessa:"
 
 #: qcsrc/menu/xonotic/util.qc:525
 msgid "Autogenerating mapinfo for newly added maps..."
@@ -9777,6 +10049,8 @@ msgid ""
 "^1ERROR: Texture compression is required but not supported.\n"
 "^1Expect visual problems."
 msgstr ""
+"^1VIRHE: Tekstuuripakkaus vaaditaan mutta se ei ole tuettuna.\n"
+"^1Odotettavissa graafisia virheitä."
 
 #: qcsrc/menu/xonotic/util.qc:788
 msgid "Use default"
index ee357ff605160effe8a34046d3ac77053a7a4cb6..6cbefcfb800d1d9d228008929860ea63fff2122a 100644 (file)
@@ -4,14 +4,15 @@
 #
 # Translators:
 # nad le <nadavlevi726@gmail.com>, 2018
+# Roi Asher Gerszkoviez <gerszkoviez@gmail.com>, 2020
 # Tal Leibman <leibman2@gmail.com>, 2019
 msgid ""
 msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2019-05-19 07:23+0200\n"
-"PO-Revision-Date: 2019-05-19 05:23+0000\n"
-"Last-Translator: divVerent <divVerent@xonotic.org>\n"
+"PO-Revision-Date: 2020-03-05 22:01+0000\n"
+"Last-Translator: Roi Asher Gerszkoviez <gerszkoviez@gmail.com>\n"
 "Language-Team: Hebrew (http://www.transifex.com/team-xonotic/xonotic/"
 "language/he/)\n"
 "Language: he\n"
@@ -46,24 +47,24 @@ msgstr ""
 #: qcsrc/client/hud/panel/centerprint.qc:144
 #, c-format
 msgid "Message at time %s"
-msgstr ""
+msgstr "הודעה בזמן %s"
 
 #: qcsrc/client/hud/panel/centerprint.qc:149
 msgid "Generic message"
-msgstr ""
+msgstr "הודעה גנרית"
 
 #: qcsrc/client/hud/panel/chat.qc:84
 msgid "^3Player^7: This is the chat area."
-msgstr ""
+msgstr "^3שחקן^7: זהו אזור הצ'אט."
 
 #: qcsrc/client/hud/panel/engineinfo.qc:72
 #, c-format
 msgid "FPS: %.*f"
-msgstr ""
+msgstr "FPS: %.*f"
 
 #: qcsrc/client/hud/panel/infomessages.qc:89
 msgid "^1Observing"
-msgstr ""
+msgstr "^1משקיף"
 
 #: qcsrc/client/hud/panel/infomessages.qc:91
 #, c-format
@@ -73,7 +74,7 @@ msgstr ""
 #: qcsrc/client/hud/panel/infomessages.qc:102
 #, c-format
 msgid "^1Press ^3%s^1 to spectate"
-msgstr ""
+msgstr "^1לחץ ^3%s^1 כדי להשקיף"
 
 #: qcsrc/client/hud/panel/infomessages.qc:102
 #: qcsrc/menu/xonotic/keybinder.qc:47
@@ -88,12 +89,12 @@ msgstr ""
 #: qcsrc/client/hud/panel/infomessages.qc:104
 #: qcsrc/client/hud/panel/infomessages.qc:108
 msgid "next weapon"
-msgstr "נשק הבא"
+msgstr "×\94נשק ×\94×\91×\90"
 
 #: qcsrc/client/hud/panel/infomessages.qc:104
 #: qcsrc/client/hud/panel/infomessages.qc:108
 msgid "previous weapon"
-msgstr "נשק קודם"
+msgstr "×\94נשק ×\94קודם"
 
 #: qcsrc/client/hud/panel/infomessages.qc:108
 #, c-format
@@ -108,7 +109,7 @@ msgstr ""
 #: qcsrc/client/hud/panel/infomessages.qc:110
 #: qcsrc/common/vehicles/cl_vehicles.qc:190
 msgid "drop weapon"
-msgstr ""
+msgstr "זרוק נשק"
 
 #: qcsrc/client/hud/panel/infomessages.qc:110
 #: qcsrc/menu/xonotic/keybinder.qc:48
@@ -233,18 +234,18 @@ msgstr ""
 #: qcsrc/client/hud/panel/score.qc:63
 #, c-format
 msgid "Player %d"
-msgstr ""
+msgstr "שחקן %d"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:591
 #: qcsrc/client/hud/panel/quickmenu.qc:593
 #, c-format
 msgid "Submenu%d"
-msgstr ""
+msgstr "תת-תפריט%d"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:598
 #, c-format
 msgid "Command%d"
-msgstr ""
+msgstr "פקודה%d"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:624
 msgid "Continue..."
@@ -253,11 +254,11 @@ msgstr "המשך..."
 #: qcsrc/client/hud/panel/quickmenu.qc:781
 #: qcsrc/client/hud/panel/quickmenu.qc:788
 msgid "Chat"
-msgstr ""
+msgstr "צ'אט"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:782
 msgid "QMCMD^Send public message to"
-msgstr ""
+msgstr "QMCMD^שלח הודעה פומבית אל"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:783
 msgid "QMCMD^:-) / nice one"
@@ -5951,15 +5952,15 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:52
 msgid "m/s"
-msgstr ""
+msgstr "מ\"ש"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:53
 msgid "km/h"
-msgstr ""
+msgstr "קמ\"ש"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:54
 msgid "mph"
-msgstr ""
+msgstr "מייל לשעה"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:55
 msgid "knots"
@@ -5971,11 +5972,11 @@ msgstr "הצג"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:60
 msgid "Top speed"
-msgstr ""
+msgstr "מהירות מקסימלית"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:66
 msgid "Acceleration:"
-msgstr ""
+msgstr "האצה:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_physics.qc:67
 msgid "Include vertical acceleration"
@@ -6061,23 +6062,23 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:44
 msgid "Zoom mode:"
-msgstr ""
+msgstr "מצב זום:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:46
 msgid "Zoomed in"
-msgstr ""
+msgstr "זום אין"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:47
 msgid "Zoomed out"
-msgstr ""
+msgstr "זום אאוט"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:48
 msgid "Always zoomed"
-msgstr ""
+msgstr "תמיד בזום"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_radar.qc:49
 msgid "Never zoomed"
-msgstr ""
+msgstr "לעולם לא בזום"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_radar.qh:6
 msgid "Radar Panel"
@@ -6154,7 +6155,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:34
 msgid "Alpha"
-msgstr ""
+msgstr "אלפא"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:35
 msgid "Slide"
@@ -6194,23 +6195,23 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:66
 msgid "Show Accuracy"
-msgstr ""
+msgstr "הצג דיוק"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:67
 msgid "Show Ammo"
-msgstr ""
+msgstr "הצג תחמושת"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:70
 msgid "Ammo bar alpha:"
-msgstr ""
+msgstr "אלפא של סרגל התחמושת:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:76
 msgid "Ammo bar color:"
-msgstr ""
+msgstr "צבע סרגל התחמושת:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qh:6
 msgid "Weapons Panel"
-msgstr ""
+msgstr "פאנל הנשקים"
 
 #: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:19
 msgid "HUD skins"
@@ -6406,7 +6407,7 @@ msgstr "ברירת מחדל"
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:40
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:64
 msgid "Unlimited"
-msgstr "×\9c×\90 מוגבל"
+msgstr "×\91×\9cת×\99 מוגבל"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:74
 msgid "Gametype"
@@ -8609,11 +8610,11 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:94
 msgid "Pressing \"enter console\" key also closes it"
-msgstr ""
+msgstr "כפתור \"כניסה לקונסול\" גם סוגר אותו"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:95
 msgid "Allow the console toggling bind to also close the console"
-msgstr ""
+msgstr "אפשר לכפתור שפותח את הקונסול גם לסגור אותו"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:97
 msgid "Automatically repeat jumping if holding jump"
@@ -8621,19 +8622,19 @@ msgstr "המשך לקפוץ באופן אוטומטי אם מקש קפיצה ל
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:100
 msgid "Jetpack on jump:"
-msgstr ""
+msgstr "תיק סילון בקפיצה:"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:102
 msgid "JPJUMP^Disabled"
-msgstr ""
+msgstr "JPJUMP^מבוטל"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:103
 msgid "Air only"
-msgstr ""
+msgstr "אוויר בלבד"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:104
 msgid "JPJUMP^All"
-msgstr ""
+msgstr "JPJUMP^הכל"
 
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:110
 #: qcsrc/menu/xonotic/dialog_settings_input.qc:115
@@ -8678,11 +8679,11 @@ msgstr "רשת"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:29
 msgid "Client UDP port:"
-msgstr ""
+msgstr "פתחת UDP של לקוח:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:31
 msgid "Force client to use chosen port unless it is set to 0"
-msgstr ""
+msgstr "הכרח את הלקוח להשתמש בפורט הנבחר, אלא אם הערך הוא 0"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:34
 msgid "Bandwidth:"
@@ -8694,31 +8695,31 @@ msgstr "צין את מהירות הרשת שלך"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
 msgid "56k"
-msgstr ""
+msgstr "56k"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:38
 msgid "ISDN"
-msgstr ""
+msgstr "ISDN"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "Slow ADSL"
-msgstr ""
+msgstr "ADSL איטי"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:40
 msgid "Fast ADSL"
-msgstr ""
+msgstr "ADSL מהיר"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:41
 msgid "Broadband"
-msgstr ""
+msgstr "פס רחב"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:44
 msgid "Input packets/s:"
-msgstr ""
+msgstr "פאקטות קלט/שנייה:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:46
 msgid "How many input packets to send to the server each second"
-msgstr ""
+msgstr "כמה פאקטות קלט לשלוח לשרת בכל שנייה"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:48
 msgid "Server queries/s:"
@@ -8742,7 +8743,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:73
 msgid "Show netgraph"
-msgstr ""
+msgstr "הצג גרף רשת"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:74
 msgid "Show a graph of packet sizes and other information"
@@ -8750,27 +8751,27 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:76
 msgid "Client-side movement prediction"
-msgstr ""
+msgstr "חיזוי תנועה בצד-לקוח"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:78
 msgid "Movement error compensation"
-msgstr ""
+msgstr "פיצוי על שגיאות תנועה"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:82
 msgid "Use encryption (AES) when available"
-msgstr ""
+msgstr "השתמש בהצפנה (AES) כשזה אפשרי"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:85
 msgid "Framerate"
-msgstr ""
+msgstr "קצב פריימים"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:87
 msgid "Maximum:"
-msgstr ""
+msgstr "מקסימום:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:99
 msgid "MAXFPS^Unlimited"
-msgstr ""
+msgstr "MAXFPS^בלתי מוגבל"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:102
 msgid "Target:"
@@ -8778,15 +8779,15 @@ msgstr "מטרה:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:104
 msgid "TRGT^Disabled"
-msgstr ""
+msgstr "TRGT^מבוטל"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "Idle limit:"
-msgstr ""
+msgstr "מגבלה בזמן idle:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:122
 msgid "IDLFPS^Unlimited"
-msgstr ""
+msgstr "IDLFPS^בלתי מוגבל"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:126
 msgid "Save processing time for other apps"
@@ -8845,7 +8846,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:157
 #: qcsrc/menu/xonotic/dialog_settings_misc_reset.qh:6
 msgid "Factory reset"
-msgstr ""
+msgstr "איפוס להגדרות מקוריות"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc_cvars.qc:31
 msgid "Cvar filter:"
@@ -9109,7 +9110,7 @@ msgstr "בהירות:"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:121
 msgid "Brightness of black"
-msgstr ""
+msgstr "בהירות הצבע השחור:"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:123
 msgid "Contrast:"
@@ -9117,11 +9118,11 @@ msgstr "ניגודיות:"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "Brightness of white"
-msgstr ""
+msgstr "בהירות הצבע הלבן:"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:127
 msgid "Gamma:"
-msgstr ""
+msgstr "גמא:"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:130
 msgid ""
@@ -9167,13 +9168,15 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:155
 msgid "Wait for GPU to finish each frame"
-msgstr ""
+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)"
@@ -9199,39 +9202,39 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_singleplayer.qc:110
 msgid "Instant action! (random map with bots)"
-msgstr ""
+msgstr "פעולה מיידית! (מפה אקראית עם בוטים)"
 
 #: qcsrc/menu/xonotic/dialog_singleplayer.qc:117
 msgid "???"
-msgstr ""
+msgstr "???"
 
 #: qcsrc/menu/xonotic/dialog_singleplayer.qc:130
 msgid "Campaign Difficulty:"
-msgstr ""
+msgstr "דרגת קושי של הקמפיין:"
 
 #: qcsrc/menu/xonotic/dialog_singleplayer.qc:131
 msgid "CSKL^Easy"
-msgstr ""
+msgstr "CSKL^קל"
 
 #: qcsrc/menu/xonotic/dialog_singleplayer.qc:132
 msgid "CSKL^Medium"
-msgstr ""
+msgstr "CSKL^בינוני"
 
 #: qcsrc/menu/xonotic/dialog_singleplayer.qc:133
 msgid "CSKL^Hard"
-msgstr ""
+msgstr "CSKL^קשה"
 
 #: qcsrc/menu/xonotic/dialog_singleplayer.qc:135
 msgid "Start Singleplayer!"
-msgstr ""
+msgstr "התחל במצב שחקן יחיד!"
 
 #: qcsrc/menu/xonotic/dialog_singleplayer.qh:6
 msgid "Singleplayer"
-msgstr ""
+msgstr "שחקן יחיד"
 
 #: qcsrc/menu/xonotic/dialog_singleplayer.qh:7
 msgid "Play the singleplayer campaign or instant action matches against bots"
-msgstr ""
+msgstr "שחק בקמפיין לשחקן יחיד או במשחקי פעולה מיידית נגד בוטים"
 
 #: qcsrc/menu/xonotic/dialog_singleplayer_winner.qh:7
 msgid "Winner"
@@ -9239,11 +9242,11 @@ msgstr "מנצח"
 
 #: qcsrc/menu/xonotic/dialog_teamselect.qc:32
 msgid "join 'best' team (auto-select)"
-msgstr ""
+msgstr "הצטרף לקבוצה הטובה ביותר (בחירה אוטומטית)"
 
 #: qcsrc/menu/xonotic/dialog_teamselect.qc:33
 msgid "Autoselect team (recommended)"
-msgstr ""
+msgstr "בחר קבוצה אוטומטית (מומלץ)"
 
 #: qcsrc/menu/xonotic/dialog_teamselect.qc:37
 msgid "red"
@@ -9271,11 +9274,11 @@ msgstr "בחירת צוות"
 
 #: qcsrc/menu/xonotic/dialog_uid2name.qc:10
 msgid "Allow player statistics to use your nickname?"
-msgstr ""
+msgstr "האם להרשות לסטטיסטיקות השחקן להשתמש בכינוי שלך?"
 
 #: qcsrc/menu/xonotic/dialog_uid2name.qc:12
 msgid "Answering \"No\" you will appear as \"Anonymous player\""
-msgstr ""
+msgstr "אם תענה \"לא\" אתה תופיע בתור \"שחקן אנונימי\""
 
 #: qcsrc/menu/xonotic/gametypelist.qc:87
 msgid "teamplay"
@@ -9319,7 +9322,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/keybinder.qc:43
 msgid "jetpack"
-msgstr ""
+msgstr "תיק סילון"
 
 #: qcsrc/menu/xonotic/keybinder.qc:46
 msgid "Attacking"
@@ -9327,19 +9330,19 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/keybinder.qc:52
 msgid "WEAPON^previous"
-msgstr ""
+msgstr "WEAPON^הקודם"
 
 #: qcsrc/menu/xonotic/keybinder.qc:53
 msgid "WEAPON^next"
-msgstr ""
+msgstr "WEAPON^הבא"
 
 #: qcsrc/menu/xonotic/keybinder.qc:54
 msgid "WEAPON^previously used"
-msgstr ""
+msgstr "WEAPON^האחרון שהיה בשימוש"
 
 #: qcsrc/menu/xonotic/keybinder.qc:55
 msgid "WEAPON^best"
-msgstr ""
+msgstr "WEAPON^הטוב ביותר"
 
 #: qcsrc/menu/xonotic/keybinder.qc:56
 msgid "reload"
@@ -9447,41 +9450,41 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/mainwindow.qc:65 qcsrc/menu/xonotic/mainwindow.qc:68
 msgid "Do not press this button again!"
-msgstr ""
+msgstr "אל תלחץ על כפתור זה שוב!"
 
 #: qcsrc/menu/xonotic/maplist.qc:288
 msgid ""
 "Huh? Can't play this (m is NULL). Refiltering so this won't happen again."
-msgstr ""
+msgstr "מה? אי אפשר לשחק בזה (m הוא NULL). מסנן מחדש כדי שזה לא יקרה שוב."
 
 #: qcsrc/menu/xonotic/maplist.qc:296
 #, c-format
 msgid "%s's Xonotic Server"
-msgstr ""
+msgstr "שרת ה-Xonotic של %s"
 
 #: qcsrc/menu/xonotic/maplist.qc:301
 msgid ""
 "Huh? Can't play this (invalid game type). Refiltering so this won't happen "
 "again."
-msgstr ""
+msgstr "מה? אי אפשר לשחק בזה (סוג המשחק שגוי). מסנן מחדש כדי שזה לא יקרה שוב."
 
 #: qcsrc/menu/xonotic/playerlist.qc:102 qcsrc/menu/xonotic/playerlist.qc:112
 msgid "spectator"
-msgstr ""
+msgstr "צופה"
 
 #: qcsrc/menu/xonotic/playermodel.qc:161
 msgid "<no model found>"
-msgstr ""
+msgstr "<no model found>"
 
 #: qcsrc/menu/xonotic/serverlist.qc:267
 msgid "Favorite"
-msgstr ""
+msgstr "מועדף"
 
 #: qcsrc/menu/xonotic/serverlist.qc:268
 msgid ""
 "Bookmark the currently highlighted server so that it's faster to find in the "
 "future"
-msgstr ""
+msgstr "הוסף סימניה עבור השרת המודגש כרגע כדי שיהיה קל למצוא אותו שוב בעתיד"
 
 #: qcsrc/menu/xonotic/serverlist.qc:747
 msgid "Ping"
@@ -9489,7 +9492,7 @@ msgstr "פינג"
 
 #: qcsrc/menu/xonotic/serverlist.qc:748
 msgid "Hostname"
-msgstr ""
+msgstr "שם השרת"
 
 #: qcsrc/menu/xonotic/serverlist.qc:749
 msgid "Map"
@@ -9502,7 +9505,7 @@ msgstr "סוג"
 #: qcsrc/menu/xonotic/serverlist.qc:1043
 #, c-format
 msgid "AES level %d"
-msgstr ""
+msgstr "רמת AES %d"
 
 #: qcsrc/menu/xonotic/serverlist.qc:1043
 msgid "ENC^none"
@@ -9510,30 +9513,30 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.qc:1043
 msgid "encryption:"
-msgstr ""
+msgstr "הצפנה:"
 
 #: qcsrc/menu/xonotic/serverlist.qc:1044
 #, c-format
 msgid "mod: %s"
-msgstr ""
+msgstr "מוד: %s"
 
 #: qcsrc/menu/xonotic/serverlist.qc:1046
 #, c-format
 msgid "modified settings"
-msgstr ""
+msgstr "הגדרות שנערכו"
 
 #: qcsrc/menu/xonotic/serverlist.qc:1046
 #, c-format
 msgid "official settings"
-msgstr ""
+msgstr "הגדרות רשמיות"
 
 #: qcsrc/menu/xonotic/serverlist.qc:1048
 msgid "stats disabled"
-msgstr ""
+msgstr "סטטיסטיקות מכובות"
 
 #: qcsrc/menu/xonotic/serverlist.qc:1048
 msgid "stats enabled"
-msgstr ""
+msgstr "סטטיסטיקות מופעלות"
 
 #: qcsrc/menu/xonotic/serverlist.qh:152
 msgid "SLCAT^Favorites"
@@ -9626,6 +9629,8 @@ 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"
@@ -9701,7 +9706,7 @@ msgstr "משחק אחרון:"
 
 #: qcsrc/menu/xonotic/statslist.qc:110
 msgid "Time played:"
-msgstr ""
+msgstr "זמן ששוחק:"
 
 #: qcsrc/menu/xonotic/statslist.qc:117 qcsrc/menu/xonotic/statslist.qc:230
 msgid "Favorite map:"
@@ -9711,7 +9716,7 @@ msgstr "מפה מועדפת:"
 #: qcsrc/menu/xonotic/statslist.qc:244
 #, c-format
 msgid "Matches:"
-msgstr ""
+msgstr "משחקים:"
 
 #: qcsrc/menu/xonotic/statslist.qc:154
 #, c-format
@@ -9726,7 +9731,7 @@ msgstr "אחוז ניצחונות:"
 #: qcsrc/menu/xonotic/statslist.qc:166
 #, c-format
 msgid "Kills/Deaths:"
-msgstr ""
+msgstr "הריגות/מיתות:"
 
 #: qcsrc/menu/xonotic/statslist.qc:172
 #, c-format
@@ -9735,7 +9740,7 @@ msgstr "יחס הריגות:"
 
 #: qcsrc/menu/xonotic/statslist.qc:207
 msgid "ELO:"
-msgstr ""
+msgstr "דירוג ELO:"
 
 #: qcsrc/menu/xonotic/statslist.qc:214
 msgid "Rank:"
@@ -9752,7 +9757,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/util.qc:417
 msgid "Update can be downloaded at:"
-msgstr ""
+msgstr "ניתן להוריד עדכון ב:"
 
 #: qcsrc/menu/xonotic/util.qc:525
 msgid "Autogenerating mapinfo for newly added maps..."
@@ -9766,7 +9771,7 @@ msgstr ""
 #: qcsrc/menu/xonotic/util.qc:574
 #, c-format
 msgid "Update to %s now!"
-msgstr ""
+msgstr "עדכן לגרסה %s עכשיו!"
 
 #: qcsrc/menu/xonotic/util.qc:658
 msgid ""
index 83fd3e13152029037f3a99f117d6c620026a8699..f7f4fd952cd63e8ad64db6964d95864c2aef6cc1 100644 (file)
 # Jakub P. <pedziszewski@gmail.com>, 2015
 # Jakub P. <pedziszewski@gmail.com>, 2015
 # John Smith <myrangd@gmail.com>, 2016
+# Karol Kosek, 2020
+# Karol Kosek, 2020
+# Karol Kosek, 2020
+# Karol Kosek, 2020
+# Karol Kosek, 2020
 # Kriss Chr <kriss7475@gmail.com>, 2017
 # Piotr Kozica <koza91@gmail.com>, 2016
 # Rafał Szymański <okavasly@gmail.com>, 2017
@@ -20,8 +25,8 @@ msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2019-05-19 07:23+0200\n"
-"PO-Revision-Date: 2019-05-19 05:23+0000\n"
-"Last-Translator: divVerent <divVerent@xonotic.org>\n"
+"PO-Revision-Date: 2020-02-08 12:09+0000\n"
+"Last-Translator: Karol Kosek\n"
 "Language-Team: Polish (http://www.transifex.com/team-xonotic/xonotic/"
 "language/pl/)\n"
 "Language: pl\n"
@@ -35,12 +40,12 @@ msgstr ""
 #: qcsrc/client/hud/hud_config.qc:243
 #, c-format
 msgid "^2Successfully exported to %s! (Note: It's saved in data/data/)"
-msgstr ""
+msgstr "^2Wyeksportowano do %s! (Uwaga: Zapisano w data/data/)"
 
 #: qcsrc/client/hud/hud_config.qc:247
 #, c-format
 msgid "^1Couldn't write to %s"
-msgstr ""
+msgstr "^1Nie można zapisać do %s"
 
 #: qcsrc/client/hud/panel/centerprint.qc:140
 #, c-format
@@ -61,7 +66,7 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/centerprint.qc:149
 msgid "Generic message"
-msgstr ""
+msgstr "Ogólna wiadomość"
 
 #: qcsrc/client/hud/panel/chat.qc:84
 msgid "^3Player^7: This is the chat area."
@@ -265,7 +270,7 @@ msgstr "Kontynuuj..."
 #: qcsrc/client/hud/panel/quickmenu.qc:781
 #: qcsrc/client/hud/panel/quickmenu.qc:788
 msgid "Chat"
-msgstr ""
+msgstr "Czat"
 
 #: qcsrc/client/hud/panel/quickmenu.qc:782
 msgid "QMCMD^Send public message to"
@@ -605,7 +610,7 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/scoreboard.qc:91
 msgid "Number of deaths"
-msgstr ""
+msgstr "Liczba zgonów"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:91
 msgid "SCO^deaths"
@@ -637,7 +642,7 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/scoreboard.qc:95
 msgid "Number of flag drops"
-msgstr ""
+msgstr "Liczba upuszczeń flagi"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:95
 msgid "SCO^drops"
@@ -677,11 +682,11 @@ msgstr "fckills"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:100
 msgid "FPS"
-msgstr ""
+msgstr "FPS"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:100
 msgid "SCO^fps"
-msgstr ""
+msgstr "fps"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:101
 msgid "Number of kills minus suicides"
@@ -760,7 +765,7 @@ msgstr "straty"
 #: qcsrc/client/hud/panel/scoreboard.qc:111
 #: qcsrc/client/hud/panel/scoreboard.qc:112
 msgid "Player name"
-msgstr ""
+msgstr "Nazwa gracza"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:111
 msgid "SCO^name"
@@ -797,7 +802,7 @@ msgstr "ping"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:116
 msgid "Packet loss"
-msgstr ""
+msgstr "Utrata pakietu"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:116
 msgid "SCO^pl"
@@ -853,7 +858,7 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/scoreboard.qc:123
 msgid "Number of suicides"
-msgstr ""
+msgstr "Liczba samobójstw"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:123
 msgid "SCO^suicides"
@@ -893,7 +898,7 @@ msgstr "SCO^ticks"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:128
 msgid "SCO^time"
-msgstr ""
+msgstr "czas"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:128
 msgid "Total time raced (Race/CTS)"
@@ -906,11 +911,11 @@ msgstr ""
 
 #: qcsrc/client/hud/panel/scoreboard.qc:313
 msgid "Usage:"
-msgstr ""
+msgstr "Użycie:"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:315
 msgid "^2scoreboard_columns_set ^3field1 field2 ..."
-msgstr ""
+msgstr "^2scoreboard_columns_set ^3pole1 pole2 …"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:316
 msgid ""
@@ -937,6 +942,7 @@ msgstr ""
 #: qcsrc/client/hud/panel/scoreboard.qc:320
 msgid "The following field names are recognized (case insensitive):"
 msgstr ""
+"Następujące nazwy pól są rozpoznawane (wielkość liter nie ma znaczenia)"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:326
 msgid ""
@@ -955,6 +961,7 @@ msgstr ""
 #: qcsrc/client/hud/panel/scoreboard.qc:336
 msgid "Example: scoreboard_columns_set name ping pl | +ctf/field3 -dm/field4"
 msgstr ""
+"Na przykład: scoreboard_columns_set name ping pl | +ctf/field3 -dm/field4"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:337
 msgid ""
@@ -1008,13 +1015,13 @@ msgstr "Rankingi"
 #: qcsrc/client/hud/panel/scoreboard.qc:1613
 #, c-format
 msgid "^3%1.0f minutes"
-msgstr ""
+msgstr "^3%1.0f minut"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1622
 #: qcsrc/client/hud/panel/scoreboard.qc:1629
 #, c-format
 msgid "^5%s %s"
-msgstr ""
+msgstr "^5%s %s"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1623
 #: qcsrc/client/hud/panel/scoreboard.qc:1630
@@ -1073,7 +1080,7 @@ msgstr "Jesteś martwy, wciśnij ^2%s^7 by się wskrzesić"
 
 #: qcsrc/client/hud/panel/timer.qc:67
 msgid "WARMUP"
-msgstr ""
+msgstr "ROZGRZEWKA"
 
 #: qcsrc/client/hud/panel/vote.qc:27
 msgid "^1You must answer before entering hud configure mode"
@@ -1186,11 +1193,11 @@ msgstr ""
 
 #: qcsrc/client/mapvoting.qc:515
 msgid "^1Error:^7 Couldn't find pak index."
-msgstr ""
+msgstr "^1Błąd:^7 Nie można znaleźć indeksu pak."
 
 #: qcsrc/client/mapvoting.qc:524
 msgid "Requesting preview..."
-msgstr ""
+msgstr "Oczekiwanie podglądu…"
 
 #: qcsrc/client/miscfunctions.qc:111
 msgid "Trying to remove a team which is not in the teamlist!"
@@ -1312,7 +1319,7 @@ msgstr "Limit zabójstw:"
 #: qcsrc/common/mapinfo.qh:72 qcsrc/common/mapinfo.qh:333
 #: qcsrc/common/mapinfo.qh:528
 msgid "The amount of frags needed before the match will end"
-msgstr ""
+msgstr "Ilość zabójstw potrzebnych przed końcem meczu"
 
 #: qcsrc/common/mapinfo.qh:114
 msgid "Deathmatch"
@@ -1320,7 +1327,7 @@ msgstr "Deathmatch"
 
 #: qcsrc/common/mapinfo.qh:114
 msgid "Score as many frags as you can"
-msgstr "Zdobądź jak najwięcej frag"
+msgstr "Zdobądź jak najwięcej zabójstw"
 
 #: qcsrc/common/mapinfo.qh:127
 msgid "Last Man Standing"
@@ -1726,7 +1733,7 @@ msgstr ""
 
 #: qcsrc/common/minigames/minigame/ttt.qc:2
 msgid "Tic Tac Toe"
-msgstr ""
+msgstr "Kółko i krzyżyk"
 
 #: qcsrc/common/minigames/minigame/ttt.qc:665
 msgid "Single Player"
@@ -2610,7 +2617,7 @@ msgstr "^BG%s^K1 zginął w wypadku%s%s"
 #: qcsrc/common/notifications/all.inc:336
 #, c-format
 msgid "^BG%s^K1 ran into a turret%s%s"
-msgstr ""
+msgstr "^BG%s^K1 wbiegł w wieżyczkę%s%s"
 
 #: qcsrc/common/notifications/all.inc:337
 #, c-format
@@ -3593,7 +3600,7 @@ msgstr "^BGTwój %steam mate (^BG%s%s)^BG dostał flagę! Obroń go!"
 
 #: qcsrc/common/notifications/all.inc:587
 msgid "^BGEnemies can now see you on radar!"
-msgstr ""
+msgstr "^BGPrzeciwnicy mogą teraz Cię widzieć na radarze!"
 
 #: qcsrc/common/notifications/all.inc:588
 msgid "^BGYou returned the ^TC^TT^BG flag!"
@@ -3601,7 +3608,7 @@ msgstr "^BGPrzywróciłeś ^TC^TTĄ^BG flagę!"
 
 #: qcsrc/common/notifications/all.inc:589
 msgid "^BGStalemate! Enemies can now see you on radar!"
-msgstr ""
+msgstr "^BGMartwy punkt! Przeciwnicy mogą teraz Cię widzieć na radarze!"
 
 #: qcsrc/common/notifications/all.inc:590
 msgid "^BGStalemate! Flag carriers can now be seen by enemies on radar!"
@@ -4262,7 +4269,7 @@ msgstr ""
 #: qcsrc/common/notifications/all.inc:788
 #, c-format
 msgid "^BGPress ^F2%s^BG to enter/exit the vehicle"
-msgstr ""
+msgstr "^BGWciśnij ^F2%s^BG aby wejść/wyjść z pojazdu"
 
 #: qcsrc/common/notifications/all.inc:789
 #, c-format
@@ -4272,7 +4279,7 @@ msgstr ""
 #: qcsrc/common/notifications/all.inc:790
 #, c-format
 msgid "^BGPress ^F2%s^BG to steal this vehicle"
-msgstr ""
+msgstr "^BGWciśnij ^F2%s^BG aby ukraść pojazd"
 
 #: qcsrc/common/notifications/all.inc:791
 msgid ""
@@ -5418,7 +5425,7 @@ msgstr "%02d:%02d:%02d"
 
 #: qcsrc/menu/command/menu_cmd.qc:48
 msgid "Usage: menu_cmd command..., where possible commands are:"
-msgstr ""
+msgstr "Użycie: menu_cmd polecenie…, gdzie dostępnymi poleceniami są:"
 
 #: qcsrc/menu/command/menu_cmd.qc:49
 msgid "  sync - reloads all cvars on the current menu page"
@@ -6211,7 +6218,7 @@ msgstr "Zanikanie:"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:33
 msgid "EF^None"
-msgstr ""
+msgstr "EF^Brak"
 
 #: qcsrc/menu/xonotic/dialog_hudpanel_weapons.qc:34
 msgid "Alpha"
@@ -6357,7 +6364,7 @@ msgstr "Ustawienia siatki:"
 
 #: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:124
 msgid "Snap panels to grid"
-msgstr ""
+msgstr "Przyciągaj panele do siatki"
 
 #: qcsrc/menu/xonotic/dialog_hudsetup_exit.qc:127
 msgid "Grid size:"
@@ -6479,7 +6486,7 @@ msgstr "Limit czasu:"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:81
 msgid "Timelimit in minutes that when hit, will end the match"
-msgstr ""
+msgstr "Limit czasowy w minutach, który po trafieniu zakończy mecz"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
 #, c-format
@@ -6705,7 +6712,7 @@ msgstr "Latanie Rakietami"
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:67
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:217
 msgid "Invincible Projectiles"
-msgstr "Niezniszczalne Pociski"
+msgstr "Niezniszczalne pociski"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:71
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:293
@@ -6849,7 +6856,7 @@ msgstr "Areny broni:"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:246
 msgid "Custom weapons"
-msgstr ""
+msgstr "Niestandardowe bronie"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc:268
 msgid "Most weapons"
@@ -7222,7 +7229,7 @@ msgstr "Kraj"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:153
 msgid "Select language..."
-msgstr ""
+msgstr "Wybierz język…"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_profile.qc:169
 msgid "Gender:"
@@ -8851,7 +8858,7 @@ msgstr "Wyłączone"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:116
 msgid "Idle limit:"
-msgstr "Brak limitu:"
+msgstr "Limit w trybie nieaktywnym:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:122
 msgid "IDLFPS^Unlimited"
@@ -9181,7 +9188,7 @@ msgstr "Jasność:"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:121
 msgid "Brightness of black"
-msgstr ""
+msgstr "Jasność czerni"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:123
 msgid "Contrast:"
@@ -9189,7 +9196,7 @@ msgstr "Kontrast:"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:125
 msgid "Brightness of white"
-msgstr ""
+msgstr "Jasność bieli"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:127
 msgid "Gamma:"
@@ -9770,7 +9777,7 @@ msgstr "Dołączył:"
 
 #: qcsrc/menu/xonotic/statslist.qc:103
 msgid "Last match:"
-msgstr ""
+msgstr "Ostatni mecz:"
 
 #: qcsrc/menu/xonotic/statslist.qc:110
 msgid "Time played:"
@@ -9778,7 +9785,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/statslist.qc:117 qcsrc/menu/xonotic/statslist.qc:230
 msgid "Favorite map:"
-msgstr ""
+msgstr "Ulubiona mapa:"
 
 #: qcsrc/menu/xonotic/statslist.qc:149 qcsrc/menu/xonotic/statslist.qc:201
 #: qcsrc/menu/xonotic/statslist.qc:244
index 098a0496a1cf31957d52cad0eb87fb3fadf17114..62b5b87bcd4adc13de0325cee51d00c712676904 100644 (file)
@@ -4,7 +4,7 @@
 #
 # Translators:
 # Ivan Paulos Tomé <greylica@gmail.com>, 2016
-# Jean Trindade Pereira <jean_trindade2@hotmail.com>, 2018-2019
+# Jean Trindade Pereira <jean_trindade2@hotmail.com>, 2015,2018-2020
 # Mirio <opivy@hotmail.de>, 2017
 # NotThatPrivate Yes <henriqueferreira2009@gmail.com>, 2015
 # Ricardo Manuel da Cruz Coelho da Silva <ricardo.mccs@gmail.com>, 2015
@@ -14,7 +14,7 @@ msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2019-05-19 07:23+0200\n"
-"PO-Revision-Date: 2019-07-07 02:23+0000\n"
+"PO-Revision-Date: 2020-01-27 18:03+0000\n"
 "Last-Translator: Jean Trindade Pereira <jean_trindade2@hotmail.com>\n"
 "Language-Team: Portuguese (Brazil) (http://www.transifex.com/team-xonotic/"
 "xonotic/language/pt_BR/)\n"
index 80089d0c8d7a94ef7080b9adea7d458bb30c3a37..4c19cfd4e3c39b07f3d292dab8156db8b80990fa 100644 (file)
@@ -6,7 +6,7 @@
 # adem4ik, 2014
 # Alex Talker <alextalker7@gmail.com>, 2014-2015
 # Andrei Stepanov, 2014
-# Andrei Stepanov <adem4ik@gmail.com>, 2014-2019
+# Andrei Stepanov <adem4ik@gmail.com>, 2014-2020
 # Andrey P <andrey.pyntikov@gmail.com>, 2016
 # Artem Vorotnikov <artem@vorotnikov.me>, 2015
 # Lord Canistra <lordcanistra@gmail.com>, 2011
@@ -19,7 +19,7 @@ msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2019-05-19 07:23+0200\n"
-"PO-Revision-Date: 2019-06-24 06:22+0000\n"
+"PO-Revision-Date: 2020-01-14 18:19+0000\n"
 "Last-Translator: Andrei Stepanov <adem4ik@gmail.com>\n"
 "Language-Team: Russian (http://www.transifex.com/team-xonotic/xonotic/"
 "language/ru/)\n"
@@ -551,7 +551,7 @@ msgstr "Линия финиша"
 #: qcsrc/client/hud/panel/racetimer.qc:151
 #, c-format
 msgid "Intermediate %d"
-msgstr "Ð\9fÑ\80омежÑ\83Ñ\82оÑ\87ное %d"
+msgstr "УÑ\87аÑ\81Ñ\82ок %d"
 
 #: qcsrc/client/hud/panel/racetimer.qc:154
 #: qcsrc/client/hud/panel/racetimer.qc:201
@@ -1032,7 +1032,7 @@ msgstr "Рейтинг"
 #: qcsrc/client/hud/panel/scoreboard.qc:1613
 #, c-format
 msgid "^3%1.0f minutes"
-msgstr "^3%1.0f минуты"
+msgstr "^3%1.0f минут(ы)"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:1622
 #: qcsrc/client/hud/panel/scoreboard.qc:1629
@@ -1155,7 +1155,7 @@ msgstr "Недоступен"
 
 #: qcsrc/client/main.qc:1027
 msgid " qu/s"
-msgstr "юнит/с"
+msgstr " юнит/с"
 
 #: qcsrc/client/main.qc:1029
 msgid " m/s"
@@ -1202,7 +1202,7 @@ msgstr "Голосование за карту"
 #: qcsrc/client/mapvoting.qc:392
 #, c-format
 msgid "%d seconds left"
-msgstr "СекÑ\83нд Ð¾Ñ\81Ñ\82алоÑ\81Ñ\8c: %d"
+msgstr "Ð\9eÑ\81Ñ\82алоÑ\81Ñ\8c Ñ\81екÑ\83нд: %d"
 
 #: qcsrc/client/mapvoting.qc:505
 msgid "mv_mapdownload: ^3You're not supposed to use this command on your own!"
@@ -1326,7 +1326,7 @@ msgstr "Щит"
 #: qcsrc/common/mapinfo.qc:626
 #, no-c-format
 msgid "@!#%'n Tuba Throwing"
-msgstr "@!#%'n Ð¨Ð²Ñ\8bÑ\80Ñ\8fние Ð¢Ñ\80Ñ\83бой"
+msgstr "@!#%'n Швыряние Тубой"
 
 #: qcsrc/common/mapinfo.qh:72 qcsrc/common/mapinfo.qh:333
 #: qcsrc/common/mapinfo.qh:528
@@ -3024,7 +3024,7 @@ msgstr "^BG%s^BG отказался от гонки"
 #: qcsrc/common/notifications/all.inc:428
 #, c-format
 msgid "^BG%s^BG couldn't break their %s%s^BG place record of %s%s %s"
-msgstr "^BG%s^BG не смог побить рекорд %s%s^BG места со временем %s%s %s"
+msgstr "^BG%s^BG Ð½Ðµ Ñ\81мог Ð¿Ð¾Ð±Ð¸Ñ\82Ñ\8c Ñ\81вой Ñ\80екоÑ\80д %s%s^BG Ð¼ÐµÑ\81Ñ\82а Ñ\81о Ð²Ñ\80еменем %s%s %s"
 
 #: qcsrc/common/notifications/all.inc:429
 #, c-format
@@ -3933,7 +3933,7 @@ msgstr "^K1Вы не смогли укрыться от ракеты Гонщи
 
 #: qcsrc/common/notifications/all.inc:667
 msgid "^K1Watch your step!"
-msgstr "^K1Смотри под ноги!"
+msgstr "^K1Смотрите под ноги!"
 
 #: qcsrc/common/notifications/all.inc:669
 #, c-format
@@ -4100,7 +4100,7 @@ msgid ""
 "Need active players for: %s"
 msgstr ""
 "^BGОжидание игроков...\n"
-"Активные игроки необходимы для: %s"
+"%s нуждается в активных игроках"
 
 #: qcsrc/common/notifications/all.inc:725
 #, c-format
@@ -4589,19 +4589,19 @@ msgstr " с %d %s"
 
 #: qcsrc/common/teams.qh:31
 msgid "TEAM^Red"
-msgstr "TEAM^Красные"
+msgstr "TEAM^Красная"
 
 #: qcsrc/common/teams.qh:32
 msgid "TEAM^Blue"
-msgstr "TEAM^Синие"
+msgstr "TEAM^Синяя"
 
 #: qcsrc/common/teams.qh:33
 msgid "TEAM^Yellow"
-msgstr "TEAM^Жёлтые"
+msgstr "TEAM^Жёлтая"
 
 #: qcsrc/common/teams.qh:34
 msgid "TEAM^Pink"
-msgstr "TEAM^Розовые"
+msgstr "TEAM^Розовая"
 
 #: qcsrc/common/teams.qh:35
 msgid "Team"
@@ -5260,7 +5260,7 @@ msgstr "Дробовик"
 #: qcsrc/common/weapons/weapon/tuba.qh:18
 #, no-c-format
 msgid "@!#%'n Tuba"
-msgstr "@!#%'n Ð¢Ñ\80Ñ\83ба"
+msgstr "@!#%'n Туба"
 
 #: qcsrc/common/weapons/weapon/vaporizer.qh:19
 msgid "Vaporizer"
@@ -5393,12 +5393,12 @@ msgstr "%d часов"
 #: qcsrc/lib/counting.qh:46
 #, c-format
 msgid "CI_DEC^%s minutes"
-msgstr "%s минут"
+msgstr "%s минут(ы)"
 
 #: qcsrc/lib/counting.qh:49
 #, c-format
 msgid "CI_ZER^%d minutes"
-msgstr "%d минут"
+msgstr "%d минут(ы)"
 
 #: qcsrc/lib/counting.qh:50
 #, c-format
@@ -5408,17 +5408,17 @@ msgstr "%d минута"
 #: qcsrc/lib/counting.qh:51
 #, c-format
 msgid "CI_SEC^%d minutes"
-msgstr "%d минуты"
+msgstr "%d минут(ы)"
 
 #: qcsrc/lib/counting.qh:52
 #, c-format
 msgid "CI_THI^%d minutes"
-msgstr "%d минуты"
+msgstr "%d минут(ы)"
 
 #: qcsrc/lib/counting.qh:53
 #, c-format
 msgid "CI_MUL^%d minutes"
-msgstr "%d минут"
+msgstr "%d минут(ы)"
 
 #: qcsrc/lib/counting.qh:55
 #, c-format
@@ -6564,7 +6564,7 @@ msgstr "Ограничение времени в минутах, после ко
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:82
 #, c-format
 msgid "%d minutes"
-msgstr "%d минуты"
+msgstr "%d минут(ы)"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create.qc:83
 msgid "TIMLIM^Default"
@@ -9519,7 +9519,7 @@ msgstr "вправо"
 
 #: qcsrc/menu/xonotic/keybinder.qc:40
 msgid "jump / swim"
-msgstr "прыжок / плыть"
+msgstr "пÑ\80Ñ\8bжок / Ð²Ñ\81плÑ\8bÑ\82Ñ\8c"
 
 #: qcsrc/menu/xonotic/keybinder.qc:41
 msgid "crouch / sink"
@@ -9559,7 +9559,7 @@ msgstr "перезарядить"
 
 #: qcsrc/menu/xonotic/keybinder.qc:57
 msgid "drop weapon / throw nade"
-msgstr "бÑ\80оÑ\81иÑ\82Ñ\8c Ð¾Ñ\80Ñ\83жие / ÐºÐ¸Ð½Ñ\83Ñ\82Ñ\8c Ð³Ñ\80анаÑ\82Ñ\83"
+msgstr "бросить оружие / гранату"
 
 #: qcsrc/menu/xonotic/keybinder.qc:86
 msgid "hold zoom"
@@ -9635,7 +9635,7 @@ msgstr "автовыбор команды"
 
 #: qcsrc/menu/xonotic/keybinder.qc:118
 msgid "drop key / drop flag"
-msgstr "бросить ключ или флаг"
+msgstr "бросить ключ / флаг"
 
 #: qcsrc/menu/xonotic/keybinder.qc:122
 msgid "respawn"
index 5ee89ac01adf346b3b72f99a1f2cff928f24b8b2..d69f52e8ee80a34b1ac46847de8f0773acaeebcd 100644 (file)
@@ -3,6 +3,7 @@
 # This file is distributed under the same license as the PACKAGE package.
 #
 # Translators:
+# Abdurrahman AKKUŞ <a.rahmanakkus@hotmail.com>, 2019
 # Çağlar Turalı <caglarturali@gmail.com>, 2018
 # Demiray Muhterem <mdemiray@msn.com>, 2018
 # ibra kap <ibrakap@gmail.com>, 2019
@@ -11,8 +12,8 @@ msgstr ""
 "Project-Id-Version: Xonotic\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2019-05-19 07:23+0200\n"
-"PO-Revision-Date: 2019-09-11 17:17+0000\n"
-"Last-Translator: ibra kap <ibrakap@gmail.com>\n"
+"PO-Revision-Date: 2019-12-18 07:52+0000\n"
+"Last-Translator: Abdurrahman AKKUŞ <a.rahmanakkus@hotmail.com>\n"
 "Language-Team: Turkish (http://www.transifex.com/team-xonotic/xonotic/"
 "language/tr/)\n"
 "Language: tr\n"
@@ -24,12 +25,12 @@ msgstr ""
 #: qcsrc/client/hud/hud_config.qc:243
 #, c-format
 msgid "^2Successfully exported to %s! (Note: It's saved in data/data/)"
-msgstr ""
+msgstr "^2Başarıyla %s'e aktarıldı! (Dikkat: data/data/'ya kaydedildi)"
 
 #: qcsrc/client/hud/hud_config.qc:247
 #, c-format
 msgid "^1Couldn't write to %s"
-msgstr ""
+msgstr "^1 %s'e yazılamadı"
 
 #: qcsrc/client/hud/panel/centerprint.qc:140
 #, c-format
index 47631f0fa6cb70b4a664e493ff5dd06bd300bfae..ae3fec0805b9dfbeeccec68a43bc63d8df6c639f 100644 (file)
@@ -32,10 +32,10 @@ seta crosshair_hitindication_speed 5
 
 // hit testing/tracing for special effects for the crosshair
 set g_trueaim_minrange 44 "TrueAim minimum range (TrueAim adjusts shots so they hit the crosshair point even though the gun is not at the screen center)"
-seta crosshair_hittest 1 "do a crosshair hit evaluation, applying effects from the _blur, _scale, and _showipact cvars"
+seta crosshair_hittest 1 "do a crosshair hit evaluation, applying effects from the _blur and _scale cvars"
 seta crosshair_hittest_blur 1 "blur the crosshair if the shot is obstructed"
 seta crosshair_hittest_scale 1.25 "shrink crosshair if shot is obstructed or aiming at a teammate"
-seta crosshair_hittest_showimpact 0 "move the crosshair to the actual impact location if obstructed"
+seta crosshair_hittest_showimpact 0 "move the crosshair to the actual impact location if obstructed (debug setting, very glitchy!)"
 
 // change color based on special case
 seta crosshair_color_special 1 "special color handling for crosshair... 1 = per-weapon crosshair color (see crosshair_per_weapon), 2 = crosshair changes color based on health, 3 = rainbow/random color selection"
index 129dba36e2c6a09ec35974649391ee051a7a9853..8c6a51feaa9fa55bc4ff0c15f2acc28a3a487944 100644 (file)
@@ -8355,3 +8355,27 @@ effect tr_bullet_weak
        trailspacing 32
        underwater
        velocityjitter 16 16 16
+effect TE_TEI_G3_HIT
+       type beam
+       alpha 128 128 256
+       color 0xFFFFFF 0xFFFFFF
+       countabsolute 1
+       size 8 8
+       tex 200 200
+effect TE_TEI_G3_HIT
+       type smoke
+       airfriction -4
+       alpha 256 256 512
+       color 0xFFFFFF 0xFFFFFF
+       sizeincrease -2
+       size 2 2
+       trailspacing 20
+       velocityjitter 2 2 2
+effect TE_TEI_G3_HIT
+       type smoke
+       airfriction -4
+       alpha 256 256 512
+       color 0xFFFFFF 0xFFFFFF
+       sizeincrease -6
+       size 10 10
+       trailspacing 40
index 597bb4660a9f0e063e6009652c8c0997dbbbd99e..b935b03b1738c3c62d043efe94bfe79ed09319cb 100644 (file)
@@ -31,6 +31,7 @@ r_shadow_realtime_world_shadows 0
 r_shadow_shadowmapping 0
 r_shadow_usenormalmap 1
 r_showsurfaces 0
+r_sky 1
 r_subdivisions_tolerance 3
 r_texture_dds_load 1
 r_water 1
index c9549581bddb35ebfc0fa858b347760aed609b13..7c9921a32bfd17415af5327764facb5641c89290 100644 (file)
@@ -31,6 +31,7 @@ r_shadow_realtime_world_shadows 0
 r_shadow_shadowmapping 0
 r_shadow_usenormalmap 0
 r_showsurfaces 0
+r_sky 1
 r_subdivisions_tolerance 8
 r_texture_dds_load 1
 r_water 0
index 4ea20a1699d110c6742eab52260963c581b9ee66..b701674693a2578d58b85d52dc331d1df65c3c8c 100644 (file)
@@ -31,6 +31,7 @@ r_shadow_realtime_world_shadows 0
 r_shadow_shadowmapping 0
 r_shadow_usenormalmap 0
 r_showsurfaces 0
+r_sky 1
 r_subdivisions_tolerance 4
 r_texture_dds_load 1
 r_water 0
index ba708cb9f803e9c4446f0f1861c019a3e3510892..c519617f68b3dc0550991fd8dcd8ed5e534ef65c 100644 (file)
@@ -31,6 +31,7 @@ r_shadow_realtime_world_shadows 0
 r_shadow_shadowmapping 0
 r_shadow_usenormalmap 1
 r_showsurfaces 0
+r_sky 1
 r_subdivisions_tolerance 3
 r_texture_dds_load 1
 r_water 0
index 7614417ce2027e42c4d711fce396faaaf7c1cd14..7b05a1eaad79a6b773df475300a2d901bb1d25e0 100644 (file)
@@ -31,6 +31,7 @@ r_shadow_realtime_world_shadows 0
 r_shadow_shadowmapping 0
 r_shadow_usenormalmap 0
 r_showsurfaces 3
+r_sky 0
 r_subdivisions_tolerance 16
 r_texture_dds_load 1
 r_water 0
index 6d8ee6f07364532ee1ecb47cc6e051b8a4181823..b1631b2333f56e6ba6ad1d9290fd89f0f77cddb8 100644 (file)
@@ -29,7 +29,9 @@ alias sv_hook_gamestart_ka
 alias sv_hook_gamestart_ft
 alias sv_hook_gamestart_inv
 alias sv_hook_gamestart_duel
-alias sv_hook_gamerestart
+// there is currently no hook for when the match is restarted
+// see sv_hook_readyrestart for previous uses of this hook
+//alias sv_hook_gamerestart
 alias sv_hook_gameend
 
 
@@ -74,7 +76,7 @@ alias sv_vote_gametype_hook_duel
 // ===========
 // this means that timelimit can be overidden globally and fraglimit can be overidden for each game mode: DM/TDM, Domination, CTF, and Runematch.
 set leadlimit 0
-set leadlimit_and_fraglimit 0 "if set, leadlimit is ANDed with fraglimit (otherwise ORed)"
+set leadlimit_and_fraglimit 0 "both leadlimit AND fraglimit must be reached"
 set timelimit_override -1      "Time limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)"
 set fraglimit_override -1      "Frag limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)"
 set leadlimit_override -1      "Lead limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)"
@@ -245,6 +247,8 @@ set g_ctf_flag_return_dropped 100 "automatically return the flag to base if drop
 set g_ctf_flag_return_damage 0 "allow the flag to be damaged, reducing time needed to automatically return to base"
 set g_ctf_flag_return_damage_delay 0 "how much time the flag takes to automatically return to base if it falls into lava/slime/trigger hurt"
 set g_ctf_flag_return_when_unreachable 1 "automatically return the flag if it falls into lava/slime/trigger hurt"
+set g_ctf_flag_waypoint 1 "show a waypoint at the flag for easy discovery and directions"
+set g_ctf_flag_waypoint_maxdistance 0 "maximum distance from a flag from which their waypoint is shown, a value of 0 means no limit"
 set g_ctf_flagcarrier_auto_helpme_damage 100 "automatically place a helpme notification on flag carrier waypointsprite if they get hit and their health dips below this value"
 set g_ctf_flagcarrier_auto_helpme_time 2 "antispam time for the helpme notification"
 set g_ctf_flagcarrier_selfdamagefactor 1
@@ -307,7 +311,7 @@ set g_ctf_flag_neutral_model "models/ctf/flags.md3"
 set g_ctf_flag_neutral_skin 4
 set g_ctf_flag_glowtrails 1
 set g_ctf_fullbrightflags 0
-set g_ctf_dynamiclights 0
+set g_ctf_dynamiclights 0 "flags (not flag carriers) cast light of their team's colour"
 
 set g_ctf_ignore_frags 0       "1: regular frags give no points"
 exec ctfscoring-samual.cfg
index d8151425127d8fc80f1cd3e9d7c2250c229e06ad..7b83618169ce12dc6176bf97f9ecfdc14ea177e7 100644 (file)
@@ -22,6 +22,7 @@ seta hud_progressbar_shield_color "0.36 1 0.07"
 seta hud_progressbar_health_color "0.83 0.12 0"
 seta hud_progressbar_armor_color "0.28 0.8 0"
 seta hud_progressbar_fuel_color "0.77 0.67 0"
+seta hud_progressbar_oxygen_color "0.1 1 1"
 seta hud_progressbar_nexball_color "0.2 0.65 0.93"
 seta hud_progressbar_speed_color "0.77 0.67 0"
 seta hud_progressbar_acceleration_color "0.2 0.65 0.93"
@@ -64,7 +65,6 @@ seta hud_panel_weapons_timeout_fadefgmin "0.4"
 seta hud_panel_weapons_timeout_speed_in "0.25"
 seta hud_panel_weapons_timeout_speed_out "0.75"
 seta hud_panel_weapons_onlyowned "1"
-seta hud_panel_weapons_orderbyimpulse "1"
 seta hud_panel_weapons_noncurrent_alpha "0.8"
 seta hud_panel_weapons_noncurrent_scale "0.9"
 seta hud_panel_weapons_selection_radius "0"
@@ -276,6 +276,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_time "3"
 seta hud_panel_centerprint_fade_in "0.2"
 seta hud_panel_centerprint_fade_out "0.5"
index 8766bcb24835825fed6417263ba6b169455a38b4..a7e95f56f32ea1909493a71f5416c8b262e5ed36 100644 (file)
@@ -22,6 +22,7 @@ seta hud_progressbar_shield_color "0.6 0 0.6"
 seta hud_progressbar_health_color "0.6 0 0"
 seta hud_progressbar_armor_color "0 0.6 0"
 seta hud_progressbar_fuel_color "0.6 0.6 0"
+seta hud_progressbar_oxygen_color "0 1 1"
 seta hud_progressbar_nexball_color "0.7 0.1 0"
 seta hud_progressbar_speed_color "1 0.75 0"
 seta hud_progressbar_acceleration_color "0.5 0.75 1"
@@ -64,7 +65,6 @@ seta hud_panel_weapons_timeout_fadefgmin "0.4"
 seta hud_panel_weapons_timeout_speed_in "0.25"
 seta hud_panel_weapons_timeout_speed_out "0.75"
 seta hud_panel_weapons_onlyowned "1"
-seta hud_panel_weapons_orderbyimpulse "1"
 seta hud_panel_weapons_noncurrent_alpha "1"
 seta hud_panel_weapons_noncurrent_scale "1"
 seta hud_panel_weapons_selection_radius "0"
@@ -276,6 +276,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_time "3"
 seta hud_panel_centerprint_fade_in "0.2"
 seta hud_panel_centerprint_fade_out "0.5"
index 02940f8d3ab5b8c1e81e61bc00c4b57381839652..646b149d6ca8773132503d938b87323917eb983d 100644 (file)
@@ -22,6 +22,7 @@ seta hud_progressbar_shield_color "0.6 0 0.6"
 seta hud_progressbar_health_color "0.6 0 0"
 seta hud_progressbar_armor_color "0 0.6 0"
 seta hud_progressbar_fuel_color "0.6 0.6 0"
+seta hud_progressbar_oxygen_color "0 1 1"
 seta hud_progressbar_nexball_color "0.7 0.1 0"
 seta hud_progressbar_speed_color "1 0.75 0"
 seta hud_progressbar_acceleration_color "0.5 0.75 1"
@@ -64,7 +65,6 @@ seta hud_panel_weapons_timeout_fadefgmin "0"
 seta hud_panel_weapons_timeout_speed_in "0.25"
 seta hud_panel_weapons_timeout_speed_out "0.75"
 seta hud_panel_weapons_onlyowned "1"
-seta hud_panel_weapons_orderbyimpulse "1"
 seta hud_panel_weapons_noncurrent_alpha "1"
 seta hud_panel_weapons_noncurrent_scale "1"
 seta hud_panel_weapons_selection_radius "0"
@@ -276,6 +276,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_time "3"
 seta hud_panel_centerprint_fade_in "0.2"
 seta hud_panel_centerprint_fade_out "0.5"
index 41a47d7ab2d77cd1e6cc4d486eb5a0bf924b37f8..f8716369d3b9541d295f4d2051743d1aa6d2891e 100644 (file)
@@ -22,6 +22,7 @@ seta hud_progressbar_shield_color "0.6 0 0.6"
 seta hud_progressbar_health_color "0.6 0 0"
 seta hud_progressbar_armor_color "0 0.6 0"
 seta hud_progressbar_fuel_color "0.6 0.6 0"
+seta hud_progressbar_oxygen_color "0 1 1"
 seta hud_progressbar_nexball_color "0.7 0.1 0"
 seta hud_progressbar_speed_color "1 0.75 0"
 seta hud_progressbar_acceleration_color "0.5 0.75 1"
@@ -64,7 +65,6 @@ seta hud_panel_weapons_timeout_fadefgmin "0"
 seta hud_panel_weapons_timeout_speed_in "0.25"
 seta hud_panel_weapons_timeout_speed_out "0.75"
 seta hud_panel_weapons_onlyowned "1"
-seta hud_panel_weapons_orderbyimpulse "1"
 seta hud_panel_weapons_noncurrent_alpha "1"
 seta hud_panel_weapons_noncurrent_scale "1"
 seta hud_panel_weapons_selection_radius "0"
@@ -276,6 +276,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_time "3"
 seta hud_panel_centerprint_fade_in "0.2"
 seta hud_panel_centerprint_fade_out "0.5"
index f4a5e0441b97f3b5c7c5940330cc2585a9afde01..16b498a75a059d31b6720e803e5441dfa8b9014e 100644 (file)
@@ -22,6 +22,7 @@ seta hud_progressbar_shield_color "0.6 0 0.6"
 seta hud_progressbar_health_color "0.6 0 0"
 seta hud_progressbar_armor_color "0 0.6 0"
 seta hud_progressbar_fuel_color "0.6 0.6 0"
+seta hud_progressbar_oxygen_color "0 1 1"
 seta hud_progressbar_nexball_color "0.7 0.1 0"
 seta hud_progressbar_speed_color "1 0.75 0"
 seta hud_progressbar_acceleration_color "0.5 0.75 1"
@@ -64,7 +65,6 @@ seta hud_panel_weapons_timeout_fadefgmin "0"
 seta hud_panel_weapons_timeout_speed_in "0.25"
 seta hud_panel_weapons_timeout_speed_out "0.75"
 seta hud_panel_weapons_onlyowned "1"
-seta hud_panel_weapons_orderbyimpulse "1"
 seta hud_panel_weapons_noncurrent_alpha "1"
 seta hud_panel_weapons_noncurrent_scale "1"
 seta hud_panel_weapons_selection_radius "0"
@@ -276,6 +276,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_time "3"
 seta hud_panel_centerprint_fade_in "0.2"
 seta hud_panel_centerprint_fade_out "0.5"
index ea5dc69a240f1fee326c3fd58e07b94fc6add213..0e0f079e8e25d214aa6553a8b7589dc3b3eb1854 100644 (file)
@@ -22,6 +22,7 @@ seta hud_progressbar_shield_color "0.6 0 0.6"
 seta hud_progressbar_health_color "0.6 0 0"
 seta hud_progressbar_armor_color "0 0.6 0"
 seta hud_progressbar_fuel_color "0.6 0.6 0"
+seta hud_progressbar_oxygen_color "0 1 1"
 seta hud_progressbar_nexball_color "0.7 0.1 0"
 seta hud_progressbar_speed_color "1 0.75 0"
 seta hud_progressbar_acceleration_color "0.5 0.75 1"
@@ -64,7 +65,6 @@ seta hud_panel_weapons_timeout_fadefgmin "0"
 seta hud_panel_weapons_timeout_speed_in "0.25"
 seta hud_panel_weapons_timeout_speed_out "0.75"
 seta hud_panel_weapons_onlyowned "0"
-seta hud_panel_weapons_orderbyimpulse "1"
 seta hud_panel_weapons_noncurrent_alpha "1"
 seta hud_panel_weapons_noncurrent_scale "1"
 seta hud_panel_weapons_selection_radius "0"
@@ -276,6 +276,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_time "3"
 seta hud_panel_centerprint_fade_in "0.2"
 seta hud_panel_centerprint_fade_out "0.5"
index 0c5c485d4b8f16869666e5bf47d3f9ae27ef2afc..de3fc8a13c701fc583c2e4234599eceb702bc894 100644 (file)
@@ -9,11 +9,11 @@ ga    "Irish" "Irish" 32%
 it    "Italian" "Italiano" 100%
 hu    "Hungarian" "Magyar" 48%
 nl    "Dutch" "Nederlands" 63%
-pl    "Polish" "Polski" 72%
+pl    "Polish" "Polski" 74%
 pt    "Portuguese" "Português" 86%
 pt_BR "Portuguese (Brazil)" "Português (Brasil)" 100%
 ro    "Romanian" "Romana" 75%
-fi    "Finnish" "Suomi" 30%
+fi    "Finnish" "Suomi" 100%
 el    "Greek" "Ελληνική" 47%
 be    "Belarusian" "Беларуская" 55%
 bg    "Bulgarian" "Български" 60%
index 0fcbed2f2e45e5e9b273b92f7b3e2175a5358907..2d52893786d5d7d02c9e4969f4bc300fb8ddcaa8 100644 (file)
@@ -6,9 +6,10 @@
 // =========
 //  dodging
 // =========
-set g_dodging 0 "set to 1 to enable dodging in games"
+set g_dodging 0 "set to 1 to enable dodging (quick acceleration in a given direction)"
 
 seta cl_dodging_timeout 0.2 "determines how long apart (in seconds) two taps on the same direction key are considered a dodge. use 0 to disable"
+seta cl_dodging 0 "enable dodging, requires sv_dodging_clientselect to be enabled on the server"
 
 set sv_dodging_air_dodging 0
 set sv_dodging_wall_dodging 0 "allow dodging off walls"
@@ -27,6 +28,7 @@ set sv_dodging_frozen 0 "allow dodging while frozen"
 set sv_dodging_frozen_doubletap 0
 set sv_dodging_maxspeed 350 "maximum speed a player can be moving at to use the standard dodging from an (almost) standstill"
 set sv_dodging_air_maxspeed 450 "maximum speed a player can be moving at before they dodge again when air dodging is enabled"
+set sv_dodging_clientselect 0 "allow clients to opt-in to dodging movement with the cl_dodging cvar, dodging will be off for clients by default with this enabled"
 
 
 // ===========
@@ -110,7 +112,7 @@ set g_invincible_projectiles 0 "set to 1 to disable any damage to projectiles in
 // ===============
 //  rocket flying
 // ===============
-set g_rocket_flying 0 "set to 1 to enable rocket flying in all balance configs"
+set g_rocket_flying 0 "make rocket jumping easier - use the remote_jump weapon cvars for selfdamage and selfpush force"
 set g_rocket_flying_disabledelays 1 "disable detonation delays on rockets and mines"
 
 
@@ -144,7 +146,7 @@ set g_nix_with_powerups 0 "when 1, powerups still show up in NIX"
 // ================
 set g_physical_items 0 "1 uses ODE physics for dropped weapons, 2 for all items, requires physics_ode to be enabled"
 set g_physical_items_damageforcescale 3 "how affected physical weapons are by damage"
-set g_physical_items_reset 1 "return map items to their original lotation after being picked up"
+set g_physical_items_reset 1 "return map items to their original location after being picked up"
 
 
 // ===============
@@ -152,9 +154,9 @@ set g_physical_items_reset 1 "return map items to their original lotation after
 // ===============
 set g_touchexplode 0 "touching other players causes an explosion"
 set g_touchexplode_radius 50
-set g_touchexplode_damage 10
+set g_touchexplode_damage 20
 set g_touchexplode_edgedamage 0
-set g_touchexplode_force 150
+set g_touchexplode_force 300
 
 
 // ================
@@ -184,7 +186,7 @@ set g_random_gravity_negative 1000 "negative gravity multiplier"
 // =======
 //  Nades
 // =======
-set g_nades 0 "enable off-hand grenades"
+set g_nades 0 "enable off-hand grenades - use the 'dropweapon' (second press throws) or 'hook' (release throws) binds"
 set g_nades_spread 0.04 "random spread offset of throw direction"
 set g_nades_throw_offset "0 -25 0" "nade throwing offset"
 set g_nades_spawn 1 "give nades right away when player spawns rather than delaying entire refire"
@@ -290,6 +292,7 @@ set g_campcheck 0 "damages campers every few seconds"
 set g_campcheck_interval 10
 set g_campcheck_damage 100
 set g_campcheck_distance 1800
+set g_campcheck_typecheck 0 "damage campers who are typing"
 
 
 // ==========
@@ -309,7 +312,8 @@ set g_buffs_effects 1 "show particle effects from carried buffs"
 set g_buffs_waypoint_distance 1024 "maximum distance at which buff waypoint can be seen from item"
 set g_buffs_pickup_anyway 0 "instantly respawn the buff when it is picked up, instead of waiting for the player to drop it"
 set g_buffs_pickup_delay 0.7 "cooldown before player can pick up another buff after dropping one"
-set g_buffs_randomize 1 "randomize buff type when player drops buff"
+set g_buffs_randomize 1 "randomize buff type when player drops the buff, only applies to teamplay gamemodes if g_buffs_randomize_teamplay is enabled"
+set g_buffs_randomize_teamplay 1 "in teamplay gamemodes, randomize buff type when player drops the buff, requires g_buffs_randomize"
 set g_buffs_random_lifetime 30 "re-spawn the buff again if it hasn't been touched after this time in seconds"
 set g_buffs_random_location 0 "randomize buff location on start and when reset"
 set g_buffs_random_location_attempts 10 "number of random locations a single buff will attempt to respawn at before giving up"
@@ -387,7 +391,7 @@ set g_buffs_flight_time 60 "flight buff carry time"
 // ================
 //  grappling hook
 // ================
-set g_grappling_hook 0 "let players spawn with the grappling hook which allows them to pull themselves up"
+set g_grappling_hook 0 "let players spawn with the grappling hook which allows them to pull themselves"
 set g_grappling_hook_useammo 0 "use ammunition with the off-hand grappling hook"
 
 
@@ -442,8 +446,9 @@ set g_breakablehook_owner 0 "allow owner to break their own hook"
 // ===========
 //  multijump
 // ===========
-seta cl_multijump 1 "allow multijump mutator"
+seta cl_multijump -1 "allow multijump mutator, set to -1 for the server to decide whether it's enabled"
 set g_multijump 0      "Number of multiple jumps to allow (jumping again in the air), -1 allows for infinite jumps"
+set g_multijump_client 1 "If the client sets cl_multijump to -1, this setting is used for them as a default"
 set g_multijump_add 0  "0 = make the current z velocity equal to jumpvelocity, 1 = add jumpvelocity to the current z velocity"
 set g_multijump_speed -999999  "Minimum vertical speed a player must have in order to jump again"
 set g_multijump_maxspeed 0
@@ -521,3 +526,9 @@ set g_smneg_cooldown_factor 0.25 "Stale-move negation: penalty cooldown factor"
 set g_random_items 0 "Whether to enable random items."
 set g_random_loot 0 "Whether to enable random loot."
 exec randomitems-xonotic.cfg
+
+// ===============
+//  pinata
+// ===============
+set g_pinata 0 "if set to 1 you will not only drop your current weapon when you are killed, but you will drop all weapons that you possessed"
+set g_pinata_offhand 0 "if enabled, the second weapon will drop as well while dual wielding"
index 54929f2d0b2e7816ca49b6fd3150e04c7395b61a..41f0706ea3d72f95c1d2b4180c3a27d5dd6232ad 100644 (file)
@@ -356,6 +356,7 @@ seta notification_CENTER_ALONE "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_ASSAULT_ATTACKING "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_ASSAULT_DEFENDING "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_ASSAULT_OBJ_DESTROYED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CAMPAIGN_MESSAGE "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_CAMPCHECK "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_COINTOSS "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_COUNTDOWN_BEGIN "1" "0 = off, 1 = centerprint"
@@ -525,7 +526,6 @@ seta notification_CENTER_ROUND_PLAYER_WIN "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_ROUND_TEAM_LOSS "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_ROUND_TEAM_WIN "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_ROUND_TIED "1" "0 = off, 1 = centerprint"
-seta notification_CENTER_SECONDARY_NODAMAGE "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_SEQUENCE_COMPLETED "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_SEQUENCE_COUNTER "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_SEQUENCE_COUNTER_FEWMORE "1" "0 = off, 1 = centerprint"
index 823e85bce3c237bae128e9840a882762f4a6ab88..b74f68b3db4d1c3c341c70216e80765f7c28f8cc 100644 (file)
@@ -7,7 +7,7 @@
 //  Main options
 // ==============
 set g_physics_clientselect 0 "allow clients to select their physics set"
-set g_physics_clientselect_options "xonotic nexuiz quake warsow defrag quake3 vecxis quake2 bones overkill"
+set g_physics_clientselect_options "xonotic nexuiz quake warsow defrag quake3 vecxis quake2 bones"
 set g_physics_clientselect_default "" "override default physics"
 
 // =========
index d09b2c5ccffa730255a6545d0f411a11adc05fc5..7c8e3b8ad16f7207d5296f16a4cde3a61863c540 100644 (file)
@@ -93,8 +93,8 @@ pk3: csprogs-$(VER).pk3
        $(eval DAT=$(PROG)-$(VER).dat)
        $(eval LNO=$(PROG)-$(VER).lno)
        @ echo "http://xonotic.org" > $(TXT)
-       @ ln -f $(PROGS_OUT)/$(PROG).dat $(DAT)
-       @ ln -f $(PROGS_OUT)/$(PROG).lno $(LNO)
+       @ cp -f $(PROGS_OUT)/$(PROG).dat $(DAT)
+       @ cp -f $(PROGS_OUT)/$(PROG).lno $(LNO)
        @ $(RM) *.pk3
        $(ZIP) $(PK3) $(TXT) $(DAT) $(LNO)
        @ $(RM) $(TXT) $(DAT) $(LNO)
index d11355659aa8071a5795e030b555a01361aeeb8b..90bf6fb91ffa0cccbb9ef81320af6047ed59e7ba 100644 (file)
@@ -70,8 +70,8 @@ bool autocvar_cl_spawn_event_particles;
 bool autocvar_cl_spawn_event_sound = 1;
 // float autocvar_cl_spawn_point_model;
 bool autocvar_cl_spawn_point_particles;
-float autocvar_cl_spawn_point_dist_min = 1200;
-float autocvar_cl_spawn_point_dist_max = 1600;
+float autocvar_cl_spawn_point_dist_min = 800;
+float autocvar_cl_spawn_point_dist_max = 1200;
 bool autocvar_cl_spawnzoom = 1;
 float autocvar_cl_spawnzoom_speed = 1;
 float autocvar_cl_spawnzoom_factor = 2;
@@ -151,7 +151,7 @@ float autocvar_crosshair_ring_reload_alpha;
 float autocvar_crosshair_ring_reload_size;
 float autocvar_crosshair_size;
 bool autocvar_crosshair_chase = true;
-float crosshair_chase_playeralpha = 0.25;
+float autocvar_crosshair_chase_playeralpha = 0.25;
 int autocvar_ekg;
 float autocvar_fov;
 bool autocvar_hud_cursormode = true;
@@ -243,6 +243,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_time;
 bool autocvar_hud_panel_chat;
 bool autocvar_hud_panel_engineinfo;
@@ -363,6 +364,7 @@ vector autocvar_hud_progressbar_acceleration_neg_color;
 float autocvar_hud_progressbar_alpha;
 vector autocvar_hud_progressbar_armor_color;
 vector autocvar_hud_progressbar_fuel_color;
+vector autocvar_hud_progressbar_oxygen_color = '0.1 1 1';
 vector autocvar_hud_progressbar_health_color;
 vector autocvar_hud_progressbar_nexball_color;
 vector autocvar_hud_progressbar_shield_color;
@@ -413,9 +415,9 @@ float autocvar_cl_hitsound_min_pitch = 0.75;
 float autocvar_cl_hitsound_max_pitch = 1.5;
 float autocvar_cl_hitsound_nom_damage = 25;
 float autocvar_cl_hitsound_antispam_time;
-int autocvar_cl_eventchase_spectated_change = 1;
+bool autocvar_cl_eventchase_spectated_change = false;
 float autocvar_cl_eventchase_spectated_change_time = 1;
-int autocvar_cl_eventchase_death = 1;
+int autocvar_cl_eventchase_death = 2;
 float autocvar_cl_eventchase_distance = 140;
 bool autocvar_cl_eventchase_frozen = false;
 float autocvar_cl_eventchase_speed = 1.3;
@@ -444,6 +446,7 @@ int autocvar__cl_color;
 int autocvar__cl_playerskin;
 string autocvar__cl_playermodel;
 float autocvar_cl_deathglow;
+float autocvar_cl_deathglow_min = 0.5;
 bool autocvar_developer_csqcentities;
 float autocvar_cl_jetpack_attenuation = 2;
 bool autocvar_cl_showspectators;
index 1272758f76cee3de642322d9ce6ffb2419660e7a..624d997fecd7cc5bb5b51cc83fb106c72755a079 100644 (file)
@@ -1,6 +1,5 @@
 #include "csqcmodel_hooks.qh"
 #include "autocvars.qh"
-#include "csqcmodel_hooks.qh"
 #include "miscfunctions.qh"
 #include <client/mutators/_mod.qh>
 #include "player_skeleton.qh"
@@ -109,7 +108,6 @@ string forceplayermodels_goodmodel;
 int forceplayermodels_goodmodelindex;
 
 .vector glowmod;
-.vector old_glowmod;
 
 void CSQCPlayer_ModelAppearance_PreUpdate(entity this)
 {
@@ -294,16 +292,14 @@ void CSQCPlayer_ModelAppearance_Apply(entity this, bool islocalplayer)
        {
                if(this.csqcmodel_isdead)
                {
-                       // Fade out to black now...
-                       if(this.old_glowmod == '0 0 0') { this.old_glowmod = this.glowmod; }
-                       this.colormap = 0;
-
-                       this.glowmod = this.old_glowmod * bound(0, 1 - (time - this.death_time) / autocvar_cl_deathglow, 1);
-                       this.glowmod_x = max(this.glowmod.x, 0.0001);
-                       this.glowmod_y = max(this.glowmod.y, 0.0001);
-                       this.glowmod_z = max(this.glowmod.z, 0.0001);
+                       float min_factor = bound(0, autocvar_cl_deathglow_min, 1);
+                       if(this.colormap > 0)
+                               min_factor /= 2;
+                       float glow_fade = bound(0, 1 - (time - this.death_time) / autocvar_cl_deathglow, 1);
+                       this.glowmod *= (min_factor + glow_fade * (1 - min_factor));
+                       if (this.glowmod == '0 0 0')
+                               this.glowmod.x = 0.000001;
                }
-               else if(this.old_glowmod != '0 0 0') { this.old_glowmod = '0 0 0'; }
        }
 
        //printf("CSQCPlayer_ModelAppearance_Apply(): state = %s, colormap = %f, glowmod = %s\n", (this.csqcmodel_isdead ? "DEAD" : "ALIVE"), this.colormap, vtos(this.glowmod));
index db1a5afacaed87760c210bde6088c475c7dab29c..0cf71294a78936db18f480c5af6eb4047468405c 100644 (file)
@@ -173,10 +173,6 @@ REPLICATE(cvar_cl_weaponpriorities[9], string, "cl_weaponpriority9");
 
 float bgmtime;
 
-string weaponorder_byimpulse; // NOTE: this is a misnomer, weapon order is not always sorted by impulse
-string weaponorder_bypriority;
-bool weapons_orderbyimpulse; // update priority list when toggling this
-
 float vortex_charge_movingavg;
 
 int serverflags;
index 9da25ebe9145e27f7cf400afd30e4b1f74343fc5..3a13048d823b6398cdde1c7b9c52ced193a33449 100644 (file)
@@ -398,6 +398,8 @@ Main HUD system
 ==================
 */
 
+float lasthud;
+float vh_notice_time;
 void HUD_Vehicle()
 {
        if(autocvar__hud_configure) return;
@@ -409,6 +411,11 @@ void HUD_Vehicle()
                Vehicle info = Vehicles_from(hud);
                info.vr_hud(info);
        }
+
+       if(hud != HUD_NORMAL && lasthud == HUD_NORMAL)
+               vh_notice_time = time + autocvar_cl_vehicles_notify_time;
+
+       lasthud = hud;
 }
 
 void HUD_Panel_Draw(entity panent)
@@ -588,6 +595,7 @@ bool HUD_WouldShowCursor()
        return false;
 }
 
+float prev_myteam;
 void HUD_Main()
 {
        int i;
@@ -596,6 +604,13 @@ void HUD_Main()
        else
                hud_fade_alpha = 1 - autocvar__menu_alpha;
 
+       if(myteam != prev_myteam)
+       {
+               myteamcolors = colormapPaletteColor(myteam, 1);
+               FOREACH(hud_panels, true, it.update_time = time);
+               prev_myteam = myteam;
+       }
+
        HUD_Configure_Frame();
 
        if(scoreboard_fade_alpha == 1)
index a6c22c74eee9bf113f4d71570b90ec57f7a33938..e23647fb3fb6dd919047b77e9695d386f7d98f6b 100644 (file)
@@ -45,6 +45,7 @@ void HUD_Panel_ExportCfg(string cfgname)
                HUD_Write_Cvar("hud_progressbar_health_color");
                HUD_Write_Cvar("hud_progressbar_armor_color");
                HUD_Write_Cvar("hud_progressbar_fuel_color");
+               HUD_Write_Cvar("hud_progressbar_oxygen_color");
                HUD_Write_Cvar("hud_progressbar_nexball_color");
                HUD_Write_Cvar("hud_progressbar_speed_color");
                HUD_Write_Cvar("hud_progressbar_acceleration_color");
@@ -97,7 +98,6 @@ void HUD_Panel_ExportCfg(string cfgname)
                                        HUD_Write_Cvar("hud_panel_weapons_timeout_speed_in");
                                        HUD_Write_Cvar("hud_panel_weapons_timeout_speed_out");
                                        HUD_Write_Cvar("hud_panel_weapons_onlyowned");
-                                       HUD_Write_Cvar("hud_panel_weapons_orderbyimpulse");
                                        HUD_Write_Cvar("hud_panel_weapons_noncurrent_alpha");
                                        HUD_Write_Cvar("hud_panel_weapons_noncurrent_scale");
                                        HUD_Write_Cvar("hud_panel_weapons_selection_radius");
@@ -193,6 +193,7 @@ void HUD_Panel_ExportCfg(string cfgname)
                                        HUD_Write_Cvar("hud_panel_centerprint_align");
                                        HUD_Write_Cvar("hud_panel_centerprint_flip");
                                        HUD_Write_Cvar("hud_panel_centerprint_fontscale");
+                                       HUD_Write_Cvar("hud_panel_centerprint_fontscale_bold");
                                        HUD_Write_Cvar("hud_panel_centerprint_time");
                                        HUD_Write_Cvar("hud_panel_centerprint_fade_in");
                                        HUD_Write_Cvar("hud_panel_centerprint_fade_out");
index d5601e5a34f86387a532baef847a42e52f903793..446a64ec65649c7266c890f56fdc803f366dec72 100644 (file)
@@ -6,6 +6,9 @@
 #include <client/miscfunctions.qh>
 
 // CenterPrint (#16)
+// These are the functions that draw the text at the center of the screen (e.g. frag messages and server MOTDs).
+// Usually local_notification_centerprint_generic() is called, which in turn calls centerprint_generic(), which
+// uses some kind of macro magic to call HUD_CenterPrint, which draws them on screen using drawcolorcodedstring().
 
 const int CENTERPRINT_MAX_MSGS = 10;
 const int CENTERPRINT_MAX_ENTRIES = 50;
@@ -113,6 +116,7 @@ void reset_centerprint_messages()
                strfree(centerprint_messages[i]);
        }
 }
+
 float hud_configure_cp_generation_time;
 void HUD_CenterPrint ()
 {
@@ -191,15 +195,11 @@ void HUD_CenterPrint ()
                panel_size -= '2 2 0' * panel_bg_padding;
        }
 
+       bool is_bold;
+       string centerprint_message = strzone("");
        int entries;
        float height;
        vector fontsize;
-       // entries = bound(1, floor(CENTERPRINT_MAX_ENTRIES * 4 * panel_size_y/panel_size_x), CENTERPRINT_MAX_ENTRIES);
-       // height = panel_size_y/entries;
-       // fontsize = '1 1 0' * height;
-       height = vid_conheight/50 * autocvar_hud_panel_centerprint_fontscale;
-       fontsize = '1 1 0' * height;
-       entries = bound(1, floor(panel_size.y/height), CENTERPRINT_MAX_ENTRIES);
 
        int i, j, k, n, g;
        float a, sz, align, current_msg_posY = 0, msg_size;
@@ -213,6 +213,21 @@ void HUD_CenterPrint ()
        align = bound(0, autocvar_hud_panel_centerprint_align, 1);
        for (g=0, i=0, j=cpm_index; i<CENTERPRINT_MAX_MSGS; ++i, ++j)
        {
+               // if the notification starts with ^BOLD make it bold (e.g. frag messages);
+               is_bold = (substring(centerprint_messages[j], 0, 5) == BOLD_OPERATOR);
+               // remove ^BOLD so it doesn't get printed onscreen
+               if (is_bold)
+                       strcpy(centerprint_message, substring(centerprint_messages[j], 5, -1));
+               else
+                       strcpy(centerprint_message, centerprint_messages[j]);
+
+               // entries = bound(1, floor(CENTERPRINT_MAX_ENTRIES * 4 * panel_size_y/panel_size_x), CENTERPRINT_MAX_ENTRIES);
+               // height = panel_size_y/entries;
+               // fontsize = '1 1 0' * height;
+               height = (is_bold) ? vid_conheight/50 * autocvar_hud_panel_centerprint_fontscale_bold : vid_conheight/50 * autocvar_hud_panel_centerprint_fontscale;
+               fontsize = '1 1 0' * height;
+               entries = bound(1, floor(panel_size.y/height), CENTERPRINT_MAX_ENTRIES);
+
                if (j == CENTERPRINT_MAX_MSGS)
                        j = 0;
                if (centerprint_expire_time[j] == -1)
@@ -272,9 +287,9 @@ void HUD_CenterPrint ()
                drawfontscale = hud_scale * sz;
 
                if (centerprint_countdown_num[j])
-                       n = tokenizebyseparator(strreplace("^COUNT", count_seconds(centerprint_countdown_num[j]), centerprint_messages[j]), "\n");
+                       n = tokenizebyseparator(strreplace("^COUNT", count_seconds(centerprint_countdown_num[j]), centerprint_message), "\n");
                else
-                       n = tokenizebyseparator(centerprint_messages[j], "\n");
+                       n = tokenizebyseparator(centerprint_message, "\n");
 
                if (autocvar_hud_panel_centerprint_flip)
                {
@@ -306,7 +321,9 @@ void HUD_CenterPrint ()
                                        if (align)
                                                pos.x = panel_pos.x + (panel_size.x - stringwidth(ts, true, fontsize) * sz) * align;
                                        if (a > 0.5/255.0)  // Otherwise guaranteed invisible - don't show. This is checked a second time after some multiplications with other factors were done so temporary changes of these cannot cause flicker.
+                                               if (is_bold) draw_beginBoldFont();
                                                drawcolorcodedstring(pos + eY * 0.5 * (1 - sz * hud_scale.x) * fontsize.y, ts, fontsize, a, DRAWFLAG_NORMAL);
+                                               if (is_bold) draw_endBoldFont();
                                        pos.y += fontsize.y;
                                }
                                else
@@ -326,6 +343,7 @@ void HUD_CenterPrint ()
                        if (pos.y < panel_pos.y) // check if the next message can be shown
                        {
                                drawfontscale = hud_scale;
+                               strfree(centerprint_message);
                                return;
                        }
                }
@@ -338,10 +356,13 @@ void HUD_CenterPrint ()
                        if(pos.y > panel_pos.y + panel_size.y - fontsize.y) // check if the next message can be shown
                        {
                                drawfontscale = hud_scale;
+                               strfree(centerprint_message);
                                return;
                        }
                }
        }
+       strfree(centerprint_message);
+
        drawfontscale = hud_scale;
        if (all_messages_expired)
        {
index 1e124dd94243fa63af52906cd410d927933d83f8..1a61a96d3d1c90bad00b39a7f0fa79ddf9a181c8 100644 (file)
@@ -9,7 +9,7 @@
 
 void HUD_HealthArmor()
 {
-       int armor, health, fuel;
+       int armor, health, fuel, air_time;
        if(!autocvar__hud_configure)
        {
                if((!autocvar_hud_panel_healtharmor) || (spectatee_status == -1))
@@ -52,12 +52,14 @@ void HUD_HealthArmor()
                        prev_armor = 0;
                }
                fuel = STAT(FUEL);
+               air_time = bound(0, STAT(AIR_FINISHED) - time, 10);
        }
        else
        {
                health = 150;
                armor = 75;
                fuel = 20;
+               air_time = 6;
        }
 
        HUD_Panel_LoadCvars();
@@ -79,6 +81,13 @@ void HUD_HealthArmor()
                mySize -= '2 2 0' * panel_bg_padding;
        }
 
+       float air_alpha = 1;
+       if (STAT(AIR_FINISHED) && time > STAT(AIR_FINISHED))
+       {
+               air_alpha = blink_synced(0.5, 0.5, 7, STAT(AIR_FINISHED), -1);
+               air_time = 10;
+       }
+
        int baralign = autocvar_hud_panel_healtharmor_baralign;
        int iconalign = autocvar_hud_panel_healtharmor_iconalign;
 
@@ -112,6 +121,8 @@ void HUD_HealthArmor()
 
                if(fuel)
                        HUD_Panel_DrawProgressBar(pos, vec2(mySize.x, 0.2 * mySize.y), "progressbar", fuel/100, 0, (baralign == 1 || baralign == 3), autocvar_hud_progressbar_fuel_color, panel_fg_alpha * 0.8, DRAWFLAG_NORMAL);
+               if(air_time)
+                       HUD_Panel_DrawProgressBar(pos + eY * 0.8 * mySize.y, vec2(mySize.x, 0.2 * mySize.y), "progressbar", air_time / 10, 0, (baralign == 1 || baralign == 3), autocvar_hud_progressbar_oxygen_color, air_alpha * panel_fg_alpha * 0.8, DRAWFLAG_NORMAL);
        }
        else
        {
@@ -135,13 +146,13 @@ void HUD_HealthArmor()
                                armor_offset.y = mySize.y;
                }
 
-               bool health_baralign, armor_baralign, fuel_baralign;
+               bool health_baralign, armor_baralign, fuel_baralign, air_align;
                bool health_iconalign, armor_iconalign;
                if (autocvar_hud_panel_healtharmor_flip)
                {
                        armor_baralign = (autocvar_hud_panel_healtharmor_baralign == 2 || autocvar_hud_panel_healtharmor_baralign == 1);
                        health_baralign = (autocvar_hud_panel_healtharmor_baralign == 3 || autocvar_hud_panel_healtharmor_baralign == 1);
-                       fuel_baralign = health_baralign;
+                       air_align = fuel_baralign = health_baralign;
                        armor_iconalign = (autocvar_hud_panel_healtharmor_iconalign == 2 || autocvar_hud_panel_healtharmor_iconalign == 1);
                        health_iconalign = (autocvar_hud_panel_healtharmor_iconalign == 3 || autocvar_hud_panel_healtharmor_iconalign == 1);
                }
@@ -149,7 +160,7 @@ void HUD_HealthArmor()
                {
                        health_baralign = (autocvar_hud_panel_healtharmor_baralign == 2 || autocvar_hud_panel_healtharmor_baralign == 1);
                        armor_baralign = (autocvar_hud_panel_healtharmor_baralign == 3 || autocvar_hud_panel_healtharmor_baralign == 1);
-                       fuel_baralign = armor_baralign;
+                       air_align = fuel_baralign = armor_baralign;
                        health_iconalign = (autocvar_hud_panel_healtharmor_iconalign == 2 || autocvar_hud_panel_healtharmor_iconalign == 1);
                        armor_iconalign = (autocvar_hud_panel_healtharmor_iconalign == 3 || autocvar_hud_panel_healtharmor_iconalign == 1);
                }
@@ -197,10 +208,7 @@ void HUD_HealthArmor()
 
                                        if (health <= autocvar_hud_panel_healtharmor_progressbar_gfx_lowhealth)
                                        {
-                                               float BLINK_FACTOR = 0.15;
-                                               float BLINK_BASE = 0.85;
-                                               float BLINK_FREQ = 9;
-                                               pain_health_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ);
+                                               pain_health_alpha = blink(0.85, 0.15, 9);
                                        }
                                }
                                HUD_Panel_DrawProgressBar(pos + health_offset, mySize, autocvar_hud_panel_healtharmor_progressbar_health, p_health/maxhealth, is_vertical, health_baralign, autocvar_hud_progressbar_health_color, autocvar_hud_progressbar_alpha * panel_fg_alpha * pain_health_alpha, DRAWFLAG_NORMAL);
@@ -256,7 +264,8 @@ void HUD_HealthArmor()
                                DrawNumIcon(pos + armor_offset, mySize, armor, "armor", is_vertical, armor_iconalign, HUD_Get_Num_Color(armor, maxarmor), 1);
                }
 
-               if(fuel)
+               vector cell_size = mySize;
+               if (fuel || air_time)
                {
                        if (is_vertical)
                                mySize.x *= 0.2 / 2; //if vertical always halve x to not cover too much numbers with 3 digits
@@ -266,7 +275,20 @@ void HUD_HealthArmor()
                                mySize.x *= 2; //restore full panel size
                        else if (panel_ar < 1/4)
                                mySize.y *= 2; //restore full panel size
-                       HUD_Panel_DrawProgressBar(pos, mySize, "progressbar", fuel/100, is_vertical, fuel_baralign, autocvar_hud_progressbar_fuel_color, panel_fg_alpha * 0.8, DRAWFLAG_NORMAL);
+                       if (fuel)
+                               HUD_Panel_DrawProgressBar(pos, mySize, "progressbar", fuel/100, is_vertical, fuel_baralign, autocvar_hud_progressbar_fuel_color, panel_fg_alpha * 0.8, DRAWFLAG_NORMAL);
+                       if (air_time)
+                       {
+                               if (panel_ar > 1 && panel_ar < 4)
+                                       pos.y += cell_size.y;
+                               else if (panel_ar > 1/4 && panel_ar <= 1)
+                                       pos.x += cell_size.x;
+                               if (is_vertical)
+                                       pos.x += cell_size.x - mySize.x;
+                               else
+                                       pos.y += cell_size.y - mySize.y;
+                               HUD_Panel_DrawProgressBar(pos, mySize, "progressbar", air_time / 10, is_vertical, air_align, autocvar_hud_progressbar_oxygen_color, air_alpha * panel_fg_alpha * 0.8, DRAWFLAG_NORMAL);
+                       }
                }
        }
 
index 0bf9b8dd0543c6f0cb1a59cb10592baccc093a4d..3c87a1c1d58ebd259491f3988d6d6a92b5d0386d 100644 (file)
@@ -10,7 +10,7 @@ void HUD_PressedKeys()
 {
        if(!autocvar__hud_configure)
        {
-               if(!autocvar_hud_panel_pressedkeys) return;
+               if(!autocvar_hud_panel_pressedkeys || spectatee_status < 0) return;
                if(spectatee_status <= 0 && autocvar_hud_panel_pressedkeys < 2) return;
        }
 
index 38419bdc5a38b68fa281bbeb214bdfb6ab73e135..a0bd8727a99d271004951553a1d1653f0213cd91 100644 (file)
@@ -790,7 +790,7 @@ void QuickMenu_Default(string target_submenu)
        if(teamplay)
        {
        QUICKMENU_SMENU(CTX(_("QMCMD^Team chat")), "Team chat")
-               QUICKMENU_ENTRY_TC(CTX(_("QMCMD^quad soon")), "say_team %s", "quad soon", CTX(_("QMCMD^quad soon")))
+               QUICKMENU_ENTRY_TC(CTX(_("QMCMD^strength soon")), "say_team %s", "strength soon", CTX(_("QMCMD^strength soon")))
                QUICKMENU_ENTRY_TC(CTX(_("QMCMD^free item, icon")), "say_team %s; g_waypointsprite_team_here_p", "free item %x^7 (l:%y^7)", CTX(_("QMCMD^free item %x^7 (l:%y^7)")))
                QUICKMENU_ENTRY_TC(CTX(_("QMCMD^took item, icon")), "say_team %s; g_waypointsprite_team_here", "took item (l:%l^7)", CTX(_("QMCMD^took item (l:%l^7)")))
                QUICKMENU_ENTRY_TC(CTX(_("QMCMD^negative")), "say_team %s", "negative", CTX(_("QMCMD^negative")))
@@ -854,11 +854,16 @@ void QuickMenu_Default(string target_submenu)
                QUICKMENU_ENTRY(CTX(_("QMCMD^Shuffle teams")), "vcall shuffleteams")
        QUICKMENU_SMENU(CTX(_("QMCMD^Call a vote")), "Call a vote")
 
+       if(spectatee_status != 0)
+       {
+       QUICKMENU_SMENU_PL(CTX(_("QMCMD^Spectate a player")), "Spectate a player", "spectate \"%s^7\"", 0, 1)
+       }
+
        if(target_submenu != "" && !target_submenu_found)
        {
                LOG_INFOF("Couldn't find submenu \"%s\"", target_submenu);
                if(prvm_language != "en")
-                       LOG_INFOF("^3Warning: submenu title must be in English", target_submenu);
+                       LOG_INFO("^3Warning: submenu title must be in English");
                QuickMenu_Buffer_Size = 0;
        }
 }
index 281b2377ff10e839439cd83f002a5ef6ebf93130..ecf8f9f33851ecb3fa8659c76448b134e0f90f8d 100644 (file)
@@ -5,7 +5,7 @@
 #include <client/miscfunctions.qh>
 #include <common/mapinfo.qh>
 
-// Race timer (#6)
+// Race timer (#8)
 
 // return the string of the onscreen race timer
 string MakeRaceString(int cp, float mytime, float theirtime, float othertime, float lapdelta, string theirname)
index e11a134558519acaa873875f8da9922b390b1786..08a1a73bb0977148aa8174f48ef67d836aad4ded 100644 (file)
@@ -1604,11 +1604,11 @@ void Scoreboard_Draw()
        draw_endBoldFont();
 
        // Game Info: Game Detail
-       float tl, fl, ll;
-       str = ""; // optionally "^7Limits: "
-       tl = STAT(TIMELIMIT);
-       fl = STAT(FRAGLIMIT);
-       ll = STAT(LEADLIMIT);
+       float tl = STAT(TIMELIMIT);
+       float fl = STAT(FRAGLIMIT);
+       float ll = STAT(LEADLIMIT);
+       float ll_and_fl = STAT(LEADLIMIT_AND_FRAGLIMIT);
+       str = "";
        if(tl > 0)
                str = strcat(str, sprintf(_("^3%1.0f minutes"), tl));
        if(!ISGAMETYPE(LMS))
@@ -1621,33 +1621,40 @@ void Scoreboard_Draw()
                        {
                                str = strcat(str, sprintf(_("^5%s %s"), ScoreString(teamscores_flags(ts_primary), fl),
                                        (teamscores_label(ts_primary) == "score")   ? CTX(_("SCO^points")) :
-                                       (teamscores_label(ts_primary) == "fastest") ? CTX(_("SCO^is beaten")) :
+                                       (teamscores_label(ts_primary) == "fastest") ? "" :
                                        TranslateScoresLabel(teamscores_label(ts_primary))));
                        }
                        else
                        {
                                str = strcat(str, sprintf(_("^5%s %s"), ScoreString(scores_flags(ps_primary), fl),
                                        (scores_label(ps_primary) == "score")   ? CTX(_("SCO^points")) :
-                                       (scores_label(ps_primary) == "fastest") ? CTX(_("SCO^is beaten")) :
+                                       (scores_label(ps_primary) == "fastest") ? "" :
                                        TranslateScoresLabel(scores_label(ps_primary))));
                        }
                }
                if(ll > 0)
                {
                        if(tl > 0 || fl > 0)
-                               str = strcat(str, "^7 / "); // delimiter
+                       {
+                               // delimiter
+                               if (ll_and_fl && fl > 0)
+                                       str = strcat(str, "^7 & ");
+                               else
+                                       str = strcat(str, "^7 / ");
+                       }
+
                        if(teamplay)
                        {
                                str = strcat(str, sprintf(_("^2+%s %s"), ScoreString(teamscores_flags(ts_primary), ll),
                                        (teamscores_label(ts_primary) == "score")   ? CTX(_("SCO^points")) :
-                                       (teamscores_label(ts_primary) == "fastest") ? CTX(_("SCO^is beaten")) :
+                                       (teamscores_label(ts_primary) == "fastest") ? "" :
                                        TranslateScoresLabel(teamscores_label(ts_primary))));
                        }
                        else
                        {
                                str = strcat(str, sprintf(_("^2+%s %s"), ScoreString(scores_flags(ps_primary), ll),
                                        (scores_label(ps_primary) == "score")   ? CTX(_("SCO^points")) :
-                                       (scores_label(ps_primary) == "fastest") ? CTX(_("SCO^is beaten")) :
+                                       (scores_label(ps_primary) == "fastest") ? "" :
                                        TranslateScoresLabel(scores_label(ps_primary))));
                        }
                }
index 832ffad0b38ca9b27727451808c44570e5d5eb79..8668886a91282da36356f92d9577a8fdfffa9601 100644 (file)
@@ -39,6 +39,8 @@ int weaponorder_cmp(int i, int j, entity pass)
        weapon_size.y = panel_size.y / rows; \
 MACRO_END
 
+string cl_weaponpriority_old;
+bool weapons_orderbyimpulse_old;
 void HUD_Weapons()
 {
        // declarations
@@ -90,19 +92,19 @@ void HUD_Weapons()
        // update generic hud functions
        HUD_Panel_LoadCvars();
 
-       // figure out weapon order (how the weapons are sorted) // TODO make this configurable
-       if(weaponorder_bypriority != autocvar_cl_weaponpriority || autocvar_hud_panel_weapons_orderbyimpulse != weapons_orderbyimpulse || !weaponorder[0])
+       if(cl_weaponpriority_old != autocvar_cl_weaponpriority || weapons_orderbyimpulse_old != autocvar_hud_panel_weapons_orderbyimpulse || weaponorder[0] == NULL)
        {
-               int weapon_cnt;
-               weapons_orderbyimpulse = autocvar_hud_panel_weapons_orderbyimpulse;
-               strcpy(weaponorder_bypriority, autocvar_cl_weaponpriority);
-               string weporder = W_FixWeaponOrder_ForceComplete(W_NumberWeaponOrder(weaponorder_bypriority));
+               weapons_orderbyimpulse_old = autocvar_hud_panel_weapons_orderbyimpulse;
+               strcpy(cl_weaponpriority_old, autocvar_cl_weaponpriority);
+               string weporder = W_FixWeaponOrder_ForceComplete(W_NumberWeaponOrder(cl_weaponpriority_old));
                if(autocvar_hud_panel_weapons_orderbyimpulse)
+               {
                        weporder = W_FixWeaponOrder_BuildImpulseList(weporder);
-               strcpy(weaponorder_byimpulse, weporder);
-               weaponorder_cmp_str = strcat(" ", weaponorder_byimpulse, " ");
+               }
+
+               weaponorder_cmp_str = strcat(" ", weporder, " ");
 
-               weapon_cnt = 0;
+               int weapon_cnt = 0;
                FOREACH(Weapons, it != WEP_Null && it.impulse >= 0, weaponorder[weapon_cnt++] = it);
                for(i = weapon_cnt; i < Weapons_MAX; ++i)
                        weaponorder[i] = NULL;
index b61f425aa6da44b8d9d4f073a7929275f54a5685..d6a073a5de91d4798917c424c2f37cc8b3fd70eb 100644 (file)
@@ -136,7 +136,9 @@ void CSQC_Init()
 
        registercvar("cl_shootfromfixedorigin", "");
 
-       registercvar("cl_multijump", "1");
+       registercvar("cl_multijump", "-1");
+
+       registercvar("cl_dodging", "0");
 
        registercvar("cl_spawn_near_teammate", "1");
 
@@ -240,7 +242,7 @@ void Shutdown()
 bool SetTeam(entity o, int Team)
 {
        TC(int, Team);
-       devassert_once(Team);
+       //devassert_once(Team);
        entity tm;
        if(teamplay)
        {
index 360305601a8b71cfdd345436f213f9eafb5e50ee..1af1b971ffe91272af6cfcb915c1de041cbf49a8 100644 (file)
@@ -214,6 +214,28 @@ vector expandingbox_resize_centered_box_offset(float sz, vector boxsize, float b
        return boxsize * (0.5 * (1 - sz));
 }
 
+// NOTE base is the central value
+// freq: circle frequency, = 2*pi*frequency in hertz
+// start_pos:
+//  -1 start from the lower value
+//   0 start from the base value
+//   1 start from the higher value
+float blink_synced(float base, float range, float freq, float start_time, int start_pos)
+{
+       // note:
+       //   RMS = sqrt(base^2 + 0.5 * range^2)
+       // thus
+       //   base = sqrt(RMS^2 - 0.5 * range^2)
+       // ensure RMS == 1
+
+       return base + range * sin((time - start_time - (M_PI / 2) * start_pos) * freq);
+}
+
+float blink(float base, float range, float freq)
+{
+       return blink_synced(base, range, freq, 0, 0);
+}
+
 void drawborderlines(float thickness, vector pos, vector dim, vector color, float theAlpha, float drawflag)
 {
        vector line_dim = '0 0 0';
@@ -382,7 +404,7 @@ float PolyDrawModelSurface(entity e, float i_s)
        for(i_t = 0; i_t < n_t; ++i_t)
        {
                tri = getsurfacetriangle(e, i_s, i_t);
-               R_BeginPolygon(tex, 0);
+               R_BeginPolygon(tex, 0, false);
                R_PolygonVertex(getsurfacepoint(e, i_s, tri.x), getsurfacepointattribute(e, i_s, tri.x, SPA_TEXCOORDS0), '1 1 1', 1);
                R_PolygonVertex(getsurfacepoint(e, i_s, tri.y), getsurfacepointattribute(e, i_s, tri.y, SPA_TEXCOORDS0), '1 1 1', 1);
                R_PolygonVertex(getsurfacepoint(e, i_s, tri.z), getsurfacepointattribute(e, i_s, tri.z, SPA_TEXCOORDS0), '1 1 1', 1);
@@ -400,22 +422,15 @@ void PolyDrawModel(entity e)
 
 void DrawCircleClippedPic(vector centre, float radi, string pic, float f, vector rgb, float a, float drawflag)
 {
-       float d;
        vector ringsize, v, t;
        ringsize = radi * '1 1 0';
        centre = HUD_Shift(centre);
        ringsize = HUD_Scale(ringsize);
 
-       float co = cos(f * 2 * M_PI);
-       float si = sin(f * 2 * M_PI);
-       float q = fabs(co) + fabs(si);
-       co /= q;
-       si /= q;
-
        if(f >= 1)
        {
                // draw full rectangle
-               R_BeginPolygon(pic, drawflag);
+               R_BeginPolygon(pic, drawflag, true);
                        v = centre;                     t = '0.5 0.5 0';
                        v.x += 0.5 * ringsize.x;        t += '0.5 0.5 0';
                        R_PolygonVertex(v, t, rgb, a);
@@ -432,23 +447,19 @@ void DrawCircleClippedPic(vector centre, float radi, string pic, float f, vector
                        v.y -= 0.5 * ringsize.y;        t -= '0.5 -0.5 0';
                        R_PolygonVertex(v, t, rgb, a);
                R_EndPolygon();
+               return;  // Complete rectangle, nothing more needed.
+       }
 
-               d = q - 1;
-               if(d > 0)
-               {
-                       R_BeginPolygon(pic, drawflag);
-                               v = centre;                     t = '0.5 0.5 0';
-                               R_PolygonVertex(v, t, rgb, a);
+       float co = cos(f * 2 * M_PI);
+       float si = sin(f * 2 * M_PI);
+       float q = fabs(co) + fabs(si);
+       co /= q;
+       si /= q;
 
-                               v = centre;                     t = '0.5 0.5 0';
-                               v.x += 0.5 * ringsize.x;        t += '0.5 0.5 0';
-                               R_PolygonVertex(v, t, rgb, a);
-               }
-       }
-       else if(f > 0.75)
+       if(f > 0.75)
        {
-               // draw upper and first triangle
-               R_BeginPolygon(pic, drawflag);
+               // draw upper half in full
+               R_BeginPolygon(pic, drawflag, true);
                        v = centre;                     t = '0.5 0.5 0';
                        v.x += 0.5 * ringsize.x;        t += '0.5 0.5 0';
                        R_PolygonVertex(v, t, rgb, a);
@@ -461,7 +472,8 @@ void DrawCircleClippedPic(vector centre, float radi, string pic, float f, vector
                        v.x -= 0.5 * ringsize.x;        t -= '0.5 0.5 0';
                        R_PolygonVertex(v, t, rgb, a);
                R_EndPolygon();
-               R_BeginPolygon(pic, drawflag);
+               // draw clipped lower half as a quad
+               R_BeginPolygon(pic, drawflag, true);
                        v = centre;                     t = '0.5 0.5 0';
                        R_PolygonVertex(v, t, rgb, a);
 
@@ -472,15 +484,11 @@ void DrawCircleClippedPic(vector centre, float radi, string pic, float f, vector
                        v = centre;                     t = '0.5 0.5 0';
                        v.y -= 0.5 * ringsize.y;        t -= '0.5 -0.5 0';
                        R_PolygonVertex(v, t, rgb, a);
-
-               d = q - 0.75;
-               if(d <= 0)
-                       R_EndPolygon();
        }
        else if(f > 0.5)
        {
-               // draw upper triangle
-               R_BeginPolygon(pic, drawflag);
+               // draw upper half in full
+               R_BeginPolygon(pic, drawflag, true);
                        v = centre;                     t = '0.5 0.5 0';
                        v.x += 0.5 * ringsize.x;        t += '0.5 0.5 0';
                        R_PolygonVertex(v, t, rgb, a);
@@ -493,23 +501,19 @@ void DrawCircleClippedPic(vector centre, float radi, string pic, float f, vector
                        v.x -= 0.5 * ringsize.x;        t -= '0.5 0.5 0';
                        R_PolygonVertex(v, t, rgb, a);
                R_EndPolygon();
+               // draw clipped lower half as a triangle
+               R_BeginPolygon(pic, drawflag, true);
+                       v = centre;                     t = '0.5 0.5 0';
+                       R_PolygonVertex(v, t, rgb, a);
 
-               d = q - 0.5;
-               if(d > 0)
-               {
-                       R_BeginPolygon(pic, drawflag);
-                               v = centre;                     t = '0.5 0.5 0';
-                               R_PolygonVertex(v, t, rgb, a);
-
-                               v = centre;                     t = '0.5 0.5 0';
-                               v.x -= 0.5 * ringsize.x;        t -= '0.5 0.5 0';
-                               R_PolygonVertex(v, t, rgb, a);
-               }
+                       v = centre;                     t = '0.5 0.5 0';
+                       v.x -= 0.5 * ringsize.x;        t -= '0.5 0.5 0';
+                       R_PolygonVertex(v, t, rgb, a);
        }
        else if(f > 0.25)
        {
-               // draw first triangle
-               R_BeginPolygon(pic, drawflag);
+               // draw clipped lower half as a quad
+               R_BeginPolygon(pic, drawflag, true);
                        v = centre;                     t = '0.5 0.5 0';
                        R_PolygonVertex(v, t, rgb, a);
 
@@ -520,34 +524,30 @@ void DrawCircleClippedPic(vector centre, float radi, string pic, float f, vector
                        v = centre;                     t = '0.5 0.5 0';
                        v.y += 0.5 * ringsize.y;        t += '0.5 -0.5 0';
                        R_PolygonVertex(v, t, rgb, a);
-
-               d = q - 0.25;
-               if(d <= 0)
-                       R_EndPolygon();
        }
-       else
+       else if (f > 0)
        {
-               d = q;
-               if(d > 0)
-               {
-                       R_BeginPolygon(pic, drawflag);
-                               v = centre;                     t = '0.5 0.5 0';
-                               R_PolygonVertex(v, t, rgb, a);
-
-                               v = centre;                     t = '0.5 0.5 0';
-                               v.x += 0.5 * ringsize.x;        t += '0.5 0.5 0';
-                               R_PolygonVertex(v, t, rgb, a);
-               }
-       }
+               // draw clipped lower half as a triangle
+               R_BeginPolygon(pic, drawflag, true);
+                       v = centre;                     t = '0.5 0.5 0';
+                       R_PolygonVertex(v, t, rgb, a);
 
-       if(d > 0)
-       {
                        v = centre;                     t = '0.5 0.5 0';
-                       v.x += co * 0.5 * ringsize.x;   t += co * '0.5 0.5 0';
-                       v.y += si * 0.5 * ringsize.y;   t += si * '0.5 -0.5 0';
+                       v.x += 0.5 * ringsize.x;        t += '0.5 0.5 0';
                        R_PolygonVertex(v, t, rgb, a);
-               R_EndPolygon();
        }
+       else
+       {
+               // Nothing to draw.
+               return;
+       }
+
+       // The last, moving vertex.
+               v = centre;                     t = '0.5 0.5 0';
+               v.x += co * 0.5 * ringsize.x;   t += co * '0.5 0.5 0';
+               v.y += si * 0.5 * ringsize.y;   t += si * '0.5 -0.5 0';
+               R_PolygonVertex(v, t, rgb, a);
+       R_EndPolygon();
 }
 
 /** engine callback */
index d259efe66036ed21404fac890ca60b32b9d28787..3397ab7059133106f8f8a2008a44c619ac7dbafe 100644 (file)
@@ -52,6 +52,9 @@ float expandingbox_sizefactor_from_fadelerp(float fadelerp);
 
 vector expandingbox_resize_centered_box_offset(float sz, vector boxsize, float boxxsizefactor);
 
+float blink_synced(float base, float range, float freq, float start_time, int start_blink);
+float blink(float base, float range, float freq);
+
 void drawborderlines(float thickness, vector pos, vector dim, vector color, float theAlpha, float drawflag);
 
 void drawpic_tiled(vector pos, string pic, vector sz, vector area, vector color, float theAlpha, float drawflag);
index 74136906e4c6a955c1bace120df660ea08dcdc68..87633056de69b7dbb52e5916b6447352fb3acda7 100644 (file)
@@ -88,7 +88,7 @@ void Draw_ShowNames(entity this)
                        if (eo.z < 0 || eo.x < 0 || eo.y < 0 || eo.x > vid_conwidth || eo.y > vid_conheight) continue;
                        eo.z = 0;
                        if (vdist((vec2(o) - eo), <, autocvar_hud_shownames_antioverlap_distance)
-                           && vlen2(it.origin - view_origin) < vlen2(this.origin - view_origin))
+                               && vlen2(it.origin - view_origin) < vlen2(this.origin - view_origin))
                        {
                                overlap = 1;
                                break;
@@ -97,14 +97,14 @@ void Draw_ShowNames(entity this)
        }
        bool onscreen = (o.z >= 0 && o.x >= 0 && o.y >= 0 && o.x <= vid_conwidth && o.y <= vid_conheight);
        if (!this.fadedelay) this.fadedelay = time + SHOWNAMES_FADEDELAY;
-       if (this.csqcmodel_isdead)                                                                   // dead player, fade out slowly
+       if (this.csqcmodel_isdead) // dead player, fade out slowly
        {
                this.alpha = max(0, this.alpha - SHOWNAMES_FADESPEED * 0.25 * frametime);
        }
        else if (!onscreen || (!this.sameteam && !hit)) // out of view, fade out
        {
                this.alpha = max(0, this.alpha - SHOWNAMES_FADESPEED * frametime);
-               this.fadedelay = 0;                         // reset fade in delay, enemy has left the view
+               this.fadedelay = 0; // reset fade in delay, enemy has left the view
        }
        else if (overlap > 0) // tag overlap detected, fade out
        {
@@ -119,14 +119,12 @@ void Draw_ShowNames(entity this)
                this.alpha = min(1, this.alpha + SHOWNAMES_FADESPEED * frametime);
        }
        float a = autocvar_hud_shownames_alpha * this.alpha;
-       // multiply by player alpha
        if (!this.sameteam || (this.sv_entnum == player_localentnum))
        {
                float f = entcs_GetAlpha(this.sv_entnum - 1);
                if (f == 0) f = 1;
                if (f < 0) f = 0;
-               // FIXME: alpha is negative when dead, breaking death fade
-               if (!this.csqcmodel_isdead) a *= f;
+               a *= f;
        }
        if (a < ALPHA_MIN_VISIBLE && ISGAMETYPE(CTS)) return;
        if (vdist(this.origin - view_origin, >=, max_shot_distance)) return;
@@ -156,11 +154,10 @@ void Draw_ShowNames(entity this)
                myPos.x += 0.5 * (mySize.x / resize - mySize.x);
                myPos.y += (mySize.y / resize - mySize.y);
                // this is where the origin of the string
-               vector namepos = myPos;
                float namewidth = mySize.x;
                if (autocvar_hud_shownames_status && this.sameteam)
                {
-                       vector pos = namepos + eY * autocvar_hud_shownames_fontsize * resize;
+                       vector pos = myPos + eY * autocvar_hud_shownames_fontsize * resize;
                        vector sz = vec2(0.5 * mySize.x, resize * autocvar_hud_shownames_statusbar_height);
                        if (autocvar_hud_shownames_statusbar_highlight)
                                drawfill(pos + eX * 0.25 * mySize.x, sz, '0.7 0.7 0.7', a / 2, DRAWFLAG_NORMAL);
@@ -178,13 +175,13 @@ void Draw_ShowNames(entity this)
                        }
                }
                string s = entcs_GetName(this.sv_entnum - 1);
-               if ((autocvar_hud_shownames_decolorize == 1 && teamplay)
-                   || autocvar_hud_shownames_decolorize == 2) s = playername(s, entcs_GetTeam(this.sv_entnum - 1));
+               if ((autocvar_hud_shownames_decolorize == 1 && teamplay) || autocvar_hud_shownames_decolorize == 2)
+                       s = playername(s, entcs_GetTeam(this.sv_entnum - 1));
                drawfontscale = '1 1 0' * resize;
                s = textShortenToWidth(s, namewidth, '1 1 0' * autocvar_hud_shownames_fontsize, stringwidth_colors);
                float width = stringwidth(s, true, '1 1 0' * autocvar_hud_shownames_fontsize);
-               if (width != namewidth) namepos.x += (namewidth - width) / 2;
-               drawcolorcodedstring(namepos, s, '1 1 0' * autocvar_hud_shownames_fontsize, a, DRAWFLAG_NORMAL);
+               myPos.x = o.x - (width * resize) / 2;
+               drawcolorcodedstring(myPos, s, '1 1 0' * autocvar_hud_shownames_fontsize, a, DRAWFLAG_NORMAL);
                drawfontscale = '1 1 0';
        }
 }
@@ -216,7 +213,8 @@ void Draw_ShowNames_All()
                        it.sameteam = false;
                }
                bool dead = entcs_IsDead(i) || entcs_IsSpectating(i);
-               if (!it.csqcmodel_isdead) setorigin(it, entcs.origin);
+               if (!it.csqcmodel_isdead || it.alpha > 0)
+                       setorigin(it, entcs.origin);
                it.csqcmodel_isdead = dead;
                Draw_ShowNames(it);
        });
index c565651d4a3a0b49daee81ae6a76649b60889d66..cdb8894a8dab6dab3872e191c7340afeb48206dc 100644 (file)
@@ -68,7 +68,7 @@ void draw_teamradar_background(float fg)
        {
                fga = 1;
                fgc = '1 1 1' * fg;
-               R_BeginPolygon(minimapname, DRAWFLAG_SCREEN | DRAWFLAG_MIPMAP);
+               R_BeginPolygon(minimapname, DRAWFLAG_SCREEN | DRAWFLAG_MIPMAP, true);
                if(v_flipped)
                {
                        R_PolygonVertex(teamradar_texcoord_to_2dcoord(mi_pictexcoord3), yinvert(mi_pictexcoord3), fgc, fga);
@@ -112,14 +112,14 @@ void draw_teamradar_player(vector coord3d, vector pangles, vector rgb)
        else
                rgb2 = '1 1 1';
 
-       R_BeginPolygon("", 0);
+       R_BeginPolygon("", 0, true);
        R_PolygonVertex(coord+forward*3, '0 0 0', rgb2, panel_fg_alpha);
        R_PolygonVertex(coord+right*4-forward*2.5, '0 1 0', rgb2, panel_fg_alpha);
        R_PolygonVertex(coord-forward*2, '1 0 0', rgb2, panel_fg_alpha);
        R_PolygonVertex(coord-right*4-forward*2.5, '1 1 0', rgb2, panel_fg_alpha);
        R_EndPolygon();
 
-       R_BeginPolygon("", 0);
+       R_BeginPolygon("", 0, true);
        R_PolygonVertex(coord+forward*2, '0 0 0', rgb, panel_fg_alpha);
        R_PolygonVertex(coord+right*3-forward*2, '0 1 0', rgb, panel_fg_alpha);
        R_PolygonVertex(coord-forward, '1 0 0', rgb, panel_fg_alpha);
@@ -164,7 +164,7 @@ void draw_teamradar_link(vector start, vector end, int colors)
        c0 = colormapPaletteColor(colors & 0x0F, false);
        c1 = colormapPaletteColor((colors & 0xF0) / 0x10, false);
 
-       R_BeginPolygon("", 0);
+       R_BeginPolygon("", 0, true);
        R_PolygonVertex(start - norm, '0 0 0', c0, panel_fg_alpha);
        R_PolygonVertex(start + norm, '0 1 0', c0, panel_fg_alpha);
        R_PolygonVertex(end + norm, '1 1 0', c1, panel_fg_alpha);
index 4b8bc4899a788de78152dec7a1990b56a1de01c0..57cd15a78bd7fd68cac6454b13232d56a4b1d1c4 100644 (file)
@@ -48,7 +48,7 @@
 #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;
+float autocvar_cl_viewmodel_alpha = 1;
 
 bool autocvar_cl_bobmodel;
 float autocvar_cl_bobmodel_speed;
@@ -394,7 +394,6 @@ STATIC_INIT(fpscounter_init)
        showfps_prevfps_time = currentTime; // we must initialize it to avoid an instant low frame sending
 }
 
-float drawtime;
 float avgspeed;
 vector GetCurrentFov(float fov)
 {
@@ -755,6 +754,146 @@ int WantEventchase(entity this, bool want_vehiclechase)
        return 0;
 }
 
+void View_EventChase(entity this)
+{
+       // event chase camera
+       if(autocvar_chase_active <= 0) // greater than 0 means it's enabled manually, and this code is skipped
+       {
+               if(STAT(CAMERA_SPECTATOR))
+               {
+                       if(spectatee_status > 0)
+                       {
+                               if(!autocvar_chase_active)
+                               {
+                                       cvar_set("chase_active", "-2");
+                                       return;
+                               }
+                       }
+                       else if(autocvar_chase_active == -2)
+                               cvar_set("chase_active", "0");
+
+                       if(autocvar_chase_active == -2)
+                               return;
+               }
+               else if(autocvar_chase_active == -2)
+                       cvar_set("chase_active", "0");
+
+               bool vehicle_chase = (hud != HUD_NORMAL && (autocvar_cl_eventchase_vehicle || spectatee_status > 0));
+
+               float vehicle_viewdist = 0;
+               vector vehicle_viewofs = '0 0 0';
+
+               if(vehicle_chase)
+               {
+                       if(hud != HUD_BUMBLEBEE_GUN)
+                       {
+                               Vehicle info = Vehicles_from(hud);
+                               vehicle_viewdist = info.height;
+                               vehicle_viewofs = info.view_ofs;
+                               if(vehicle_viewdist < 0) // when set below 0, this vehicle doesn't use third person view (gunner slots)
+                                       vehicle_chase = false;
+                       }
+                       else
+                               vehicle_chase = false;
+               }
+
+               int eventchase = WantEventchase(this, vehicle_chase);
+               if (eventchase)
+               {
+                       vector current_view_origin_override = '0 0 0';
+                       vector view_offset_override = '0 0 0';
+                       float chase_distance_override = 0;
+                       bool custom_eventchase = MUTATOR_CALLHOOK(CustomizeEventchase, this);
+                       if(custom_eventchase)
+                       {
+                               current_view_origin_override = M_ARGV(0, vector);
+                               view_offset_override = M_ARGV(1, vector);
+                               chase_distance_override = M_ARGV(0, float);
+                       }
+                       eventchase_running = true;
+
+                       // make special vector since we can't use view_origin (It is one frame old as of this code, it gets set later with the results this code makes.)
+                       vector current_view_origin = (csqcplayer ? csqcplayer.origin : pmove_org);
+                       if (custom_eventchase)
+                               current_view_origin = current_view_origin_override;
+
+                       // detect maximum viewoffset and use it
+                       vector view_offset = autocvar_cl_eventchase_viewoffset;
+                       if(vehicle_chase)
+                       {
+                               if(vehicle_viewofs)
+                                       view_offset = vehicle_viewofs;
+                               else
+                                       view_offset = autocvar_cl_eventchase_vehicle_viewoffset;
+                       }
+                       if (custom_eventchase)
+                               view_offset = view_offset_override;
+
+                       if(view_offset)
+                       {
+                               WarpZone_TraceLine(current_view_origin, current_view_origin + view_offset + ('0 0 1' * autocvar_cl_eventchase_maxs.z), MOVE_WORLDONLY, this);
+                               if(trace_fraction == 1) { current_view_origin += view_offset; }
+                               else { current_view_origin.z += max(0, (trace_endpos.z - current_view_origin.z) - autocvar_cl_eventchase_maxs.z); }
+                       }
+
+                       // We must enable chase_active to get a third person view (weapon viewmodel hidden and own player model showing).
+                       // Ideally, there should be another way to enable third person cameras, such as through setproperty()
+                       // -1 enables chase_active while marking it as set by this code, and not by the user (which would be 1)
+                       if(!autocvar_chase_active) { cvar_set("chase_active", "-1"); }
+
+                       // make the camera smooth back
+                       float chase_distance = autocvar_cl_eventchase_distance;
+                       if(vehicle_chase)
+                       {
+                               if(vehicle_viewofs)
+                                       chase_distance = vehicle_viewdist;
+                               else
+                                       chase_distance = autocvar_cl_eventchase_vehicle_distance;
+                       }
+                       if (custom_eventchase)
+                               chase_distance = chase_distance_override;
+
+                       if(autocvar_cl_eventchase_speed && eventchase_current_distance < chase_distance)
+                               eventchase_current_distance += autocvar_cl_eventchase_speed * (chase_distance - eventchase_current_distance) * frametime; // slow down the further we get
+                       else if(eventchase_current_distance != chase_distance)
+                               eventchase_current_distance = chase_distance;
+
+                       vector forward, right, up;
+                       MAKE_VECTORS(view_angles, forward, right, up);
+
+                       vector eventchase_target_origin = (current_view_origin - (forward * eventchase_current_distance));
+                       WarpZone_TraceBox(current_view_origin, autocvar_cl_eventchase_mins, autocvar_cl_eventchase_maxs, eventchase_target_origin, MOVE_WORLDONLY, this);
+
+                       // If the boxtrace fails, revert back to line tracing.
+                       if(!this.viewloc)
+                       if(trace_startsolid)
+                       {
+                               eventchase_target_origin = (current_view_origin - (forward * eventchase_current_distance));
+                               WarpZone_TraceLine(current_view_origin, eventchase_target_origin, MOVE_WORLDONLY, this);
+                               setproperty(VF_ORIGIN, (trace_endpos - (forward * autocvar_cl_eventchase_mins.z)));
+                       }
+                       else { setproperty(VF_ORIGIN, trace_endpos); }
+
+                       if(!this.viewloc)
+                               setproperty(VF_ANGLES, WarpZone_TransformVAngles(WarpZone_trace_transform, view_angles));
+               }
+
+               if (eventchase <= 0 && autocvar_chase_active < 0) // time to disable chase_active if it was set by this code
+               {
+                       eventchase_running = false;
+                       cvar_set("chase_active", "0");
+                       eventchase_current_distance = 0; // start from 0 next time
+               }
+       }
+       // workaround for camera stuck between player's legs when using chase_active 1
+       // because the engine stops updating the chase_active camera when the game ends
+       else if(intermission)
+       {
+               cvar_settemp("chase_active", "-1");
+               eventchase_current_distance = 0;
+       }
+}
+
 void HUD_Crosshair_Vehicle(entity this)
 {
        if(hud != HUD_BUMBLEBEE_GUN)
@@ -780,7 +919,7 @@ void UpdateDamage()
        if (damage_dealt_time != damage_dealt_time_prev)
        {
                unaccounted_damage += unaccounted_damage_new;
-               LOG_TRACE("dmg total: ", ftos(unaccounted_damage), " (+", ftos(unaccounted_damage_new), ")");
+               //LOG_TRACE("dmg total: ", ftos(unaccounted_damage), " (+", ftos(unaccounted_damage_new), ")");
        }
        damage_dealt_time_prev = damage_dealt_time;
 
@@ -829,7 +968,7 @@ void HitSound()
                                pitch_shift = mirror_value + (mirror_value - pitch_shift);
                        }
 
-                       LOG_TRACE("dmg total (dmg): ", ftos(unaccounted_damage), " , pitch shift: ", ftos(pitch_shift));
+                       //LOG_TRACE("dmg total (dmg): ", ftos(unaccounted_damage), " , pitch shift: ", ftos(pitch_shift));
 
                        // todo: avoid very long and very short sounds from wave stretching using different sound files? seems unnecessary
                        // todo: normalize sound pressure levels? seems unnecessary
@@ -981,12 +1120,12 @@ void HUD_Crosshair(entity this)
                else if(autocvar_chase_active > 0 && autocvar_crosshair_chase)
                {
                        vector player_org = ((csqcplayer) ? csqcplayer.origin + csqcplayer.view_ofs : view_origin);
-                       if(csqcplayer && crosshair_chase_playeralpha && crosshair_chase_playeralpha < 1)
+                       if(csqcplayer && autocvar_crosshair_chase_playeralpha && autocvar_crosshair_chase_playeralpha < 1)
                        {
                                traceline(view_origin, view_origin + max_shot_distance * view_forward, MOVE_NORMAL, NULL);
                                float myalpha = (!csqcplayer.m_alpha) ? 1 : csqcplayer.m_alpha;
                                if(trace_ent == csqcplayer && STAT(HEALTH) > 0)
-                                       csqcplayer.alpha = min(crosshair_chase_playeralpha, myalpha);
+                                       csqcplayer.alpha = min(autocvar_crosshair_chase_playeralpha, myalpha);
                                else
                                        csqcplayer.alpha = csqcplayer.m_alpha;
                        }
@@ -1281,10 +1420,10 @@ void HUD_Crosshair(entity this)
                                }
 
                                if (autocvar_crosshair_ring_inner && ring_inner_value) // lets draw a ring inside a ring so you can ring while you ring
-                                       DrawCircleClippedPic(wcross_origin, wcross_size.x * ring_scale, ring_inner_image, ring_inner_value, ring_inner_rgb, wcross_alpha * ring_inner_alpha, DRAWFLAG_ADDITIVE);
+                                       DrawCircleClippedPic(wcross_origin, wcross_size.x * wcross_resolution * ring_scale, ring_inner_image, ring_inner_value, ring_inner_rgb, wcross_alpha * ring_inner_alpha, DRAWFLAG_ADDITIVE);
 
                                if (ring_value)
-                                       DrawCircleClippedPic(wcross_origin, wcross_size.x * ring_scale, ring_image, ring_value, ring_rgb, wcross_alpha * ring_alpha, DRAWFLAG_ADDITIVE);
+                                       DrawCircleClippedPic(wcross_origin, wcross_size.x * wcross_resolution * ring_scale, ring_image, ring_value, ring_rgb, wcross_alpha * ring_alpha, DRAWFLAG_ADDITIVE);
                        }
 
 #define CROSSHAIR_DO_BLUR(M,sz,wcross_name,wcross_alpha) \
@@ -1553,267 +1692,517 @@ void HUD_Mouse(entity player)
        HUD_Cursor_Show();
 }
 
-bool ov_enabled;
-float oldr_nearclip;
-float oldr_farclip_base;
-float oldr_farclip_world;
-float oldr_novis;
-float oldr_useportalculling;
-float oldr_useinfinitefarclip;
-
-float prev_myteam;
-int lasthud;
-float vh_notice_time;
-void CSQC_UpdateView(entity this, float w, float h)
+void View_NightVision()
 {
-       TC(int, w); TC(int, h);
-       entity e;
-       float fov;
-       float f;
-       vector vf_size, vf_min;
+       if(!(autocvar_r_fakelight >= 2 || autocvar_r_fullbright) || (serverflags & SERVERFLAG_ALLOW_FULLBRIGHT))
+               return;
+
+       // apply night vision effect
+       vector tc_00, tc_01, tc_10, tc_11;
+       vector rgb = '0 0 0';
        float a;
 
-       execute_next_frame();
+       if(!nightvision_noise)
+       {
+               nightvision_noise = new(nightvision_noise);
+       }
+       if(!nightvision_noise2)
+       {
+               nightvision_noise2 = new(nightvision_noise2);
+       }
+
+       // color tint in yellow
+       drawfill('0 0 0', autocvar_vid_conwidth * '1 0 0' + autocvar_vid_conheight * '0 1 0', '0.5 1 0.3', 1, DRAWFLAG_MODULATE);
+
+       // draw BG
+       a = Noise_Pink(nightvision_noise, frametime * 1.5) * 0.05 + 0.15;
+       rgb = '1 1 1';
+       tc_00 = '0 0 0' + '0.2 0 0' * sin(time * 0.3) + '0 0.3 0' * cos(time * 0.7);
+       tc_01 = '0 2.25 0' + '0.6 0 0' * cos(time * 1.2) - '0 0.3 0' * sin(time * 2.2);
+       tc_10 = '1.5 0 0' - '0.2 0 0' * sin(time * 0.5) + '0 0.5 0' * cos(time * 1.7);
+       //tc_11 = '1 1 0' + '0.6 0 0' * sin(time * 0.6) + '0 0.3 0' * cos(time * 0.1);
+       tc_11 = tc_01 + tc_10 - tc_00;
+       R_BeginPolygon("gfx/nightvision-bg.tga", DRAWFLAG_ADDITIVE, true);
+       R_PolygonVertex('0 0 0', tc_00, rgb, a);
+       R_PolygonVertex(autocvar_vid_conwidth * '1 0 0', tc_10, rgb, a);
+       R_PolygonVertex(autocvar_vid_conwidth * '1 0 0' + autocvar_vid_conheight * '0 1 0', tc_11, rgb, a);
+       R_PolygonVertex(autocvar_vid_conheight * '0 1 0', tc_01, rgb, a);
+       R_EndPolygon();
+
+       // draw FG
+       a = Noise_Pink(nightvision_noise2, frametime * 0.1) * 0.05 + 0.12;
+       rgb = '0.3 0.6 0.4' + '0.1 0.4 0.2' * Noise_White(nightvision_noise2, frametime);
+       tc_00 = '0 0 0' + '1 0 0' * Noise_White(nightvision_noise2, frametime) + '0 1 0' * Noise_White(nightvision_noise2, frametime);
+       tc_01 = tc_00 + '0 3 0' * (1 + Noise_White(nightvision_noise2, frametime) * 0.2);
+       tc_10 = tc_00 + '2 0 0' * (1 + Noise_White(nightvision_noise2, frametime) * 0.3);
+       tc_11 = tc_01 + tc_10 - tc_00;
+       R_BeginPolygon("gfx/nightvision-fg.tga", DRAWFLAG_ADDITIVE, true);
+       R_PolygonVertex('0 0 0', tc_00, rgb, a);
+       R_PolygonVertex(autocvar_vid_conwidth * '1 0 0', tc_10, rgb, a);
+       R_PolygonVertex(autocvar_vid_conwidth * '1 0 0' + autocvar_vid_conheight * '0 1 0', tc_11, rgb, a);
+       R_PolygonVertex(autocvar_vid_conheight * '0 1 0', tc_01, rgb, a);
+       R_EndPolygon();
+}
 
-       ++framecount;
+void DrawReticle(entity this)
+{
+       if(!autocvar_cl_reticle || MUTATOR_CALLHOOK(DrawReticle))
+       {
+               reticle_type = 0;
+               return;
+       }
 
-       stats_get();
-       hud = STAT(HUD);
+       float is_dead = (STAT(HEALTH) <= 0);
+       string reticle_image = string_null;
+       bool wep_zoomed = false;
+       for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+       {
+               entity wepe = viewmodels[slot];
+               Weapon wep = wepe.activeweapon;
+               if(wep != WEP_Null && wep.wr_zoom)
+               {
+                       bool do_zoom = wep.wr_zoom(wep, NULL);
+                       if(!reticle_image && wep.w_reticle && wep.w_reticle != "")
+                               reticle_image = wep.w_reticle;
+                       wep_zoomed += do_zoom;
+               }
+       }
+       // Draw the aiming reticle for weapons that use it
+       // reticle_type is changed to the item we are zooming / aiming with, to decide which reticle to use
+       // It must be a persisted float for fading out to work properly (you let go of the zoom button for
+       // the view to go back to normal, so reticle_type would become 0 as we fade out)
+       if(spectatee_status || is_dead || hud != HUD_NORMAL || this.viewloc)
+       {
+               // no zoom reticle while dead
+               reticle_type = 0;
+       }
+       else if(wep_zoomed && autocvar_cl_reticle_weapon)
+       {
+               if(reticle_image) { reticle_type = 2; }
+               else { reticle_type = 0; }
+       }
+       else if(button_zoom || zoomscript_caught)
+       {
+               // normal zoom
+               reticle_type = 1;
+       }
 
-       if(hud != HUD_NORMAL && lasthud == HUD_NORMAL)
-               vh_notice_time = time + autocvar_cl_vehicles_notify_time;
+       if(reticle_type)
+       {
+               vector reticle_pos = '0 0 0', reticle_size = '0 0 0';
+               if(autocvar_cl_reticle_stretch)
+               {
+                       reticle_size.x = vid_conwidth;
+                       reticle_size.y = vid_conheight;
+                       reticle_pos.x = 0;
+                       reticle_pos.y = 0;
+               }
+               else
+               {
+                       reticle_size.x = max(vid_conwidth, vid_conheight);
+                       reticle_size.y = max(vid_conwidth, vid_conheight);
+                       reticle_pos.x = (vid_conwidth - reticle_size.x) / 2;
+                       reticle_pos.y = (vid_conheight - reticle_size.y) / 2;
+               }
 
-       lasthud = hud;
+               float f = (zoomscript_caught) ? 1 : current_zoomfraction;
 
-       ReplicateVars(false);
-       if (ReplicateVars_NOT_SENDING())
-               ReplicateVars_DELAY(0.8 + random() * 0.4); // no need to check cvars every frame
+               if(f)
+               {
+                       switch(reticle_type)
+                       {
+                               case 1: drawpic(reticle_pos, "gfx/reticle_normal", reticle_size, '1 1 1', f * autocvar_cl_reticle_normal_alpha, DRAWFLAG_NORMAL); break;
+                               case 2: if(reticle_image) drawpic(reticle_pos, reticle_image, reticle_size, '1 1 1', f * autocvar_cl_reticle_weapon_alpha, DRAWFLAG_NORMAL); break;
+                       }
+               }
+       }
+}
 
-       HUD_Scale_Disable();
+// visual overlay while in liquids
+// provides some effects to the postprocessing function
+void HUD_Contents()
+{
+       if(!autocvar_hud_contents || MUTATOR_CALLHOOK(HUD_Contents))
+               return;
 
-       if(autocvar__hud_showbinds_reload) // menu can set this one
+       // improved polyblend
+       float contentalpha_temp, incontent, liquidalpha, contentfadetime;
+       vector liquidcolor;
+
+       switch(pointcontents(view_origin))
        {
-               db_close(binddb);
-               binddb = db_create();
-               cvar_set("_hud_showbinds_reload", "0");
+               case CONTENT_WATER:
+                       liquidalpha = autocvar_hud_contents_water_alpha;
+                       liquidcolor = stov(autocvar_hud_contents_water_color);
+                       incontent = 1;
+                       break;
+
+               case CONTENT_LAVA:
+                       liquidalpha = autocvar_hud_contents_lava_alpha;
+                       liquidcolor = stov(autocvar_hud_contents_lava_color);
+                       incontent = 1;
+                       break;
+
+               case CONTENT_SLIME:
+                       liquidalpha = autocvar_hud_contents_slime_alpha;
+                       liquidcolor = stov(autocvar_hud_contents_slime_color);
+                       incontent = 1;
+                       break;
+
+               default:
+                       liquidalpha = 0;
+                       liquidcolor = '0 0 0';
+                       incontent = 0;
+                       break;
        }
 
-       if(checkextension("DP_CSQC_MINFPS_QUALITY"))
-               view_quality = getproperty(VF_MINFPS_QUALITY);
+       if(incontent) // fade in/out at different speeds so you can do e.g. instant fade when entering water and slow when leaving it.
+       { // also lets delcare previous values for blending properties, this way it isn't reset until after you have entered a different content
+               contentfadetime = autocvar_hud_contents_fadeintime;
+               liquidalpha_prev = liquidalpha;
+               liquidcolor_prev = liquidcolor;
+       }
        else
-               view_quality = 1;
+               contentfadetime = autocvar_hud_contents_fadeouttime;
 
-       button_attack2 = PHYS_INPUT_BUTTON_ATCK2(this);
-       button_zoom = PHYS_INPUT_BUTTON_ZOOM(this);
+       contentalpha_temp = bound(0, drawframetime / max(0.0001, contentfadetime), 1);
+       contentavgalpha = contentavgalpha * (1 - contentalpha_temp) + incontent * contentalpha_temp;
 
-       vf_size = getpropertyvec(VF_SIZE);
-       vf_min = getpropertyvec(VF_MIN);
-       vid_width = vf_size.x;
-       vid_height = vf_size.y;
+       if(contentavgalpha)
+               drawfill('0 0 0', vec2(vid_conwidth, vid_conheight), liquidcolor_prev, contentavgalpha * liquidalpha_prev, DRAWFLAG_NORMAL);
+
+       if(autocvar_hud_postprocessing)
+       {
+               if(autocvar_hud_contents_blur && contentavgalpha)
+               {
+                       content_blurpostprocess.x = 1;
+                       content_blurpostprocess.y = contentavgalpha * autocvar_hud_contents_blur;
+                       content_blurpostprocess.z = contentavgalpha * autocvar_hud_contents_blur_alpha;
+               }
+               else
+               {
+                       content_blurpostprocess.x = 0;
+                       content_blurpostprocess.y = 0;
+                       content_blurpostprocess.z = 0;
+               }
+       }
+}
+
+// visual pain effects on the screen
+// provides some effects to the postprocessing function
+void HUD_Damage()
+{
+       if(!autocvar_hud_damage || STAT(FROZEN))
+               return;
 
-       vector reticle_pos = '0 0 0', reticle_size = '0 0 0';
        vector splash_pos = '0 0 0', splash_size = '0 0 0';
+       splash_size.x = max(vid_conwidth, vid_conheight);
+       splash_size.y = max(vid_conwidth, vid_conheight);
+       splash_pos.x = (vid_conwidth - splash_size.x) / 2;
+       splash_pos.y = (vid_conheight - splash_size.y) / 2;
 
-       WaypointSprite_Load();
+       float myhealth_flash_temp;
+       myhealth = STAT(HEALTH);
 
-       CSQCPlayer_SetCamera();
+       // fade out
+       myhealth_flash = max(0, myhealth_flash - autocvar_hud_damage_fade_rate * frametime);
+       // add new damage
+       myhealth_flash = bound(0, myhealth_flash + dmg_take * autocvar_hud_damage_factor, autocvar_hud_damage_maxalpha);
 
-       if(player_localentnum <= maxclients) // is it a client?
-               current_player = player_localentnum - 1;
-       else // then player_localentnum is the vehicle I'm driving
-               current_player = player_localnum;
-       myteam = entcs_GetTeam(current_player);
+       float pain_threshold, pain_threshold_lower, pain_threshold_lower_health;
+       pain_threshold = autocvar_hud_damage_pain_threshold;
+       pain_threshold_lower = autocvar_hud_damage_pain_threshold_lower;
+       pain_threshold_lower_health = autocvar_hud_damage_pain_threshold_lower_health;
 
-       if(myteam != prev_myteam)
+       if(pain_threshold_lower && myhealth < pain_threshold_lower_health)
        {
-               myteamcolors = colormapPaletteColor(myteam, 1);
-               FOREACH(hud_panels, true, it.update_time = time);
-               prev_myteam = myteam;
+               pain_threshold = pain_threshold - max(autocvar_hud_damage_pain_threshold_pulsating_min, fabs(sin(M_PI * time / autocvar_hud_damage_pain_threshold_pulsating_period))) * pain_threshold_lower * (1 - max(0, myhealth)/pain_threshold_lower_health);
        }
 
-       ticrate = STAT(MOVEVARS_TICRATE) * STAT(MOVEVARS_TIMESCALE);
-
-       float is_dead = (STAT(HEALTH) <= 0);
+       myhealth_flash_temp = bound(0, myhealth_flash - pain_threshold, 1);
 
-       // FIXME do we need this hack?
-       if(isdemo())
+       if(myhealth_prev < 1)
        {
-               // in demos, input_buttons do not work
-               button_zoom = (autocvar__togglezoom == "-");
+               if(myhealth >= 1)
+               {
+                       myhealth_flash = 0; // just spawned, clear the flash immediately
+                       myhealth_flash_temp = 0;
+               }
+               else
+               {
+                       myhealth_flash += autocvar_hud_damage_fade_rate * frametime; // dead
+               }
        }
-       else if(button_zoom
-               && autocvar_cl_unpress_zoom_on_death
-               && (spectatee_status >= 0)
-               && (is_dead || intermission))
+
+       if(spectatee_status == -1 || intermission)
        {
-               // no zoom while dead or in intermission please
-               localcmd("-zoom\n");
-               button_zoom = false;
+               myhealth_flash = 0; // observing, or match ended
+               myhealth_flash_temp = 0;
        }
 
-       // abused multiple places below
-       entity local_player = ((csqcplayer) ? csqcplayer : CSQCModel_server2csqc(player_localentnum - 1));
-       if(!local_player)
-               local_player = this; // fall back!
+       myhealth_prev = myhealth;
 
-       // event chase camera
-       if(autocvar_chase_active <= 0) // greater than 0 means it's enabled manually, and this code is skipped
+       // IDEA: change damage color/picture based on player model for robot/alien species?
+       // pro: matches model better
+       // contra: it's not red because blood is red, but because red is an alarming color, so red should stay
+       // maybe different reddish pics?
+       if(autocvar_cl_gentle_damage || autocvar_cl_gentle)
        {
-               if(STAT(CAMERA_SPECTATOR))
+               if(autocvar_cl_gentle_damage == 2)
                {
-                       if(spectatee_status > 0)
-                       {
-                               if(!autocvar_chase_active)
-                               {
-                                       cvar_set("chase_active", "-2");
-                                       goto skip_eventchase_death;
-                               }
-                       }
-                       else if(autocvar_chase_active == -2)
-                               cvar_set("chase_active", "0");
-
-                       if(autocvar_chase_active == -2)
-                               goto skip_eventchase_death;
+                       if(myhealth_flash < pain_threshold) // only randomize when the flash is gone
+                               myhealth_gentlergb = randomvec();
                }
-               else if(autocvar_chase_active == -2)
-                       cvar_set("chase_active", "0");
-
-               bool vehicle_chase = (hud != HUD_NORMAL && (autocvar_cl_eventchase_vehicle || spectatee_status > 0));
+               else
+                       myhealth_gentlergb = stov(autocvar_hud_damage_gentle_color);
 
-               float vehicle_viewdist = 0;
-               vector vehicle_viewofs = '0 0 0';
+               if(myhealth_flash_temp > 0)
+                       drawfill('0 0 0', vec2(vid_conwidth, vid_conheight), myhealth_gentlergb, autocvar_hud_damage_gentle_alpha_multiplier * bound(0, myhealth_flash_temp, 1) * autocvar_hud_damage, DRAWFLAG_NORMAL);
+       }
+       else if(myhealth_flash_temp > 0)
+               drawpic(splash_pos, "gfx/blood", splash_size, stov(autocvar_hud_damage_color), bound(0, myhealth_flash_temp, 1) * autocvar_hud_damage, DRAWFLAG_NORMAL);
 
-               if(vehicle_chase)
+       if(autocvar_hud_postprocessing) // we still need to set this anyway even when chase_active is set, this way it doesn't get stuck on.
+       {
+               if(autocvar_hud_damage_blur && myhealth_flash_temp)
                {
-                       if(hud != HUD_BUMBLEBEE_GUN)
-                       {
-                               Vehicle info = Vehicles_from(hud);
-                               vehicle_viewdist = info.height;
-                               vehicle_viewofs = info.view_ofs;
-                               if(vehicle_viewdist < 0) // when set below 0, this vehicle doesn't use third person view (gunner slots)
-                                       vehicle_chase = false;
-                       }
-                       else
-                               vehicle_chase = false;
+                       damage_blurpostprocess.x = 1;
+                       damage_blurpostprocess.y = bound(0, myhealth_flash_temp, 1) * autocvar_hud_damage_blur;
+                       damage_blurpostprocess.z = bound(0, myhealth_flash_temp, 1) * autocvar_hud_damage_blur_alpha;
                }
+               else
+               {
+                       damage_blurpostprocess.x = 0;
+                       damage_blurpostprocess.y = 0;
+                       damage_blurpostprocess.z = 0;
+               }
+       }
+}
 
-               int eventchase = WantEventchase(this, vehicle_chase);
-               if (eventchase)
+void View_PostProcessing()
+{
+       float e1 = (autocvar_hud_postprocessing_maxbluralpha != 0);
+       float e2 = (autocvar_hud_powerup != 0);
+       if(autocvar_hud_postprocessing && (e1 || e2)) // TODO: Remove this code and re-do the postprocess handling in the engine, where it properly belongs.
+       {
+               // enable or disable rendering types if they are used or not
+               if(cvar("r_glsl_postprocess_uservec1_enable") != e1) { cvar_set("r_glsl_postprocess_uservec1_enable", ftos(e1)); }
+               if(cvar("r_glsl_postprocess_uservec2_enable") != e2) { cvar_set("r_glsl_postprocess_uservec2_enable", ftos(e2)); }
+
+               // blur postprocess handling done first (used by hud_damage and hud_contents)
+               if((damage_blurpostprocess.x || content_blurpostprocess.x))
                {
-                       vector current_view_origin_override = '0 0 0';
-                       vector view_offset_override = '0 0 0';
-                       float chase_distance_override = 0;
-                       bool custom_eventchase = MUTATOR_CALLHOOK(CustomizeEventchase, this);
-                       if(custom_eventchase)
+                       float blurradius = bound(0, damage_blurpostprocess.y + content_blurpostprocess.y, autocvar_hud_postprocessing_maxblurradius);
+                       float bluralpha = bound(0, damage_blurpostprocess.z + content_blurpostprocess.z, autocvar_hud_postprocessing_maxbluralpha);
+                       if(blurradius != old_blurradius || bluralpha != old_bluralpha) // reduce cvar_set spam as much as possible
                        {
-                               current_view_origin_override = M_ARGV(0, vector);
-                               view_offset_override = M_ARGV(1, vector);
-                               chase_distance_override = M_ARGV(0, float);
+                               cvar_set("r_glsl_postprocess_uservec1", strcat(ftos(blurradius), " ", ftos(bluralpha), " 0 0"));
+                               old_blurradius = blurradius;
+                               old_bluralpha = bluralpha;
                        }
-                       eventchase_running = true;
+               }
+               else if(cvar_string("r_glsl_postprocess_uservec1") != "0 0 0 0") // reduce cvar_set spam as much as possible
+               {
+                       cvar_set("r_glsl_postprocess_uservec1", "0 0 0 0");
+                       old_blurradius = 0;
+                       old_bluralpha = 0;
+               }
 
-                       // make special vector since we can't use view_origin (It is one frame old as of this code, it gets set later with the results this code makes.)
-                       vector current_view_origin = (csqcplayer ? csqcplayer.origin : pmove_org);
-                       if (custom_eventchase)
-                               current_view_origin = current_view_origin_override;
+               // edge detection postprocess handling done second (used by hud_powerup)
+               float sharpen_intensity = 0, strength_finished = STAT(STRENGTH_FINISHED), invincible_finished = STAT(INVINCIBLE_FINISHED);
+               if (strength_finished - time > 0) { sharpen_intensity += (strength_finished - time); }
+               if (invincible_finished - time > 0) { sharpen_intensity += (invincible_finished - time); }
 
-                       // detect maximum viewoffset and use it
-                       vector view_offset = autocvar_cl_eventchase_viewoffset;
-                       if(vehicle_chase)
-                       {
-                               if(vehicle_viewofs)
-                                       view_offset = vehicle_viewofs;
-                               else
-                                       view_offset = autocvar_cl_eventchase_vehicle_viewoffset;
-                       }
-                       if (custom_eventchase)
-                               view_offset = view_offset_override;
+               sharpen_intensity = bound(0, ((STAT(HEALTH) > 0) ? sharpen_intensity : 0), 5); // Check to see if player is alive (if not, set 0) - also bound to fade out starting at 5 seconds.
 
-                       if(view_offset)
+               if(autocvar_hud_powerup && sharpen_intensity > 0)
+               {
+                       if(sharpen_intensity != old_sharpen_intensity) // reduce cvar_set spam as much as possible
                        {
-                               WarpZone_TraceLine(current_view_origin, current_view_origin + view_offset + ('0 0 1' * autocvar_cl_eventchase_maxs.z), MOVE_WORLDONLY, this);
-                               if(trace_fraction == 1) { current_view_origin += view_offset; }
-                               else { current_view_origin.z += max(0, (trace_endpos.z - current_view_origin.z) - autocvar_cl_eventchase_maxs.z); }
+                               cvar_set("r_glsl_postprocess_uservec2", strcat(ftos((sharpen_intensity / 5) * autocvar_hud_powerup), " ", ftos(-sharpen_intensity * autocvar_hud_powerup), " 0 0"));
+                               old_sharpen_intensity = sharpen_intensity;
                        }
+               }
+               else if(cvar_string("r_glsl_postprocess_uservec2") != "0 0 0 0") // reduce cvar_set spam as much as possible
+               {
+                       cvar_set("r_glsl_postprocess_uservec2", "0 0 0 0");
+                       old_sharpen_intensity = 0;
+               }
 
-                       // We must enable chase_active to get a third person view (weapon viewmodel hidden and own player model showing).
-                       // Ideally, there should be another way to enable third person cameras, such as through setproperty()
-                       // -1 enables chase_active while marking it as set by this code, and not by the user (which would be 1)
-                       if(!autocvar_chase_active) { cvar_set("chase_active", "-1"); }
+               if(cvar("r_glsl_postprocess") == 0)
+                       cvar_set("r_glsl_postprocess", "2");
+       }
+       else if(cvar("r_glsl_postprocess") == 2)
+               cvar_set("r_glsl_postprocess", "0");
+}
 
-                       // make the camera smooth back
-                       float chase_distance = autocvar_cl_eventchase_distance;
-                       if(vehicle_chase)
-                       {
-                               if(vehicle_viewofs)
-                                       chase_distance = vehicle_viewdist;
-                               else
-                                       chase_distance = autocvar_cl_eventchase_vehicle_distance;
-                       }
-                       if (custom_eventchase)
-                               chase_distance = chase_distance_override;
+void View_Lock()
+{
+       if(autocvar_cl_lockview || (!autocvar_hud_cursormode && (autocvar__hud_configure && spectatee_status <= 0 || intermission > 1 || QuickMenu_IsOpened())))
+       {
+               setproperty(VF_ORIGIN, freeze_org);
+               setproperty(VF_ANGLES, freeze_ang);
+       }
+       else
+       {
+               freeze_org = getpropertyvec(VF_ORIGIN);
+               freeze_ang = getpropertyvec(VF_ANGLES);
+       }
+}
 
-                       if(autocvar_cl_eventchase_speed && eventchase_current_distance < chase_distance)
-                               eventchase_current_distance += autocvar_cl_eventchase_speed * (chase_distance - eventchase_current_distance) * frametime; // slow down the further we get
-                       else if(eventchase_current_distance != chase_distance)
-                               eventchase_current_distance = chase_distance;
+void View_DemoCamera()
+{
+       if(camera_active) // Camera for demo playback
+       {
+               if(autocvar_camera_enable)
+                       CSQC_Demo_Camera();
+               else
+               {
+                       cvar_set("chase_active", ftos(chase_active_backup));
+                       cvar_set("cl_demo_mousegrab", "0");
+                       camera_active = false;
+               }
+       }
+       else
+       {
+#ifdef CAMERATEST
+               if(autocvar_camera_enable)
+#else
+               if(autocvar_camera_enable && isdemo())
+#endif
+               {
+                       // Enable required Darkplaces cvars
+                       chase_active_backup = autocvar_chase_active;
+                       cvar_set("chase_active", "2");
+                       cvar_set("cl_demo_mousegrab", "1");
+                       camera_active = true;
+                       camera_mode = false;
+               }
+       }
+}
 
-                       vector forward, right, up;
-                       MAKE_VECTORS(view_angles, forward, right, up);
+#ifdef BLURTEST
+void View_BlurTest()
+{
+       if(time > blurtest_time0 && time < blurtest_time1)
+       {
+               float t = (time - blurtest_time0) / (blurtest_time1 - blurtest_time0);
+               float r = t * blurtest_radius;
+               float f = 1 / (t ** blurtest_power) - 1;
 
-                       vector eventchase_target_origin = (current_view_origin - (forward * eventchase_current_distance));
-                       WarpZone_TraceBox(current_view_origin, autocvar_cl_eventchase_mins, autocvar_cl_eventchase_maxs, eventchase_target_origin, MOVE_WORLDONLY, this);
+               cvar_set("r_glsl_postprocess", "1");
+               cvar_set("r_glsl_postprocess_uservec1", strcat(ftos(r), " ", ftos(f), " 0 0"));
+       }
+       else
+       {
+               cvar_set("r_glsl_postprocess", "0");
+               cvar_set("r_glsl_postprocess_uservec1", "0 0 0 0");
+       }
+}
+#endif
 
-                       // If the boxtrace fails, revert back to line tracing.
-                       if(!local_player.viewloc)
-                       if(trace_startsolid)
-                       {
-                               eventchase_target_origin = (current_view_origin - (forward * eventchase_current_distance));
-                               WarpZone_TraceLine(current_view_origin, eventchase_target_origin, MOVE_WORLDONLY, this);
-                               setproperty(VF_ORIGIN, (trace_endpos - (forward * autocvar_cl_eventchase_mins.z)));
-                       }
-                       else { setproperty(VF_ORIGIN, trace_endpos); }
+void View_CheckButtonStatus()
+{
+       float is_dead = (STAT(HEALTH) <= 0);
 
-                       if(!local_player.viewloc)
-                               setproperty(VF_ANGLES, WarpZone_TransformVAngles(WarpZone_trace_transform, view_angles));
-               }
+       // FIXME do we need this hack?
+       if(isdemo())
+       {
+               // in demos, input_buttons do not work
+               button_zoom = (autocvar__togglezoom == "-");
+       }
+       else if(button_zoom
+               && autocvar_cl_unpress_zoom_on_death
+               && (spectatee_status >= 0)
+               && (is_dead || intermission))
+       {
+               // no zoom while dead or in intermission please
+               localcmd("-zoom\n");
+               button_zoom = false;
+       }
 
-               if (eventchase <= 0 && autocvar_chase_active < 0) // time to disable chase_active if it was set by this code
+       if(autocvar_fov <= 59.5)
+       {
+               if(!zoomscript_caught)
                {
-                       eventchase_running = false;
-                       cvar_set("chase_active", "0");
-                       eventchase_current_distance = 0; // start from 0 next time
+                       localcmd("+button9\n");
+                       zoomscript_caught = 1;
                }
        }
-       // workaround for camera stuck between player's legs when using chase_active 1
-       // because the engine stops updating the chase_active camera when the game ends
-       else if(intermission)
+       else
        {
-               cvar_settemp("chase_active", "-1");
-               eventchase_current_distance = 0;
+               if(zoomscript_caught)
+               {
+                       localcmd("-button9\n");
+                       zoomscript_caught = 0;
+               }
        }
 
-       LABEL(skip_eventchase_death);
-
-       // do lockview after event chase camera so that it still applies whenever necessary.
-       if(autocvar_cl_lockview || (!autocvar_hud_cursormode && (autocvar__hud_configure && spectatee_status <= 0 || intermission > 1 || QuickMenu_IsOpened())))
+       if(active_minigame && HUD_MinigameMenu_IsOpened())
        {
-               setproperty(VF_ORIGIN, freeze_org);
-               setproperty(VF_ANGLES, freeze_ang);
+               if(!minigame_wasactive)
+               {
+                       localcmd("+button12\n");
+                       minigame_wasactive = true;
+               }
        }
-       else
+       else if(minigame_wasactive)
        {
-               freeze_org = getpropertyvec(VF_ORIGIN);
-               freeze_ang = getpropertyvec(VF_ANGLES);
+               localcmd("-button12\n");
+               minigame_wasactive = false;
        }
 
-       WarpZone_FixView();
-       //WarpZone_FixPMove();
+       for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+       {
+               entity wepent = viewmodels[slot];
+
+               if(wepent.last_switchweapon != wepent.switchweapon)
+               {
+                       weapontime = time;
+                       wepent.last_switchweapon = wepent.switchweapon;
+                       if(slot == 0 && button_zoom && autocvar_cl_unpress_zoom_on_weapon_switch)
+                       {
+                               localcmd("-zoom\n");
+                               button_zoom = false;
+                       }
+                       if(slot == 0 && autocvar_cl_unpress_attack_on_weapon_switch)
+                       {
+                               localcmd("-fire\n");
+                               localcmd("-fire2\n");
+                               button_attack2 = false;
+                       }
+               }
+               if(wepent.last_activeweapon != wepent.activeweapon)
+               {
+                       wepent.last_activeweapon = wepent.activeweapon;
+
+                       entity e = wepent.activeweapon;
+                       if(e.netname != "")
+                               localcmd(strcat("\ncl_hook_activeweapon ", e.netname), "\n");
+                       else if(slot == 0)
+                               localcmd("\ncl_hook_activeweapon none\n");
+               }
+       }
+}
 
-       vector ov_org = '0 0 0';
-       vector ov_mid = '0 0 0';
-       vector ov_worldmin = '0 0 0';
-       vector ov_worldmax = '0 0 0';
+bool ov_enabled;
+float oldr_nearclip;
+float oldr_farclip_base;
+float oldr_farclip_world;
+float oldr_novis;
+float oldr_useportalculling;
+float oldr_useinfinitefarclip;
+vector ov_org = '0 0 0';
+vector ov_mid = '0 0 0';
+vector ov_worldmin = '0 0 0';
+vector ov_worldmax = '0 0 0';
+
+void View_Ortho()
+{
+       ov_org = '0 0 0';
+       ov_mid = '0 0 0';
+       ov_worldmin = '0 0 0';
+       ov_worldmax = '0 0 0';
        if(autocvar_cl_orthoview)
        {
                ov_worldmin = mi_picmin;
@@ -1888,6 +2277,84 @@ void CSQC_UpdateView(entity this, float w, float h)
                }
                ov_enabled = false;
        }
+}
+
+void View_UpdateFov()
+{
+       vector fov;
+       if(autocvar_cl_orthoview)
+               fov = GetOrthoviewFOV(ov_worldmin, ov_worldmax, ov_mid, ov_org);
+       else if(csqcplayer.viewloc)
+               fov = GetViewLocationFOV(110); // enforce 110 fov, so things don't look odd
+       else
+               fov = GetCurrentFov(autocvar_fov);
+
+       setproperty(VF_FOV, fov);
+}
+
+void CSQC_UpdateView(entity this, float w, float h)
+{
+       TC(int, w); TC(int, h);
+
+       execute_next_frame();
+
+       ++framecount;
+
+       stats_get();
+       hud = STAT(HUD);
+
+       ReplicateVars(false);
+       if (ReplicateVars_NOT_SENDING())
+               ReplicateVars_DELAY(0.8 + random() * 0.4); // no need to check cvars every frame
+
+       HUD_Scale_Disable();
+
+       if(autocvar__hud_showbinds_reload) // menu can set this one
+       {
+               db_close(binddb);
+               binddb = db_create();
+               cvar_set("_hud_showbinds_reload", "0");
+       }
+
+       if(checkextension("DP_CSQC_MINFPS_QUALITY"))
+               view_quality = getproperty(VF_MINFPS_QUALITY);
+       else
+               view_quality = 1;
+
+       button_attack2 = PHYS_INPUT_BUTTON_ATCK2(this);
+       button_zoom = PHYS_INPUT_BUTTON_ZOOM(this);
+
+       vector vf_size = getpropertyvec(VF_SIZE);
+       vector vf_min = getpropertyvec(VF_MIN);
+       vid_width = vf_size.x;
+       vid_height = vf_size.y;
+
+       ticrate = STAT(MOVEVARS_TICRATE) * STAT(MOVEVARS_TIMESCALE);
+
+       WaypointSprite_Load();
+
+       CSQCPlayer_SetCamera();
+
+       if(player_localentnum <= maxclients) // is it a client?
+               current_player = player_localentnum - 1;
+       else // then player_localentnum is the vehicle I'm driving
+               current_player = player_localnum;
+       myteam = entcs_GetTeam(current_player);
+
+       // abused multiple places below
+       entity local_player = ((csqcplayer) ? csqcplayer : CSQCModel_server2csqc(player_localentnum - 1));
+       if(!local_player)
+               local_player = this; // fall back!
+
+       View_EventChase(local_player);
+
+       // do lockview after event chase camera so that it still applies whenever necessary.
+       View_Lock();
+
+       WarpZone_FixView();
+       //WarpZone_FixPMove();
+
+       View_Ortho();
 
        // run viewmodel_draw before updating view_angles to the angles calculated by WarpZone_FixView
        // viewmodel_draw needs to use the view_angles set by the engine on every CSQC_UpdateView call
@@ -1899,23 +2366,8 @@ void CSQC_UpdateView(entity this, float w, float h)
        view_angles = getpropertyvec(VF_ANGLES);
        MAKE_VECTORS(view_angles, view_forward, view_right, view_up);
 
-#ifdef BLURTEST
-       if(time > blurtest_time0 && time < blurtest_time1)
-       {
-               float r, t;
-
-               t = (time - blurtest_time0) / (blurtest_time1 - blurtest_time0);
-               r = t * blurtest_radius;
-               f = 1 / (t ** blurtest_power) - 1;
-
-               cvar_set("r_glsl_postprocess", "1");
-               cvar_set("r_glsl_postprocess_uservec1", strcat(ftos(r), " ", ftos(f), " 0 0"));
-       }
-       else
-       {
-               cvar_set("r_glsl_postprocess", "0");
-               cvar_set("r_glsl_postprocess_uservec1", "0 0 0 0");
-       }
+#ifdef BLURTEST
+       View_BlurTest();
 #endif
 
        TargetMusic_Advance();
@@ -1948,72 +2400,10 @@ void CSQC_UpdateView(entity this, float w, float h)
 
        Announcer();
 
-       fov = autocvar_fov;
-       if(fov <= 59.5)
-       {
-               if(!zoomscript_caught)
-               {
-                       localcmd("+button9\n");
-                       zoomscript_caught = 1;
-               }
-       }
-       else
-       {
-               if(zoomscript_caught)
-               {
-                       localcmd("-button9\n");
-                       zoomscript_caught = 0;
-               }
-       }
-
-       if(active_minigame && HUD_MinigameMenu_IsOpened())
-       {
-               if(!minigame_wasactive)
-               {
-                       localcmd("+button12\n");
-                       minigame_wasactive = true;
-               }
-       }
-       else if(minigame_wasactive)
-       {
-               localcmd("-button12\n");
-               minigame_wasactive = false;
-       }
+       View_CheckButtonStatus();
 
        ColorTranslateMode = autocvar_cl_stripcolorcodes;
 
-       for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
-       {
-               entity wepent = viewmodels[slot];
-
-               if(wepent.last_switchweapon != wepent.switchweapon)
-               {
-                       weapontime = time;
-                       wepent.last_switchweapon = wepent.switchweapon;
-                       if(slot == 0 && button_zoom && autocvar_cl_unpress_zoom_on_weapon_switch)
-                       {
-                               localcmd("-zoom\n");
-                               button_zoom = false;
-                       }
-                       if(slot == 0 && autocvar_cl_unpress_attack_on_weapon_switch)
-                       {
-                               localcmd("-fire\n");
-                               localcmd("-fire2\n");
-                               button_attack2 = false;
-                       }
-               }
-               if(wepent.last_activeweapon != wepent.activeweapon)
-               {
-                       wepent.last_activeweapon = wepent.activeweapon;
-
-                       e = wepent.activeweapon;
-                       if(e.netname != "")
-                               localcmd(strcat("\ncl_hook_activeweapon ", e.netname), "\n");
-                       else if(slot == 0)
-                               localcmd("\ncl_hook_activeweapon none\n");
-               }
-       }
-
        // ALWAYS Clear Current Scene First
        clearscene();
 
@@ -2033,37 +2423,9 @@ void CSQC_UpdateView(entity this, float w, float h)
        vid_conheight = autocvar_vid_conheight;
        vid_pixelheight = autocvar_vid_pixelheight;
 
-       if(autocvar_cl_orthoview) { setproperty(VF_FOV, GetOrthoviewFOV(ov_worldmin, ov_worldmax, ov_mid, ov_org)); }
-       else if(csqcplayer.viewloc) { setproperty(VF_FOV, GetViewLocationFOV(110)); } // enforce 110 fov, so things dont look odd
-       else { setproperty(VF_FOV, GetCurrentFov(fov)); }
+       View_UpdateFov();
 
-       if(camera_active) // Camera for demo playback
-       {
-               if(autocvar_camera_enable)
-                       CSQC_Demo_Camera();
-               else
-               {
-                       cvar_set("chase_active", ftos(chase_active_backup));
-                       cvar_set("cl_demo_mousegrab", "0");
-                       camera_active = false;
-               }
-       }
-       else
-       {
-#ifdef CAMERATEST
-               if(autocvar_camera_enable)
-#else
-               if(autocvar_camera_enable && isdemo())
-#endif
-               {
-                       // Enable required Darkplaces cvars
-                       chase_active_backup = autocvar_chase_active;
-                       cvar_set("chase_active", "2");
-                       cvar_set("cl_demo_mousegrab", "1");
-                       camera_active = true;
-                       camera_mode = false;
-               }
-       }
+       View_DemoCamera();
 
        // Draw the Crosshair
        setproperty(VF_DRAWCROSSHAIR, 0); //Make sure engine crosshairs are always hidden
@@ -2083,342 +2445,13 @@ void CSQC_UpdateView(entity this, float w, float h)
        addentities(MASK_NORMAL | MASK_ENGINE | MASK_ENGINEVIEWMODELS); // TODO: .health is used in cl_deathfade (a feature we have turned off currently)
        renderscene();
 
-       // now switch to 2D drawing mode by calling a 2D drawing function
-       // then polygon drawing will draw as 2D stuff, and NOT get queued until the
-       // next R_RenderScene call
-       drawstring('0 0 0', "", '1 1 0', '1 1 1', 0, 0);
-
-       if(autocvar_r_fakelight >= 2 || autocvar_r_fullbright)
-       if (!(serverflags & SERVERFLAG_ALLOW_FULLBRIGHT))
-       {
-               // apply night vision effect
-               vector tc_00, tc_01, tc_10, tc_11;
-               vector rgb = '0 0 0';
-
-               if(!nightvision_noise)
-               {
-                       nightvision_noise = new(nightvision_noise);
-               }
-               if(!nightvision_noise2)
-               {
-                       nightvision_noise2 = new(nightvision_noise2);
-               }
-
-               // color tint in yellow
-               drawfill('0 0 0', autocvar_vid_conwidth * '1 0 0' + autocvar_vid_conheight * '0 1 0', '0.5 1 0.3', 1, DRAWFLAG_MODULATE);
-
-               // draw BG
-               a = Noise_Pink(nightvision_noise, frametime * 1.5) * 0.05 + 0.15;
-               rgb = '1 1 1';
-               tc_00 = '0 0 0' + '0.2 0 0' * sin(time * 0.3) + '0 0.3 0' * cos(time * 0.7);
-               tc_01 = '0 2.25 0' + '0.6 0 0' * cos(time * 1.2) - '0 0.3 0' * sin(time * 2.2);
-               tc_10 = '1.5 0 0' - '0.2 0 0' * sin(time * 0.5) + '0 0.5 0' * cos(time * 1.7);
-               //tc_11 = '1 1 0' + '0.6 0 0' * sin(time * 0.6) + '0 0.3 0' * cos(time * 0.1);
-               tc_11 = tc_01 + tc_10 - tc_00;
-               R_BeginPolygon("gfx/nightvision-bg.tga", DRAWFLAG_ADDITIVE);
-               R_PolygonVertex('0 0 0', tc_00, rgb, a);
-               R_PolygonVertex(autocvar_vid_conwidth * '1 0 0', tc_10, rgb, a);
-               R_PolygonVertex(autocvar_vid_conwidth * '1 0 0' + autocvar_vid_conheight * '0 1 0', tc_11, rgb, a);
-               R_PolygonVertex(autocvar_vid_conheight * '0 1 0', tc_01, rgb, a);
-               R_EndPolygon();
-
-               // draw FG
-               a = Noise_Pink(nightvision_noise2, frametime * 0.1) * 0.05 + 0.12;
-               rgb = '0.3 0.6 0.4' + '0.1 0.4 0.2' * Noise_White(nightvision_noise2, frametime);
-               tc_00 = '0 0 0' + '1 0 0' * Noise_White(nightvision_noise2, frametime) + '0 1 0' * Noise_White(nightvision_noise2, frametime);
-               tc_01 = tc_00 + '0 3 0' * (1 + Noise_White(nightvision_noise2, frametime) * 0.2);
-               tc_10 = tc_00 + '2 0 0' * (1 + Noise_White(nightvision_noise2, frametime) * 0.3);
-               tc_11 = tc_01 + tc_10 - tc_00;
-               R_BeginPolygon("gfx/nightvision-fg.tga", DRAWFLAG_ADDITIVE);
-               R_PolygonVertex('0 0 0', tc_00, rgb, a);
-               R_PolygonVertex(autocvar_vid_conwidth * '1 0 0', tc_10, rgb, a);
-               R_PolygonVertex(autocvar_vid_conwidth * '1 0 0' + autocvar_vid_conheight * '0 1 0', tc_11, rgb, a);
-               R_PolygonVertex(autocvar_vid_conheight * '0 1 0', tc_01, rgb, a);
-               R_EndPolygon();
-       }
-
-       if(autocvar_cl_reticle && !MUTATOR_CALLHOOK(DrawReticle))
-       {
-               string reticle_image = string_null;
-               bool wep_zoomed = false;
-               for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
-               {
-                       entity wepe = viewmodels[slot];
-                       Weapon wep = wepe.activeweapon;
-                       if(wep != WEP_Null && wep.wr_zoom)
-                       {
-                               bool do_zoom = wep.wr_zoom(wep, NULL);
-                               if(!reticle_image && wep.w_reticle && wep.w_reticle != "")
-                                       reticle_image = wep.w_reticle;
-                               wep_zoomed += do_zoom;
-                       }
-               }
-               // Draw the aiming reticle for weapons that use it
-               // reticle_type is changed to the item we are zooming / aiming with, to decide which reticle to use
-               // It must be a persisted float for fading out to work properly (you let go of the zoom button for
-               // the view to go back to normal, so reticle_type would become 0 as we fade out)
-               if(spectatee_status || is_dead || hud != HUD_NORMAL || local_player.viewloc)
-               {
-                       // no zoom reticle while dead
-                       reticle_type = 0;
-               }
-               else if(wep_zoomed && autocvar_cl_reticle_weapon)
-               {
-                       if(reticle_image) { reticle_type = 2; }
-                       else { reticle_type = 0; }
-               }
-               else if(button_zoom || zoomscript_caught)
-               {
-                       // normal zoom
-                       reticle_type = 1;
-               }
-
-               if(reticle_type)
-               {
-                       if(autocvar_cl_reticle_stretch)
-                       {
-                               reticle_size.x = vid_conwidth;
-                               reticle_size.y = vid_conheight;
-                               reticle_pos.x = 0;
-                               reticle_pos.y = 0;
-                       }
-                       else
-                       {
-                               reticle_size.x = max(vid_conwidth, vid_conheight);
-                               reticle_size.y = max(vid_conwidth, vid_conheight);
-                               reticle_pos.x = (vid_conwidth - reticle_size.x) / 2;
-                               reticle_pos.y = (vid_conheight - reticle_size.y) / 2;
-                       }
-
-                       if(zoomscript_caught)
-                               f = 1;
-                       else
-                               f = current_zoomfraction;
-
-                       if(f)
-                       {
-                               switch(reticle_type)
-                               {
-                                       case 1: drawpic(reticle_pos, "gfx/reticle_normal", reticle_size, '1 1 1', f * autocvar_cl_reticle_normal_alpha, DRAWFLAG_NORMAL); break;
-                                       case 2: if(reticle_image) drawpic(reticle_pos, reticle_image, reticle_size, '1 1 1', f * autocvar_cl_reticle_weapon_alpha, DRAWFLAG_NORMAL); break;
-                               }
-                       }
-               }
-       }
-       else
-       {
-               if(reticle_type != 0) { reticle_type = 0; }
-       }
-
-
-       // improved polyblend
-       if(autocvar_hud_contents && !MUTATOR_CALLHOOK(HUD_Contents))
-       {
-               float contentalpha_temp, incontent, liquidalpha, contentfadetime;
-               vector liquidcolor;
-
-               switch(pointcontents(view_origin))
-               {
-                       case CONTENT_WATER:
-                               liquidalpha = autocvar_hud_contents_water_alpha;
-                               liquidcolor = stov(autocvar_hud_contents_water_color);
-                               incontent = 1;
-                               break;
-
-                       case CONTENT_LAVA:
-                               liquidalpha = autocvar_hud_contents_lava_alpha;
-                               liquidcolor = stov(autocvar_hud_contents_lava_color);
-                               incontent = 1;
-                               break;
-
-                       case CONTENT_SLIME:
-                               liquidalpha = autocvar_hud_contents_slime_alpha;
-                               liquidcolor = stov(autocvar_hud_contents_slime_color);
-                               incontent = 1;
-                               break;
-
-                       default:
-                               liquidalpha = 0;
-                               liquidcolor = '0 0 0';
-                               incontent = 0;
-                               break;
-               }
-
-               if(incontent) // fade in/out at different speeds so you can do e.g. instant fade when entering water and slow when leaving it.
-               { // also lets delcare previous values for blending properties, this way it isn't reset until after you have entered a different content
-                       contentfadetime = autocvar_hud_contents_fadeintime;
-                       liquidalpha_prev = liquidalpha;
-                       liquidcolor_prev = liquidcolor;
-               }
-               else
-                       contentfadetime = autocvar_hud_contents_fadeouttime;
-
-               contentalpha_temp = bound(0, drawframetime / max(0.0001, contentfadetime), 1);
-               contentavgalpha = contentavgalpha * (1 - contentalpha_temp) + incontent * contentalpha_temp;
-
-               if(contentavgalpha)
-                       drawfill('0 0 0', vec2(vid_conwidth, vid_conheight), liquidcolor_prev, contentavgalpha * liquidalpha_prev, DRAWFLAG_NORMAL);
-
-               if(autocvar_hud_postprocessing)
-               {
-                       if(autocvar_hud_contents_blur && contentavgalpha)
-                       {
-                               content_blurpostprocess.x = 1;
-                               content_blurpostprocess.y = contentavgalpha * autocvar_hud_contents_blur;
-                               content_blurpostprocess.z = contentavgalpha * autocvar_hud_contents_blur_alpha;
-                       }
-                       else
-                       {
-                               content_blurpostprocess.x = 0;
-                               content_blurpostprocess.y = 0;
-                               content_blurpostprocess.z = 0;
-                       }
-               }
-       }
-
-       if(autocvar_hud_damage && !STAT(FROZEN))
-       {
-               splash_size.x = max(vid_conwidth, vid_conheight);
-               splash_size.y = max(vid_conwidth, vid_conheight);
-               splash_pos.x = (vid_conwidth - splash_size.x) / 2;
-               splash_pos.y = (vid_conheight - splash_size.y) / 2;
-
-               float myhealth_flash_temp;
-               myhealth = STAT(HEALTH);
-
-               // fade out
-               myhealth_flash = max(0, myhealth_flash - autocvar_hud_damage_fade_rate * frametime);
-               // add new damage
-               myhealth_flash = bound(0, myhealth_flash + dmg_take * autocvar_hud_damage_factor, autocvar_hud_damage_maxalpha);
-
-               float pain_threshold, pain_threshold_lower, pain_threshold_lower_health;
-               pain_threshold = autocvar_hud_damage_pain_threshold;
-               pain_threshold_lower = autocvar_hud_damage_pain_threshold_lower;
-               pain_threshold_lower_health = autocvar_hud_damage_pain_threshold_lower_health;
-
-               if(pain_threshold_lower && myhealth < pain_threshold_lower_health)
-               {
-                       pain_threshold = pain_threshold - max(autocvar_hud_damage_pain_threshold_pulsating_min, fabs(sin(M_PI * time / autocvar_hud_damage_pain_threshold_pulsating_period))) * pain_threshold_lower * (1 - max(0, myhealth)/pain_threshold_lower_health);
-               }
-
-               myhealth_flash_temp = bound(0, myhealth_flash - pain_threshold, 1);
-
-               if(myhealth_prev < 1)
-               {
-                       if(myhealth >= 1)
-                       {
-                               myhealth_flash = 0; // just spawned, clear the flash immediately
-                               myhealth_flash_temp = 0;
-                       }
-                       else
-                       {
-                               myhealth_flash += autocvar_hud_damage_fade_rate * frametime; // dead
-                       }
-               }
-
-               if(spectatee_status == -1 || intermission)
-               {
-                       myhealth_flash = 0; // observing, or match ended
-                       myhealth_flash_temp = 0;
-               }
-
-               myhealth_prev = myhealth;
-
-               // IDEA: change damage color/picture based on player model for robot/alien species?
-               // pro: matches model better
-               // contra: it's not red because blood is red, but because red is an alarming color, so red should stay
-               // maybe different reddish pics?
-               if(autocvar_cl_gentle_damage || autocvar_cl_gentle)
-               {
-                       if(autocvar_cl_gentle_damage == 2)
-                       {
-                               if(myhealth_flash < pain_threshold) // only randomize when the flash is gone
-                                       myhealth_gentlergb = randomvec();
-                       }
-                       else
-                               myhealth_gentlergb = stov(autocvar_hud_damage_gentle_color);
-
-                       if(myhealth_flash_temp > 0)
-                               drawfill('0 0 0', vec2(vid_conwidth, vid_conheight), myhealth_gentlergb, autocvar_hud_damage_gentle_alpha_multiplier * bound(0, myhealth_flash_temp, 1) * autocvar_hud_damage, DRAWFLAG_NORMAL);
-               }
-               else if(myhealth_flash_temp > 0)
-                       drawpic(splash_pos, "gfx/blood", splash_size, stov(autocvar_hud_damage_color), bound(0, myhealth_flash_temp, 1) * autocvar_hud_damage, DRAWFLAG_NORMAL);
-
-               if(autocvar_hud_postprocessing) // we still need to set this anyway even when chase_active is set, this way it doesn't get stuck on.
-               {
-                       if(autocvar_hud_damage_blur && myhealth_flash_temp)
-                       {
-                               damage_blurpostprocess.x = 1;
-                               damage_blurpostprocess.y = bound(0, myhealth_flash_temp, 1) * autocvar_hud_damage_blur;
-                               damage_blurpostprocess.z = bound(0, myhealth_flash_temp, 1) * autocvar_hud_damage_blur_alpha;
-                       }
-                       else
-                       {
-                               damage_blurpostprocess.x = 0;
-                               damage_blurpostprocess.y = 0;
-                               damage_blurpostprocess.z = 0;
-                       }
-               }
-       }
-
-       float e1 = (autocvar_hud_postprocessing_maxbluralpha != 0);
-       float e2 = (autocvar_hud_powerup != 0);
-       if(autocvar_hud_postprocessing && (e1 || e2)) // TODO: Remove this code and re-do the postprocess handling in the engine, where it properly belongs.
-       {
-               // enable or disable rendering types if they are used or not
-               if(cvar("r_glsl_postprocess_uservec1_enable") != e1) { cvar_set("r_glsl_postprocess_uservec1_enable", ftos(e1)); }
-               if(cvar("r_glsl_postprocess_uservec2_enable") != e2) { cvar_set("r_glsl_postprocess_uservec2_enable", ftos(e2)); }
-
-               // blur postprocess handling done first (used by hud_damage and hud_contents)
-               if((damage_blurpostprocess.x || content_blurpostprocess.x))
-               {
-                       float blurradius = bound(0, damage_blurpostprocess.y + content_blurpostprocess.y, autocvar_hud_postprocessing_maxblurradius);
-                       float bluralpha = bound(0, damage_blurpostprocess.z + content_blurpostprocess.z, autocvar_hud_postprocessing_maxbluralpha);
-                       if(blurradius != old_blurradius || bluralpha != old_bluralpha) // reduce cvar_set spam as much as possible
-                       {
-                               cvar_set("r_glsl_postprocess_uservec1", strcat(ftos(blurradius), " ", ftos(bluralpha), " 0 0"));
-                               old_blurradius = blurradius;
-                               old_bluralpha = bluralpha;
-                       }
-               }
-               else if(cvar_string("r_glsl_postprocess_uservec1") != "0 0 0 0") // reduce cvar_set spam as much as possible
-               {
-                       cvar_set("r_glsl_postprocess_uservec1", "0 0 0 0");
-                       old_blurradius = 0;
-                       old_bluralpha = 0;
-               }
-
-               // edge detection postprocess handling done second (used by hud_powerup)
-               float sharpen_intensity = 0, strength_finished = STAT(STRENGTH_FINISHED), invincible_finished = STAT(INVINCIBLE_FINISHED);
-               if (strength_finished - time > 0) { sharpen_intensity += (strength_finished - time); }
-               if (invincible_finished - time > 0) { sharpen_intensity += (invincible_finished - time); }
-
-               sharpen_intensity = bound(0, ((STAT(HEALTH) > 0) ? sharpen_intensity : 0), 5); // Check to see if player is alive (if not, set 0) - also bound to fade out starting at 5 seconds.
-
-               if(autocvar_hud_powerup && sharpen_intensity > 0)
-               {
-                       if(sharpen_intensity != old_sharpen_intensity) // reduce cvar_set spam as much as possible
-                       {
-                               cvar_set("r_glsl_postprocess_uservec2", strcat(ftos((sharpen_intensity / 5) * autocvar_hud_powerup), " ", ftos(-sharpen_intensity * autocvar_hud_powerup), " 0 0"));
-                               old_sharpen_intensity = sharpen_intensity;
-                       }
-               }
-               else if(cvar_string("r_glsl_postprocess_uservec2") != "0 0 0 0") // reduce cvar_set spam as much as possible
-               {
-                       cvar_set("r_glsl_postprocess_uservec2", "0 0 0 0");
-                       old_sharpen_intensity = 0;
-               }
-
-               if(cvar("r_glsl_postprocess") == 0)
-                       cvar_set("r_glsl_postprocess", "2");
-       }
-       else if(cvar("r_glsl_postprocess") == 2)
-               cvar_set("r_glsl_postprocess", "0");
+       // Now the the scene has been rendered, begin with the 2D drawing functions
 
-       /*if(ISGAMETYPE(CTF))
-         {
-         ctf_view();
-         } else */
+       View_NightVision();
+       DrawReticle(local_player);
+       HUD_Contents();
+       HUD_Damage();
+       View_PostProcessing();
 
        // draw 2D entities
        IL_EACH(g_drawables_2d, it.draw2d, it.draw2d(it));
index f3c1f4139fff3543ca272c7a750a3cd3328422b5..448361d05f2075d992d3f47a11e83fba5964c439 100644 (file)
@@ -20,3 +20,5 @@ const int CURSOR_NORMAL = 0;
 const int CURSOR_MOVE = 1;
 const int CURSOR_RESIZE = 2;
 const int CURSOR_RESIZE2 = 3;
+
+float drawtime;
index 25c008d260d12329b2e16aed6dfdf97fdaf0973d..088aefea09a0479c2061e483491923090653df60 100644 (file)
@@ -11,8 +11,8 @@ string campaign_gametype[CAMPAIGN_MAX_ENTRIES];
 string campaign_mapname[CAMPAIGN_MAX_ENTRIES];
 float campaign_bots[CAMPAIGN_MAX_ENTRIES];
 float campaign_botskill[CAMPAIGN_MAX_ENTRIES];
-float campaign_fraglimit[CAMPAIGN_MAX_ENTRIES];
-float campaign_timelimit[CAMPAIGN_MAX_ENTRIES];
+string campaign_fraglimit[CAMPAIGN_MAX_ENTRIES];
+string campaign_timelimit[CAMPAIGN_MAX_ENTRIES];
 string campaign_mutators[CAMPAIGN_MAX_ENTRIES];
 string campaign_shortdesc[CAMPAIGN_MAX_ENTRIES];
 string campaign_longdesc[CAMPAIGN_MAX_ENTRIES];
index 4f099b53301010a383b9efaa5a27d9e2e5ceebaf..8bac6f35ee05678647caf62ec410df13bf5da770 100644 (file)
@@ -58,8 +58,8 @@ float CampaignFile_Load(int offset, float n)
                                CAMPAIGN_GETARG; campaign_mapname[campaign_entries] = strzone(a);
                                CAMPAIGN_GETARG; campaign_bots[campaign_entries] = stof(a);
                                CAMPAIGN_GETARG; campaign_botskill[campaign_entries] = stof(a);
-                               CAMPAIGN_GETARG; campaign_fraglimit[campaign_entries] = stof(a);
-                               CAMPAIGN_GETARG; campaign_timelimit[campaign_entries] = stof(a);
+                               CAMPAIGN_GETARG; campaign_fraglimit[campaign_entries] = strzone(a);
+                               CAMPAIGN_GETARG; campaign_timelimit[campaign_entries] = strzone(a);
                                CAMPAIGN_GETARG; campaign_mutators[campaign_entries] = strzone(a);
                                CAMPAIGN_GETARG; campaign_shortdesc[campaign_entries] = strzone(a);
                                CAMPAIGN_GETARG; campaign_longdesc[campaign_entries] = strzone(strreplace("\\n", "\n", a));
@@ -91,6 +91,8 @@ void CampaignFile_Unload()
                {
                        strfree(campaign_gametype[i]);
                        strfree(campaign_mapname[i]);
+                       strfree(campaign_fraglimit[i]);
+                       strfree(campaign_timelimit[i]);
                        strfree(campaign_mutators[i]);
                        strfree(campaign_shortdesc[i]);
                        strfree(campaign_longdesc[i]);
index dcd8d958422b660a941e639fbb23d6eb82de838a..2c34fea44a50813493007c2c2cedc1f88840025a 100644 (file)
@@ -169,7 +169,7 @@ void GenericCommand_qc_curl(int request, int argc)
        }
 }
 
-GENERIC_COMMAND(dumpcommands, "Dump all commands on the program to <program>_cmd_dump.txt")
+GENERIC_COMMAND(dumpcommands, "Dump all commands on the program to <program>_cmd_dump.txt", false)
 {
        switch(request)
        {
@@ -532,16 +532,16 @@ void GenericCommand_(int request)
 */
 
 // Do not hard code aliases for these, instead create them in commands.cfg... also: keep in alphabetical order, please ;)
-GENERIC_COMMAND(addtolist, "Add a string to a cvar") { GenericCommand_addtolist(request, arguments); }
-GENERIC_COMMAND(maplist, "Automatic control of maplist") { GenericCommand_maplist(request, arguments); }
-GENERIC_COMMAND(nextframe, "Execute the given command next frame of this VM") { GenericCommand_nextframe(request, command); }
-GENERIC_COMMAND(qc_curl, "Queries a URL") { GenericCommand_qc_curl(request, arguments); }
-GENERIC_COMMAND(removefromlist, "Remove a string from a cvar") { GenericCommand_removefromlist(request, arguments); }
-GENERIC_COMMAND(restartnotifs, "Re-initialize all notifications") { GenericCommand_restartnotifs(request); }
-GENERIC_COMMAND(rpn, "RPN calculator") { GenericCommand_rpn(request, arguments, command); }
-GENERIC_COMMAND(settemp, "Temporarily set a value to a cvar which is restored later") { GenericCommand_settemp(request, arguments); }
-GENERIC_COMMAND(settemp_restore, "Restore all cvars set by settemp command") { GenericCommand_settemp_restore(request); }
-GENERIC_COMMAND(runtest, "Run unit tests") { GenericCommand_runtest(request, arguments); }
+GENERIC_COMMAND(addtolist, "Add a string to a cvar", true) { GenericCommand_addtolist(request, arguments); }
+GENERIC_COMMAND(maplist, "Automatic control of maplist", true) { GenericCommand_maplist(request, arguments); }
+GENERIC_COMMAND(nextframe, "Execute the given command next frame of this VM", true) { GenericCommand_nextframe(request, command); }
+GENERIC_COMMAND(qc_curl, "Queries a URL", true) { GenericCommand_qc_curl(request, arguments); }
+GENERIC_COMMAND(removefromlist, "Remove a string from a cvar", true) { GenericCommand_removefromlist(request, arguments); }
+GENERIC_COMMAND(restartnotifs, "Re-initialize all notifications", false) { GenericCommand_restartnotifs(request); }
+GENERIC_COMMAND(rpn, "RPN calculator", true) { GenericCommand_rpn(request, arguments, command); }
+GENERIC_COMMAND(settemp, "Temporarily set a value to a cvar which is restored later", false) { GenericCommand_settemp(request, arguments); }
+GENERIC_COMMAND(settemp_restore, "Restore all cvars set by settemp command", false) { GenericCommand_settemp_restore(request); }
+GENERIC_COMMAND(runtest, "Run unit tests", false) { GenericCommand_runtest(request, arguments); }
 
 void GenericCommand_macro_help()
 {
index 9868e2490afc54a4affeedf5216b4782d402f188..a6f669fd91e04c461a2710837ae760e070c9523a 100644 (file)
@@ -6,14 +6,17 @@ REGISTRY(GENERIC_COMMANDS, BITS(7))
 REGISTER_REGISTRY(GENERIC_COMMANDS)
 REGISTRY_SORT(GENERIC_COMMANDS)
 
-#define GENERIC_COMMAND(id, description) \
+.bool m_menubased; // switch to tell whether this alias should be registered as a menu or client based command
+
+#define GENERIC_COMMAND(id, description, menubased) \
        CLASS(genericcommand_##id, Command) \
                ATTRIB(genericcommand_##id, m_name, string, #id); \
        ATTRIB(genericcommand_##id, m_description, string, description); \
+       ATTRIB(genericcommand_##id, m_menubased, bool, menubased); \
        ENDCLASS(genericcommand_##id) \
     REGISTER(GENERIC_COMMANDS, CMD_G, id, m_id, NEW(genericcommand_##id)); \
        METHOD(genericcommand_##id, m_invokecmd, void(genericcommand_##id this, int request, entity caller, int arguments, string command))
 
 STATIC_INIT(GENERIC_COMMANDS_aliases) {
-       FOREACH(GENERIC_COMMANDS, true, localcmd(sprintf("alias %1$s \"%2$s %1$s ${* ?}\"\n", it.m_name, "qc_cmd_svmenu")));
+       FOREACH(GENERIC_COMMANDS, true, localcmd(sprintf("alias %1$s \"%2$s %1$s ${* ?}\"\n", it.m_name, ((it.m_menubased) ? "qc_cmd_svmenu" : "qc_cmd_svcl"))));
 }
index 0998fad9dbd4ea4ea02ed815840ff18a8b3f548f..4165d3dddac289b34a2ffc42ed9f09dccd259b8b 100644 (file)
@@ -53,6 +53,12 @@ float rpn_popf() { return stof(rpn_pop()); }
 void rpn_pushf(float f) { return rpn_push(sprintf("%.9g", f)); }
 void rpn_setf(float f) { return rpn_set(sprintf("%.9g", f)); }
 
+SHUTDOWN(_rpndb)
+{
+       if(rpn_db)
+               db_close(rpn_db);
+}
+
 void GenericCommand_rpn(int request, int argc, string command)
 {
        switch(request)
index 05064ca96742c395ab0beb863f6bffb186549867..e5012f8cc1b8771a0b7d8f53225c59ef6b9308ae 100644 (file)
@@ -69,7 +69,7 @@ REGISTER_NET_TEMP(net_debug)
  * 6: on (.solid != 0)
  */
 bool autocvar_debugdraw;
-#endif
+#endif // GAMEQC
 
 #ifdef CSQC
        string autocvar_debugdraw_filter, autocvar_debugdraw_filterout;
@@ -161,8 +161,7 @@ bool autocvar_debugdraw;
             });
                });
        }
-#endif
-
+#endif // CSQC
 
 #ifdef SVQC
        COMMON_COMMAND(debugdraw_sv, "Dump all server entities")
@@ -193,11 +192,11 @@ bool autocvar_debugdraw;
                        }
                }
        }
-#endif
-#endif
+#endif // SVQC
+#endif // ENABLE_DEBUGDRAW
 
 
-GENERIC_COMMAND(bufstr_get, "Examine a string buffer object")
+GENERIC_COMMAND(bufstr_get, "Examine a string buffer object", false)
 {
        switch (request)
        {
@@ -219,13 +218,13 @@ GENERIC_COMMAND(bufstr_get, "Examine a string buffer object")
 }
 
 
-GENERIC_COMMAND(version, "Print the current version")
+GENERIC_COMMAND(version, "Print the current version", false)
 {
        switch (request)
        {
                case CMD_REQUEST_COMMAND:
                {
-                       LOG_INFO(WATERMARK);
+                       LOG_INFO(PROGNAME, " version: ", WATERMARK);
                        return;
                }
                default:
@@ -241,7 +240,8 @@ GENERIC_COMMAND(version, "Print the current version")
 #ifdef CSQC
 void(float bufhandle, string pattern, string antipattern) buf_cvarlist = #517;
 #endif
-GENERIC_COMMAND(cvar_localchanges, "Print locally changed cvars")
+
+GENERIC_COMMAND(cvar_localchanges, "Print locally changed cvars", false)
 {
        switch (request)
        {
@@ -275,6 +275,7 @@ GENERIC_COMMAND(cvar_localchanges, "Print locally changed cvars")
 
 #if ENABLE_DEBUGTRACE
 REGISTER_STAT(TRACE_ENT, int)
+
 #ifdef SVQC
 bool autocvar_debugtrace;
 
@@ -310,7 +311,8 @@ MUTATOR_HOOKFUNCTION(trace, SV_StartFrame)
                stuffcmd(it, sprintf("prvm_edict server %d\n", i));
        });
 }
-#endif
+#endif // SVQC
+
 #ifdef CSQC
 entity TRACE_ENT;
 void Trace_draw2d(entity this)
@@ -328,11 +330,12 @@ STATIC_INIT(TRACE_ENT)
        e.draw2d = Trace_draw2d;
        IL_PUSH(g_drawables_2d, e);
 }
-#endif
+#endif // CSQC
+
 #endif
 
 
-GENERIC_COMMAND(find, "Search through entities for matching classname")
+GENERIC_COMMAND(find, "Search through entities for matching classname", false)
 {
        switch (request)
        {
@@ -363,7 +366,7 @@ GENERIC_COMMAND(find, "Search through entities for matching classname")
 }
 
 
-GENERIC_COMMAND(findat, "Search through entities for matching origin")
+GENERIC_COMMAND(findat, "Search through entities for matching origin", false)
 {
        switch (request)
        {
@@ -399,7 +402,7 @@ CLASS(DebugText3d, Object)
        ATTRIB(DebugText3d, message, string); // the text (i wanted to use the .text field but then this whole macro-based-inheritance thing shat itself)
        ATTRIB(DebugText3d, health, float); // text alignment (recycled field)
        ATTRIB(DebugText3d, hit_time, float); // when it was created
-       ATTRIB(DebugText3d, fade_rate, float); // how fast is should disappear
+       ATTRIB(DebugText3d, fade_rate, float); // how fast it should disappear
        ATTRIB(DebugText3d, velocity, vector);
 
        CONSTRUCTOR(DebugText3d, vector pos, string msg, float align, float fade_rate_, vector vel) {
index d45bdf36d4c0a4b29e30da4c65c6246cb5c49184..3713e9a1abc80601fe7aece807abd579a1714790 100644 (file)
@@ -9043,3 +9043,46 @@ SUB(tr_bullet_weak) {
        MY(underwater) = true;
        MY(velocityjitter) = '16.0 16.0 16.0';
 }
+
+// Vaporizer hit effect
+DEF(TE_TEI_G3_HIT);
+SUB(TE_TEI_G3_HIT) {
+       MY(alpha_min) = 128;
+       MY(alpha_max) = 128;
+       MY(alpha_fade) = 256;
+       MY(color_min) = "0xFFFFFF";
+       MY(color_max) = "0xFFFFFF";
+       MY(countabsolute) = 1;
+       MY(size_min) = 8;
+       MY(size_max) = 8;
+       MY(tex_min) = 200;
+       MY(tex_max) = 200;
+       MY(type) = "beam";
+}
+SUB(TE_TEI_G3_HIT) /* rings */ {
+       MY(airfriction) = -4;
+       MY(alpha_min) = 256;
+       MY(alpha_max) = 256;
+       MY(alpha_fade) = 512;
+       MY(color_min) = "0xFFFFFF";
+       MY(color_max) = "0xFFFFFF";
+       MY(sizeincrease) = -2;
+       MY(size_min) = 2;
+       MY(size_max) = 2;
+       MY(trailspacing) = 20;
+       MY(type) = "smoke";
+       MY(velocityjitter) = '2.0 2.0 2.0';
+}
+SUB(TE_TEI_G3_HIT) {
+       MY(airfriction) = -4;
+       MY(alpha_min) = 256;
+       MY(alpha_max) = 256;
+       MY(alpha_fade) = 512;
+       MY(color_min) = "0xFFFFFF";
+       MY(color_max) = "0xFFFFFF";
+       MY(sizeincrease) = -6;
+       MY(size_min) = 10;
+       MY(size_max) = 10;
+       MY(trailspacing) = 40;
+       MY(type) = "smoke";
+}
index 68c245db4a7df2674b7ceb79ddd061234b3ff7fd..79d31eb46bc5efdb473e4322a02b985101511401 100644 (file)
@@ -285,7 +285,7 @@ void effectinfo_dump(int fh, bool alsoprint)
     #undef WRITE
 }
 
-GENERIC_COMMAND(dumpeffectinfo, "Dump all effectinfo to effectinfo_dump.txt")
+GENERIC_COMMAND(dumpeffectinfo, "Dump all effectinfo to effectinfo_dump.txt", false)
 {
     switch (request) {
         case CMD_REQUEST_COMMAND: {
index 589e343c8df91ae795a94c1375903c429ae17296..359d3d8a532641c82a189b7d37855d1ec6293b3d 100644 (file)
@@ -19,22 +19,25 @@ REPLICATE(cvar_cl_casings, bool, "cl_casings");
 #ifdef SVQC
 void SpawnCasing(vector vel, float randomvel, vector ang, vector avel, float randomavel, int casingtype, entity casingowner, .entity weaponentity)
 {
-       if (!(CS(casingowner).cvar_cl_casings))
-               return;
-
-    entity wep = casingowner.(weaponentity);
-    vector org = casingowner.origin + casingowner.view_ofs + wep.spawnorigin.x * v_forward - wep.spawnorigin.y * v_right + wep.spawnorigin.z * v_up;
-
-    if (!sound_allowed(MSG_BROADCAST, casingowner))
-        casingtype |= 0x80;
-
-    WriteHeader(MSG_ALL, casings);
-    WriteByte(MSG_ALL, casingtype);
-    WriteVector(MSG_ALL, org);
-    WriteShort(MSG_ALL, compressShortVector(vel)); // actually compressed velocity
-    WriteByte(MSG_ALL, ang.x * 256 / 360);
-    WriteByte(MSG_ALL, ang.y * 256 / 360);
-    WriteByte(MSG_ALL, ang.z * 256 / 360);
+       entity wep = casingowner.(weaponentity);
+       vector org = casingowner.origin + casingowner.view_ofs + wep.spawnorigin.x * v_forward - wep.spawnorigin.y * v_right + wep.spawnorigin.z * v_up;
+
+       FOREACH_CLIENT(true, {
+               if (!(CS(it).cvar_cl_casings))
+                       continue;
+
+               msg_entity = it;
+               if (!sound_allowed(MSG_ONE, it))
+                       casingtype |= 0x80; // silent
+
+               WriteHeader(MSG_ONE, casings);
+               WriteByte(MSG_ONE, casingtype);
+               WriteVector(MSG_ONE, org);
+               WriteShort(MSG_ONE, compressShortVector(vel)); // actually compressed velocity
+               WriteByte(MSG_ONE, ang.x * 256 / 360);
+               WriteByte(MSG_ONE, ang.y * 256 / 360);
+               WriteByte(MSG_ONE, ang.z * 256 / 360);
+       });
 }
 #endif
 
@@ -153,6 +156,7 @@ NET_HANDLE(casings, bool isNew)
     casing.velocity = casing.velocity + 2 * prandomvec();
     casing.avelocity = '0 250 0' + 100 * prandomvec();
     set_movetype(casing, MOVETYPE_BOUNCE);
+    casing.bouncefactor = 0.25;
     settouch(casing, Casing_Touch);
     casing.move_time = time;
     casing.event_damage = Casing_Damage;
index 4653f4a956084108ac62bc36e9eb4b006389da1e..9fc46ff67537b6cbf42d9a33e03e467feda2772b 100644 (file)
                                if (GetPlayerSoundSampleField_notFound) field = GetVoiceMessageSampleField(key);
                                if (GetPlayerSoundSampleField_notFound)
                                {
-                                       LOG_TRACEF("Invalid sound info field: %s", key);
+                                       LOG_TRACEF("Invalid sound info field in player sound file '%s': %s", f, key);
                                        continue;
                                }
                                string file = argv(1);
index 8b1570f030053124aae84b13ee04ba92394ff471..b5631ed5fd246774277adb823dae760d31700b9d 100644 (file)
@@ -40,11 +40,11 @@ REGISTER_PLAYERSOUND(pain75)
 
 .bool instanceOfVoiceMessage;
 .int m_playersoundvt;
-#define REGISTER_VOICEMSG(id, vt) \
+#define REGISTER_VOICEMSG(id, vt, listed) \
        .string _playersound_##id; \
        REGISTER(PlayerSounds, playersound, id, m_id, new_pure(VoiceMessage)) \
        { \
-               this.instanceOfVoiceMessage = true; \
+               this.instanceOfVoiceMessage = listed; \
                this.m_playersoundstr = #id; \
                this.m_playersoundfld = _playersound_##id; \
                this.m_playersoundvt = vt; \
@@ -57,30 +57,30 @@ const int VOICETYPE_LASTATTACKER_ONLY = 13;
 const int VOICETYPE_AUTOTAUNT = 14;
 const int VOICETYPE_TAUNT = 15;
 
-REGISTER_VOICEMSG(attack, VOICETYPE_TEAMRADIO)
-REGISTER_VOICEMSG(attackinfive, VOICETYPE_TEAMRADIO)
-REGISTER_VOICEMSG(coverme, VOICETYPE_TEAMRADIO)
-REGISTER_VOICEMSG(defend, VOICETYPE_TEAMRADIO)
-REGISTER_VOICEMSG(freelance, VOICETYPE_TEAMRADIO)
-REGISTER_VOICEMSG(incoming, VOICETYPE_TEAMRADIO)
-REGISTER_VOICEMSG(meet, VOICETYPE_TEAMRADIO)
-REGISTER_VOICEMSG(needhelp, VOICETYPE_TEAMRADIO)
-REGISTER_VOICEMSG(seenflag, VOICETYPE_TEAMRADIO)
-REGISTER_VOICEMSG(taunt, VOICETYPE_TAUNT)
-REGISTER_VOICEMSG(teamshoot, VOICETYPE_LASTATTACKER)
-
-// reserved sound names for the future (some models lack sounds for them):
-// _VOICEMSG(flagcarriertakingdamage)
-// _VOICEMSG(getflag)
-// reserved sound names for the future (ALL models lack sounds for them):
-// _VOICEMSG(affirmative)
-// _VOICEMSG(attacking)
-// _VOICEMSG(defending)
-// _VOICEMSG(roaming)
-// _VOICEMSG(onmyway)
-// _VOICEMSG(droppedflag)
-// _VOICEMSG(negative)
-// _VOICEMSG(seenenemy)
+REGISTER_VOICEMSG(attack, VOICETYPE_TEAMRADIO, true)
+REGISTER_VOICEMSG(attackinfive, VOICETYPE_TEAMRADIO, true)
+REGISTER_VOICEMSG(coverme, VOICETYPE_TEAMRADIO, true)
+REGISTER_VOICEMSG(defend, VOICETYPE_TEAMRADIO, true)
+REGISTER_VOICEMSG(freelance, VOICETYPE_TEAMRADIO, true)
+REGISTER_VOICEMSG(incoming, VOICETYPE_TEAMRADIO, true)
+REGISTER_VOICEMSG(meet, VOICETYPE_TEAMRADIO, true)
+REGISTER_VOICEMSG(needhelp, VOICETYPE_TEAMRADIO, true)
+REGISTER_VOICEMSG(seenflag, VOICETYPE_TEAMRADIO, true)
+REGISTER_VOICEMSG(taunt, VOICETYPE_TAUNT, true)
+REGISTER_VOICEMSG(teamshoot, VOICETYPE_LASTATTACKER, true)
+
+//NOTE: some models lack sounds for these:
+REGISTER_VOICEMSG(flagcarriertakingdamage, VOICETYPE_TEAMRADIO, false)
+REGISTER_VOICEMSG(getflag, VOICETYPE_TEAMRADIO, false)
+//NOTE: ALL models lack sounds for these (only available in default sounds currently):
+REGISTER_VOICEMSG(affirmative, VOICETYPE_TEAMRADIO, false)
+REGISTER_VOICEMSG(attacking, VOICETYPE_TEAMRADIO, false)
+REGISTER_VOICEMSG(defending, VOICETYPE_TEAMRADIO, false)
+REGISTER_VOICEMSG(roaming, VOICETYPE_TEAMRADIO, false)
+REGISTER_VOICEMSG(onmyway, VOICETYPE_TEAMRADIO, false)
+REGISTER_VOICEMSG(droppedflag, VOICETYPE_TEAMRADIO, false)
+REGISTER_VOICEMSG(negative, VOICETYPE_TEAMRADIO, false)
+REGISTER_VOICEMSG(seenenemy, VOICETYPE_TEAMRADIO, false)
 
 .string m_globalsoundstr;
 REGISTRY(GlobalSounds, BITS(8) - 1)
index c82e0bce9310b978ea4e943fe1b34e88e0183a53..cbbe9afb7efd5545b4967b16c96ce445df078d02 100644 (file)
@@ -69,15 +69,6 @@ void HUD_Mod_CTF(vector pos, vector mySize)
     X(neutral);
     #undef X
 
-    const float BLINK_FACTOR = 0.15;
-    const float BLINK_BASE = 0.85;
-    // note:
-    //   RMS = sqrt(BLINK_BASE^2 + 0.5 * BLINK_FACTOR^2)
-    // thus
-    //   BLINK_BASE = sqrt(RMS^2 - 0.5 * BLINK_FACTOR^2)
-    // ensure RMS == 1
-    const float BLINK_FREQ = 5; // circle frequency, = 2*pi*frequency in hertz
-
     #define X(team, cond) \
     string team##_icon = string_null, team##_icon_prevstatus = string_null; \
     int team##_alpha, team##_alpha_prevstatus; \
@@ -86,7 +77,7 @@ void HUD_Mod_CTF(vector pos, vector mySize)
         switch (team##flag) { \
             case 1: team##_icon = "flag_" #team "_taken"; break; \
             case 2: team##_icon = "flag_" #team "_lost"; break; \
-            case 3: team##_icon = "flag_" #team "_carrying"; team##_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break; \
+            case 3: team##_icon = "flag_" #team "_carrying"; team##_alpha = blink(0.85, 0.15, 5); break; \
             default: \
                 if ((stat_items & CTF_SHIELDED) && (cond)) { \
                     team##_icon = "flag_" #team "_shielded"; \
@@ -98,7 +89,7 @@ void HUD_Mod_CTF(vector pos, vector mySize)
         switch (team##flag_prevstatus) { \
             case 1: team##_icon_prevstatus = "flag_" #team "_taken"; break; \
             case 2: team##_icon_prevstatus = "flag_" #team "_lost"; break; \
-            case 3: team##_icon_prevstatus = "flag_" #team "_carrying"; team##_alpha_prevstatus = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break; \
+            case 3: team##_icon_prevstatus = "flag_" #team "_carrying"; team##_alpha_prevstatus = blink(0.85, 0.15, 5); break; \
             default: \
                 if (team##flag == 3) { \
                     team##_icon_prevstatus = "flag_" #team "_carrying"; /* make it more visible */\
index 03b2ec9d1d428a3c7dfce3b0d3cbcb2d5fe05bd1..9f38cd9c36252dfe596b2a62e92fc849d2462682 100644 (file)
@@ -48,6 +48,8 @@ bool autocvar_g_ctf_flag_return_when_unreachable;
 float autocvar_g_ctf_flag_return_damage;
 float autocvar_g_ctf_flag_return_damage_delay;
 float autocvar_g_ctf_flag_return_dropped;
+bool autocvar_g_ctf_flag_waypoint = true;
+float autocvar_g_ctf_flag_waypoint_maxdistance;
 float autocvar_g_ctf_flagcarrier_auto_helpme_damage;
 float autocvar_g_ctf_flagcarrier_auto_helpme_time;
 float autocvar_g_ctf_flagcarrier_selfdamagefactor;
@@ -436,7 +438,19 @@ void ctf_Handle_Throw(entity player, entity receiver, int droptype)
        if(!flag) { return; }
        if((droptype == DROP_PASS) && !receiver) { return; }
 
-       if(flag.speedrunning) { ctf_RespawnFlag(flag); return; }
+       if(flag.speedrunning)
+       {
+               // ensure old waypoints are removed before resetting the flag
+               WaypointSprite_Kill(player.wps_flagcarrier);
+
+               if(player.wps_enemyflagcarrier)
+                       WaypointSprite_Kill(player.wps_enemyflagcarrier);
+
+               if(player.wps_flagreturn)
+                       WaypointSprite_Kill(player.wps_flagreturn);
+               ctf_RespawnFlag(flag);
+               return;
+       }
 
        // reset the flag
        setattachment(flag, NULL, "");
@@ -1133,6 +1147,7 @@ METHOD(Flag, giveTo, bool(Flag this, entity flag, entity toucher))
 .float last_respawn;
 void ctf_RespawnFlag(entity flag)
 {
+       flag.watertype = CONTENT_EMPTY; // TODO: it is unclear why this workaround is needed, likely many other potential breakage points!!
        // check for flag respawn being called twice in a row
        if(flag.last_respawn > time - 0.5)
                { backtrace("flag respawn called twice quickly! please notify Samual about this..."); }
@@ -1224,10 +1239,14 @@ void ctf_DelayedFlagSetup(entity this) // called after a flag is placed on a map
                default: basename = WP_FlagBaseNeutral; break;
        }
 
-       entity wp = WaypointSprite_SpawnFixed(basename, this.origin + FLAG_WAYPOINT_OFFSET, this, wps_flagbase, RADARICON_FLAG);
-       wp.colormod = ((this.team) ? Team_ColorRGB(this.team) : '1 1 1');
-       WaypointSprite_UpdateTeamRadar(this.wps_flagbase, RADARICON_FLAG, ((this.team) ? colormapPaletteColor(this.team - 1, false) : '1 1 1'));
-       setcefc(wp, ctf_FlagBase_Customize);
+       if(autocvar_g_ctf_flag_waypoint)
+       {
+               entity wp = WaypointSprite_SpawnFixed(basename, this.origin + FLAG_WAYPOINT_OFFSET, this, wps_flagbase, RADARICON_FLAG);
+               wp.colormod = ((this.team) ? Team_ColorRGB(this.team) : '1 1 1');
+               wp.fade_rate = autocvar_g_ctf_flag_waypoint_maxdistance;
+               WaypointSprite_UpdateTeamRadar(this.wps_flagbase, RADARICON_FLAG, ((this.team) ? colormapPaletteColor(this.team - 1, false) : '1 1 1'));
+               setcefc(wp, ctf_FlagBase_Customize);
+       }
 
        // captureshield setup
        ctf_CaptureShield_Spawn(this);
@@ -1235,7 +1254,7 @@ void ctf_DelayedFlagSetup(entity this) // called after a flag is placed on a map
 
 .bool pushable;
 
-void ctf_FlagSetup(int teamnumber, entity flag) // called when spawning a flag entity on the map as a spawnfunc
+void ctf_FlagSetup(int teamnum, entity flag) // called when spawning a flag entity on the map as a spawnfunc
 {
        // main setup
        flag.ctf_worldflagnext = ctf_worldflaglist; // link flag into ctf_worldflaglist
@@ -1243,8 +1262,8 @@ void ctf_FlagSetup(int teamnumber, entity flag) // called when spawning a flag e
 
        setattachment(flag, NULL, "");
 
-       flag.netname = strzone(sprintf("%s%s^7 flag", Team_ColorCode(teamnumber), Team_ColorName_Upper(teamnumber)));
-       flag.team = teamnumber;
+       flag.netname = strzone(sprintf("%s%s^7 flag", Team_ColorCode(teamnum), Team_ColorName_Upper(teamnum)));
+       flag.team = teamnum;
        flag.classname = "item_flag_team";
        flag.target = "###item###"; // for finding the nearest item using findnearest
        flag.flags = FL_ITEM | FL_NOTARGET;
@@ -1274,24 +1293,24 @@ void ctf_FlagSetup(int teamnumber, entity flag) // called when spawning a flag e
        if(autocvar_g_ctf_score_ignore_fields)
                flag.cnt = flag.score_assist = flag.score_team_capture = flag.score_capture = flag.score_drop = flag.score_pickup = flag.score_return = 0;
 
-       string teamname = Static_Team_ColorName_Lower(teamnumber);
+       string teamname = Static_Team_ColorName_Lower(teamnum);
        // appearence
        if(!flag.scale)                         { flag.scale = FLAG_SCALE; }
        if(flag.skin == 0)                      { flag.skin = cvar(sprintf("g_ctf_flag_%s_skin", teamname)); }
        if(flag.model == "")            { flag.model = cvar_string(sprintf("g_ctf_flag_%s_model", teamname)); }
-       if (flag.toucheffect == "") { flag.toucheffect = EFFECT_FLAG_TOUCH(teamnumber).eent_eff_name; }
-       if (flag.passeffect == "")      { flag.passeffect = EFFECT_PASS(teamnumber).eent_eff_name; }
-       if (flag.capeffect == "")       { flag.capeffect = EFFECT_CAP(teamnumber).eent_eff_name; }
+       if (flag.toucheffect == "") { flag.toucheffect = EFFECT_FLAG_TOUCH(teamnum).eent_eff_name; }
+       if (flag.passeffect == "")      { flag.passeffect = EFFECT_PASS(teamnum).eent_eff_name; }
+       if (flag.capeffect == "")       { flag.capeffect = EFFECT_CAP(teamnum).eent_eff_name; }
 
        // sounds
 #define X(s,b) \
                if(flag.s == "") flag.s = b; \
                precache_sound(flag.s);
 
-       X(snd_flag_taken,               strzone(SND(CTF_TAKEN(teamnumber))))
-       X(snd_flag_returned,    strzone(SND(CTF_RETURNED(teamnumber))))
-       X(snd_flag_capture,     strzone(SND(CTF_CAPTURE(teamnumber))))
-       X(snd_flag_dropped,     strzone(SND(CTF_DROPPED(teamnumber))))
+       X(snd_flag_taken,               strzone(SND(CTF_TAKEN(teamnum))))
+       X(snd_flag_returned,    strzone(SND(CTF_RETURNED(teamnum))))
+       X(snd_flag_capture,     strzone(SND(CTF_CAPTURE(teamnum))))
+       X(snd_flag_dropped,     strzone(SND(CTF_DROPPED(teamnum))))
        X(snd_flag_respawn,     strzone(SND(CTF_RESPAWN)))
        X(snd_flag_touch,               strzone(SND(CTF_TOUCH)))
        X(snd_flag_pass,                strzone(SND(CTF_PASS)))
@@ -1309,7 +1328,7 @@ void ctf_FlagSetup(int teamnumber, entity flag) // called when spawning a flag e
 
        if(autocvar_g_ctf_flag_glowtrails)
        {
-               switch(teamnumber)
+               switch(teamnum)
                {
                        case NUM_TEAM_1: flag.glow_color = 251; break;
                        case NUM_TEAM_2: flag.glow_color = 210; break;
@@ -1325,7 +1344,7 @@ void ctf_FlagSetup(int teamnumber, entity flag) // called when spawning a flag e
        if(autocvar_g_ctf_fullbrightflags) { flag.effects |= EF_FULLBRIGHT; }
        if(autocvar_g_ctf_dynamiclights)
        {
-               switch(teamnumber)
+               switch(teamnum)
                {
                        case NUM_TEAM_1: flag.effects |= EF_RED; break;
                        case NUM_TEAM_2: flag.effects |= EF_BLUE; break;
@@ -1387,7 +1406,7 @@ void havocbot_ctf_calculate_middlepoint()
                // for symmetrical editing of waypoints
                entity f1 = ctf_worldflaglist;
                entity f2 = f1.ctf_worldflagnext;
-               float m = -(f1.origin.y - f2.origin.y) / (f1.origin.x - f2.origin.x);
+               float m = -(f1.origin.y - f2.origin.y) / (max(f1.origin.x - f2.origin.x, FLOAT_EPSILON));
                float q = havocbot_middlepoint.y - m * havocbot_middlepoint.x;
                havocbot_symmetry_axis_m = m;
                havocbot_symmetry_axis_q = q;
index 54f6268e36da53d537e2effef2c5c72c62afadbf..5b4c80e7f619c6fc0ce768f8c2cb2a09e5067004 100644 (file)
@@ -130,7 +130,7 @@ bool freezetag_CheckWinner()
        {
                Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, APP_TEAM_NUM(winner_team, CENTER_ROUND_TEAM_WIN));
                Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(winner_team, INFO_ROUND_TEAM_WIN));
-               TeamScore_AddToTeam(winner_team, ST_SCORE, +1);
+               TeamScore_AddToTeam(winner_team, ST_FT_ROUNDS, +1);
        }
        else if(winner_team == -1)
        {
@@ -366,6 +366,9 @@ MUTATOR_HOOKFUNCTION(ft, PlayerDies)
                return true;
        }
 
+       frag_target.respawn_time = time + 1;
+       frag_target.respawn_flags |= RESPAWN_FORCE;
+
        // Cases DEATH_TEAMCHANGE and DEATH_AUTOTEAMCHANGE are needed to fix a bug whe
        // you succeed changing team through the menu: you both really die (gibbing) and get frozen
        if(ITEM_DAMAGE_NEEDKILL(frag_deathtype)
@@ -472,15 +475,18 @@ MUTATOR_HOOKFUNCTION(ft, PlayerPreThink, CBC_ORDER_FIRST)
        if(!round_handler_IsRoundStarted())
                return true;
 
-       int n;
        entity player = M_ARGV(0, entity);
        //if (STAT(FROZEN, player) == FROZEN_NORMAL)
        //if(player.freezetag_frozen_timeout > 0 && time < player.freezetag_frozen_timeout)
                //player.iceblock.alpha = ICE_MIN_ALPHA + (ICE_MAX_ALPHA - ICE_MIN_ALPHA) * (player.freezetag_frozen_timeout - time) / (player.freezetag_frozen_timeout - player.freezetag_frozen_time);
 
+       if (!(frametime && IS_PLAYER(player)))
+               return true;
+
        entity reviving_players_last = NULL;
        entity reviving_players_first = NULL;
 
+       int n;
        if(player.freezetag_frozen_timeout > 0 && time >= player.freezetag_frozen_timeout)
                n = -1;
        else
@@ -617,6 +623,12 @@ MUTATOR_HOOKFUNCTION(ft, SV_ParseServerCommand)
        return false;
 }
 
+MUTATOR_HOOKFUNCTION(ft, Scores_CountFragsRemaining)
+{
+       // announce remaining frags
+       return true;
+}
+
 void freezetag_Initialize()
 {
        freezetag_teams = autocvar_g_freezetag_teams_override;
@@ -625,6 +637,7 @@ void freezetag_Initialize()
 
        freezetag_teams = BITS(bound(2, freezetag_teams, 4));
        GameRules_scoring(freezetag_teams, SFL_SORT_PRIO_PRIMARY, SFL_SORT_PRIO_PRIMARY, {
+               field_team(ST_FT_ROUNDS, "rounds", SFL_SORT_PRIO_PRIMARY);
                field(SP_FREEZETAG_REVIVALS, "revivals", 0);
        });
 
index 3eb753020b35a857da4cde61e2b9b95879727c47..b77318ca2e808d8929caa9996e184e293b3b6be5 100644 (file)
@@ -8,6 +8,8 @@ int autocvar_g_freezetag_point_leadlimit;
 bool autocvar_g_freezetag_team_spawns;
 string autocvar_g_freezetag_weaponarena = "most_available";
 
+const int ST_FT_ROUNDS = 1;
+
 void freezetag_Initialize();
 
 REGISTER_MUTATOR(ft, false)
index b2d08742854e6cf04f2f68e6cbc346c5b9e77934..660a5511ec551f9f2e57ef7bc2a2a8a9a3e76f59 100644 (file)
@@ -13,10 +13,7 @@ void HUD_Mod_Keepaway(vector pos, vector mySize)
 {
        mod_active = 1; // keepaway should always show the mod HUD
 
-       float BLINK_FACTOR = 0.15;
-       float BLINK_BASE = 0.85;
-       float BLINK_FREQ = 5;
-       float kaball_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ);
+       float kaball_alpha = blink(0.85, 0.15, 5);
 
        int stat_items = STAT(ITEMS);
        int kaball = (stat_items/IT_KEY1) & 1;
index 0b8144deb7d5ae5cf147f2a326bbc727a55510c5..f3c140fd11472c37437644e22aa3c5fe56db721f 100644 (file)
@@ -350,6 +350,12 @@ MUTATOR_HOOKFUNCTION(ka, GiveFragsForKill)
        return true; // you deceptive little bugger ;3 This needs to be true in order for this function to even count.
 }
 
+MUTATOR_HOOKFUNCTION(ka, Scores_CountFragsRemaining)
+{
+       // announce remaining frags, but only when timed scoring is off
+       return !autocvar_g_keepaway_score_timepoints;
+}
+
 MUTATOR_HOOKFUNCTION(ka, PlayerPreThink)
 {
        entity player = M_ARGV(0, entity);
index 21d9208bf96b74746cbb7f35c074b2a5f228ad27..5d52ed7cb0379916ea8841585c46c04f71718dfa 100644 (file)
@@ -541,7 +541,12 @@ void kh_WinnerTeam(int winner_team)  // runs when a team wins
                midpoint += thisorigin;
 
                if(!first)
-                       te_lightning2(NULL, lastorigin, thisorigin);
+               {
+                       // TODO: this effect has been replaced due to a possible crash it causes
+                       // see https://gitlab.com/xonotic/darkplaces/issues/123
+                       //te_lightning2(NULL, lastorigin, thisorigin);
+                       Send_Effect(EFFECT_TR_NEXUIZPLASMA, lastorigin, thisorigin, 1);
+               }
                lastorigin = thisorigin;
                if(first)
                        firstorigin = thisorigin;
@@ -549,7 +554,8 @@ void kh_WinnerTeam(int winner_team)  // runs when a team wins
        }
        if(NumTeams(kh_teams) > 2)
        {
-               te_lightning2(NULL, lastorigin, firstorigin);
+               //te_lightning2(NULL, lastorigin, firstorigin); // TODO see above
+               Send_Effect(EFFECT_TR_NEXUIZPLASMA, lastorigin, firstorigin, 1);
        }
        midpoint = midpoint * (1 / NumTeams(kh_teams));
        te_customflash(midpoint, 1000, 1, Team_ColorRGB(winner_team) * 0.5 + '0.5 0.5 0.5');  // make the color >=0.5 in each component
@@ -1037,7 +1043,7 @@ void havocbot_goalrating_kh(entity this, float ratingscale_team, float ratingsca
                        navigation_routerating(this, head.owner, ratingscale_enemy * 10000, 100000);
        }
 
-       havocbot_goalrating_items(this, 1, this.origin, 10000);
+       havocbot_goalrating_items(this, 80000, this.origin, 10000);
 }
 
 void havocbot_role_kh_carrier(entity this)
index aceb66e0310db714e640c16250b7bcd8d4a547c5..bff9722d08a766785229f3ea4744f58aaf94bc12 100644 (file)
@@ -10,11 +10,10 @@ int autocvar_g_lms_last_join;
 bool autocvar_g_lms_regenerate;
 
 // main functions
-float LMS_NewPlayerLives()
+int LMS_NewPlayerLives()
 {
-       float fl;
-       fl = autocvar_fraglimit;
-       if(fl == 0)
+       int fl = floor(autocvar_fraglimit);
+       if(fl == 0 || fl > 999)
                fl = 999;
 
        // first player has left the game for dying too much? Nobody else can get in.
@@ -22,7 +21,7 @@ float LMS_NewPlayerLives()
                return 0;
 
        if(!autocvar_g_lms_join_anytime)
-               if(lms_lowest_lives < fl - autocvar_g_lms_last_join)
+               if(lms_lowest_lives < fl - max(0, floor(autocvar_g_lms_last_join)))
                        return 0;
 
        return bound(1, lms_lowest_lives, fl);
@@ -184,27 +183,25 @@ void lms_RemovePlayer(entity player)
        float player_rank = GameRules_scoring_add(player, LMS_RANK, 0);
        if (!player_rank)
        {
-               int pl_cnt = 0;
-               FOREACH_CLIENT(IS_PLAYER(it) && it.frags != FRAGS_PLAYER_OUT_OF_GAME, {
-                       pl_cnt++;
-               });
                if (player.lms_spectate_warning < 2)
                {
                        if(IS_BOT_CLIENT(player))
                                bot_clear(player);
                        player.frags = FRAGS_PLAYER_OUT_OF_GAME;
+                       int pl_cnt = 0;
+                       FOREACH_CLIENT(IS_PLAYER(it) && it.frags != FRAGS_PLAYER_OUT_OF_GAME, {
+                               pl_cnt++;
+                       });
                        GameRules_scoring_add(player, LMS_RANK, pl_cnt + 1);
                }
                else
                {
-                       lms_lowest_lives = 999;
                        FOREACH_CLIENT(true, {
                                if (it.frags == FRAGS_PLAYER_OUT_OF_GAME)
                                {
                                        float it_rank = GameRules_scoring_add(it, LMS_RANK, 0);
                                        if (it_rank > player_rank && it_rank <= 256)
                                                GameRules_scoring_add(it, LMS_RANK, -1);
-                                       lms_lowest_lives = 0;
                                }
                                else if (it.frags != FRAGS_SPECTATOR)
                                {
@@ -384,7 +381,7 @@ MUTATOR_HOOKFUNCTION(lms, ItemTouch)
 
        if(item.itemdef == ITEM_ExtraLife)
        {
-               Send_Notification(NOTIF_ONE, toucher, MSG_CENTER, CENTER_EXTRALIVES);
+               Send_Notification(NOTIF_ONE, toucher, MSG_CENTER, CENTER_EXTRALIVES, autocvar_g_lms_extra_lives);
                GameRules_scoring_add(toucher, LMS_LIVES, autocvar_g_lms_extra_lives);
                return MUT_ITEMTOUCH_PICKUP;
        }
@@ -449,5 +446,5 @@ MUTATOR_HOOKFUNCTION(lms, AddPlayerScore)
 
 void lms_Initialize()
 {
-       lms_lowest_lives = 9999;
+       lms_lowest_lives = 999;
 }
index 996d371fe05b84e736283ccc042251aaa60e8a3a..bf02920d2c1616207ac54545d3b331a617de90e6 100644 (file)
@@ -3,7 +3,10 @@
 #include <common/mutators/base.qh>
 #include <common/scores.qh>
 
-.float lms_spectate_warning;
+// 1 when player presses F3 to spectate for the first time (he only gets a warning)
+// 2 when player goes spectator (presses F3 to spectate for the second time)
+// 3 when player disconnects
+.int lms_spectate_warning;
 
 #define autocvar_g_lms_lives_override cvar("g_lms_lives_override")
 string autocvar_g_lms_weaponarena = "most_available";
@@ -29,5 +32,5 @@ REGISTER_MUTATOR(lms, false)
 }
 
 // lives related defs
-float lms_lowest_lives;
-float LMS_NewPlayerLives();
+int lms_lowest_lives;
+int LMS_NewPlayerLives();
index 6f12f3cc0deba003059fb4207497a15362c0ed6b..9675634ec7b5c64780e8707421028ef821b7b11f 100644 (file)
@@ -313,15 +313,15 @@ void ons_DelayedLinkSetup(entity this)
 // Main Control Point Functions
 // =============================
 
-int ons_ControlPoint_CanBeLinked(entity cp, int teamnumber)
+int ons_ControlPoint_CanBeLinked(entity cp, int teamnum)
 {
-       if(cp.aregensneighbor & BIT(teamnumber)) return 2;
-       if(cp.arecpsneighbor & BIT(teamnumber)) return 1;
+       if(cp.aregensneighbor & BIT(teamnum)) return 2;
+       if(cp.arecpsneighbor & BIT(teamnum)) return 1;
 
        return 0;
 }
 
-int ons_ControlPoint_Attackable(entity cp, int teamnumber)
+int ons_ControlPoint_Attackable(entity cp, int teamnum)
        // -2: SAME TEAM, attackable by enemy!
        // -1: SAME TEAM!
        // 0: off limits
@@ -339,16 +339,16 @@ int ons_ControlPoint_Attackable(entity cp, int teamnumber)
        else if(cp.goalentity)
        {
                // if there's already an icon built, nothing happens
-               if(cp.team == teamnumber)
+               if(cp.team == teamnum)
                {
-                       a = ons_ControlPoint_CanBeLinked(cp, teamnumber);
+                       a = ons_ControlPoint_CanBeLinked(cp, teamnum);
                        if(a) // attackable by enemy?
                                return -2; // EMERGENCY!
                        return -1;
                }
                // we know it can be linked, so no need to check
                // but...
-               a = ons_ControlPoint_CanBeLinked(cp, teamnumber);
+               a = ons_ControlPoint_CanBeLinked(cp, teamnum);
                if(a == 2) // near our generator?
                        return 3; // EMERGENCY!
                return 1;
@@ -356,9 +356,9 @@ int ons_ControlPoint_Attackable(entity cp, int teamnumber)
        else
        {
                // free point
-               if(ons_ControlPoint_CanBeLinked(cp, teamnumber))
+               if(ons_ControlPoint_CanBeLinked(cp, teamnum))
                {
-                       a = ons_ControlPoint_CanBeLinked(cp, teamnumber); // why was this here NUM_TEAM_1 + NUM_TEAM_2 - t
+                       a = ons_ControlPoint_CanBeLinked(cp, teamnum); // why was this here NUM_TEAM_1 + NUM_TEAM_2 - t
                        if(a == 2)
                                return 4; // GET THIS ONE NOW!
                        else
@@ -1063,16 +1063,16 @@ void onslaught_generator_touch(entity this, entity toucher)
 void ons_GeneratorSetup(entity gen) // called when spawning a generator entity on the map as a spawnfunc
 {
        // declarations
-       int teamnumber = gen.team;
+       int teamnum = gen.team;
 
        // main setup
        gen.ons_worldgeneratornext = ons_worldgeneratorlist; // link generator into ons_worldgeneratorlist
        ons_worldgeneratorlist = gen;
 
-       gen.netname = sprintf("%s generator", Team_ColoredFullName(teamnumber));
+       gen.netname = sprintf("%s generator", Team_ColoredFullName(teamnum));
        gen.classname = "onslaught_generator";
        gen.solid = SOLID_BBOX;
-       gen.team_saved = teamnumber;
+       gen.team_saved = teamnum;
        IL_PUSH(g_saved_team, gen);
        set_movetype(gen, MOVETYPE_NONE);
        gen.lasthealth = gen.max_health = autocvar_g_onslaught_gen_health;
@@ -1094,7 +1094,7 @@ void ons_GeneratorSetup(entity gen) // called when spawning a generator entity o
        // model handled by CSQC
        setsize(gen, GENERATOR_MIN, GENERATOR_MAX);
        setorigin(gen, (gen.origin + CPGEN_SPAWN_OFFSET));
-       gen.colormap = 1024 + (teamnumber - 1) * 17;
+       gen.colormap = 1024 + (teamnum - 1) * 17;
 
        // generator placement
        droptofloor(gen);
index 7a9b192a5a7b041e313c807dd464b04d3e0c3e98..0800ae10fd1623edd71da495808ae2e20ef0024c 100644 (file)
@@ -67,7 +67,7 @@ float ons_notification_time[17];
 // declarations for functions used outside gamemode_onslaught.qc
 void ons_Generator_UpdateSprite(entity e);
 void ons_ControlPoint_UpdateSprite(entity e);
-bool ons_ControlPoint_Attackable(entity cp, int teamnumber);
+bool ons_ControlPoint_Attackable(entity cp, int teamnum);
 
 // CaptureShield: Prevent capturing or destroying control point/generator if it is not available yet
 float ons_captureshield_force; // push force of the shield
index 3ff4a54155a3cccaf0ea91b69a38a02ac90c15dc..3ae473503db46e24d8f8877a2fb05cd998142082 100644 (file)
@@ -19,7 +19,7 @@ STATIC_INIT(Items) { FOREACH(Items, true, it.m_id = i); }
 
 void Dump_Items();
 
-GENERIC_COMMAND(dumpitems, "Dump all items to the console") {
+GENERIC_COMMAND(dumpitems, "Dump all items to the console", false) {
     switch (request) {
         case CMD_REQUEST_COMMAND: {
             Dump_Items();
index 017ada75c0288df84ce093b80dffefa8316a810c..9f0a43a0750959f08d1847886e09e88ea017673d 100644 (file)
@@ -42,7 +42,7 @@ NET_HANDLE(ENT_CLIENT_INVENTORY, bool isnew)
             .int fld = inv_items[it.m_id];
             int prev = this.(fld);
             int next = this.(fld) = ReadByte();
-            LOG_TRACEF("%s: %.0f -> %.0f", it.m_name, prev, next);
+            LOG_DEBUGF("%s: %.0f -> %.0f", it.m_name, prev, next);
         }
     }
     return true;
index 8ba0096713342a7c7a5364b95ffe8fb58674c2e2..d095c81347e25414956bbae4ae0fe8fc5ef4b7c4 100644 (file)
@@ -47,8 +47,8 @@ const int IT_STRENGTH                                 = BIT(22);
 const int IT_PICKUPMASK                        = IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPERWEAPONS | IT_JETPACK | IT_FUEL_REGEN; // strength and invincible are handled separately
 
 #ifdef SVQC
-const .float strength_finished = _STAT(STRENGTH_FINISHED);
-const .float invincible_finished = _STAT(INVINCIBLE_FINISHED);
+.float strength_finished; // NOTE: this field is used only by map entities, it does not directly apply the strength stat
+.float invincible_finished; // ditto
 
 #define spawnfunc_body(item) \
        if (!Item_IsDefinitionAllowed(item)) \
index 0f09901af214c9c24bd78023b163b365400bd8d2..7e31994075c244277201a4d02799825c89346f44 100644 (file)
@@ -34,7 +34,7 @@ CLASS(Pickup, GameItem)
     ATTRIB(Pickup, m_itemid, int, 0);
 #ifdef SVQC
     ATTRIB(Pickup, m_mins, vector, '-16 -16 0');
-    ATTRIB(Pickup, m_maxs, vector, '16 16 32');
+    ATTRIB(Pickup, m_maxs, vector, '16 16 48');
     ATTRIB(Pickup, m_botvalue, int, 0);
     ATTRIB(Pickup, m_itemflags, int, 0);
     float generic_pickupevalfunc(entity player, entity item);
index 3e6478b2db50ca25a54716a137d75ca7ba01e4e6..f771b0f83cfea0d7c2a9545c96ea28f04af00d10 100644 (file)
@@ -9,10 +9,10 @@
     #include <common/monsters/_mod.qh>
 #endif
 
-bool autocvar_g_mapinfo_ignore_warnings;
 #ifdef MENUQC
-#define WARN_COND (!autocvar_g_mapinfo_ignore_warnings)
+#define WARN_COND false
 #else
+bool autocvar_g_mapinfo_ignore_warnings;
 #define WARN_COND (!autocvar_g_mapinfo_ignore_warnings && MapInfo_Map_bspname == mi_shortname)
 #endif
 
@@ -671,11 +671,8 @@ void _MapInfo_Parse_Settemp(string pFilename, string acl, float type, string s,
                        }
                        else
                        {
-                               for (;;)
+                               while((s = fgets(fh)))
                                {
-                                       if (!((s = fgets(fh))))
-                                               break;
-
                                        // catch different sorts of comments
                                        if(s == "")                    // empty lines
                                                continue;
@@ -843,12 +840,6 @@ float MapInfo_Get_ByName_NoFallbacks(string pFilename, int pAllowGenerate, Gamet
                                fputs(fh, sprintf("gametype %s // defaults: %s\n", MapInfo_Type_ToString(it), _MapInfo_GetDefaultEx(it)));
                        });
 
-                       if(fexists(strcat("scripts/", pFilename, ".arena")))
-                               fputs(fh, "settemp_for_type all sv_q3acompat_machineshotgunswap 1\n");
-
-                       if(fexists(strcat("scripts/", pFilename, ".defi")))
-                               fputs(fh, "settemp_for_type all sv_vq3compat 1\n");
-
                        fputs(fh, "// optional: fog density red green blue alpha mindist maxdist\n");
                        fputs(fh, "// optional: settemp_for_type (all|gametypename) cvarname value\n");
                        fputs(fh, "// optional: clientsettemp_for_type (all|gametypename) cvarname value\n");
@@ -1147,7 +1138,9 @@ string MapInfo_FixName(string s)
 int MapInfo_CurrentFeatures()
 {
        int req = 0;
-       if(!(cvar("g_lms") || cvar("g_instagib") || cvar("g_overkill") || cvar("g_nix") || cvar("g_weaponarena") || !cvar("g_pickup_items") || cvar("g_race") || cvar("g_cts") || cvar("g_nexball")))
+    // TODO: find a better way to check if weapons are required on the map
+       if(!(cvar("g_instagib") || cvar("g_overkill") || cvar("g_nix") || cvar("g_weaponarena") || !cvar("g_pickup_items") 
+               || cvar("g_race") || cvar("g_cts") || cvar("g_nexball") || cvar("g_ca") || cvar("g_freezetag") || cvar("g_lms")))
                req |= MAPINFO_FEATURE_WEAPONS;
        return req;
 }
index 32926d4908cfa8fff4941f31773a3725ccb90bbc..e92af677cc565dabd71a4177c94b17983f0ab6a0 100644 (file)
@@ -343,7 +343,7 @@ spawnfunc(func_breakable)
                this.dmg_force = 200;
 
        this.mdl = this.model;
-       SetBrushEntityModel(this);
+       SetBrushEntityModel(this, true);
 
        if(this.spawnflags & BREAKABLE_NODAMAGE)
                this.use = func_breakable_destroy;
index 56bfd4148d70bf7cde682bec1c83d4fb0f633d3a..423ac5e7b6d927f9fa2f8cdd42cf9797fe6b2f56 100644 (file)
@@ -206,6 +206,9 @@ spawnfunc(func_button)
        if (!this.lip)
                this.lip = 4;
 
+       if(this.wait == -1 && autocvar_sv_q3defragcompat)
+               this.wait = 0.1; // compatibility for q3df: "instant" return
+
     if(this.noise != "")
         precache_sound(this.noise);
 
index c765a4293b9e79c34fc5d922b6846058ebb3b440..4f4d4d0aca59349bd04975b75b514c4501e3c7c4 100644 (file)
@@ -13,6 +13,7 @@ bool rainsnow_SendEntity(entity this, entity to, float sf)
        WriteShort(MSG_ENTITY, compressShortVector(this.dest));
        WriteShort(MSG_ENTITY, this.count);
        WriteByte(MSG_ENTITY, this.cnt);
+       WriteShort(MSG_ENTITY, bound(0, this.fade_end, 65535));
        return true;
 }
 
@@ -36,7 +37,7 @@ spawnfunc(func_rain)
        this.angles = '0 0 0';
        set_movetype(this, MOVETYPE_NONE);
        this.solid = SOLID_NOT;
-       SetBrushEntityModel(this);
+       SetBrushEntityModel(this, true);
        if (!this.cnt)
        {
                this.cnt = 12;
@@ -44,7 +45,7 @@ spawnfunc(func_rain)
        if (!this.count)
                this.count = 2000;
        // relative to absolute particle count
-       this.count = 0.1 * this.count * (this.size_x / 1024) * (this.size_y / 1024);
+       //this.count = 0.1 * this.count * (this.size_x / 1024) * (this.size_y / 1024);
        if (this.count < 1)
                this.count = 1;
        if(this.count > 65535)
@@ -76,7 +77,7 @@ spawnfunc(func_snow)
        this.angles = '0 0 0';
        set_movetype(this, MOVETYPE_NONE);
        this.solid = SOLID_NOT;
-       SetBrushEntityModel(this);
+       SetBrushEntityModel(this, true);
        if (!this.cnt)
        {
                this.cnt = 12;
@@ -84,7 +85,7 @@ spawnfunc(func_snow)
        if (!this.count)
                this.count = 2000;
        // relative to absolute particle count
-       this.count = 0.1 * this.count * (this.size_x / 1024) * (this.size_y / 1024);
+       //this.count = 0.1 * this.count * (this.size_x / 1024) * (this.size_y / 1024);
        if (this.count < 1)
                this.count = 1;
        if(this.count > 65535)
@@ -95,24 +96,26 @@ spawnfunc(func_snow)
        Net_LinkEntity(this, false, 0, rainsnow_SendEntity);
 }
 #elif defined(CSQC)
-float autocvar_cl_rainsnow_maxdrawdist = 2048;
+float autocvar_cl_rainsnow_maxdrawdist = 1000;
 
-void Draw_Rain(entity this)
+void Draw_RainSnow(entity this)
 {
-       vector maxdist = '1 1 0' * autocvar_cl_rainsnow_maxdrawdist;
-       maxdist.z = 5;
-       if(boxesoverlap(vec2(view_origin) - maxdist, vec2(view_origin) + maxdist, vec2(this.absmin) - '0 0 5', vec2(this.absmax) + '0 0 5'))
-       //if(autocvar_cl_rainsnow_maxdrawdist <= 0 || vdist(vec2(this.origin) - vec2(this.absmin + this.absmax * 0.5), <=, autocvar_cl_rainsnow_maxdrawdist))
-       te_particlerain(this.origin + this.mins, this.origin + this.maxs, this.velocity, floor(this.count * drawframetime + random()), this.glow_color);
-}
+       float drawdist = ((this.fade_end) ? this.fade_end : autocvar_cl_rainsnow_maxdrawdist);
+       vector maxdist = '1 1 1' * drawdist;
 
-void Draw_Snow(entity this)
-{
-       vector maxdist = '1 1 0' * autocvar_cl_rainsnow_maxdrawdist;
-       maxdist.z = 5;
-       if(boxesoverlap(vec2(view_origin) - maxdist, vec2(view_origin) + maxdist, vec2(this.absmin) - '0 0 5', vec2(this.absmax) + '0 0 5'))
-       //if(autocvar_cl_rainsnow_maxdrawdist <= 0 || vdist(vec2(this.origin) - vec2(this.absmin + this.absmax * 0.5), <=, autocvar_cl_rainsnow_maxdrawdist))
-       te_particlesnow(this.origin + this.mins, this.origin + this.maxs, this.velocity, floor(this.count * drawframetime + random()), this.glow_color);
+       vector effbox_min = vec_to_max(view_origin - maxdist, this.origin + this.mins);
+       vector effbox_max = vec_to_min(view_origin + maxdist, this.origin + this.maxs);
+
+       vector mysize = effbox_max - effbox_min;
+       float mycount = bound(1, 0.1 * this.count * (mysize.x / 1024) * (mysize.y / 1024), 65535);
+
+       if(boxesoverlap(view_origin - maxdist, view_origin + maxdist, this.absmin, this.absmax)) // optimisation: don't render any rain if the player is outside the view distance
+       {
+               if(this.state == RAINSNOW_RAIN)
+               te_particlerain(effbox_min, effbox_max, this.velocity, floor(mycount * drawframetime + random()), this.glow_color);
+       else
+               te_particlesnow(effbox_min, effbox_max, this.velocity, floor(mycount * drawframetime + random()), this.glow_color);
+       }
 }
 
 NET_HANDLE(ENT_CLIENT_RAINSNOW, bool isnew)
@@ -123,6 +126,7 @@ NET_HANDLE(ENT_CLIENT_RAINSNOW, bool isnew)
        this.velocity = decompressShortVector(ReadShort());
        this.count = ReadShort();
        this.glow_color = ReadByte(); // color
+       this.fade_end = ReadShort();
 
        return = true;
 
@@ -134,9 +138,6 @@ NET_HANDLE(ENT_CLIENT_RAINSNOW, bool isnew)
        setsize(this, this.mins, this.maxs);
        this.solid = SOLID_NOT;
        if (isnew) IL_PUSH(g_drawables, this);
-       if(this.state == RAINSNOW_RAIN)
-               this.draw = Draw_Rain;
-       else
-               this.draw = Draw_Snow;
+       this.draw = Draw_RainSnow;
 }
 #endif
index 44a13522a4c5b348dcf0bb224c5775b342c72292..18d033663eaff85541fadfffe49dcbf849370484 100644 (file)
@@ -168,7 +168,7 @@ bool g_clientmodel_genericsendentity(entity this, entity to, int sf)
 #define G_MODEL_INIT(ent,sol) \
        if(ent.geomtype && autocvar_physics_ode && checkextension("DP_PHYSICS_ODE")) set_movetype(ent, MOVETYPE_PHYSICS); \
        if(!ent.scale) ent.scale = ent.modelscale; \
-       SetBrushEntityModel(ent); \
+       SetBrushEntityModel(ent,true); \
        ent.use = g_model_setcolormaptoactivator; \
        InitializeEntity(ent, g_model_dropbyspawnflags, INITPRIO_DROPTOFLOOR); \
        if(!ent.solid) ent.solid = (sol); \
@@ -177,7 +177,7 @@ bool g_clientmodel_genericsendentity(entity this, entity to, int sf)
 #define G_CLIENTMODEL_INIT(ent,sol) \
        if(ent.geomtype && autocvar_physics_ode && checkextension("DP_PHYSICS_ODE")) set_movetype(ent, MOVETYPE_PHYSICS); \
        if(!ent.scale) ent.scale = ent.modelscale; \
-       SetBrushEntityModel(ent); \
+       SetBrushEntityModel(ent,true); \
        ent.use = g_clientmodel_use; \
        InitializeEntity(ent, g_clientmodel_dropbyspawnflags, INITPRIO_DROPTOFLOOR); \
        if(!ent.solid) ent.solid = (sol); \
index f9e50dcf8f19d819509c9c6a460050da0a120954..9adccb4924e3721a91ae31c4c6a4d90ff458e442 100644 (file)
@@ -398,7 +398,7 @@ void ApplyMinMaxScaleAngles(entity e)
                setsize(e, e.mins, e.maxs);
 }
 
-void SetBrushEntityModel(entity this)
+void SetBrushEntityModel(entity this, bool with_lod)
 {
        if(this.model != "")
        {
@@ -412,26 +412,11 @@ void SetBrushEntityModel(entity this)
                }
                else
                        _setmodel(this, this.model); // no precision needed
-               InitializeEntity(this, LODmodel_attach, INITPRIO_FINDTARGET);
-       }
-       setorigin(this, this.origin);
-       ApplyMinMaxScaleAngles(this);
-}
+               if(with_lod)
+                       InitializeEntity(this, LODmodel_attach, INITPRIO_FINDTARGET);
 
-void SetBrushEntityModelNoLOD(entity this)
-{
-       if(this.model != "")
-       {
-               precache_model(this.model);
-               if(this.mins != '0 0 0' || this.maxs != '0 0 0')
-               {
-                       vector mi = this.mins;
-                       vector ma = this.maxs;
-                       _setmodel(this, this.model); // no precision needed
-                       setsize(this, mi, ma);
-               }
-               else
-                       _setmodel(this, this.model); // no precision needed
+               if(endsWith(this.model, ".obj")) // WORKAROUND: darkplaces currently rotates .obj models on entities incorrectly, we need to add 180 degrees to the Y axis
+                       this.angles_y = anglemods(this.angles_y - 180);
        }
        setorigin(this, this.origin);
        ApplyMinMaxScaleAngles(this);
@@ -553,7 +538,7 @@ void InitTrigger(entity this)
 // to mean no restrictions, so use a yaw of 360 instead.
        SetMovedir(this);
        this.solid = SOLID_TRIGGER;
-       SetBrushEntityModelNoLOD(this);
+       SetBrushEntityModel(this, false);
        set_movetype(this, MOVETYPE_NONE);
        this.modelindex = 0;
        this.model = "";
@@ -565,7 +550,7 @@ void InitSolidBSPTrigger(entity this)
 // to mean no restrictions, so use a yaw of 360 instead.
        SetMovedir(this);
        this.solid = SOLID_BSP;
-       SetBrushEntityModelNoLOD(this);
+       SetBrushEntityModel(this, false);
        set_movetype(this, MOVETYPE_NONE); // why was this PUSH? -div0
 //     this.modelindex = 0;
        this.model = "";
@@ -576,7 +561,7 @@ bool InitMovingBrushTrigger(entity this)
 // trigger angles are used for one-way touches.  An angle of 0 is assumed
 // to mean no restrictions, so use a yaw of 360 instead.
        this.solid = SOLID_BSP;
-       SetBrushEntityModel(this);
+       SetBrushEntityModel(this, true);
        set_movetype(this, MOVETYPE_PUSH);
        if(this.modelindex == 0)
        {
index 861d73e72f28d6522ea9c488d91a6ae465f6a87d..c1d4d06e56f276cc1bff37f9d93e7e250f01788b 100644 (file)
@@ -115,9 +115,7 @@ void SUB_CalcMoveEnt (entity ent, vector tdest, float tspeedtype, float tspeed,
 #ifdef SVQC
 void ApplyMinMaxScaleAngles(entity e);
 
-void SetBrushEntityModel(entity this);
-
-void SetBrushEntityModelNoLOD(entity this);
+void SetBrushEntityModel(entity this, bool with_lod);
 
 int autocvar_loddebug;
 .string lodtarget1;
index db255ebb7aff0d80f596dfeb91cdf35a43cf988d..44cbd9045307f844f473b15e0895c4a959aebfa2 100644 (file)
@@ -5,11 +5,26 @@ void counter_reset(entity this);
 void counter_use(entity this, entity actor, entity trigger)
 {
        entity store = this;
-       if(this.spawnflags & COUNTER_PER_PLAYER) // FIXME: multiple counters in the map will not function correctly, and upon trigger reset the player won't be able to use it again!
+       if(this.spawnflags & COUNTER_PER_PLAYER)
        {
                if(!IS_PLAYER(actor))
                        return;
-               store = actor;
+               entity mycounter = NULL;
+               IL_EACH(g_counters, it.realowner == actor && it.owner == this,
+               {
+                       mycounter = it;
+                       break;
+               });
+               if(!mycounter)
+               {
+                       mycounter = new_pure(counter);
+                       IL_PUSH(g_counters, mycounter);
+                       mycounter.owner = this;
+                       mycounter.realowner = actor;
+                       mycounter.reset = counter_reset; // NOTE: this may be useless as the player deletes their counters upon respawning
+                       mycounter.counter_cnt = 0;
+               }
+               store = mycounter;
        }
 
        store.counter_cnt += 1;
@@ -27,8 +42,8 @@ void counter_use(entity this, entity actor, entity trigger)
 
                if(this.respawntime)
                {
-                       setthink(this, counter_reset);
-                       this.nextthink = time + this.respawntime;
+                       setthink(store, counter_reset);
+                       store.nextthink = time + this.respawntime;
                }
        }
        else
index d36bd0293cc933ead43f3e2248b46d157cdc91c3..403a87a8920b45361bbbd404a1ff55588c19b6ae 100644 (file)
@@ -4,6 +4,9 @@
 spawnfunc(trigger_counter);
 
 .float counter_cnt;
+
+IntrusiveList g_counters;
+STATIC_INIT(g_counters) { g_counters = IL_NEW(); }
 #endif
 
 const int COUNTER_FIRE_AT_COUNT = BIT(2);
index eee61c993535f063b5ba30eeccdd6db3550b0273..dde1a77c73aeb1a18568da54de88c600107ff70d 100644 (file)
@@ -2,18 +2,21 @@
 #ifdef SVQC
 void trigger_disablerelay_use(entity this, entity actor, entity trigger)
 {
+       if(this.active != ACTIVE_ACTIVE)
+               return;
+
        int a = 0, b = 0;
 
        for(entity e = NULL; (e = find(e, targetname, this.target)); )
        {
-               if(e.use == SUB_UseTargets)
+               if(e.active == ACTIVE_ACTIVE)
                {
-                       e.use = SUB_DontUseTargets;
+                       e.active = ACTIVE_NOT;
                        ++a;
                }
-               else if(e.use == SUB_DontUseTargets)
+               else if(e.active == ACTIVE_NOT)
                {
-                       e.use = SUB_UseTargets;
+                       e.active = ACTIVE_ACTIVE;
                        ++b;
                }
        }
@@ -24,6 +27,8 @@ void trigger_disablerelay_use(entity this, entity actor, entity trigger)
 
 spawnfunc(trigger_disablerelay)
 {
+       this.reset = spawnfunc_trigger_disablerelay; // this spawnfunc resets fully
+       this.active = ACTIVE_ACTIVE;
        this.use = trigger_disablerelay_use;
 }
 #endif
index ccdf2c7d0b96a291086be949e2c53db8180b725d..8c21c509c5643419bb937d1d4170a81d711f12df 100644 (file)
@@ -25,7 +25,7 @@ void trigger_hurt_touch(entity this, entity toucher)
                if (toucher.triggerhurttime < time)
                {
                        EXACTTRIGGER_TOUCH(this, toucher);
-                       toucher.triggerhurttime = time + ((autocvar_sv_vq3compat && !(this.spawnflags & HURT_SLOW)) ? 0.1 : 1);
+                       toucher.triggerhurttime = time + ((autocvar_sv_q3defragcompat && !(this.spawnflags & HURT_SLOW)) ? 0.1 : 1);
 
                        entity own;
                        own = this.enemy;
@@ -66,7 +66,7 @@ spawnfunc(trigger_hurt)
        this.use = trigger_hurt_use;
        this.enemy = world; // I hate you all
        if (!this.dmg)
-               this.dmg = ((autocvar_sv_vq3compat) ? 5 : 10000);
+               this.dmg = ((autocvar_sv_q3defragcompat) ? 5 : 10000);
        if (this.message == "")
                this.message = "was in the wrong place";
        if (this.message2 == "")
index f438fbf01f5f8295032f45aa8e76647825377b04..2c160eae95e8a05e75f1ead2512b81c257716242 100644 (file)
@@ -36,8 +36,8 @@ vector trigger_push_calculatevelocity(vector org, entity tgt, float ht, entity p
        torg = tgt.origin + (tgt.mins + tgt.maxs) * 0.5;
 
        grav = PHYS_GRAVITY(NULL);
-       if(pushed_entity && PHYS_ENTGRAVITY(pushed_entity))
-               grav *= PHYS_ENTGRAVITY(pushed_entity);
+       if(pushed_entity && pushed_entity.gravity)
+               grav *= pushed_entity.gravity;
 
        zdist = torg.z - org.z;
        sdist = vlen(torg - org - zdist * '0 0 1');
@@ -135,9 +135,9 @@ bool jumppad_push(entity this, entity targ)
 
        vector org = targ.origin;
 #ifdef SVQC
-       if(autocvar_sv_vq3compat)
+       if(autocvar_sv_q3defragcompat)
 #elif defined(CSQC)
-       if(STAT(VQ3COMPAT))
+       if(STAT(Q3DEFRAGCOMPAT))
 #endif
        {
                org.z += targ.mins_z;
index c71dc3794822d5f41094411a7a6f3242b904219f..df915a649695c34ade16a31051dc9bdb6ce02b32 100644 (file)
@@ -176,6 +176,9 @@ spawnfunc(trigger_multiple)
                this.wait = 0;
        this.use = multi_use;
 
+       if(this.wait == -1 && autocvar_sv_q3defragcompat)
+               this.wait = 0.1; // compatibility for q3df: "instant" return
+
        EXACTTRIGGER_INIT;
 
        this.team_saved = this.team;
index 9adcd666ecc7ab3e73a8416ddfd118c869adce91..7586bd338428ef644cef1f060ff3db537b630ac2 100644 (file)
@@ -2,6 +2,9 @@
 #ifdef SVQC
 void trigger_relay_if_use(entity this, entity actor, entity trigger)
 {
+       if(this.active != ACTIVE_ACTIVE)
+               return;
+
        int n = this.count;
 
        // TODO make this generic AND faster than nextent()ing through all, if somehow possible
@@ -15,6 +18,8 @@ void trigger_relay_if_use(entity this, entity actor, entity trigger)
 
 spawnfunc(trigger_relay_if)
 {
+       this.reset = spawnfunc_trigger_relay_if; // this spawnfunc resets fully
+       this.active = ACTIVE_ACTIVE;
        this.use = trigger_relay_if_use;
 }
 #endif
index bf03b1542f0f957279c80f8f81ed1dbb891c0eaa..5291f529062b8dd57bfbcaa5d9beaa4342b0cf2b 100644 (file)
@@ -2,6 +2,9 @@
 #ifdef SVQC
 void trigger_relay_teamcheck_use(entity this, entity actor, entity trigger)
 {
+       if(this.active != ACTIVE_ACTIVE)
+               return;
+
        if(actor.team)
        {
                if(this.spawnflags & RELAYTEAMCHECK_INVERT)
@@ -24,11 +27,13 @@ void trigger_relay_teamcheck_use(entity this, entity actor, entity trigger)
 
 void trigger_relay_teamcheck_reset(entity this)
 {
+       this.active = ACTIVE_ACTIVE;
        this.team = this.team_saved;
 }
 
 spawnfunc(trigger_relay_teamcheck)
 {
+       this.active = ACTIVE_ACTIVE;
        this.team_saved = this.team;
        IL_PUSH(g_saved_team, this);
        this.use = trigger_relay_teamcheck_use;
index f7d9df2900c4c8c40403ede1f45bc71ea3fcf326..495deb7988693b565c3d5e9eec12816ec5d22853 100644 (file)
 *              2005 11 29
 */
 
-
-/*
-* Uses a entity calld swampslug to handle players in the swamp
-* It works like this: When the plyer enters teh swamp the spawnfunc_trigger_swamp
-* attaches a new "swampslug" to the player. As long as the plyer is inside
-* the swamp the swamp gives the slug new health. But the slug slowly kills itself
-* so when the player goes outside the swamp, it dies and releases the player from the
-* swamps curses (dmg/slowdown)
-*
-* I do it this way becuz there is no "untouch" event.
-*/
-void swampslug_think(entity this)
-{
-       //Slowly kill the slug
-       this.swamp_lifetime -= 1;
-
-       //Slug dead? then remove curses.
-       if(GetResource(this, RES_HEALTH) <= 0)
-       {
-               if(this.owner.swampslug == this)
-               {
-                       this.owner.in_swamp = false;
-                       this.owner.swampslug = NULL;
-               }
-               delete(this);
-               //centerprint(this.owner,"Killing slug...\n");
-               return;
-       }
-
-       // Slug still alive, so we are still in the swamp
-       // Or we have exited it very recently.
-       // Do the damage and renew the timer.
 #ifdef SVQC
-       Damage (this.owner, this, this, this.dmg, DEATH_SWAMP.m_id, DMG_NOWEP, this.owner.origin, '0 0 0');
-#endif
-
-       this.nextthink = time + this.swamp_interval;
-}
-
-void swamp_touch(entity this, entity toucher)
+void swamp_think(entity this)
 {
-       // If whatever thats touching the swamp is not a player
-       // or if its a dead player, just dont care abt it.
-       if(!IS_PLAYER(toucher) || IS_DEAD(toucher))
-               return;
-
-       EXACTTRIGGER_TOUCH(this, toucher);
+       // set myself as current swampslug where possible
+       IL_EACH(g_swamped, it.swampslug == this,
+       {
+               it.swampslug = NULL;
+               IL_REMOVE(g_swamped, it);
+       });
 
-       // Chech if player alredy got a swampslug.
-       if(!toucher.in_swamp)
+       if(this.active == ACTIVE_ACTIVE)
        {
-               // If not attach one.
-               //centerprint(toucher,"Entering swamp!\n");
-               if(!toucher.swampslug) // just incase
-                       toucher.swampslug = spawn();
-               toucher.swampslug.swamp_lifetime = 2;
-               setthink(toucher.swampslug, swampslug_think);
-               toucher.swampslug.nextthink = time;
-               toucher.swampslug.owner = toucher;
-               toucher.swampslug.dmg = this.dmg;
-               toucher.swampslug.swamp_interval = this.swamp_interval;
-               toucher.swamp_slowdown = this.swamp_slowdown;
-               toucher.in_swamp = true;
-               return;
+               FOREACH_ENTITY_RADIUS((this.absmin + this.absmax) * 0.5, vlen(this.absmax - this.absmin) * 0.5 + 1, it.swampslug.active == ACTIVE_NOT && IS_PLAYER(it) && !IS_DEAD(it),
+               {
+                       vector emin = it.absmin;
+                       vector emax = it.absmax;
+                       if(this.solid == SOLID_BSP)
+                       {
+                               emin -= '1 1 1';
+                               emax += '1 1 1';
+                       }
+                       if(boxesoverlap(emin, emax, this.absmin, this.absmax)) // quick
+                               if(WarpZoneLib_BoxTouchesBrush(emin, emax, this, it)) // accurate
+                               {
+                                       if(!it.swampslug)
+                                               IL_PUSH(g_swamped, it);
+                                       it.swampslug = this;
+                               }
+               });
+
+               IL_EACH(g_swamped, it.swampslug == this,
+               {
+                       if(time > it.swamp_interval)
+                       {
+                               Damage (it, this, this, this.dmg, DEATH_SWAMP.m_id, DMG_NOWEP, it.origin, '0 0 0');
+                               it.swamp_interval = time + this.swamp_interval;
+                       }
+               });
        }
 
-       //toucher.in_swamp = true;
-
-       //Revitalize players swampslug
-       toucher.swampslug.swamp_lifetime = 2;
-}
-
-REGISTER_NET_LINKED(ENT_CLIENT_SWAMP)
-
-#ifdef SVQC
-float swamp_send(entity this, entity to, float sf)
-{
-       WriteHeader(MSG_ENTITY, ENT_CLIENT_SWAMP);
-
-       WriteByte(MSG_ENTITY, this.dmg); // can probably get away with using a single byte here
-       WriteByte(MSG_ENTITY, this.swamp_slowdown);
-       WriteByte(MSG_ENTITY, this.swamp_interval);
-
-       trigger_common_write(this, false);
-
-       return true;
-}
-
-void swamp_link(entity this)
-{
-       trigger_link(this, swamp_send);
+       this.nextthink = time;
 }
 
 /*QUAKED spawnfunc_trigger_swamp (.5 .5 .5) ?
@@ -116,37 +66,18 @@ slowed down and damaged over time
 spawnfunc(trigger_swamp)
 {
        // Init stuff
-       trigger_init(this);
-       settouch(this, swamp_touch);
+       EXACTTRIGGER_INIT;
+       this.active = ACTIVE_ACTIVE;
+       //trigger_init(this);
+       setthink(this, swamp_think);
+       this.nextthink = time;
 
        // Setup default keys, if missing
-       if(this.dmg <= 0)
+       if(!this.dmg)
                this.dmg = 5;
-       if(this.swamp_interval <= 0)
+       if(!this.swamp_interval)
                this.swamp_interval = 1;
-       if(this.swamp_slowdown <= 0)
+       if(!this.swamp_slowdown)
                this.swamp_slowdown = 0.5;
-
-       swamp_link(this);
-}
-
-#elif defined(CSQC)
-
-NET_HANDLE(ENT_CLIENT_SWAMP, bool isnew)
-{
-       this.dmg = ReadByte();
-       this.swamp_slowdown = ReadByte();
-       this.swamp_interval = ReadByte();
-
-       trigger_common_read(this, false);
-
-       return = true;
-
-       this.classname = "trigger_swamp";
-       this.solid = SOLID_TRIGGER;
-       settouch(this, swamp_touch);
-       this.drawmask = MASK_NORMAL;
-       this.move_time = time;
-       this.entremove = trigger_remove_generic;
 }
 #endif
index bfe860ed03af9561d2c4e37720adb873a4f83438..acb0cb26a920a62a14b3a32394cf4b17fa4bca9d 100644 (file)
@@ -1,17 +1,11 @@
 #pragma once
 
-.float swamp_interval; //Hurt players in swamp with this interval
-.float swamp_slowdown; //Players in swamp get slowd down by this mutch 0-1 is slowdown 1-~ is speedup (!?)
+#ifdef SVQC
+IntrusiveList g_swamped;
+STATIC_INIT(g_swamped) { g_swamped = IL_NEW(); }
 
-.bool in_swamp;
 .entity swampslug;            // Uses this to release from swamp ("untouch" fix)
 
 .float swamp_interval; //Hurt players in swamp with this interval
-.float swamp_slowdown; //Players in swamp get slowd down by this mutch 0-1 is slowdown 1-~ is speedup (!?)
-.float swamp_lifetime;  // holds the points remaining until slug dies (not quite health!)
-
-#ifdef SVQC
-spawnfunc(trigger_swamp);
+.float swamp_slowdown; //Players in swamp get slowed down by this mutch 0-1 is slowdown 1-~ is speedup (!?)
 #endif
-void swamp_touch(entity this, entity toucher);
-void swampslug_think(entity this);
index 9a7181d3a2250a530466a1d3dcbf59a9e9d1f0d8..27ffead9c7582bed0e81d63e1c99c926dc0d7980 100644 (file)
@@ -235,7 +235,7 @@ match (string)this.target and call their .use function
 ==============================
 */
 
-void SUB_UseTargets_Ex(entity this, entity actor, entity trigger, bool preventReuse)
+void SUB_UseTargets_Ex(entity this, entity actor, entity trigger, bool preventReuse, int skiptargets)
 {
 //
 // check for a delay
@@ -249,10 +249,10 @@ void SUB_UseTargets_Ex(entity this, entity actor, entity trigger, bool preventRe
                t.enemy = actor;
                t.message = this.message;
                t.killtarget = this.killtarget;
-               t.target = this.target;
-               t.target2 = this.target2;
-               t.target3 = this.target3;
-               t.target4 = this.target4;
+               if(!(skiptargets & BIT(1))) t.target = this.target;
+               if(!(skiptargets & BIT(2))) t.target2 = this.target2;
+               if(!(skiptargets & BIT(3))) t.target3 = this.target3;
+               if(!(skiptargets & BIT(4))) t.target4 = this.target4;
                t.antiwall_flag = this.antiwall_flag;
                return;
        }
@@ -292,6 +292,8 @@ void SUB_UseTargets_Ex(entity this, entity actor, entity trigger, bool preventRe
 
        for(int i = 0; i < 4; ++i)
        {
+               if(skiptargets & BIT(i + 1))
+                       continue;
                switch(i)
                {
                        default:
@@ -329,5 +331,6 @@ void SUB_UseTargets_Ex(entity this, entity actor, entity trigger, bool preventRe
        }
 }
 
-void SUB_UseTargets(entity this, entity actor, entity trigger) { SUB_UseTargets_Ex(this, actor, trigger, false); }
-void SUB_UseTargets_PreventReuse(entity this, entity actor, entity trigger) { SUB_UseTargets_Ex(this, actor, trigger, true); }
+void SUB_UseTargets(entity this, entity actor, entity trigger) { SUB_UseTargets_Ex(this, actor, trigger, false, 0); }
+void SUB_UseTargets_PreventReuse(entity this, entity actor, entity trigger) { SUB_UseTargets_Ex(this, actor, trigger, true, 0); }
+void SUB_UseTargets_SkipTargets(entity this, entity actor, entity trigger, int skiptargets) { SUB_UseTargets_Ex(this, actor, trigger, false, skiptargets); }
index b9baf63f1c70ed30fcaaaf89559d298b45c93084..797c9767f6a084271f6b4ae64327d9ce8650caf6 100644 (file)
@@ -26,6 +26,10 @@ void SUB_UseTargets(entity this, entity actor, entity trigger);
 
 void SUB_UseTargets_PreventReuse(entity this, entity actor, entity trigger);
 
+// allow excluding certain .target* fields without needing to nullify them
+// use BIT(1) through BIT(4)
+void SUB_UseTargets_SkipTargets(entity this, entity actor, entity trigger, int skiptargets);
+
 void generic_setactive(entity this, int act);
 // generic methods for netlinked entities
 void generic_netlinked_reset(entity this);
index efdd836d21e8af7bedd7de2ebffe8555031e173a..1cba349ed96e39fe5baa594b4f447b04d7af8651 100644 (file)
@@ -12,6 +12,7 @@ METHOD(MageSpike, wr_think, void(MageSpike thiswep, entity actor, .entity weapon
     if (!IS_PLAYER(actor) || weapon_prepareattack(thiswep, actor, weaponentity, false, 0.2)) {
         if (!actor.target_range) actor.target_range = autocvar_g_monsters_target_range;
         actor.enemy = Monster_FindTarget(actor);
+        monster_makevectors(actor, actor.enemy);
         W_SetupShot_Dir(actor, weaponentity, v_forward, false, 0, SND_MageSpike_FIRE, CH_WEAPON_B, 0, DEATH_MONSTER_MAGE.m_id);
        if (!IS_PLAYER(actor)) w_shotdir = normalize((actor.enemy.origin + '0 0 10') - actor.origin);
         M_Mage_Attack_Spike(actor, w_shotdir);
index 9390f5d23a74dcc0249f4d395caf2119d944ed30..2e3f02a0623a86f5591c5b922e0f8ce13ee27b7d 100644 (file)
@@ -116,8 +116,6 @@ void M_Shambler_Attack_Lightning_Think(entity this)
 
 void M_Shambler_Attack_Lightning(entity this)
 {
-       monster_makevectors(this, this.enemy);
-
        entity gren = new(grenade);
        gren.owner = gren.realowner = this;
        gren.bot_dodge = true;
index 52bf37f7d2608f175ddc373c060d95c90c28990f..d9a51c05e9a4649718deac200f0e5f4beeff9b6a 100644 (file)
@@ -66,6 +66,7 @@ METHOD(SpiderAttack, wr_think, void(SpiderAttack thiswep, entity actor, .entity
                        actor.anim_finished = time + 1;
                }
         if (isPlayer) actor.enemy = Monster_FindTarget(actor);
+        monster_makevectors(actor, actor.enemy);
         W_SetupShot_Dir(actor, weaponentity, v_forward, false, 0, SND_SpiderAttack_FIRE, CH_WEAPON_B, 0, DEATH_MONSTER_SPIDER.m_id);
        if (!isPlayer) w_shotdir = normalize((actor.enemy.origin + '0 0 10') - actor.origin);
                M_Spider_Attack_Web(actor);
@@ -128,8 +129,6 @@ void adaptor_think2use_hittype_splash(entity this);
 
 void M_Spider_Attack_Web(entity this)
 {
-       monster_makevectors(this, this.enemy);
-
        sound(this, CH_SHOTS, SND_ELECTRO_FIRE2, VOL_BASE, ATTEN_NORM);
 
        entity proj = new(plasma);
index 8a4ad160560fa87583ab87a6dd861c7c0f274d54..4de122e8494419205178cc87dc74f77957699c7f 100644 (file)
@@ -18,11 +18,11 @@ METHOD(WyvernAttack, wr_think, void(WyvernAttack thiswep, entity actor, .entity
     TC(WyvernAttack, thiswep);
     if (fire & 1)
     if (time > actor.attack_finished_single[0] || weapon_prepareattack(thiswep, actor, weaponentity, false, 1.2)) {
+       monster_makevectors(actor, actor.enemy);
         if (IS_PLAYER(actor)) W_SetupShot_Dir(actor, weaponentity, v_forward, false, 0, SND_WyvernAttack_FIRE, CH_WEAPON_B, 0, DEATH_MONSTER_WYVERN.m_id);
                if (IS_MONSTER(actor)) {
                        actor.attack_finished_single[0] = time + 1.2;
                        actor.anim_finished = time + 1.2;
-                       monster_makevectors(actor, actor.enemy);
                }
 
                entity missile = spawn();
index 0673cd0baf24810d20dc452ce469e73a6ae31a51..4f2139cc170a56c78d49548f47b360e8ca8e78b3 100644 (file)
@@ -189,7 +189,11 @@ void monster_changeteam(entity this, int newteam)
 .void(entity) monster_delayedfunc;
 void Monster_Delay_Action(entity this)
 {
-       if(Monster_ValidTarget(this.owner, this.owner.enemy)) { this.monster_delayedfunc(this.owner); }
+       if(Monster_ValidTarget(this.owner, this.owner.enemy))
+       {
+               monster_makevectors(this.owner, this.owner.enemy);
+               this.monster_delayedfunc(this.owner);
+       }
 
        if(this.cnt > 1)
        {
@@ -359,8 +363,6 @@ bool Monster_Attack_Melee(entity this, entity targ, float damg, vector anim, flo
        else
                this.attack_finished_single[0] = this.anim_finished = time + animtime;
 
-       monster_makevectors(this, targ);
-
        traceline(this.origin + this.view_ofs, this.origin + v_forward * er, 0, this);
 
        if(trace_ent.takedamage)
@@ -424,6 +426,7 @@ void Monster_Attack_Check(entity this, entity targ, .entity weaponentity)
 
        if(vdist(targ.origin - this.origin, <=, this.attack_range))
        {
+               monster_makevectors(this, targ);
                int attack_success = this.monster_attackfunc(MONSTER_ATTACK_MELEE, this, targ, weaponentity);
                if(attack_success == 1)
                        Monster_Sound(this, monstersound_melee, 0, false, CH_VOICE);
@@ -433,6 +436,7 @@ void Monster_Attack_Check(entity this, entity targ, .entity weaponentity)
 
        if(vdist(targ.origin - this.origin, >, this.attack_range))
        {
+               monster_makevectors(this, targ);
                int attack_success = this.monster_attackfunc(MONSTER_ATTACK_RANGED, this, targ, weaponentity);
                if(attack_success == 1)
                        Monster_Sound(this, monstersound_melee, 0, false, CH_VOICE);
index cf858487058de2bbeac734fff836481bae3e4504..6ee9574d057ed13876ea96d22e8ac7bc1dd72f42 100644 (file)
@@ -112,3 +112,11 @@ MUTATOR_HOOKABLE(WeaponSound, EV_WeaponSound);
     /**/          o(string, MUTATOR_ARGV_1_string) \
     /**/
 MUTATOR_HOOKABLE(WeaponModel, EV_WeaponModel);
+
+/** decides whether a player can crouch or not */
+#define EV_PlayerCanCrouch(i, o) \
+    /** player */      i(entity, MUTATOR_ARGV_0_entity) \
+    /** do_crouch */   i(bool, MUTATOR_ARGV_1_bool) \
+    /**/               o(bool, MUTATOR_ARGV_1_bool) \
+    /**/
+MUTATOR_HOOKABLE(PlayerCanCrouch, EV_PlayerCanCrouch);
index 768808db71f1cb41d9acf29090865a5c7d35a09c..16e6308acf9d39e466c350241b96d3ece7f990e6 100644 (file)
@@ -1,4 +1,2 @@
 // generated file; do not modify
-#ifdef SVQC
-    #include <common/mutators/mutator/bloodloss/sv_bloodloss.qc>
-#endif
+#include <common/mutators/mutator/bloodloss/bloodloss.qc>
index e6ad248c622d6aaad3d8f0e2b93744037e9c5577..b1d45e2791b07d3e3d1b8572fed442328348f863 100644 (file)
@@ -1,4 +1,2 @@
 // generated file; do not modify
-#ifdef SVQC
-    #include <common/mutators/mutator/bloodloss/sv_bloodloss.qh>
-#endif
+#include <common/mutators/mutator/bloodloss/bloodloss.qh>
diff --git a/qcsrc/common/mutators/mutator/bloodloss/bloodloss.qc b/qcsrc/common/mutators/mutator/bloodloss/bloodloss.qc
new file mode 100644 (file)
index 0000000..41ceaa9
--- /dev/null
@@ -0,0 +1,70 @@
+#include "bloodloss.qh"
+
+#ifdef GAMEQC
+#ifdef SVQC
+REGISTER_MUTATOR(bloodloss, autocvar_g_bloodloss);
+#elif defined(CSQC)
+REGISTER_MUTATOR(bloodloss, true);
+#endif
+
+#ifdef SVQC
+.float bloodloss_timer;
+
+MUTATOR_HOOKFUNCTION(bloodloss, PlayerPreThink)
+{
+       entity player = M_ARGV(0, entity);
+
+       if(game_stopped)
+               return; // during intermission, the player's health changes to strange values for the engine, let's not cause damage during this phase!
+
+       if(IS_PLAYER(player))
+       if(GetResource(player, RES_HEALTH) <= autocvar_g_bloodloss && !IS_DEAD(player) && time >= player.bloodloss_timer)
+       {
+               if(player.vehicle)
+                       vehicles_exit(player.vehicle, VHEF_RELEASE); // TODO: boots player out of their vehicle each health rot tick!
+               if(player.event_damage)
+                       player.event_damage(player, player, player, 1, DEATH_ROT.m_id, DMG_NOWEP, player.origin, '0 0 0');
+               player.bloodloss_timer = time + 0.5 + random() * 0.5;
+       }
+}
+
+MUTATOR_HOOKFUNCTION(bloodloss, PlayerCanCrouch)
+{
+       entity player = M_ARGV(0, entity);
+       if(GetResource(player, RES_HEALTH) <= autocvar_g_bloodloss)
+               M_ARGV(1, bool) = true; // do_crouch
+}
+
+MUTATOR_HOOKFUNCTION(bloodloss, PlayerJump)
+{
+       entity player = M_ARGV(0, entity);
+
+       if(GetResource(player, RES_HEALTH) <= autocvar_g_bloodloss)
+               return true;
+}
+
+MUTATOR_HOOKFUNCTION(bloodloss, BuildMutatorsString)
+{
+       M_ARGV(0, string) = strcat(M_ARGV(0, string), ":bloodloss");
+}
+
+MUTATOR_HOOKFUNCTION(bloodloss, BuildMutatorsPrettyString)
+{
+       M_ARGV(0, string) = strcat(M_ARGV(0, string), ", Blood loss");
+}
+#endif
+
+#ifdef CSQC
+MUTATOR_HOOKFUNCTION(bloodloss, PlayerCanCrouch)
+{
+       if(STAT(HEALTH) > 0 && STAT(HEALTH) <= STAT(BLOODLOSS))
+               M_ARGV(1, bool) = true; // do_crouch
+}
+MUTATOR_HOOKFUNCTION(bloodloss, PlayerJump)
+{
+       if(STAT(HEALTH) > 0 && STAT(HEALTH) <= STAT(BLOODLOSS))
+               return true;
+}
+#endif
+
+#endif
diff --git a/qcsrc/common/mutators/mutator/bloodloss/bloodloss.qh b/qcsrc/common/mutators/mutator/bloodloss/bloodloss.qh
new file mode 100644 (file)
index 0000000..6f70f09
--- /dev/null
@@ -0,0 +1 @@
+#pragma once
diff --git a/qcsrc/common/mutators/mutator/bloodloss/sv_bloodloss.qc b/qcsrc/common/mutators/mutator/bloodloss/sv_bloodloss.qc
deleted file mode 100644 (file)
index a89691d..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-#include "sv_bloodloss.qh"
-
-float autocvar_g_bloodloss;
-REGISTER_MUTATOR(bloodloss, autocvar_g_bloodloss);
-
-.float bloodloss_timer;
-
-MUTATOR_HOOKFUNCTION(bloodloss, PlayerPreThink)
-{
-       entity player = M_ARGV(0, entity);
-
-       if(IS_PLAYER(player))
-       if(GetResource(player, RES_HEALTH) <= autocvar_g_bloodloss && !IS_DEAD(player))
-       {
-               PHYS_INPUT_BUTTON_CROUCH(player) = true;
-
-               if(time >= player.bloodloss_timer)
-               {
-                       if(player.vehicle)
-                               vehicles_exit(player.vehicle, VHEF_RELEASE);
-                       if(player.event_damage)
-                               player.event_damage(player, player, player, 1, DEATH_ROT.m_id, DMG_NOWEP, player.origin, '0 0 0');
-                       player.bloodloss_timer = time + 0.5 + random() * 0.5;
-               }
-       }
-}
-
-MUTATOR_HOOKFUNCTION(bloodloss, PlayerJump)
-{
-       entity player = M_ARGV(0, entity);
-
-       if(GetResource(player, RES_HEALTH) <= autocvar_g_bloodloss)
-               return true;
-}
-
-MUTATOR_HOOKFUNCTION(bloodloss, BuildMutatorsString)
-{
-       M_ARGV(0, string) = strcat(M_ARGV(0, string), ":bloodloss");
-}
-
-MUTATOR_HOOKFUNCTION(bloodloss, BuildMutatorsPrettyString)
-{
-       M_ARGV(0, string) = strcat(M_ARGV(0, string), ", Blood loss");
-}
diff --git a/qcsrc/common/mutators/mutator/bloodloss/sv_bloodloss.qh b/qcsrc/common/mutators/mutator/bloodloss/sv_bloodloss.qh
deleted file mode 100644 (file)
index 6f70f09..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#pragma once
index 0c9b8890189c7337f774db335c7555c5d40eaea2..5b53b3d651c2d76e49ac25e6778fc24a781e7fde 100644 (file)
@@ -4,7 +4,8 @@ string Buff_UndeprecateName(string buffname)
     {
         case "ammoregen": return "ammo";
         case "haste": case "scout": return "speed";
-        case "guard": case "revival": case "regen": return "medic";
+        case "guard": return "resistance";
+        case "revival": case "regen": return "medic";
         case "invis": return "invisible";
         case "jumper": return "jump";
         default: return buffname;
@@ -27,7 +28,7 @@ REGISTER_BUFF(RESISTANCE) {
     this.m_color = '0.36 1 0.07';
 }
 BUFF_SPAWNFUNCS(resistance, BUFF_RESISTANCE)
-BUFF_SPAWNFUNC_Q3TA_COMPAT(resistance, BUFF_RESISTANCE)
+BUFF_SPAWNFUNC_Q3TA_COMPAT(guard, BUFF_RESISTANCE)
 
 REGISTER_BUFF(SPEED) {
     this.m_name = _("Speed");
@@ -46,7 +47,6 @@ REGISTER_BUFF(MEDIC) {
     this.m_color = '1 0.12 0';
 }
 BUFF_SPAWNFUNCS(medic, BUFF_MEDIC)
-BUFF_SPAWNFUNC_Q3TA_COMPAT(guard, BUFF_MEDIC)
 BUFF_SPAWNFUNC_Q3TA_COMPAT(regen, BUFF_MEDIC)
 BUFF_SPAWNFUNC_Q3TA_COMPAT(revival, BUFF_MEDIC)
 
@@ -57,6 +57,7 @@ REGISTER_BUFF(BASH) {
     this.m_color = '1 0.39 0';
 }
 BUFF_SPAWNFUNCS(bash, BUFF_BASH)
+BUFF_SPAWNFUNC_Q3TA_COMPAT(doubler, BUFF_BASH)
 
 REGISTER_BUFF(VAMPIRE) {
     this.m_name = _("Vampire");
index 790a10a86b8f16da4b5f0f0f65900d1813ca89a2..349ca20b872c17f468117dccecaa1152128778ca 100644 (file)
@@ -3,10 +3,11 @@
 REGISTER_MUTATOR(cl_buffs, true);
 MUTATOR_HOOKFUNCTION(cl_buffs, HUD_Powerups_add)
 {
-    int allBuffs = STAT(BUFFS);
-    FOREACH(Buffs, it.m_itemid & allBuffs, {
-               addPowerupItem(it.m_name, strcat("buff_", it.netname), it.m_color, bound(0, STAT(BUFF_TIME) - time, 99), 60);
-       });
+       int allBuffs = STAT(BUFFS);
+       if (allBuffs)
+               FOREACH(Buffs, it.m_itemid & allBuffs, {
+                       addPowerupItem(it.m_name, strcat("buff_", it.netname), it.m_color, bound(0, STAT(BUFF_TIME) - time, 99), 60);
+               });
 }
 MUTATOR_HOOKFUNCTION(cl_buffs, WP_Format)
 {
index 256af90affb3650cfc444b0e9d33827af1504ab1..82c9a595a64455255c783a84a4ca87f27b7cb45e 100644 (file)
@@ -203,6 +203,7 @@ void buff_Touch(entity this, entity toucher)
        Send_Effect(EFFECT_ITEM_PICKUP, CENTER_OR_VIEWOFS(this), '0 0 0', 1);
        sound(toucher, CH_TRIGGER, SND_SHIELD_RESPAWN, VOL_BASE, ATTN_NORM);
        STAT(BUFFS, toucher) |= (STAT(BUFFS, this));
+       STAT(LAST_PICKUP, toucher) = time;
        float bufftime = ((this.count) ? this.count : thebuff.m_time(thebuff));
        if(bufftime)
                STAT(BUFF_TIME, toucher) = min(time + bufftime, max(STAT(BUFF_TIME, toucher), time) + bufftime);
@@ -227,7 +228,8 @@ void buff_NewType(entity ent)
        FOREACH(Buffs, buff_Available(it),
        {
                // if it's already been chosen, give it a lower priority
-               RandomSelection_AddEnt(it, max(0.2, 1 / it.buff_seencount), 1);
+               float myseencount = (it.buff_seencount > 0) ? it.buff_seencount : 1; // no division by zero please!
+               RandomSelection_AddEnt(it, max(0.2, 1 / myseencount), 1);
        });
        entity newbuff = RandomSelection_chosen_ent;
        newbuff.buff_seencount += 1; // lower chances of seeing this buff again soon
@@ -259,7 +261,7 @@ void buff_Think(entity this)
        }
 
        if(!game_stopped)
-       if((round_handler_IsActive() && !round_handler_IsRoundStarted()) || time >= game_starttime)
+       if((round_handler_IsActive() && round_handler_IsRoundStarted()) || time >= game_starttime)
        if(!this.buff_activetime_updated)
        {
                buff_SetCooldown(this, this.buff_activetime);
@@ -271,7 +273,7 @@ void buff_Think(entity this)
        {
                buff_SetCooldown(this, autocvar_g_buffs_cooldown_respawn + frametime);
                this.owner = NULL;
-               if(autocvar_g_buffs_randomize)
+               if(autocvar_g_buffs_randomize && (!teamplay || autocvar_g_buffs_randomize_teamplay))
                        buff_NewType(this);
 
                if(autocvar_g_buffs_random_location || (this.spawnflags & 64))
@@ -280,7 +282,7 @@ void buff_Think(entity this)
 
        if(this.buff_activetime)
        if(!game_stopped)
-       if((round_handler_IsActive() && !round_handler_IsRoundStarted()) || time >= game_starttime)
+       if((round_handler_IsActive() && round_handler_IsRoundStarted()) || time >= game_starttime)
        {
                this.buff_activetime = max(0, this.buff_activetime - frametime);
 
@@ -315,7 +317,7 @@ void buff_Waypoint_Reset(entity this)
 
 void buff_Reset(entity this)
 {
-       if(autocvar_g_buffs_randomize)
+       if(autocvar_g_buffs_randomize && (!teamplay || autocvar_g_buffs_randomize_teamplay))
                buff_NewType(this);
        this.owner = NULL;
        buff_SetCooldown(this, autocvar_g_buffs_cooldown_activate);
@@ -953,7 +955,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink)
 
                BUFF_ONADD(BUFF_INVISIBLE)
                {
-                       if(time < player.strength_finished && MUTATOR_IS_ENABLED(mutator_instagib))
+                       if(time < STAT(STRENGTH_FINISHED, player) && MUTATOR_IS_ENABLED(mutator_instagib))
                                player.buff_invisible_prev_alpha = default_player_alpha; // we don't want to save the powerup's alpha, as player may lose the powerup while holding the buff
                        else
                                player.buff_invisible_prev_alpha = player.alpha;
@@ -962,7 +964,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink)
 
                BUFF_ONREM(BUFF_INVISIBLE)
                {
-                       if(time < player.strength_finished && MUTATOR_IS_ENABLED(mutator_instagib))
+                       if(time < STAT(STRENGTH_FINISHED, player) && MUTATOR_IS_ENABLED(mutator_instagib))
                                player.alpha = autocvar_g_instagib_invis_alpha;
                        else
                                player.alpha = player.buff_invisible_prev_alpha;
index 671a524f9eea2132f773c333c35b06ee3d02431d..b585811873758a94aee4a68592364f36ca749005 100644 (file)
@@ -9,6 +9,7 @@ float autocvar_g_buffs_waypoint_distance;
 bool autocvar_g_buffs_pickup_anyway = false;
 float autocvar_g_buffs_pickup_delay = 0.7;
 bool autocvar_g_buffs_randomize;
+bool autocvar_g_buffs_randomize_teamplay = true;
 float autocvar_g_buffs_random_lifetime;
 bool autocvar_g_buffs_random_location;
 int autocvar_g_buffs_random_location_attempts;
@@ -81,3 +82,5 @@ const vector BUFF_MAX = ('16 16 60');
 
 // client side options
 .float cvar_cl_buffs_autoreplace;
+
+float buff_Available(entity buff);
index 40f19d6b1770bc88fa1fded89aa345397f2f3812..38a687f014556ec386a130e42adb7478fc9e5bb2 100644 (file)
@@ -309,6 +309,8 @@ MUTATOR_HOOKFUNCTION(bugrigs, PlayerPhysics)
 #ifdef SVQC
        entity player = M_ARGV(0, entity);
        player.bugrigs_prevangles = player.angles;
+
+       player.disableclientprediction = 2;
 #endif
 }
 
index 97e63161d54a062a771fd8129a9884ebff34cd52..f53d8c356a5bac8c59f0f2e5682c65fb0d5b00cc 100644 (file)
@@ -4,6 +4,7 @@ string autocvar_g_campcheck;
 float autocvar_g_campcheck_damage;
 float autocvar_g_campcheck_distance;
 float autocvar_g_campcheck_interval;
+bool autocvar_g_campcheck_typecheck;
 
 REGISTER_MUTATOR(campcheck, expr_evaluate(autocvar_g_campcheck));
 
@@ -24,9 +25,7 @@ MUTATOR_HOOKFUNCTION(campcheck, Damage_Calculate)
        entity frag_attacker = M_ARGV(1, entity);
        entity frag_target = M_ARGV(2, entity);
 
-       if(IS_PLAYER(frag_target))
-       if(IS_PLAYER(frag_attacker))
-       if(frag_attacker != frag_target)
+       if(frag_attacker != frag_target && IS_PLAYER(frag_target) && IS_PLAYER(frag_attacker))
        {
                frag_target.campcheck_traveled_distance = autocvar_g_campcheck_distance;
                frag_attacker.campcheck_traveled_distance = autocvar_g_campcheck_distance;
@@ -40,11 +39,9 @@ MUTATOR_HOOKFUNCTION(campcheck, PlayerPreThink)
 
        if(autocvar_g_campcheck_interval)
        if(!game_stopped && !warmup_stage && time >= game_starttime)
-       if(IS_PLAYER(player))
-       if(!IS_DEAD(player))
-       if(!STAT(FROZEN, player))
-       if(!PHYS_INPUT_BUTTON_CHAT(player))
-       if(IS_REAL_CLIENT(player)) // bots may camp, but that's no reason to constantly kill them
+       if(IS_PLAYER(player) && !IS_DEAD(player) && !STAT(FROZEN, player))
+       if(autocvar_g_campcheck_typecheck || !PHYS_INPUT_BUTTON_CHAT(player))
+       if(IS_REAL_CLIENT(player)) // only apply to real clients (bots may "camp" due to missing waypoints in the map, but that's no reason to constantly kill them, clones can't move)
        if(!weaponLocked(player))
        {
                // calculate player movement (in 2 dimensions only, so jumping on one spot doesn't count as movement)
index 84f77314edde094cacbc1b03de4bef5a342f8a1b..696a2d9e5856c64c9c12329b66b4664fd607cbdc 100644 (file)
@@ -2,3 +2,6 @@
 
 float cvar_cl_dodging_timeout;
 REPLICATE(cvar_cl_dodging_timeout, float, "cl_dodging_timeout");
+
+float cvar_cl_dodging;
+REPLICATE(cvar_cl_dodging, float, "cl_dodging");
index 66d18ac671e8ad9c5ce074c8f74eee7e494fb9f5..3651e9aa07286d42db46bc13b430cb869f74cf83 100644 (file)
@@ -18,6 +18,7 @@
 #define PHYS_DODGING_AIR                                       autocvar_sv_dodging_air_dodging
 #define PHYS_DODGING_MAXSPEED                          autocvar_sv_dodging_maxspeed
 #define PHYS_DODGING_AIR_MAXSPEED                      autocvar_sv_dodging_air_maxspeed
+#define PHYS_DODGING_CLIENTSELECT                      autocvar_sv_dodging_clientselect
 
 // we ran out of stats slots! TODO: re-enable this when prediction is available for dodging
 #if 0
 #define PHYS_DODGING_AIR                                       STAT(DODGING_AIR, this)
 #define PHYS_DODGING_MAXSPEED                          STAT(DODGING_MAXSPEED, this)
 #define PHYS_DODGING_AIR_MAXSPEED                      STAT(DODGING_AIR_MAXSPEED, this)
+#define PHYS_DODGING_CLIENTSELECT                      STAT(DODGING_CLIENTSELECT, this)
 #endif
 
 #ifdef CSQC
        float cvar_cl_dodging_timeout;
+       bool cvar_cl_dodging;
+       bool autocvar_cl_dodging;
        #define PHYS_DODGING_FRAMETIME                          (1 / (frametime <= 0 ? 60 : frametime))
        #define PHYS_DODGING_TIMEOUT(s)                         STAT(DODGING_TIMEOUT)
        #define PHYS_DODGING_PRESSED_KEYS(s)            (s).pressedkeys
+       #define PHYS_DODGING_ENABLED(s)                         autocvar_cl_dodging
 #elif defined(SVQC)
        .float cvar_cl_dodging_timeout;
+       .bool cvar_cl_dodging;
        #define PHYS_DODGING_FRAMETIME                          sys_frametime
        #define PHYS_DODGING_TIMEOUT(s)                         CS(s).cvar_cl_dodging_timeout
        #define PHYS_DODGING_PRESSED_KEYS(s)            CS(s).pressedkeys
+       #define PHYS_DODGING_ENABLED(s)                         CS(s).cvar_cl_dodging
 #endif
 
 #ifdef SVQC
@@ -214,7 +221,7 @@ void PM_dodging(entity this)
        if (!this.dodging_action) return;
 
        // when swimming or dead, no dodging allowed..
-       if (this.waterlevel >= WATERLEVEL_SWIMMING || IS_DEAD(this))
+       if (this.waterlevel >= WATERLEVEL_SWIMMING || IS_DEAD(this) || (PHYS_DODGING_CLIENTSELECT && !PHYS_DODGING_ENABLED(this)))
        {
                this.dodging_action = 0;
                this.dodging_direction.x = 0;
@@ -299,6 +306,7 @@ MUTATOR_HOOKFUNCTION(dodging, PlayerPhysics)
 #ifdef SVQC
 
 REPLICATE(cvar_cl_dodging_timeout, float, "cl_dodging_timeout");
+REPLICATE(cvar_cl_dodging, bool, "cl_dodging");
 
 MUTATOR_HOOKFUNCTION(dodging, GetPressedKeys)
 {
index c4f4b5d00cd861d9c717beb3fcc2edeca2157346..0e0716dd1805263c9eeb7b715bd979c3b91a00d0 100644 (file)
@@ -14,7 +14,6 @@ bool autocvar_g_instagib_ammo_convert_cells;
 bool autocvar_g_instagib_ammo_convert_rockets;
 bool autocvar_g_instagib_ammo_convert_shells;
 bool autocvar_g_instagib_ammo_convert_bullets;
-int autocvar_g_instagib_extralives;
 float autocvar_g_instagib_speed_highspeed;
 
 IntrusiveList g_instagib_items;
@@ -233,8 +232,8 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, PlayerPowerups)
 
        if (player.items & ITEM_Invisibility.m_itemid)
        {
-               play_countdown(player, player.strength_finished, SND_POWEROFF);
-               if (time > player.strength_finished)
+               play_countdown(player, STAT(STRENGTH_FINISHED, player), SND_POWEROFF);
+               if (time > STAT(STRENGTH_FINISHED, player))
                {
                        player.alpha = default_player_alpha;
                        player.exteriorweaponentity.alpha = default_weapon_alpha;
@@ -244,7 +243,7 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, PlayerPowerups)
        }
        else
        {
-               if (time < player.strength_finished)
+               if (time < STAT(STRENGTH_FINISHED, player))
                {
                        player.alpha = autocvar_g_instagib_invis_alpha;
                        player.exteriorweaponentity.alpha = autocvar_g_instagib_invis_alpha;
@@ -256,8 +255,8 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, PlayerPowerups)
 
        if (player.items & ITEM_Speed.m_itemid)
        {
-               play_countdown(player, player.invincible_finished, SND_POWEROFF);
-               if (time > player.invincible_finished)
+               play_countdown(player, STAT(INVINCIBLE_FINISHED, player), SND_POWEROFF);
+               if (time > STAT(INVINCIBLE_FINISHED, player))
                {
                        player.items &= ~ITEM_Speed.m_itemid;
                        Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_POWERDOWN_SPEED);
@@ -265,7 +264,7 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, PlayerPowerups)
        }
        else
        {
-               if (time < player.invincible_finished)
+               if (time < STAT(INVINCIBLE_FINISHED, player))
                {
                        player.items |= ITEM_Speed.m_itemid;
                        Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_POWERUP_SPEED, player.netname);
@@ -353,7 +352,6 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, Damage_Calculate)
 
                                if(frag_target != frag_attacker)
                                {
-                                       if(frag_damage <= 0 && GetResource(frag_target, RES_HEALTH) > 0) { Send_Notification(NOTIF_ONE, frag_attacker, MSG_CENTER, CENTER_SECONDARY_NODAMAGE); }
                                        if(!autocvar_g_instagib_blaster_keepforce)
                                                frag_force = '0 0 0';
                                }
@@ -386,7 +384,7 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, Damage_Calculate)
        M_ARGV(6, vector) = frag_force;
 }
 
-MUTATOR_HOOKFUNCTION(mutator_instagib, SetStartItems)
+MUTATOR_HOOKFUNCTION(mutator_instagib, SetStartItems, CBC_ORDER_LAST)
 {
        start_health       = warmup_start_health       = 100;
        start_armorvalue   = warmup_start_armorvalue   = 0;
@@ -529,7 +527,7 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, ItemTouch)
        if(item.itemdef == ITEM_ExtraLife)
        {
                GiveResource(toucher, RES_ARMOR, autocvar_g_instagib_extralives);
-               Send_Notification(NOTIF_ONE, toucher, MSG_CENTER, CENTER_EXTRALIVES);
+               Send_Notification(NOTIF_ONE, toucher, MSG_CENTER, CENTER_EXTRALIVES, autocvar_g_instagib_extralives);
                return MUT_ITEMTOUCH_PICKUP;
        }
 
index 56f4ac7daaaace7d5d831d281107ed0632d75eaf..1f74f1fe53c9ed39eb687cd14bf5caf62b34005a 100644 (file)
@@ -3,6 +3,7 @@
 #include "items.qh"
 
 float autocvar_g_instagib_invis_alpha;
+int autocvar_g_instagib_extralives;
 
 void instagib_invisibility(entity this);
 void instagib_extralife(entity this);
index 8d2bb318f0f2443f1200545a675f23b1d31d433c..5add006c3d2c6bc7082ff8f7cc59294652f9dcef 100644 (file)
@@ -194,12 +194,7 @@ void DrawItemsTimeItem(vector myPos, vector mySize, float ar, string item_icon,
     if (autocvar_hud_panel_itemstime_hidespawned == 2)
         picalpha = 1;
     else if (item_available)
-    {
-        float BLINK_FACTOR = 0.15;
-        float BLINK_BASE = 0.85;
-        float BLINK_FREQ = 5;
-        picalpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ);
-    }
+        picalpha = blink(0.85, 0.15, 5);
     else
         picalpha = 0.5;
     t = floor(item_time - time + 0.999);
index 0efd85635cc88503b9998675c59eaf2369fd347c..40bc9a33e96d57c469a5fa27e1dcef40a30e14d6 100644 (file)
@@ -20,16 +20,17 @@ REGISTER_MUTATOR(multijump, true);
 #define PHYS_MULTIJUMP_MAXSPEED(s)             STAT(MULTIJUMP_MAXSPEED, s)
 #define PHYS_MULTIJUMP_DODGING(s)              STAT(MULTIJUMP_DODGING, s)
 #define PHYS_MULTIJUMP_COUNT(s)                STAT(MULTIJUMP_COUNT, s)
+#define PHYS_MULTIJUMP_CLIENTDEFAULT(s)        STAT(MULTIJUMP_CLIENT, s)
 
 .bool multijump_ready;
 
 #ifdef CSQC
-bool cvar_cl_multijump;
-bool autocvar_cl_multijump = true;
+int cvar_cl_multijump;
+int autocvar_cl_multijump = -1;
 
        #define PHYS_MULTIJUMP_CLIENT(s)        autocvar_cl_multijump
 #elif defined(SVQC)
-.bool cvar_cl_multijump;
+.int cvar_cl_multijump;
 
        #define PHYS_MULTIJUMP_CLIENT(s)        CS(s).cvar_cl_multijump
 #endif
@@ -54,6 +55,8 @@ MUTATOR_HOOKFUNCTION(multijump, PlayerJump)
        if(!PHYS_MULTIJUMP(player)) { return; }
 
        int client_multijump = PHYS_MULTIJUMP_CLIENT(player);
+       if(client_multijump == -1)
+               client_multijump = PHYS_MULTIJUMP_CLIENTDEFAULT(player);
        if(client_multijump > 1)
                return; // nope
 
@@ -115,7 +118,7 @@ MUTATOR_HOOKFUNCTION(multijump, PlayerJump)
        }
 }
 
-REPLICATE(cvar_cl_multijump, bool, "cl_multijump");
+REPLICATE(cvar_cl_multijump, int, "cl_multijump");
 
 #ifdef SVQC
 
index d48319a421fa599861a11ba4aaabe1dabe71ac1b..9ac33b45bb328a612a395fb74f5a206fd62a7644 100644 (file)
@@ -1,6 +1,7 @@
 #include "nades.qh"
 
 #include "../overkill/okmachinegun.qh"
+#include "../overkill/okshotgun.qh"
 
 #ifdef SVQC
 bool autocvar_g_nades_nade_small;
@@ -670,7 +671,9 @@ void nade_heal_boom(entity this)
 
 void nade_monster_boom(entity this)
 {
-       entity e = spawnmonster(spawn(), this.pokenade_type, 0, this.realowner, this.realowner, this.origin, false, false, 1);
+       entity e = spawn();
+       e.noalign = true; // don't drop to floor
+       e = spawnmonster(e, this.pokenade_type, 0, this.realowner, this.realowner, this.origin, false, false, 1);
 
        if(autocvar_g_nades_pokenade_monster_lifetime > 0)
                e.monster_lifetime = time + autocvar_g_nades_pokenade_monster_lifetime;
@@ -892,7 +895,7 @@ void nade_damage(entity this, entity inflictor, entity attacker, float damage, i
        }
        else if(DEATH_ISWEAPON(deathtype, WEP_MACHINEGUN) || DEATH_ISWEAPON(deathtype, WEP_OVERKILL_MACHINEGUN))
                damage = this.max_health * 0.1;
-       else if(DEATH_ISWEAPON(deathtype, WEP_SHOCKWAVE) || DEATH_ISWEAPON(deathtype, WEP_SHOTGUN)) // WEAPONTODO
+       else if(DEATH_ISWEAPON(deathtype, WEP_SHOCKWAVE) || DEATH_ISWEAPON(deathtype, WEP_SHOTGUN) || DEATH_ISWEAPON(deathtype, WEP_OVERKILL_SHOTGUN)) // WEAPONTODO
        {
                if(!(deathtype & HITTYPE_SECONDARY))
                        damage = this.max_health * 1.15;
@@ -1189,7 +1192,6 @@ void nades_CheckThrow(entity this)
                this.nade_altbutton = true;
                if(time > this.nade_refire)
                {
-                       Send_Notification(NOTIF_ONE, this, MSG_CENTER, CENTER_NADE_THROW);
                        nade_prime(this);
                        this.nade_refire = time + autocvar_g_nades_nade_refire;
                }
@@ -1294,7 +1296,10 @@ MUTATOR_HOOKFUNCTION(nades, PlayerPreThink)
                held_nade.angles_y = player.angles.y;
 
                if (time + 0.1 >= held_nade.wait)
+               {
                        toss_nade(player, false, '0 0 0', time + 0.05);
+                       Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_NADE_THROW);
+               }
        }
 
        if(IS_PLAYER(player))
@@ -1345,44 +1350,47 @@ MUTATOR_HOOKFUNCTION(nades, PlayerPreThink)
                }
        }
 
-       int n = 0;
-
-       IntrusiveList reviving_players = NULL;
-
-       if(player.freezetag_frozen_timeout > 0 && time >= player.freezetag_frozen_timeout)
-               n = -1;
-       else if (STAT(FROZEN, player) == FROZEN_TEMP_DYING)
+       if (frametime && IS_PLAYER(player))
        {
-               vector revive_extra_size = '1 1 1' * autocvar_g_freezetag_revive_extra_size;
-               n = 0;
-               FOREACH_CLIENT(IS_PLAYER(it) && IS_REVIVING(player, it, revive_extra_size), {
-                       if (!reviving_players)
-                               reviving_players = IL_NEW();
-                       IL_PUSH(reviving_players, it);
-                       ++n;
-               });
-       }
+               int n = 0;
 
-       if (n > 0 && STAT(FROZEN, player) == FROZEN_TEMP_DYING) // OK, there is at least one teammate reviving us
-       {
-               STAT(REVIVE_PROGRESS, player) = bound(0, STAT(REVIVE_PROGRESS, player) + frametime * max(1/60, autocvar_g_freezetag_revive_speed), 1);
-               SetResource(player, RES_HEALTH, max(1, STAT(REVIVE_PROGRESS, player) * start_health));
+               IntrusiveList reviving_players = NULL;
 
-               if(STAT(REVIVE_PROGRESS, player) >= 1)
+               if(player.freezetag_frozen_timeout > 0 && time >= player.freezetag_frozen_timeout)
+                       n = -1;
+               else if (STAT(FROZEN, player) == FROZEN_TEMP_DYING)
                {
-                       Unfreeze(player, false);
-
-                       entity first = IL_FIRST(reviving_players);
-                       Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_FREEZETAG_REVIVED, first.netname);
-                       Send_Notification(NOTIF_ONE, first, MSG_CENTER, CENTER_FREEZETAG_REVIVE, player.netname);
+                       vector revive_extra_size = '1 1 1' * autocvar_g_freezetag_revive_extra_size;
+                       n = 0;
+                       FOREACH_CLIENT(IS_PLAYER(it) && IS_REVIVING(player, it, revive_extra_size), {
+                               if (!reviving_players)
+                                       reviving_players = IL_NEW();
+                               IL_PUSH(reviving_players, it);
+                               ++n;
+                       });
                }
 
-               IL_EACH(reviving_players, true, {
-                       STAT(REVIVE_PROGRESS, it) = STAT(REVIVE_PROGRESS, player);
-               });
+               if (n > 0 && STAT(FROZEN, player) == FROZEN_TEMP_DYING) // OK, there is at least one teammate reviving us
+               {
+                       STAT(REVIVE_PROGRESS, player) = bound(0, STAT(REVIVE_PROGRESS, player) + frametime * max(1/60, autocvar_g_freezetag_revive_speed), 1);
+                       SetResource(player, RES_HEALTH, max(1, STAT(REVIVE_PROGRESS, player) * start_health));
+
+                       if(STAT(REVIVE_PROGRESS, player) >= 1)
+                       {
+                               Unfreeze(player, false);
+
+                               entity first = IL_FIRST(reviving_players);
+                               Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_FREEZETAG_REVIVED, first.netname);
+                               Send_Notification(NOTIF_ONE, first, MSG_CENTER, CENTER_FREEZETAG_REVIVE, player.netname);
+                       }
+
+                       IL_EACH(reviving_players, true, {
+                               STAT(REVIVE_PROGRESS, it) = STAT(REVIVE_PROGRESS, player);
+                       });
+               }
+               if (reviving_players)
+                       IL_DELETE(reviving_players);
        }
-       if (reviving_players)
-               IL_DELETE(reviving_players);
 }
 
 MUTATOR_HOOKFUNCTION(nades, PlayerPhysics_UpdateStats)
@@ -1453,7 +1461,6 @@ MUTATOR_HOOKFUNCTION(nades, PlayerDies, CBC_ORDER_LAST)
        {
                float killcount_bonus = ((CS(frag_attacker).killcount >= 1) ? bound(0, autocvar_g_nades_bonus_score_minor * CS(frag_attacker).killcount, autocvar_g_nades_bonus_score_medium) 
                                                                                                                                        : autocvar_g_nades_bonus_score_minor);
-
                if (SAME_TEAM(frag_attacker, frag_target) || frag_attacker == frag_target)
                        nades_RemoveBonus(frag_attacker);
                else if(GameRules_scoring_is_vip(frag_target))
index df55fb88c42a4663b96b9aaa5a6f3b61d908692f..68d69ab2f027f25408d1b953cbc627b271b1b72f 100644 (file)
@@ -57,10 +57,8 @@ void W_OverkillHeavyMachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity
 
 METHOD(OverkillHeavyMachineGun, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
 {
-    if(vdist(actor.origin - actor.enemy.origin, <, 3000 - bound(0, skill, 10) * 200))
-        PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false);
-    else
-        PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false);
+       if(vdist(actor.origin - actor.enemy.origin, <, 3000 - bound(0, skill, 10) * 200))
+               PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false);
 }
 
 METHOD(OverkillHeavyMachineGun, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
@@ -74,14 +72,11 @@ METHOD(OverkillHeavyMachineGun, wr_think, void(entity thiswep, entity actor, .en
                        (actor.(weaponentity).wframe == WFRAME_FIRE2))
                {
                        // Set secondary fire animation.
-                       vector a = '0 0 0';
                        actor.(weaponentity).wframe = WFRAME_FIRE2;
-                       a = actor.(weaponentity).anim_fire2;
-                       a.z *= g_weaponratefactor;
                        FOREACH_CLIENT(true, LAMBDA(
                                if (it == actor || (IS_SPEC(it) && it.enemy == actor))
                                {
-                                       wframe_send(it, actor.(weaponentity), a, true);
+                                       wframe_send(it, actor.(weaponentity), WFRAME_FIRE2, g_weaponratefactor, true);
                                }
                        ));
                        animdecide_setaction(actor, ANIMACTION_SHOOT, true);
index 768e364a78535f8274516388f47519ed4294da21..817e369816ac69ad599ac19474fd1d39b1798ab0 100644 (file)
@@ -53,8 +53,6 @@ METHOD(OverkillMachineGun, wr_aim, void(entity thiswep, entity actor, .entity we
 {
        if(vdist(actor.origin - actor.enemy.origin, <, 3000 - bound(0, skill, 10) * 200))
                PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false);
-       else
-               PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, 1000000, 0, 0.001, false);
 }
 
 METHOD(OverkillMachineGun, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
@@ -68,14 +66,11 @@ METHOD(OverkillMachineGun, wr_think, void(entity thiswep, entity actor, .entity
                        (actor.(weaponentity).wframe == WFRAME_FIRE2))
                {
                        // Set secondary fire animation.
-                       vector a = '0 0 0';
                        actor.(weaponentity).wframe = WFRAME_FIRE2;
-                       a = actor.(weaponentity).anim_fire2;
-                       a.z *= g_weaponratefactor;
                        FOREACH_CLIENT(true, LAMBDA(
                                if (it == actor || (IS_SPEC(it) && it.enemy == actor))
                                {
-                                       wframe_send(it, actor.(weaponentity), a, true);
+                                       wframe_send(it, actor.(weaponentity), WFRAME_FIRE2, g_weaponratefactor, true);
                                }
                        ));
                        animdecide_setaction(actor, ANIMACTION_SHOOT, true);
index 83a3a3cc052c3e9adbaf0143af71242def1946a5..ca44a070a0cf99c2db176642d49cd07efaa34bfc 100644 (file)
@@ -150,14 +150,11 @@ METHOD(OverkillNex, wr_think, void(entity thiswep, entity actor, .entity weapone
                        (actor.(weaponentity).wframe == WFRAME_FIRE2))
                {
                        // Set secondary fire animation.
-                       vector a = '0 0 0';
                        actor.(weaponentity).wframe = WFRAME_FIRE2;
-                       a = actor.(weaponentity).anim_fire2;
-                       a.z *= g_weaponratefactor;
                        FOREACH_CLIENT(true, LAMBDA(
                                if (it == actor || (IS_SPEC(it) && it.enemy == actor))
                                {
-                                       wframe_send(it, actor.(weaponentity), a, true);
+                                       wframe_send(it, actor.(weaponentity), WFRAME_FIRE2, g_weaponratefactor, true);
                                }
                        ));
                        animdecide_setaction(actor, ANIMACTION_SHOOT, true);
index fa4ffc4b5e2709b294f4399cb9a515deb0a5d215..362f14846f1368b07b0603e53292df50c6eb8b2e 100644 (file)
@@ -149,14 +149,11 @@ METHOD(OverkillRocketPropelledChainsaw, wr_think, void(entity thiswep, entity ac
                        (actor.(weaponentity).wframe == WFRAME_FIRE2))
                {
                        // Set secondary fire animation.
-                       vector a = '0 0 0';
                        actor.(weaponentity).wframe = WFRAME_FIRE2;
-                       a = actor.(weaponentity).anim_fire2;
-                       a.z *= g_weaponratefactor;
                        FOREACH_CLIENT(true, LAMBDA(
                                if (it == actor || (IS_SPEC(it) && it.enemy == actor))
                                {
-                                       wframe_send(it, actor.(weaponentity), a, true);
+                                       wframe_send(it, actor.(weaponentity), WFRAME_FIRE2, g_weaponratefactor, true);
                                }
                        ));
                        animdecide_setaction(actor, ANIMACTION_SHOOT, true);
index 784d1c37b770f47a4110b76cc03e990dacee4063..da4c4749d04763e4fab32d8624e00ab11e1430d3 100644 (file)
@@ -24,14 +24,11 @@ METHOD(OverkillShotgun, wr_think, void(entity thiswep, entity actor, .entity wea
                        (actor.(weaponentity).wframe == WFRAME_FIRE2))
                {
                        // Set secondary fire animation.
-                       vector a = '0 0 0';
                        actor.(weaponentity).wframe = WFRAME_FIRE2;
-                       a = actor.(weaponentity).anim_fire2;
-                       a.z *= g_weaponratefactor;
                        FOREACH_CLIENT(true, LAMBDA(
                                if (it == actor || (IS_SPEC(it) && it.enemy == actor))
                                {
-                                       wframe_send(it, actor.(weaponentity), a, true);
+                                       wframe_send(it, actor.(weaponentity), WFRAME_FIRE2, g_weaponratefactor, true);
                                }
                        ));
                        animdecide_setaction(actor, ANIMACTION_SHOOT, true);
index 8176669dea78164c5b7bc0e8fecc9e8f4febf8a2..26cd9c23c863c0edd4732ab0227177ba3fefdaf4 100644 (file)
@@ -81,7 +81,6 @@ MUTATOR_HOOKFUNCTION(ok, Damage_Calculate, CBC_ORDER_LAST)
                if(!STAT(FROZEN, frag_target))
                if(!IS_DEAD(frag_target))
                {
-                       Send_Notification(NOTIF_ONE, frag_attacker, MSG_CENTER, CENTER_SECONDARY_NODAMAGE);
                        M_ARGV(6, vector) = '0 0 0'; // force
                }
 
index 779e562b4a4286235891a56c8e43e43cfd0fb716..fa8045101e55b3b94f83f83e5437390ce8f213dc 100644 (file)
@@ -1,6 +1,7 @@
 #include "sv_pinata.qh"
 
 string autocvar_g_pinata;
+bool autocvar_g_pinata_offhand;
 REGISTER_MUTATOR(pinata, expr_evaluate(autocvar_g_pinata) && !MUTATOR_IS_ENABLED(mutator_instagib) && !MUTATOR_IS_ENABLED(ok));
 
 MUTATOR_HOOKFUNCTION(pinata, PlayerDies)
@@ -14,6 +15,9 @@ MUTATOR_HOOKFUNCTION(pinata, PlayerDies)
                if(frag_target.(weaponentity).m_weapon == WEP_Null)
                        continue;
 
+               if(slot > 0 && !autocvar_g_pinata_offhand)
+                       break;
+
                FOREACH(Weapons, it != WEP_Null, {
                        if(STAT(WEAPONS, frag_target) & WepSet_FromWeapon(it))
                        if(frag_target.(weaponentity).m_weapon != it)
index eb20082359ec1f25f92643bdd3f6a2b4624ebe17..c721f4571b58fadbaa6f895f6e389bc0a470c955 100644 (file)
@@ -121,16 +121,16 @@ MUTATOR_HOOKFUNCTION(superspec, ItemTouch)
                                }
                        }
 
-               if((it.autospec_flags & ASF_SHIELD && item.invincible_finished) ||
-                       (it.autospec_flags & ASF_STRENGTH && item.strength_finished) ||
-                       (it.autospec_flags & ASF_MEGA_AR && item.itemdef == ITEM_ArmorMega) ||
-                       (it.autospec_flags & ASF_MEGA_HP && item.itemdef == ITEM_HealthMega) ||
-                       (it.autospec_flags & ASF_FLAG_GRAB && item.classname == "item_flag_team"))
+               if(((it.autospec_flags & ASF_SHIELD) && item.invincible_finished) ||
+                       ((it.autospec_flags & ASF_STRENGTH) && item.strength_finished) ||
+                       ((it.autospec_flags & ASF_MEGA_AR) && item.itemdef == ITEM_ArmorMega) ||
+                       ((it.autospec_flags & ASF_MEGA_HP) && item.itemdef == ITEM_HealthMega) ||
+                       ((it.autospec_flags & ASF_FLAG_GRAB) && item.classname == "item_flag_team"))
                {
 
                        if((it.enemy != toucher) || IS_OBSERVER(it))
                        {
-                               if(it.autospec_flags & ASF_OBSERVER_ONLY && !IS_OBSERVER(it))
+                               if((it.autospec_flags & ASF_OBSERVER_ONLY) && !IS_OBSERVER(it))
                                {
                                        if(it.superspec_flags & SSF_VERBOSE)
                                                superspec_msg("", "", it, sprintf("^8Ignored that ^7%s^8 grabbed %s^8 since the observer_only option is ON\n", toucher.netname, item.netname), 2);
@@ -346,7 +346,7 @@ MUTATOR_HOOKFUNCTION(superspec, SV_ParseClientCommand)
 
        if(cmd_name == "followpowerup")
        {
-               FOREACH_CLIENT(IS_PLAYER(it) && (it.strength_finished > time || it.invincible_finished > time), { return superspec_Spectate(player, it); });
+               FOREACH_CLIENT(IS_PLAYER(it) && (STAT(STRENGTH_FINISHED, it) > time || STAT(INVINCIBLE_FINISHED, it) > time), { return superspec_Spectate(player, it); });
 
                superspec_msg("", "", player, "No active powerup\n", 1);
                return true;
@@ -354,7 +354,7 @@ MUTATOR_HOOKFUNCTION(superspec, SV_ParseClientCommand)
 
        if(cmd_name == "followstrength")
        {
-               FOREACH_CLIENT(IS_PLAYER(it) && it.strength_finished > time, { return superspec_Spectate(player, it); });
+               FOREACH_CLIENT(IS_PLAYER(it) && STAT(STRENGTH_FINISHED, it) > time, { return superspec_Spectate(player, it); });
 
                superspec_msg("", "", player, "No active Strength\n", 1);
                return true;
@@ -362,7 +362,7 @@ MUTATOR_HOOKFUNCTION(superspec, SV_ParseClientCommand)
 
        if(cmd_name == "followshield")
        {
-               FOREACH_CLIENT(IS_PLAYER(it) && it.invincible_finished > time, { return superspec_Spectate(player, it); });
+               FOREACH_CLIENT(IS_PLAYER(it) && STAT(INVINCIBLE_FINISHED, it) > time, { return superspec_Spectate(player, it); });
 
                superspec_msg("", "", player, "No active Shield\n", 1);
                return true;
@@ -442,7 +442,7 @@ MUTATOR_HOOKFUNCTION(superspec, PlayerDies)
        entity frag_target = M_ARGV(2, entity);
 
        FOREACH_CLIENT(IS_SPEC(it), {
-               if(it.autospec_flags & ASF_FOLLOWKILLER && IS_PLAYER(frag_attacker) && it.enemy == frag_target)
+               if((it.autospec_flags & ASF_FOLLOWKILLER) && IS_PLAYER(frag_attacker) && it.enemy == frag_target)
                {
                        if(it.autospec_flags & ASF_SHOWWHAT)
                                superspec_msg("", "", it, sprintf("^7Following %s^7 due to followkiller\n", frag_attacker.netname), 2);
index c462a7e2b7c869398e733019a107f69049d16472..519159d917b386b9488261845caeed486f4f378c 100644 (file)
@@ -23,10 +23,12 @@ vector PlayerTouchWall(entity this)
 
        float dist = 10, max_normal = 0.2, scaler = 100;
        vector start = this.origin;
-       TRACE(start + v_forward * scaler)
-       TRACE(start - v_forward * scaler)
-       TRACE(start + v_right * scaler)
-       TRACE(start - v_right * scaler)
+       vector forward, right, _up;
+       MAKE_VECTORS(this.angles, forward, right, _up);
+       TRACE(start + forward * scaler)
+       TRACE(start - forward * scaler)
+       TRACE(start + right * scaler)
+       TRACE(start - right * scaler)
 #undef TRACE
        return '0 0 0';
 }
index a9e1c5f57dd2996c7f5c6cf79b365cd11de84d60..0b4fe28ff33bfde36cb81653d0cac7ac3c291ae5 100644 (file)
@@ -296,7 +296,7 @@ void drawrotpic(vector org, float rot, string pic, vector sz, vector hotspot, ve
     v4 = Rotate(v4, rot) + org;
 
     // draw them
-    R_BeginPolygon(pic, f);
+    R_BeginPolygon(pic, f, true);
     R_PolygonVertex(v1, '0 0 0', rgb, a);
     R_PolygonVertex(v2, '1 0 0', rgb, a);
     R_PolygonVertex(v3, '1 1 0', rgb, a);
@@ -306,7 +306,7 @@ void drawrotpic(vector org, float rot, string pic, vector sz, vector hotspot, ve
 
 void drawquad(vector o, vector ri, vector up, string pic, vector rgb, float a, float f)
 {
-    R_BeginPolygon(pic, f);
+    R_BeginPolygon(pic, f, true);
     R_PolygonVertex(o, '0 0 0', rgb, a);
     R_PolygonVertex(o + ri, '1 0 0', rgb, a);
     R_PolygonVertex(o + up + ri, '1 1 0', rgb, a);
@@ -354,7 +354,7 @@ vector drawspritearrow(vector o, float ang, vector rgb, float a, float t)
     vector borderX = eX * (size+borderDiag);
     vector borderY = eY * (size+borderDiag+border);
 
-    R_BeginPolygon("", DRAWFLAG_NORMAL);
+    R_BeginPolygon("", DRAWFLAG_NORMAL, true);
     R_PolygonVertex(o,                                  '0 0 0', '0 0 0', a);
     R_PolygonVertex(o + Rotate(arrowY  - borderX, ang), '0 0 0', '0 0 0', a);
     R_PolygonVertex(o + Rotate(borderY - borderX, ang), '0 0 0', '0 0 0', a);
@@ -362,7 +362,7 @@ vector drawspritearrow(vector o, float ang, vector rgb, float a, float t)
     R_PolygonVertex(o + Rotate(arrowY  + borderX, ang), '0 0 0', '0 0 0', a);
     R_EndPolygon();
 
-    R_BeginPolygon("", DRAWFLAG_ADDITIVE);
+    R_BeginPolygon("", DRAWFLAG_ADDITIVE, true);
     R_PolygonVertex(o + Rotate(eY * borderDiag, ang), '0 0 0', rgb, a);
     R_PolygonVertex(o + Rotate(arrowY - arrowX, ang), '0 0 0', rgb, a);
     R_PolygonVertex(o + Rotate(arrowY + arrowX, ang), '0 0 0', rgb, a);
index 46e0c88643d187310ad447fcb372087e353bd7b7..a9a2ee655139555dfc70bb72ae875d9fc2061a28 100644 (file)
 #define N_CONSOLE 1
 #define N_CHATCON 2
 
+// hack to work around the limitations of sprintf
+string multiteam_info_sprintf(string input, string teamname) { return ((input != "") ? sprintf(input, teamname) : ""); }
+
 #define MULTITEAM_INFO(prefix, defaultvalue, strnum, flnum, args, hudargs, icon, normal, gentle, type) \
     NOTIF_ADD_AUTOCVAR(INFO_##prefix, defaultvalue) \
-    MSG_INFO_NOTIF_TEAM(NUM_TEAM_1, prefix##_RED, prefix, defaultvalue, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_1)), TCR(normal, type, 1), TCR(gentle, type, 1)) \
-    MSG_INFO_NOTIF_TEAM(NUM_TEAM_2, prefix##_BLUE, prefix, defaultvalue, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_2)), TCR(normal, type, 2), TCR(gentle, type, 2)) \
-    MSG_INFO_NOTIF_TEAM(NUM_TEAM_3, prefix##_YELLOW, prefix, defaultvalue, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_3)), TCR(normal, type, 3), TCR(gentle, type, 3)) \
-    MSG_INFO_NOTIF_TEAM(NUM_TEAM_4, prefix##_PINK, prefix, defaultvalue, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_4)), TCR(normal, type, 4), TCR(gentle, type, 4))
+    MSG_INFO_NOTIF_TEAM(NUM_TEAM_1, prefix##_RED, prefix, defaultvalue, strnum, flnum, args, hudargs, multiteam_info_sprintf(icon, strtolower(STATIC_NAME_TEAM_1)), TCR(normal, type, 1), TCR(gentle, type, 1)) \
+    MSG_INFO_NOTIF_TEAM(NUM_TEAM_2, prefix##_BLUE, prefix, defaultvalue, strnum, flnum, args, hudargs, multiteam_info_sprintf(icon, strtolower(STATIC_NAME_TEAM_2)), TCR(normal, type, 2), TCR(gentle, type, 2)) \
+    MSG_INFO_NOTIF_TEAM(NUM_TEAM_3, prefix##_YELLOW, prefix, defaultvalue, strnum, flnum, args, hudargs, multiteam_info_sprintf(icon, strtolower(STATIC_NAME_TEAM_3)), TCR(normal, type, 3), TCR(gentle, type, 3)) \
+    MSG_INFO_NOTIF_TEAM(NUM_TEAM_4, prefix##_PINK, prefix, defaultvalue, strnum, flnum, args, hudargs, multiteam_info_sprintf(icon, strtolower(STATIC_NAME_TEAM_4)), TCR(normal, type, 4), TCR(gentle, type, 4))
 
 // MSG_INFO_NOTIFICATIONS
     MSG_INFO_NOTIF(CHAT_NOSPECTATORS,                       N_CHATCON,  0, 0, "", "",       "",     _("^F4NOTE: ^BGSpectator chat is not sent to players during the match"), "")
     MSG_INFO_NOTIF(FREEZETAG_REVIVED,                       N_CONSOLE,  2, 0, "s1 s2", "",      "",     _("^BG%s^K3 was revived by ^BG%s"), "")
     MSG_INFO_NOTIF(FREEZETAG_REVIVED_FALL,                  N_CONSOLE,  1, 0, "s1", "",         "",     _("^BG%s^K3 was revived by falling"), "")
     MSG_INFO_NOTIF(FREEZETAG_REVIVED_NADE,                  N_CONSOLE,  1, 0, "s1", "",         "",     _("^BG%s^K3 was revived by their Nade explosion"), "")
-    MSG_INFO_NOTIF(FREEZETAG_AUTO_REVIVED,                  N_CONSOLE,  1, 1, "s1 f1", "",      "",     _("^BG%s^K3 was automatically revived after %s second(s)"), "")
+    MSG_INFO_NOTIF(FREEZETAG_AUTO_REVIVED,                  N_CONSOLE,  1, 1, "s1 f1", "",      "",     _("^BG%s^K3 was automatically revived after %s seconds"), "")
     MSG_INFO_NOTIF(FREEZETAG_SELF,                          N_CONSOLE,  1, 0, "s1", "",         "",     _("^BG%s^K1 froze themself"), "")
 
     MULTITEAM_INFO(ROUND_TEAM_WIN,                          N_CONSOLE,  0, 0, "", "",           "",     _("^TC^TT^BG team wins the round"), "", NAME)
 
     #define VERBOSE_MURDER(type) strcat(MURDER_##type, "^BG%s")
 
-    #define MURDER_FRAG             _("^K3%sYou fragged ^BG%s")
-    #define MURDER_FRAG2            _("^K3%sYou scored against ^BG%s")
+    #define MURDER_FRAG             strcat(BOLD_OPERATOR, _("^K3%sYou fragged ^BG%s"))
+    #define MURDER_FRAG2            strcat(BOLD_OPERATOR, _("^K3%sYou scored against ^BG%s"))
     #define MURDER_FRAGGED          _("^K1%sYou were fragged by ^BG%s")
     #define MURDER_FRAGGED2         _("^K1%sYou were scored against by ^BG%s")
     MSG_CENTER_NOTIF(DEATH_MURDER_FRAG,                   N_ENABLE,  1, 1, "spree_cen s1",               CPID_Null,  "0 0",  MURDER_FRAG,                    MURDER_FRAG2                   )
     MSG_CENTER_NOTIF(DEATH_MURDER_FRAGGED_VERBOSE,        N_ENABLE,  1, 4, "spree_cen s1 frag_stats",    CPID_Null,  "0 0",  VERBOSE_MURDER(FRAGGED),        VERBOSE_MURDER(FRAGGED2)       )
     MSG_CENTER_NOTIF(DEATH_MURDER_FRAG_VERBOSE,           N_ENABLE,  1, 2, "spree_cen s1 frag_ping",     CPID_Null,  "0 0",  VERBOSE_MURDER(FRAG),           VERBOSE_MURDER(FRAG2)          )
 
-    #define MURDER_FRAG_FIRE        _("^K3%sYou burned ^BG%s")
-    #define MURDER_FRAG_FIRE2       _("^K3%sYou scored against ^BG%s")
+    #define MURDER_FRAG_FIRE        strcat(BOLD_OPERATOR, _("^K3%sYou burned ^BG%s"))
+    #define MURDER_FRAG_FIRE2       strcat(BOLD_OPERATOR, _("^K3%sYou scored against ^BG%s"))
     #define MURDER_FRAGGED_FIRE     _("^K1%sYou were burned by ^BG%s")
     #define MURDER_FRAGGED_FIRE2    _("^K1%sYou were scored against by ^BG%s")
     MSG_CENTER_NOTIF(DEATH_MURDER_FRAG_FIRE,              N_ENABLE,  1, 1, "spree_cen s1",               CPID_Null,  "0 0",  MURDER_FRAG_FIRE,               MURDER_FRAG_FIRE2              )
     MSG_CENTER_NOTIF(DEATH_MURDER_FRAGGED_FIRE_VERBOSE,   N_ENABLE,  1, 4, "spree_cen s1 frag_stats",    CPID_Null,  "0 0",  VERBOSE_MURDER(FRAGGED_FIRE),   VERBOSE_MURDER(FRAGGED_FIRE2)  )
     MSG_CENTER_NOTIF(DEATH_MURDER_FRAG_FIRE_VERBOSE,      N_ENABLE,  1, 2, "spree_cen s1 frag_ping",     CPID_Null,  "0 0",  VERBOSE_MURDER(FRAG_FIRE),      VERBOSE_MURDER(FRAG_FIRE2)     )
 
-    #define MURDER_FRAG_FREEZE      _("^K3%sYou froze ^BG%s")
-    #define MURDER_FRAG_FREEZE2     _("^K3%sYou scored against ^BG%s")
+    #define MURDER_FRAG_FREEZE      strcat(BOLD_OPERATOR, _("^K3%sYou froze ^BG%s"))
+    #define MURDER_FRAG_FREEZE2     strcat(BOLD_OPERATOR, _("^K3%sYou scored against ^BG%s"))
     #define MURDER_FRAGGED_FREEZE   _("^K1%sYou were frozen by ^BG%s")
     #define MURDER_FRAGGED_FREEZE2  _("^K1%sYou were scored against by ^BG%s")
     MSG_CENTER_NOTIF(DEATH_MURDER_FRAG_FREEZE,            N_ENABLE,  1, 1, "spree_cen s1",               CPID_Null,  "0 0",  MURDER_FRAG_FREEZE,             MURDER_FRAG_FREEZE2            )
     MSG_CENTER_NOTIF(DEATH_MURDER_FRAGGED_FREEZE_VERBOSE, N_ENABLE,  1, 4, "spree_cen s1 frag_stats",    CPID_Null,  "0 0",  VERBOSE_MURDER(FRAGGED_FREEZE), VERBOSE_MURDER(FRAGGED_FREEZE2))
     MSG_CENTER_NOTIF(DEATH_MURDER_FRAG_FREEZE_VERBOSE,    N_ENABLE,  1, 2, "spree_cen s1 frag_ping",     CPID_Null,  "0 0",  VERBOSE_MURDER(FRAG_FREEZE),    VERBOSE_MURDER(FRAG_FREEZE2)   )
 
-    #define MURDER_TYPEFRAG         _("^K1%sYou typefragged ^BG%s")
-    #define MURDER_TYPEFRAG2        _("^K1%sYou scored against ^BG%s^K1 while they were typing")
+    #define MURDER_TYPEFRAG         strcat(BOLD_OPERATOR, _("^K1%sYou typefragged ^BG%s"))
+    #define MURDER_TYPEFRAG2        strcat(BOLD_OPERATOR, _("^K1%sYou scored against ^BG%s^K1 while they were typing"))
     #define MURDER_TYPEFRAGGED      _("^K1%sYou were typefragged by ^BG%s")
     #define MURDER_TYPEFRAGGED2     _("^K1%sYou were scored against by ^BG%s^K1 while typing")
     MSG_CENTER_NOTIF(DEATH_MURDER_TYPEFRAG,               N_ENABLE,  1, 1, "spree_cen s1",               CPID_Null,  "0 0",  MURDER_TYPEFRAG,                MURDER_TYPEFRAG2               )
     MSG_CENTER_NOTIF(DOOR_LOCKED_ALSONEED,              N_ENABLE,    1, 0, "s1",             CPID_Null,              "0 0",  _("^BGYou also need %s^BG!"), "")
     MSG_CENTER_NOTIF(DOOR_UNLOCKED,                     N_ENABLE,    0, 0, "",               CPID_Null,              "0 0",  _("^BGDoor unlocked!"), "")
 
-    MSG_CENTER_NOTIF(EXTRALIVES,                        N_ENABLE,    0, 0, "",               CPID_Null,              "0 0",  _("^F2You picked up some extra lives"), "")
+    MSG_CENTER_NOTIF(EXTRALIVES,                        N_ENABLE,    0, 1, "f1",             CPID_Null,              "0 0",  _("^F2Extra lives taken: ^K1%s"), "")
 
     MSG_CENTER_NOTIF(FREEZETAG_REVIVE,                  N_ENABLE,    1, 0, "s1",             CPID_Null,              "0 0",  _("^K3You revived ^BG%s"), "")
     MSG_CENTER_NOTIF(FREEZETAG_REVIVE_SELF,             N_ENABLE,    0, 0, "",               CPID_Null,              "0 0",  _("^K3You revived yourself"), "")
     MSG_CENTER_NOTIF(FREEZETAG_REVIVED,                 N_ENABLE,    1, 0, "s1",             CPID_Null,              "0 0",  _("^K3You were revived by ^BG%s"), "")
-    MSG_CENTER_NOTIF(FREEZETAG_AUTO_REVIVED,            N_ENABLE,    0, 1, "f1",             CPID_Null,              "0 0",  _("^K3You were automatically revived after %s second(s)"), "")
+    MSG_CENTER_NOTIF(FREEZETAG_AUTO_REVIVED,            N_ENABLE,    0, 1, "f1",             CPID_Null,              "0 0",  _("^K3You were automatically revived after %s seconds"), "")
 
     MSG_CENTER_NOTIF(GENERATOR_UNDERATTACK,             N_ENABLE,    0, 0, "",               CPID_Null,              "0 0",  _("^BGThe generator is under attack!"), "")
 
     MSG_CENTER_NOTIF(INSTAGIB_FINDAMMO_FIRST,           N_ENABLE,    0, 0, "",               CPID_INSTAGIB_FINDAMMO, "1 10", _("^BGGet some ammo or you'll be dead in ^F4^COUNT^BG!"), _("^BGGet some ammo! ^F4^COUNT^BG left!"))
     MSG_CENTER_NOTIF(INSTAGIB_LIVES_REMAINING,          N_ENABLE,    0, 1, "f1",             CPID_Null,              "0 0",  _("^F2Extra lives remaining: ^K1%s"), "")
 
+    MSG_CENTER_NOTIF(CAMPAIGN_MESSAGE,                  N_ENABLE,    1, 1, "f1 s1 join_key", CPID_CAMPAIGN_MESSAGE,  "-1 0", strcat(_("Level %s: "), "^BG%s\n^3\n", _("^BGPress ^F2%s^BG to enter the game")), "")
     MSG_CENTER_NOTIF(MOTD,                              N_ENABLE,    1, 0, "s1",             CPID_MOTD,              "-1 0", "^BG%s", "")
 
     MSG_CENTER_NOTIF(NIX_COUNTDOWN,                     N_ENABLE,    0, 2, "item_wepname",   CPID_NIX,               "1 f2", _("^F2^COUNT^BG until weapon change...\nNext weapon: ^F1%s"), "")
 
     MSG_CENTER_NOTIF(RACE_FINISHLAP,                    N_ENABLE,    0, 0, "",               CPID_RACE_FINISHLAP,    "0 0",  _("^F2The race is over, finish your lap!"), "")
 
-    MSG_CENTER_NOTIF(SECONDARY_NODAMAGE,                N_ENABLE,    0, 0, "",               CPID_Null,              "0 0",  _("^BGSecondary fire inflicts no damage!"), "")
-
     MSG_CENTER_NOTIF(SEQUENCE_COMPLETED,                N_ENABLE,    0, 0, "",               CPID_Null,              "0 0",  _("^BGSequence completed!"), "")
     MSG_CENTER_NOTIF(SEQUENCE_COUNTER,                  N_ENABLE,    0, 0, "",               CPID_Null,              "0 0",  _("^BGThere are more to go..."), "")
     MSG_CENTER_NOTIF(SEQUENCE_COUNTER_FEWMORE,          N_ENABLE,    0, 1, "f1",             CPID_Null,              "0 0",  _("^BGOnly %s^BG more to go..."), "")
index ee39b1881ab100937221ae3604d1cac68bb817ae..3b009b25637a296b28cf93d2978e858df993cf73 100644 (file)
@@ -12,6 +12,9 @@
 #include <client/autocvars.qh>
 #endif
 
+// Operator for bold notifications
+#define BOLD_OPERATOR "^BOLD"
+
 /** main types/groups of notifications */
 ENUMCLASS(MSG)
        /** "Global" AND "personal" announcer messages */
@@ -62,6 +65,7 @@ ENUMCLASS(CPID)
        CASE(CPID, MISSING_TEAMS)
        CASE(CPID, MISSING_PLAYERS)
        CASE(CPID, INSTAGIB_FINDAMMO)
+       CASE(CPID, CAMPAIGN_MESSAGE)
        CASE(CPID, MOTD)
        CASE(CPID, NIX)
        CASE(CPID, ONSLAUGHT)
@@ -160,7 +164,7 @@ void Create_Notification_Entity_Choice(entity notif,
 
 void Dump_Notifications(int fh, bool alsoprint);
 
-GENERIC_COMMAND(dumpnotifs, "Dump all notifications into notifications_dump.txt")
+GENERIC_COMMAND(dumpnotifs, "Dump all notifications into notifications_dump.txt", false)
 {
        switch (request)
        {
@@ -423,6 +427,7 @@ string BUFF_NAME(int i);
        ARG_CASE(ARG_CS,        "missing_teams", notif_arg_missing_teams(f1)) \
        ARG_CASE(ARG_CS,        "pass_key",      getcommandkey(_("drop flag"), "+use")) \
        ARG_CASE(ARG_CS,        "nade_key",      getcommandkey(_("throw nade"), "dropweapon")) \
+       ARG_CASE(ARG_CS,        "join_key",      getcommandkey(_("jump"), "+jump")) \
        ARG_CASE(ARG_CS,        "frag_ping",     notif_arg_frag_ping(true, f2)) \
        ARG_CASE(ARG_CS,        "frag_stats",    notif_arg_frag_stats(f2, f3, f4)) \
        /*ARG_CASE(ARG_CS,      "frag_pos",      ((Should_Print_Score_Pos(f1)) ? sprintf("\n^BG%s", Read_Score_Pos(f1)) : ""))*/ \
@@ -864,8 +869,8 @@ REGISTRY_END(Notifications)
 void ReplicateVars(bool would_destroy)
 {
        if (!would_destroy)
-               FOREACH(Notifications, it.nent_type == MSG_CHOICE, {
-                       string cvarname = sprintf("notification_%s", Get_Notif_CvarName(it));
+               FOREACH(Notifications, it.nent_type == MSG_CHOICE && (!it.nent_teamnum || it.nent_teamnum == NUM_TEAM_1), {
+                       string cvarname = strcat("notification_", Get_Notif_CvarName(it));
                        // NOTE: REPLICATE_SIMPLE can return;
                        REPLICATE_SIMPLE(it.cvar_value, cvarname);
                });
index 8eb2277d54ad9cd2b98c2d9dc5d2199725245c7c..63aa3dd955716971d60c1c7c794cf7ee5a4ad6b1 100644 (file)
@@ -7,6 +7,8 @@ void set_movetype(entity this, int mt)
        if (mt == MOVETYPE_PHYSICS || mt == MOVETYPE_PUSH || mt == MOVETYPE_FAKEPUSH) {
                this.move_qcphysics = false;
        }
+       if(!IL_CONTAINS(g_moveables, this))
+               IL_PUSH(g_moveables, this); // add it to the moveable entities list (even if it doesn't move!) logic: if an object never sets its movetype, we assume it never does anything notable
        this.movetype = (this.move_qcphysics) ? MOVETYPE_NONE : mt;
 }
 #elif defined(CSQC)
@@ -54,7 +56,7 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, bool applystepno
        if(applygravity)
        {
                this.move_didgravity = 1;
-               grav = dt * (PHYS_ENTGRAVITY(this) ? PHYS_ENTGRAVITY(this) : 1) * PHYS_GRAVITY(this);
+               grav = dt * (this.gravity ? this.gravity : 1) * PHYS_GRAVITY(this);
 
                if(!GAMEPLAYFIX_NOGRAVITYONGROUND || !IS_ONGROUND(this))
                {
@@ -324,10 +326,13 @@ void _Movetype_CheckWaterTransition(entity ent)  // SV_CheckWaterTransition
 
 void _Movetype_Impact(entity this, entity oth)  // SV_Impact
 {
-       if(gettouch(this))
+       if(!this && !oth)
+               return;
+
+       if(this.solid != SOLID_NOT && gettouch(this))
                gettouch(this)(this, oth);
 
-       if(gettouch(oth))
+       if(oth.solid != SOLID_NOT && gettouch(oth))
                gettouch(oth)(oth, this);
 }
 
@@ -408,25 +413,69 @@ void _Movetype_LinkEdict(entity this, bool touch_triggers)  // SV_LinkEdict
                _Movetype_LinkEdict_TouchAreaGrid(this);
 }
 
+int _Movetype_ContentsMask(entity this)  // SV_GenericHitSuperContentsMask
+{
+       if(this)
+       {
+               if(this.dphitcontentsmask)
+                       return this.dphitcontentsmask;
+               else if(this.solid == SOLID_SLIDEBOX)
+               {
+                       if(this.flags & 32) // TODO: FL_MONSTER
+                               return DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_MONSTERCLIP;
+                       else
+                               return DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP;
+               }
+               else if(this.solid == SOLID_CORPSE)
+                       return DPCONTENTS_SOLID | DPCONTENTS_BODY;
+               else if(this.solid == SOLID_TRIGGER)
+                       return DPCONTENTS_SOLID | DPCONTENTS_BODY;
+               else
+                       return DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
+       }
+       else
+               return DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
+}
+
 entity _Movetype_TestEntityPosition_ent;
 bool _Movetype_TestEntityPosition(vector ofs)  // SV_TestEntityPosition
 {
     entity this = _Movetype_TestEntityPosition_ent;
        vector org = this.origin + ofs;
 
-       int cont = this.dphitcontentsmask;
-       this.dphitcontentsmask = DPCONTENTS_SOLID;
-       tracebox(org, this.mins, this.maxs, org, ((this.move_movetype == MOVETYPE_FLY_WORLDONLY) ? MOVE_WORLDONLY : MOVE_NOMONSTERS), this);
-       this.dphitcontentsmask = cont;
-
-       if(trace_startsolid)
+       //int cont = this.dphitcontentsmask;
+       //this.dphitcontentsmask = DPCONTENTS_SOLID;
+       tracebox(org, this.mins, this.maxs, this.origin, ((this.move_movetype == MOVETYPE_FLY_WORLDONLY) ? MOVE_WORLDONLY : MOVE_NOMONSTERS), this);
+       //this.dphitcontentsmask = cont;
+       if(trace_dpstartcontents & _Movetype_ContentsMask(this))
                return true;
 
-       if(vdist(trace_endpos - this.origin, >, 0.0001))
-               this.origin = trace_endpos;
+       if(vlen2(trace_endpos - this.origin) >= 0.0001)
+       {
+               tracebox(trace_endpos, this.mins, this.maxs, trace_endpos, MOVE_NOMONSTERS, this);
+               if(!trace_startsolid)
+                       this.origin = trace_endpos;
+       }
        return false;
 }
 
+bool _Movetype_TestEntityPosition_Offset(int offset)
+{
+       // NOTE: expects _Movetype_TestEntityPosition_ent to be set to the correct entity
+       // returns true if stuck
+
+    // start at 2, since the first position has already been checked
+    for(int j = 2; j <= offset; ++j)
+    {
+       if(!_Movetype_TestEntityPosition('0 0 -1' * j))
+               return false;
+       if(!_Movetype_TestEntityPosition('0 0 1' * j))
+               return false;
+    }
+
+       return true;
+}
+
 int _Movetype_UnstickEntity(entity this)  // SV_UnstickEntity
 {
     _Movetype_TestEntityPosition_ent = this;
@@ -434,19 +483,14 @@ int _Movetype_UnstickEntity(entity this)  // SV_UnstickEntity
            return UNSTICK_FINE;
        }
        #define X(v) if (_Movetype_TestEntityPosition(v))
+       X('0  0  -1') X(' 0  0  1')
        X('-1  0  0') X(' 1  0  0')
        X(' 0 -1  0') X(' 0  1  0')
        X('-1 -1  0') X(' 1 -1  0')
        X('-1  1  0') X(' 1  1  0')
        #undef X
        {
-        #define X(i) \
-            if (_Movetype_TestEntityPosition('0 0 -1' * i)) \
-            if (_Movetype_TestEntityPosition('0 0 1' * i))
-        X(1) X(2) X(3) X(4) X(5) X(6) X(7) X(8)
-        X(9) X(10) X(11) X(12) X(13) X(14) X(15) X(16)
-        X(17)
-        #undef X
+        if(_Movetype_TestEntityPosition_Offset(rint((this.maxs.z - this.mins.z) * 0.36)))
         {
             LOG_DEBUGF("Can't unstick an entity (edict: %d, classname: %s, origin: %s)",
                 etof(this), this.classname, vtos(this.origin));
@@ -455,7 +499,7 @@ int _Movetype_UnstickEntity(entity this)  // SV_UnstickEntity
        }
        LOG_DEBUGF("Sucessfully unstuck an entity (edict: %d, classname: %s, origin: %s)",
                etof(this), this.classname, vtos(this.origin));
-       _Movetype_LinkEdict(this, true);
+       _Movetype_LinkEdict(this, false);
        return UNSTICK_FIXED;
 }
 
@@ -526,12 +570,10 @@ bool _Movetype_PushEntity(entity this, vector push, bool failonstartsolid, bool
 
        vector last_origin = this.origin;
 
-       if(dolink)
-               _Movetype_LinkEdict(this, true);
+       _Movetype_LinkEdict(this, dolink);
 
-       if(trace_fraction < 1)
-               if(this.solid >= SOLID_TRIGGER && trace_ent && (!IS_ONGROUND(this) || (this.groundentity != trace_ent)))
-                       _Movetype_Impact(this, trace_ent);
+       if((this.solid >= SOLID_TRIGGER && trace_fraction < 1 && (!IS_ONGROUND(this) || this.groundentity != trace_ent)))
+               _Movetype_Impact(this, trace_ent);
 
        return (this.origin == last_origin); // false if teleported by touch
 }
@@ -657,12 +699,14 @@ void Movetype_Physics_MatchServer(entity this, bool sloppy)
        Movetype_Physics_MatchTicrate(this, TICRATE, sloppy);
 }
 
+// saved .move_*
 .vector tic_origin;
 .vector tic_velocity;
 .int tic_flags;
 .vector tic_avelocity;
 .vector tic_angles;
 
+// saved .*
 .vector tic_saved_origin;
 .vector tic_saved_velocity;
 .int tic_saved_flags;
@@ -670,6 +714,8 @@ void Movetype_Physics_MatchServer(entity this, bool sloppy)
 .vector tic_saved_angles;
 void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy)  // SV_Physics_Entity
 {
+       // this hack exists to contain the physics feature
+       // (so entities can place themselves in the world and not need to update .tic_* themselves)
 #define X(s) \
        if(this.(s) != this.tic_saved_##s) \
                this.tic_##s = this.(s)
@@ -681,25 +727,21 @@ void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy)  // SV_Ph
        X(angles);
 #undef X
 
+       this.flags = this.tic_flags;
+       this.velocity = this.tic_velocity;
+       setorigin(this, this.tic_origin);
+       this.avelocity = this.tic_avelocity;
+       this.angles = this.tic_angles;
+
        if(tr <= 0)
        {
-               this.flags = this.tic_flags;
-               this.velocity = this.tic_velocity;
-               this.origin = this.tic_origin;
-               this.avelocity = this.tic_avelocity;
-               this.angles = this.tic_angles;
                Movetype_Physics_NoMatchServer(this);
-               this.tic_origin = this.origin;
-               this.tic_velocity = this.velocity;
-               this.tic_avelocity = this.avelocity;
-               this.tic_angles = this.angles;
-               this.tic_flags = this.flags;
-
-               this.tic_saved_flags = this.flags;
-               this.tic_saved_velocity = this.velocity;
-               this.tic_saved_origin = this.origin;
-               this.tic_saved_avelocity = this.avelocity;
-               this.tic_saved_angles = this.angles;
+
+               this.tic_saved_flags = this.tic_flags = this.flags;
+               this.tic_saved_velocity = this.tic_velocity = this.velocity;
+               this.tic_saved_origin = this.tic_origin = this.origin;
+               this.tic_saved_avelocity = this.tic_avelocity = this.avelocity;
+               this.tic_saved_angles = this.tic_angles = this.angles;
                return;
        }
 
@@ -712,23 +754,27 @@ void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy)  // SV_Ph
        if(!this.move_didgravity)
                this.move_didgravity = ((this.move_movetype == MOVETYPE_BOUNCE || this.move_movetype == MOVETYPE_TOSS) && !(this.tic_flags & FL_ONGROUND));
 
-       for (int i = 0; i < n; ++i)
+       for (int j = 0; j < n; ++j)
        {
-               this.flags = this.tic_flags;
-               this.velocity = this.tic_velocity;
-               setorigin(this, this.tic_origin);
-               this.avelocity = this.tic_avelocity;
-               this.angles = this.tic_angles;
                _Movetype_Physics_Frame(this, tr);
-               this.tic_origin = this.origin;
-               this.tic_velocity = this.velocity;
-               this.tic_avelocity = this.avelocity;
-               this.tic_angles = this.angles;
-               this.tic_flags = this.flags;
                if(wasfreed(this))
                        return;
        }
 
+       // update the physics fields
+       this.tic_origin = this.origin;
+       this.tic_velocity = this.velocity;
+       this.tic_avelocity = this.avelocity;
+       this.tic_angles = this.angles;
+       this.tic_flags = this.flags;
+
+       // restore their actual values
+       this.flags = this.tic_saved_flags;
+       this.velocity = this.tic_saved_velocity;
+       setorigin(this, this.tic_saved_origin);
+       //this.avelocity = this.tic_saved_avelocity;
+       this.angles = this.tic_saved_angles;
+
        this.avelocity = this.tic_avelocity;
 
        if(dt > 0 && this.move_movetype != MOVETYPE_NONE && !(this.tic_flags & FL_ONGROUND))
@@ -740,7 +786,7 @@ void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy)  // SV_Ph
                {
                        this.velocity_z -= (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE ? 0.5 : 1)
                            * dt
-                           * (this.gravity ? this.gravity : 1)
+                           * ((this.gravity) ? this.gravity : 1)
                            * PHYS_GRAVITY(this);
                }
 
@@ -752,16 +798,16 @@ void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy)  // SV_Ph
                }
                else
                {
-                       vector oldorg = this.origin;
-                       this.origin = this.tic_origin;
+                       setorigin(this, this.tic_origin);
                        _Movetype_PushEntityTrace(this, dt * this.velocity);
-                       this.origin = oldorg;
                        if(!trace_startsolid)
                                setorigin(this, trace_endpos);
+                       else
+                               setorigin(this, this.tic_saved_origin);
                }
 
                if(this.move_didgravity > 0 && GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE)
-                       this.velocity_z -= 0.5 * dt * (this.gravity ? this.gravity : 1) * PHYS_GRAVITY(this);
+                       this.velocity_z -= 0.5 * dt * ((this.gravity) ? this.gravity : 1) * PHYS_GRAVITY(this);
        }
        else
        {
@@ -770,6 +816,8 @@ void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy)  // SV_Ph
                setorigin(this, this.tic_origin);
        }
 
+       this.flags = this.tic_flags;
+
        this.tic_saved_flags = this.flags;
        this.tic_saved_velocity = this.velocity;
        this.tic_saved_origin = this.origin;
index 51da5e730c1169de3b2552b93953d0b68b0720b2..52610c58b27fe31604e3e4d1ca699cb4c0671e1a 100644 (file)
@@ -16,11 +16,17 @@ const int WATERLEVEL_SUBMERGED = 3;
 #define GAMEPLAYFIX_DOWNTRACEONGROUND(s)    STAT(GAMEPLAYFIX_DOWNTRACEONGROUND)
 #define GAMEPLAYFIX_EASIERWATERJUMP(s)      STAT(GAMEPLAYFIX_EASIERWATERJUMP)
 #define GAMEPLAYFIX_STEPDOWN(s)             STAT(GAMEPLAYFIX_STEPDOWN)
+#define GAMEPLAYFIX_STEPDOWN_MAXSPEED(s)    STAT(GAMEPLAYFIX_STEPDOWN_MAXSPEED)
 #define GAMEPLAYFIX_STEPMULTIPLETIMES(s)    STAT(GAMEPLAYFIX_STEPMULTIPLETIMES)
 #define GAMEPLAYFIX_UNSTICKPLAYERS(s)       STAT(GAMEPLAYFIX_UNSTICKPLAYERS)
 #define GAMEPLAYFIX_WATERTRANSITION(s)                 STAT(GAMEPLAYFIX_WATERTRANSITION)
+#define GAMEPLAYFIX_SLIDEMOVEPROJECTILES(s) STAT(GAMEPLAYFIX_SLIDEMOVEPROJECTILES)
+#define GAMEPLAYFIX_GRENADEBOUNCESLOPES(s)     STAT(GAMEPLAYFIX_GRENADEBOUNCESLOPES)
+#define GAMEPLAYFIX_NOAIRBORNCORPSE(s)                 STAT(GAMEPLAYFIX_NOAIRBORNCORPSE)
+#define NOAIRBORNCORPSE_ALLOWSUSPENDED(s)      STAT(NOAIRBORNCORPSE_ALLOWSUSPENDED)
 #define UPWARD_VELOCITY_CLEARS_ONGROUND(s)  STAT(GAMEPLAYFIX_UPVELOCITYCLEARSONGROUND)
 
+
 #define PHYS_STEPHEIGHT(s)                  STAT(MOVEVARS_STEPHEIGHT)
 #define PHYS_NOSTEP(s)                      STAT(NOSTEP)
 #define PHYS_JUMPSTEP(s)                    STAT(MOVEVARS_JUMPSTEP)
index fc3de0859bba0a22e91c87afec51e63384d8fd59..772eb1b070c59a2be0df4aa72df5bc904e115838 100644 (file)
@@ -2,19 +2,26 @@
 
 void _Movetype_Physics_Toss(entity this, float dt)  // SV_Physics_Toss
 {
-       if (IS_ONGROUND(this))
+       if(IS_ONGROUND(this))
        {
-               if (this.velocity.z >= 1 / 32 && UPWARD_VELOCITY_CLEARS_ONGROUND(this))
+               if(this.velocity.z >= (1 / 32) && UPWARD_VELOCITY_CLEARS_ONGROUND(this))
                {
+                       // don't stick to ground if onground and moving upward
                        UNSET_ONGROUND(this);
                }
-               else if (!this.groundentity)
+               else if(!this.groundentity || !GAMEPLAYFIX_NOAIRBORNCORPSE(this))
                {
                        return;
                }
-               else if (this.move_suspendedinair && wasfreed(this.groundentity))
+               else if(this.move_suspendedinair && wasfreed(this.groundentity))
                {
                        this.groundentity = NULL;
+                       if(NOAIRBORNCORPSE_ALLOWSUSPENDED(this))
+                               return;
+               }
+               else if(boxesoverlap(this.absmin, this.absmax, this.groundentity.absmin, this.groundentity.absmax))
+               {
+                       // don't slide if still touching the groundentity
                        return;
                }
        }
@@ -23,35 +30,37 @@ void _Movetype_Physics_Toss(entity this, float dt)  // SV_Physics_Toss
 
        _Movetype_CheckVelocity(this);
 
-       /*if (this.move_movetype == MOVETYPE_BOUNCE || this.move_movetype == MOVETYPE_TOSS)
+       if(this.move_movetype == MOVETYPE_BOUNCE || this.move_movetype == MOVETYPE_TOSS)
        {
-               this.move_didgravity = 1;
+               this.move_didgravity = true;
                this.velocity_z -= (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE ? 0.5 : 1)
                    * dt
-                   * (this.gravity ? this.gravity : 1)
+                   * ((this.gravity) ? this.gravity : 1)
                    * PHYS_GRAVITY(this);
-       }*/
+       }
 
-       if (this.move_movetype == MOVETYPE_BOUNCE || this.move_movetype == MOVETYPE_TOSS)
+       /*if (this.move_movetype == MOVETYPE_BOUNCE || this.move_movetype == MOVETYPE_TOSS)
        {
                this.move_didgravity = true;
                this.velocity_z -= (((this.gravity) ? this.gravity : 1) * PHYS_GRAVITY(this) * dt);
-       }
+       }*/
 
        this.angles = this.angles + this.avelocity * dt;
 
        float movetime = dt;
-       for (int bump = 0; bump < MAX_CLIP_PLANES && movetime > 0; ++bump)
+       for (int bump = 0; bump < MAX_CLIP_PLANES && movetime > 0; bump++)
        {
                vector move = this.velocity * movetime;
-               _Movetype_PushEntity(this, move, true, false);
+               if(!_Movetype_PushEntity(this, move, true, true))
+                       return;
                if (wasfreed(this))
                        return;
 
                if (trace_startsolid)
                {
                        _Movetype_UnstickEntity(this);
-                       _Movetype_PushEntity(this, move, false, false);
+                       if(!_Movetype_PushEntity(this, move, true, true))
+                               return;
                        if (wasfreed(this))
                                return;
                }
@@ -63,28 +72,36 @@ void _Movetype_Physics_Toss(entity this, float dt)  // SV_Physics_Toss
 
                if (this.move_movetype == MOVETYPE_BOUNCEMISSILE)
                {
-                       this.velocity = _Movetype_ClipVelocity(this.velocity, trace_plane_normal, 2.0);
+                       float bouncefac = (!this.bouncefactor) ? 1.0 : this.bouncefactor;
+                       this.velocity = _Movetype_ClipVelocity(this.velocity, trace_plane_normal, 1 + bouncefac);
                        UNSET_ONGROUND(this);
+                       if(!GAMEPLAYFIX_SLIDEMOVEPROJECTILES(this))
+                               movetime = 0;
                }
                else if (this.move_movetype == MOVETYPE_BOUNCE)
                {
-                       float bouncefac = this.bouncefactor;     if (!bouncefac)  bouncefac = 0.5;
-                       float bstop = this.bouncestop; if (!bstop) bstop = 60 / 800;
-                       bstop *= (this.gravity ? this.gravity : 1) * PHYS_GRAVITY(this);
+                       float bouncefac = (!this.bouncefactor) ? 0.5 : this.bouncefactor;
+                       float bstop = (!this.bouncestop) ? (60 / 800) : this.bouncestop;
+                       float grav = ((this.gravity) ? this.gravity : 1);
 
                        this.velocity = _Movetype_ClipVelocity(this.velocity, trace_plane_normal, 1 + bouncefac);
 
                        float d = trace_plane_normal * this.velocity;
-                       if (trace_plane_normal.z > 0.7 && d < bstop && d > -bstop)
+                       if(!GAMEPLAYFIX_GRENADEBOUNCESLOPES(this))
+                               d = this.velocity.z;
+                       if (trace_plane_normal.z > 0.7 && d < PHYS_GRAVITY(this) * bstop * grav)
                        {
                                SET_ONGROUND(this);
                                this.groundentity = trace_ent;
                                this.velocity = '0 0 0';
                                this.avelocity = '0 0 0';
+                               movetime = 0;
                        }
                        else
                        {
                                UNSET_ONGROUND(this);
+                               if(!GAMEPLAYFIX_SLIDEMOVEPROJECTILES(this))
+                                       movetime = 0;
                        }
                }
                else
@@ -98,24 +115,27 @@ void _Movetype_Physics_Toss(entity this, float dt)  // SV_Physics_Toss
                                        this.move_suspendedinair = true;
                                this.velocity = '0 0 0';
                                this.avelocity = '0 0 0';
+                               movetime = 0;
                        }
                        else
                        {
                                UNSET_ONGROUND(this);
+                               if(!GAMEPLAYFIX_SLIDEMOVEPROJECTILES(this))
+                                       movetime = 0;
                        }
                }
 
                // DP revision 8905 (just, WHY...)
-               if (this.move_movetype == MOVETYPE_BOUNCEMISSILE)
-                       break;
+               //if (this.move_movetype == MOVETYPE_BOUNCEMISSILE)
+                       //break;
 
                // DP revision 8918 (WHY...)
-               if (IS_ONGROUND(this))
-                       break;
+               //if (IS_ONGROUND(this))
+                       //break;
        }
 
-       //if (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE && this.move_didgravity > 0 && !IS_ONGROUND(this))
-       //      this.velocity_z -= 0.5 * dt * (this.gravity ? this.gravity : 1) * PHYS_GRAVITY(this);
+       if (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE && this.move_didgravity > 0 && !IS_ONGROUND(this))
+               this.velocity_z -= 0.5 * dt * ((this.gravity) ? this.gravity : 1) * PHYS_GRAVITY(this);
 
        _Movetype_CheckWaterTransition(this);
 }
index 13224f8a3443d022658aa9307dca2f522979d16f..e0d05d7c557c9ab112bb2e5c0d704a619d5a082c 100644 (file)
@@ -143,7 +143,8 @@ void _Movetype_Physics_Walk(entity this, float dt)  // SV_WalkMove
                        _Movetype_WallFriction(this, move_stepnormal);
        }
        // don't do the down move if stepdown is disabled, moving upward, not in water, or the move started offground or ended onground
-       else if (!GAMEPLAYFIX_STEPDOWN(this) || this.waterlevel >= 3 || start_velocity.z >= (1.0 / 32.0) || !oldonground || IS_ONGROUND(this))
+       else if (!GAMEPLAYFIX_STEPDOWN(this) || this.waterlevel >= 3 || start_velocity.z >= (1.0 / 32.0) 
+                               || !oldonground || IS_ONGROUND(this) || (GAMEPLAYFIX_STEPDOWN_MAXSPEED(this) && vdist(start_velocity, >=, GAMEPLAYFIX_STEPDOWN_MAXSPEED(this)) && !IS_ONSLICK(this)))
        {
                return;
        }
index 5ba6e82685b3204ce2caa5da04c5862253f0c974..cba24ff8e90f2e986ba041f2f8b0597c06b318ae 100644 (file)
@@ -40,7 +40,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);
+       float maxspd_mod = PHYS_HIGHSPEED(this) * ((this.swampslug.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);
@@ -53,13 +53,13 @@ void Physics_UpdateStats(entity this)
             : 0;
           STAT(MOVEVARS_AIRSPEEDLIMIT_NONQW, this) = Physics_ClientOption(this, "airspeedlimit_nonqw", autocvar_sv_airspeedlimit_nonqw) * maxspd_mod;
         }
-       bool vq3compat = autocvar_sv_vq3compat && autocvar_sv_vq3compat_changehitbox; // NOTE: these hitboxes are off by 1 due to engine differences
-       STAT(PL_MIN, this) = (vq3compat) ? '-15 -15 -24' : autocvar_sv_player_mins;
-       STAT(PL_MAX, this) = (vq3compat) ? '15 15 32' : autocvar_sv_player_maxs;
-       STAT(PL_VIEW_OFS, this) = (vq3compat) ? '0 0 26' : autocvar_sv_player_viewoffset;
-       STAT(PL_CROUCH_MIN, this) = (vq3compat) ? '-15 -15 -24' : autocvar_sv_player_crouch_mins;
-       STAT(PL_CROUCH_MAX, this) = (vq3compat) ? '15 15 16' : autocvar_sv_player_crouch_maxs;
-       STAT(PL_CROUCH_VIEW_OFS, this) = (vq3compat) ? '0 0 12' : autocvar_sv_player_crouch_viewoffset;
+       bool q3dfcompat = autocvar_sv_q3defragcompat && autocvar_sv_q3defragcompat_changehitbox; // NOTE: these hitboxes are off by 1 due to engine differences
+       STAT(PL_MIN, this) = (q3dfcompat) ? '-15 -15 -20' : autocvar_sv_player_mins;
+       STAT(PL_MAX, this) = (q3dfcompat) ? '15 15 36' : autocvar_sv_player_maxs;
+       STAT(PL_VIEW_OFS, this) = (q3dfcompat) ? '0 0 26' : autocvar_sv_player_viewoffset;
+       STAT(PL_CROUCH_MIN, this) = (q3dfcompat) ? '-15 -15 -20' : autocvar_sv_player_crouch_mins;
+       STAT(PL_CROUCH_MAX, this) = (q3dfcompat) ? '15 15 20' : autocvar_sv_player_crouch_maxs;
+       STAT(PL_CROUCH_VIEW_OFS, this) = (q3dfcompat) ? '0 0 12' : autocvar_sv_player_crouch_viewoffset;
 
        // old stats
        // fix some new settings
@@ -145,6 +145,9 @@ void PM_ClientMovement_UpdateStatus(entity this)
                do_crouch = false;
     }
 
+    MUTATOR_CALLHOOK(PlayerCanCrouch, this, do_crouch);
+    do_crouch = M_ARGV(1, bool);
+
        if (do_crouch) {
                if (!IS_DUCKED(this)) {
                        SET_DUCKED(this);
@@ -356,7 +359,7 @@ bool PlayerJump(entity this)
        }
 
        if (!doublejump)
-               if (!IS_ONGROUND(this) && !IS_ONSLICK(this))
+               if (!IS_ONGROUND(this))
                        return IS_JUMP_HELD(this);
 
        if(PHYS_TRACK_CANJUMP(this))
@@ -687,15 +690,10 @@ void PM_check_slick(entity this)
        if(!IS_ONGROUND(this))
                return;
 
-       if(!PHYS_SLICK_APPLYGRAVITY(this))
-               return;
-
+       trace_dphitq3surfaceflags = 0;
        tracebox(this.origin, this.mins, this.maxs, this.origin - '0 0 1', MOVE_NOMONSTERS, this);
        if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK)
-       {
-               UNSET_ONGROUND(this);
                SET_ONSLICK(this);
-       }
        else
                UNSET_ONSLICK(this);
 }
index cf272e5635a1eb66e72ec90810b864b10eff9f27..511ac46e66eedc7a8b35ce447b328b56f1a89ff7 100644 (file)
@@ -490,6 +490,21 @@ void PlayerStats_PlayerBasic(entity joiningplayer, float newrequest)
        }
 }
 
+SHUTDOWN(PlayerStats_PlayerBasic_Shutdown)
+{
+       if(PS_B_IN_DB >= 0)
+       {
+               db_close(PS_B_IN_DB);
+               PS_B_IN_DB = -1;
+       }
+
+       if(PS_GR_OUT_DB >= 0)
+       {
+               db_close(PS_GR_OUT_DB);
+               PS_GR_OUT_DB = -1;
+       }
+}
+
 void PlayerStats_PlayerBasic_CheckUpdate(entity joiningplayer)
 {
        // determine whether we should retrieve playerbasic information again
index d27dd0ed1f775038bb904e57327876a84d45314d..d41a097d6d642419ecd4f8218e071774ca516f47 100644 (file)
@@ -4,7 +4,7 @@
 //float PS_PM_IN_DB = -1;   // playerstats_prematch_in_db      // db for info COLLECTED at the beginning of a match
 int PS_GR_OUT_DB = -1;  // playerstats_gamereport_out_db   // db of info SENT at the end of a match
 //float PS_GR_IN_DB = -1;   // playerstats_gamereport_in_db    // db for info COLLECTED at the end of a match
-int PS_B_IN_DB = -1;    // playerstats_playerbasic_in_db   // db for info COLLECTED for basic player info (ELO)
+float PS_B_IN_DB = -1;    // playerstats_playerbasic_in_db   // db for info COLLECTED for basic player info (ELO)
 #endif
 
 #ifdef MENUQC
index 0f40acfc6856b65ad68446091b5a9142d3d16e13..14b22e991cceed2ad0bccdd2222ee899fbcab040 100644 (file)
@@ -5,7 +5,7 @@ void Inventory_delete(entity this);
 
 void PlayerState_attach(entity this)
 {
-       if (PS(this))
+       if (PS(this) && PS(this).m_client == this)
                return;
 
        this._ps = NEW(PlayerState, this);
index 488d44220b19e46ca047d18e11511e3d2d223e0b..c77ca16be2a432043f0d8808fa1506b25b0d3a7d 100644 (file)
@@ -16,18 +16,16 @@ const int MAX_CL_STATS = 256;
 // const int STAT_NAILS = 7;
 // const int STAT_ROCKETS = 8;
 // const int STAT_CELLS = 9;
-// const int STAT_ACTIVEWEAPON = 10;
 // const int STAT_ITEMS = 15; // .items | .items2 << 23 | serverflags << 28
 // const int STAT_VIEWHEIGHT = 16;
 
 #if defined(CSQC)
     #define g_stat_HEALTH getstati(STAT_HEALTH)
-    #define g_stat_ARMOR getstat_int(STAT_ARMOR)
-    #define g_stat_SHELLS getstat_int(STAT_SHELLS)
-    #define g_stat_NAILS getstat_int(STAT_NAILS)
-    #define g_stat_ROCKETS getstat_int(STAT_ROCKETS)
-    #define g_stat_CELLS getstat_int(STAT_CELLS)
-    #define g_stat_ACTIVEWEAPON getstat_int(STAT_ACTIVEWEAPON)
+    #define g_stat_ARMOR getstati(STAT_ARMOR)
+    #define g_stat_SHELLS getstati(STAT_SHELLS)
+    #define g_stat_NAILS getstati(STAT_NAILS)
+    #define g_stat_ROCKETS getstati(STAT_ROCKETS)
+    #define g_stat_CELLS getstati(STAT_CELLS)
     #define g_stat_ITEMS getstat_int(STAT_ITEMS)
     #define g_stat_VIEWHEIGHT getstati(STAT_VIEWHEIGHT)
 #elif defined(SVQC)
@@ -37,7 +35,6 @@ const int MAX_CL_STATS = 256;
     #define stat_NAILS ammo_nails
     #define stat_ROCKETS ammo_rockets
     #define stat_CELLS ammo_cells
-    #define stat_ACTIVEWEAPON weapon
     #define stat_ITEMS items
     #define stat_VIEWHEIGHT view_ofs_z
 #endif
@@ -85,6 +82,7 @@ REGISTER_STAT(NB_METERSTART, float)
 /** compressShotOrigin */
 REGISTER_STAT(SHOTORG, int)
 REGISTER_STAT(LEADLIMIT, float, autocvar_leadlimit)
+REGISTER_STAT(LEADLIMIT_AND_FRAGLIMIT, float, autocvar_leadlimit_and_fraglimit)
 
 REGISTER_STAT(LAST_PICKUP, float)
 REGISTER_STAT(HUD, int)
@@ -92,6 +90,7 @@ REGISTER_STAT(HIT_TIME, float)
 REGISTER_STAT(DAMAGE_DEALT_TOTAL, int)
 REGISTER_STAT(TYPEHIT_TIME, float)
 REGISTER_STAT(SUPERWEAPONS_FINISHED, float)
+REGISTER_STAT(AIR_FINISHED, float)
 REGISTER_STAT(VEHICLESTAT_HEALTH, int)
 REGISTER_STAT(VEHICLESTAT_SHIELD, int)
 REGISTER_STAT(VEHICLESTAT_ENERGY, int)
@@ -143,11 +142,13 @@ float autocvar_g_multijump_add;
 float autocvar_g_multijump_speed;
 float autocvar_g_multijump_maxspeed;
 float autocvar_g_multijump_dodging = 1;
+bool autocvar_g_multijump_client = true;
 #endif
 REGISTER_STAT(MULTIJUMP_DODGING, int, autocvar_g_multijump_dodging)
 REGISTER_STAT(MULTIJUMP_MAXSPEED, float, autocvar_g_multijump_maxspeed)
 REGISTER_STAT(MULTIJUMP_ADD, int, autocvar_g_multijump_add)
 REGISTER_STAT(MULTIJUMP_SPEED, float, autocvar_g_multijump_speed)
+REGISTER_STAT(MULTIJUMP_CLIENT, bool, autocvar_g_multijump_client)
 .int multijump_count;
 REGISTER_STAT(MULTIJUMP_COUNT, int, this.multijump_count)
 REGISTER_STAT(MULTIJUMP, int, autocvar_g_multijump)
@@ -190,17 +191,27 @@ REGISTER_STAT(BUGRIGS_STEER, float, g_bugrigs_steer)
 int autocvar_sv_gameplayfix_downtracesupportsongroundflag = 1;
 int autocvar_sv_gameplayfix_easierwaterjump = 1;
 int autocvar_sv_gameplayfix_stepdown = 2;
+float autocvar_sv_gameplayfix_stepdown_maxspeed = 0;
 int autocvar_sv_gameplayfix_stepmultipletimes = 1;
 int autocvar_sv_gameplayfix_unstickplayers = 1;
 int autocvar_sv_gameplayfix_fixedcheckwatertransition = 1;
+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;
 #endif
 REGISTER_STAT(GAMEPLAYFIX_DOWNTRACEONGROUND, int, autocvar_sv_gameplayfix_downtracesupportsongroundflag)
 REGISTER_STAT(GAMEPLAYFIX_EASIERWATERJUMP, int, autocvar_sv_gameplayfix_easierwaterjump)
 REGISTER_STAT(GAMEPLAYFIX_STEPDOWN, int, autocvar_sv_gameplayfix_stepdown)
+REGISTER_STAT(GAMEPLAYFIX_STEPDOWN_MAXSPEED, float, autocvar_sv_gameplayfix_stepdown_maxspeed)
 REGISTER_STAT(GAMEPLAYFIX_STEPMULTIPLETIMES, int, autocvar_sv_gameplayfix_stepmultipletimes)
 REGISTER_STAT(GAMEPLAYFIX_UNSTICKPLAYERS, int, autocvar_sv_gameplayfix_unstickplayers)
 REGISTER_STAT(GAMEPLAYFIX_UPVELOCITYCLEARSONGROUND, int, autocvar_sv_gameplayfix_upwardvelocityclearsongroundflag)
 REGISTER_STAT(GAMEPLAYFIX_WATERTRANSITION, int, autocvar_sv_gameplayfix_fixedcheckwatertransition)
+REGISTER_STAT(GAMEPLAYFIX_SLIDEMOVEPROJECTILES, int, autocvar_sv_gameplayfix_slidemoveprojectiles)
+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(MOVEVARS_JUMPSTEP, int, cvar("sv_jumpstep"))
 REGISTER_STAT(NOSTEP, int, cvar("sv_nostep"))
@@ -232,6 +243,7 @@ bool autocvar_sv_dodging_wall_dodging;
 bool autocvar_sv_dodging_air_dodging;
 float autocvar_sv_dodging_maxspeed;
 float autocvar_sv_dodging_air_maxspeed;
+bool autocvar_sv_dodging_clientselect;
 #endif
 
 #if 0
@@ -251,6 +263,7 @@ REGISTER_STAT(DODGING_WALL, bool, autocvar_sv_dodging_wall_dodging)
 REGISTER_STAT(DODGING_AIR, bool, autocvar_sv_dodging_air_dodging)
 REGISTER_STAT(DODGING_MAXSPEED, float, autocvar_sv_dodging_maxspeed)
 REGISTER_STAT(DODGING_AIR_MAXSPEED, float, autocvar_sv_dodging_air_maxspeed)
+REGISTER_STAT(DODGING_CLIENTSELECT, bool, autocvar_sv_dodging_clientselect)
 #endif
 /** cvar loopback */
 REGISTER_STAT(DODGING_FROZEN, int, autocvar_sv_dodging_frozen)
@@ -280,6 +293,11 @@ REGISTER_STAT(WALLJUMP_DELAY, float, autocvar_g_walljump_delay)
 REGISTER_STAT(WALLJUMP_FORCE, float, autocvar_g_walljump_force)
 REGISTER_STAT(LASTWJ, float)
 
+#ifdef SVQC
+float autocvar_g_bloodloss;
+#endif
+REGISTER_STAT(BLOODLOSS, float, autocvar_g_bloodloss)
+
 // freeze tag, clan arena
 REGISTER_STAT(REDALIVE, int)
 REGISTER_STAT(BLUEALIVE, int)
@@ -306,9 +324,9 @@ bool autocvar_sv_slick_applygravity;
 REGISTER_STAT(SLICK_APPLYGRAVITY, bool, autocvar_sv_slick_applygravity)
 
 #ifdef SVQC
-bool autocvar_sv_vq3compat;
+bool autocvar_sv_q3defragcompat;
 #endif
-REGISTER_STAT(VQ3COMPAT, bool, autocvar_sv_vq3compat)
+REGISTER_STAT(Q3DEFRAGCOMPAT, bool, autocvar_sv_q3defragcompat)
 
 #ifdef SVQC
 #include "physics/movetypes/movetypes.qh"
index 9d595b9591df90326e8d188c17ef2abfdc94f6ee..e1d9d583bfbec7c42e13a557dbc2b0642fa56d51 100644 (file)
@@ -23,6 +23,7 @@
     #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)
@@ -88,20 +89,18 @@ void ItemDraw(entity this)
             this.onground_time = time + 0.5;
         }
     }
-    else if (autocvar_cl_animate_items)
+    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)
         {
-               if(!this.item_simple)
-               this.angles += this.avelocity * frametime;
+               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)
         {
-               if(!this.item_simple)
-               this.angles += this.avelocity * frametime;
+               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)));
         }
@@ -176,8 +175,7 @@ NET_HANDLE(ENT_CLIENT_ITEM, bool isnew)
 
     if(sf & ISF_SIZE)
     {
-        float use_bigsize = ReadByte();
-        setsize(this, '-16 -16 0', (use_bigsize) ? '16 16 48' : '16 16 32');
+        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.
@@ -186,9 +184,8 @@ NET_HANDLE(ENT_CLIENT_ITEM, bool isnew)
 
         Item_SetAlpha(this);
 
-        if(autocvar_cl_fullbright_items)
-            if(this.ItemStatus & ITS_ALLOWFB)
-                this.effects |= EF_FULLBRIGHT;
+        if(this.ItemStatus & ITS_ALLOWFB)
+           this.effects |= EF_FULLBRIGHT;
 
         if(this.ItemStatus & ITS_GLOW)
         {
@@ -208,8 +205,6 @@ NET_HANDLE(ENT_CLIENT_ITEM, bool isnew)
         this.solid = SOLID_TRIGGER;
         //this.flags |= FL_ITEM;
 
-        bool use_bigsize = ReadByte();
-
         this.fade_end = ReadShort();
         this.fade_start = ReadShort();
         if(!warpzone_warpzones_exist && this.fade_start && !autocvar_cl_items_nofade)
@@ -260,7 +255,7 @@ NET_HANDLE(ENT_CLIENT_ITEM, bool isnew)
         precache_model(this.mdl);
         _setmodel(this, this.mdl);
 
-        setsize(this, '-16 -16 0', (use_bigsize) ? '16 16 48' : '16 16 32');
+        setsize(this, '-16 -16 0', '16 16 48');
     }
 
     if(sf & ISF_COLORMAP)
@@ -329,19 +324,14 @@ bool ItemSend(entity this, entity to, int sf)
                WriteAngle(MSG_ENTITY, this.angles_z);
        }
 
-       if(sf & ISF_SIZE)
-       {
-               Pickup p = this.itemdef;
-               WriteByte(MSG_ENTITY, p.instanceOfPowerup || p.instanceOfHealth || p.instanceOfArmor);
-       }
+       // 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)
        {
-               Pickup p = this.itemdef;
-               WriteByte(MSG_ENTITY, p.instanceOfPowerup || p.instanceOfHealth || p.instanceOfArmor);
                WriteShort(MSG_ENTITY, this.fade_end);
                WriteShort(MSG_ENTITY, this.fade_start);
 
@@ -746,7 +736,11 @@ bool Item_GiveAmmoTo(entity item, entity player, int res_type, float ammomax)
                        return false;
        }
        else if (g_weapon_stay == 2)
+       {
                ammomax = min(amount, ammomax);
+               if(player_amount >= ammomax)
+                       return false;
+       }
        else
                return false;
        if (amount < 0)
@@ -832,17 +826,17 @@ bool Item_GiveTo(entity item, entity player)
        if (item.strength_finished)
        {
                pickedup = true;
-               player.strength_finished = max(player.strength_finished, time) + item.strength_finished;
+               STAT(STRENGTH_FINISHED, player) = max(STAT(STRENGTH_FINISHED, player), time) + item.strength_finished;
        }
        if (item.invincible_finished)
        {
                pickedup = true;
-               player.invincible_finished = max(player.invincible_finished, time) + item.invincible_finished;
+               STAT(INVINCIBLE_FINISHED, player) = max(STAT(INVINCIBLE_FINISHED, player), time) + item.invincible_finished;
        }
        if (item.superweapons_finished)
        {
                pickedup = true;
-               player.superweapons_finished = max(player.superweapons_finished, time) + item.superweapons_finished;
+               STAT(SUPERWEAPONS_FINISHED, player) = max(STAT(SUPERWEAPONS_FINISHED, player), time) + item.superweapons_finished;
        }
 
        // always eat teamed entities
@@ -1485,10 +1479,11 @@ spawnfunc(target_items)
        if(!this.superweapons_finished)
                this.superweapons_finished = autocvar_g_balance_superweapons_time;
 
+       string str;
        int n = tokenize_console(this.netname);
        if(argv(0) == "give")
        {
-               this.netname = substring(this.netname, argv_start_index(1), argv_end_index(-1) - argv_start_index(1));
+               str = substring(this.netname, argv_start_index(1), argv_end_index(-1) - argv_start_index(1));
        }
        else
        {
@@ -1556,27 +1551,29 @@ spawnfunc(target_items)
                        itemprefix = valueprefix = string_null;
                }
 
-               this.netname = "";
-               this.netname = sprintf("%s %s%d %s", this.netname, itemprefix, boolean(this.items & IT_UNLIMITED_AMMO), "unlimited_weapon_ammo");
-               this.netname = sprintf("%s %s%d %s", this.netname, itemprefix, boolean(this.items & IT_UNLIMITED_SUPERWEAPONS), "unlimited_superweapons");
-               this.netname = sprintf("%s %s%d %s", this.netname, valueprefix, this.strength_finished * boolean(this.items & ITEM_Strength.m_itemid), "strength");
-               this.netname = sprintf("%s %s%d %s", this.netname, valueprefix, this.invincible_finished * boolean(this.items & ITEM_Shield.m_itemid), "invincible");
-               this.netname = sprintf("%s %s%d %s", this.netname, valueprefix, this.superweapons_finished * boolean(this.items & IT_SUPERWEAPON), "superweapons");
-               this.netname = sprintf("%s %s%d %s", this.netname, itemprefix, boolean(this.items & ITEM_Jetpack.m_itemid), "jetpack");
-               this.netname = sprintf("%s %s%d %s", this.netname, itemprefix, boolean(this.items & ITEM_JetpackRegen.m_itemid), "fuel_regen");
-               if(GetResource(this, RES_SHELLS) != 0) this.netname = sprintf("%s %s%d %s", this.netname, valueprefix, max(0, GetResource(this, RES_SHELLS)), "shells");
-               if(GetResource(this, RES_BULLETS) != 0) this.netname = sprintf("%s %s%d %s", this.netname, valueprefix, max(0, GetResource(this, RES_BULLETS)), "nails");
-               if(GetResource(this, RES_ROCKETS) != 0) this.netname = sprintf("%s %s%d %s", this.netname, valueprefix, max(0, GetResource(this, RES_ROCKETS)), "rockets");
-               if(GetResource(this, RES_CELLS) != 0) this.netname = sprintf("%s %s%d %s", this.netname, valueprefix, max(0, GetResource(this, RES_CELLS)), "cells");
-               if(GetResource(this, RES_PLASMA) != 0) this.netname = sprintf("%s %s%d %s", this.netname, valueprefix, max(0, GetResource(this, RES_PLASMA)), "plasma");
-               if(GetResource(this, RES_FUEL) != 0) this.netname = sprintf("%s %s%d %s", this.netname, valueprefix, max(0, GetResource(this, RES_FUEL)), "fuel");
-               if(GetResource(this, RES_HEALTH) != 0) this.netname = sprintf("%s %s%d %s", this.netname, valueprefix, max(0, GetResource(this, RES_HEALTH)), "health");
-               if(GetResource(this, RES_ARMOR) != 0) this.netname = sprintf("%s %s%d %s", this.netname, valueprefix, max(0, GetResource(this, RES_ARMOR)), "armor");
-               FOREACH(Buffs, it != BUFF_Null && (STAT(BUFFS, this) & it.m_itemid), this.netname = sprintf("%s %s%d %s", this.netname, valueprefix, max(0, STAT(BUFF_TIME, this)), it.netname));
-               FOREACH(Weapons, it != WEP_Null, this.netname = sprintf("%s %s%d %s", this.netname, itemprefix, !!(STAT(WEAPONS, this) & (it.m_wepset)), it.netname));
-       }
-       this.netname = strzone(this.netname);
-       //print(this.netname, "\n");
+               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)
@@ -1622,28 +1619,36 @@ float GiveWeapon(entity e, float wpn, float op, float val)
 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:
-                       STAT(BUFF_TIME, e) = val;
+                       new_buff_time = val;
                        break;
                case OP_MIN:
-                       STAT(BUFF_TIME, e) = max(STAT(BUFF_TIME, e), val);
+                       new_buff_time = max(new_buff_time, val);
                        break;
                case OP_MAX:
-                       STAT(BUFF_TIME, e) = min(STAT(BUFF_TIME, e), val);
+                       new_buff_time = min(new_buff_time, val);
                        break;
                case OP_PLUS:
-                       STAT(BUFF_TIME, e) += val;
+                       new_buff_time += val;
                        break;
                case OP_MINUS:
-                       STAT(BUFF_TIME, e) -= val;
+                       new_buff_time -= val;
                        break;
        }
-       if(STAT(BUFF_TIME, e) <= 0)
+       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);
 }
@@ -1674,17 +1679,19 @@ void GiveRot(entity e, float v0, float v1, .float rotfield, float rottime, .floa
 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: SetResource(e, res_type, val); break;
-               case OP_MIN: SetResource(e, res_type, max(v0, val)); break;
-               case OP_MAX: SetResource(e, res_type, min(v0, val)); break;
-               case OP_PLUS: SetResource(e, res_type, v0 + val); break;
-               case OP_MINUS: SetResource(e, res_type, v0 - val); break;
-       }
-       int v1 = GetResource(e, res_type);
-       return v0 != v1;
+               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)
@@ -1710,16 +1717,16 @@ float GiveItems(entity e, float beginarg, float endarg)
                }
        }
 
-       e.strength_finished = max(0, e.strength_finished - time);
-       e.invincible_finished = max(0, e.invincible_finished - time);
-       e.superweapons_finished = max(0, e.superweapons_finished - time);
+       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, strength_finished);
-       PREGIVE(e, invincible_finished);
-       PREGIVE(e, superweapons_finished);
+       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);
@@ -1758,9 +1765,9 @@ float GiveItems(entity e, float beginarg, float endarg)
                                continue;
                        case "ALL":
                                got += GiveBit(e, items, ITEM_JetpackRegen.m_itemid, op, val);
-                               got += GiveValue(e, strength_finished, op, val);
-                               got += GiveValue(e, invincible_finished, op, val);
-                               got += GiveValue(e, superweapons_finished, 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);
@@ -1795,13 +1802,13 @@ float GiveItems(entity e, float beginarg, float endarg)
                                got += GiveBit(e, items, ITEM_JetpackRegen.m_itemid, op, val);
                                break;
                        case "strength":
-                               got += GiveValue(e, strength_finished, op, val);
+                               got += GiveValue(e, stat_STRENGTH_FINISHED, op, val);
                                break;
                        case "invincible":
-                               got += GiveValue(e, invincible_finished, op, val);
+                               got += GiveValue(e, stat_INVINCIBLE_FINISHED, op, val);
                                break;
                        case "superweapons":
-                               got += GiveValue(e, superweapons_finished, op, val);
+                               got += GiveValue(e, stat_SUPERWEAPONS_FINISHED, op, val);
                                break;
                        case "cells":
                                got += GiveResourceValue(e, RES_CELLS, op, val);
@@ -1829,7 +1836,7 @@ float GiveItems(entity e, float beginarg, float endarg)
                                got += GiveResourceValue(e, RES_FUEL, op, val);
                                break;
                        default:
-                               FOREACH(Buffs, it != BUFF_Null && Buff_UndeprecateName(cmd) == it.netname,
+                               FOREACH(Buffs, it != BUFF_Null && buff_Available(it) && Buff_UndeprecateName(cmd) == it.netname,
                                {
                                        got += GiveBuff(e, it, op, val);
                                        break;
@@ -1854,9 +1861,9 @@ float GiveItems(entity e, float beginarg, float endarg)
                        if(STAT(WEAPONS, e) & (it.m_wepset))
                                it.wr_init(it);
        });
-       POSTGIVE_VALUE(e, strength_finished, 1, SND_POWERUP, SND_POWEROFF);
-       POSTGIVE_VALUE(e, invincible_finished, 1, SND_Shield, SND_POWEROFF);
-       //POSTGIVE_VALUE(e, superweapons_finished, 1, SND_Null, SND_Null);
+       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);
@@ -1866,22 +1873,22 @@ float GiveItems(entity e, float beginarg, float endarg)
        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(e.superweapons_finished <= 0)
+       if(STAT(SUPERWEAPONS_FINISHED, e) <= 0)
                if(!g_weaponarena && (STAT(WEAPONS, e) & WEPSET_SUPERWEAPONS))
-                       e.superweapons_finished = autocvar_g_balance_superweapons_time;
+                       STAT(SUPERWEAPONS_FINISHED, e) = autocvar_g_balance_superweapons_time;
 
-       if(e.strength_finished <= 0)
-               e.strength_finished = 0;
+       if(STAT(STRENGTH_FINISHED, e) <= 0)
+               STAT(STRENGTH_FINISHED, e) = 0;
        else
-               e.strength_finished += time;
-       if(e.invincible_finished <= 0)
-               e.invincible_finished = 0;
+               STAT(STRENGTH_FINISHED, e) += time;
+       if(STAT(INVINCIBLE_FINISHED, e) <= 0)
+               STAT(INVINCIBLE_FINISHED, e) = 0;
        else
-               e.invincible_finished += time;
-       if(e.superweapons_finished <= 0)
-               e.superweapons_finished = 0;
+               STAT(INVINCIBLE_FINISHED, e) += time;
+       if(STAT(SUPERWEAPONS_FINISHED, e) <= 0)
+               STAT(SUPERWEAPONS_FINISHED, e) = 0;
        else
-               e.superweapons_finished += time;
+               STAT(SUPERWEAPONS_FINISHED, e) += time;
        if(STAT(BUFF_TIME, e) <= 0)
                STAT(BUFF_TIME, e) = 0;
        else
index 5c916866f8691f840d34f43ccdf39a51a7d5f95c..7b0d760df6e61afe908d4aaaf17b3263d1f022ca 100644 (file)
@@ -36,7 +36,6 @@ 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';
-float  autocvar_cl_fullbright_items = 0;
 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;
index 3d0528a2511825742d89fd27ac0ecfc727a1d440..9dedc89cb780253a184b45ed3f1dba2da1744d9b 100644 (file)
@@ -57,7 +57,7 @@ REGISTRY_CHECK(Turrets)
        #define TR_CONFIG_END()
 #endif
 
-GENERIC_COMMAND(dumpturrets, "Dump all turrets into turrets_dump.txt")
+GENERIC_COMMAND(dumpturrets, "Dump all turrets into turrets_dump.txt", false)
 {
     switch(request)
     {
index fff1b3991576f178bcffa4b6b33015cbb4b43649..d8587b14a809954a433f033fe88e5e33245c49d8 100644 (file)
@@ -402,7 +402,7 @@ void load_unit_settings(entity ent, bool is_reload)
        ent.ammo_max             *= ent.turret_scale_ammo;
        ent.ammo_recharge        *= ent.turret_scale_ammo;
        ent.aim_speed            *= ent.turret_scale_aim;
-       ent.health               *= ent.turret_scale_health;
+       SetResourceExplicit(ent, RES_HEALTH, GetResource(ent, RES_HEALTH) * ent.turret_scale_health);
        ent.respawntime          *= ent.turret_scale_respawn;
        ent.shot_dmg             *= ent.turret_scale_damage;
        ent.shot_refire          *= ent.turret_scale_refire;
index 7713679f3ce57a2cbaa1deb6cd9f663a3245e6d0..3b7513013dc036475976c872d628ec572d8a4b67 100644 (file)
@@ -316,20 +316,7 @@ string ScoreString(int pFlags, float pValue)
        if((pValue == 0) && (pFlags & (SFL_HIDE_ZERO | SFL_RANK | SFL_TIME)))
                valstr = "";
        else if(pFlags & SFL_RANK)
-       {
-               valstr = ftos(pValue);
-               l = strlen(valstr);
-               if((l >= 2) && (substring(valstr, l - 2, 1) == "1"))
-                       valstr = strcat(valstr, "th");
-               else if(substring(valstr, l - 1, 1) == "1")
-                       valstr = strcat(valstr, "st");
-               else if(substring(valstr, l - 1, 1) == "2")
-                       valstr = strcat(valstr, "nd");
-               else if(substring(valstr, l - 1, 1) == "3")
-                       valstr = strcat(valstr, "rd");
-               else
-                       valstr = strcat(valstr, "th");
-       }
+               valstr = count_ordinal(pValue);
        else if(pFlags & SFL_TIME)
                valstr = TIME_ENCODED_TOSTRING(pValue);
        else
@@ -457,7 +444,7 @@ STATIC_INIT(compressShortVector)
                l *= f;
        }
 
-       if(cvar("developer"))
+       if(cvar("developer") > 0)
        {
                LOG_TRACE("Verifying vector compression table...");
                for(i = 0x0F00; i < 0xFFFF; ++i)
index 6785a9f21536b0dc1f312cdb65bdae9bdc405f97..3ec02901dc14c06435cc35f4d5b738ad940f7add 100644 (file)
@@ -245,7 +245,7 @@ void vehicles_projectile_explode_use(entity this, entity actor, entity trigger)
        vehicles_projectile_explode(this, trigger);
 }
 
-entity vehicles_projectile(entity this, string _mzlfx, Sound _mzlsound,
+entity vehicles_projectile(entity this, entity _mzlfx, Sound _mzlsound,
                                                   vector _org, vector _vel,
                                                   float _dmg, float _radi, float _force,  float _size,
                                                   int _deahtype, float _projtype, float _health,
@@ -290,8 +290,8 @@ entity vehicles_projectile(entity this, string _mzlfx, Sound _mzlsound,
        if(_mzlsound != SND_Null)
                sound (this, CH_WEAPON_A, _mzlsound, VOL_BASE, ATTEN_NORM);
 
-       if(_mzlfx)
-               Send_Effect_(_mzlfx, proj.origin, proj.velocity, 1);
+       if(_mzlfx != EFFECT_Null)
+               Send_Effect(_mzlfx, proj.origin, proj.velocity, 1);
 
        setsize (proj, '-1 -1 -1' * _size, '1 1 1' * _size);
 
@@ -852,7 +852,7 @@ void vehicles_exit(entity vehic, bool eject)
                set_movetype(player, MOVETYPE_WALK);
                player.effects             &= ~EF_NODRAW;
                player.teleportable             = TELEPORT_NORMAL;
-               player.alpha                    = 1;
+               player.alpha                    = default_player_alpha;
                player.PlayerPhysplug   = func_null;
                player.vehicle                  = NULL;
                player.view_ofs                 = STAT(PL_VIEW_OFS, player);
index 7c0e61cd6e662329db5d4eea736d8a2b347ebe56..224f96564e7a0fc7347decf2350fc268b8af92e6 100644 (file)
@@ -1,5 +1,11 @@
 #include "bumblebee.qh"
 
+#ifdef GAMEQC
+
+#ifdef SVQC
+       #include <common/mutators/mutator/instagib/sv_instagib.qh>
+#endif
+
 const float BRG_SETUP = 2;
 const float BRG_START = 4;
 const float BRG_END = 8;
@@ -568,8 +574,9 @@ bool bumblebee_pilot_frame(entity this, float dt)
                                                }
                                                else if(IS_CLIENT(trace_ent))
                                                {
-                                                       if(GetResource(trace_ent, RES_ARMOR) <= autocvar_g_vehicle_bumblebee_healgun_amax && autocvar_g_vehicle_bumblebee_healgun_aps)
-                                                               GiveResourceWithLimit(trace_ent, RES_ARMOR, autocvar_g_vehicle_bumblebee_healgun_aps * dt, autocvar_g_vehicle_bumblebee_healgun_amax);
+                                                       float maxarmor = ((MUTATOR_IS_ENABLED(mutator_instagib)) ? autocvar_g_instagib_extralives : autocvar_g_vehicle_bumblebee_healgun_amax);
+                                                       if(GetResource(trace_ent, RES_ARMOR) <= maxarmor && autocvar_g_vehicle_bumblebee_healgun_aps)
+                                                               GiveResourceWithLimit(trace_ent, RES_ARMOR, autocvar_g_vehicle_bumblebee_healgun_aps * dt, maxarmor);
                                                }
                                        }
                                }
@@ -965,3 +972,5 @@ METHOD(Bumblebee, vr_setup, void(Bumblebee thisveh, entity instance))
 }
 
 #endif
+
+#endif
index 9299e938d0a2781cfa0dcb25995690316d599b11..81fd93aa02d5e2da6178ac312b0a056cbcfee878 100644 (file)
@@ -9,7 +9,7 @@ REGISTER_NET_LINKED(ENT_CLIENT_BUMBLE_RAYGUN)
 void bumblebee_fire_cannon(entity this, entity _gun, string _tagname, entity _owner)
 {
     vector v = gettaginfo(_gun, gettagindex(_gun, _tagname));
-    vehicles_projectile(this, EFFECT_BIGPLASMA_MUZZLEFLASH.eent_eff_name, SND_VEH_BUMBLEBEE_FIRE,
+    vehicles_projectile(this, EFFECT_BIGPLASMA_MUZZLEFLASH, SND_VEH_BUMBLEBEE_FIRE,
                         v, normalize(v_forward + randomvec() * autocvar_g_vehicle_bumblebee_cannon_spread) * autocvar_g_vehicle_bumblebee_cannon_speed,
                         autocvar_g_vehicle_bumblebee_cannon_damage, autocvar_g_vehicle_bumblebee_cannon_radius, autocvar_g_vehicle_bumblebee_cannon_force,  0,
                         DEATH_VH_BUMB_GUN.m_id, PROJECTILE_BUMBLE_GUN, 0, true, true, _owner);
index e2a2593948130a5d3e896dd3e779fd4c3345ecd7..ff124d0b496bf42effdc92c167d0a052716b6ad6 100644 (file)
@@ -1,5 +1,7 @@
 #include "racer.qh"
 
+#ifdef GAMEQC
+
 #ifdef SVQC
 #include <common/mapobjects/trigger/impulse.qh>
 
@@ -77,26 +79,26 @@ vector autocvar_g_vehicle_racer_bouncepain = '200 0.15 150';
 
 .float racer_watertime;
 
-var vector racer_force_from_tag(entity this, string tag_name, float spring_length, float max_power);
+var .vector(entity this, string tag_name, float spring_length, float max_power) racer_force_from_tag;
 
-void racer_align4point(entity this, float _delta)
+void racer_align4point(entity this, entity player, float _delta)
 {
        vector push_vector;
        float fl_push, fr_push, bl_push, br_push;
 
-       push_vector  = racer_force_from_tag(this, "tag_engine_fr", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower);
+       push_vector  = this.racer_force_from_tag(this, "tag_engine_fr", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower);
        fr_push   = force_fromtag_normpower;
        //vehicles_sweap_collision(force_fromtag_origin, this.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier);
 
-       push_vector += racer_force_from_tag(this, "tag_engine_fl", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower);
+       push_vector += this.racer_force_from_tag(this, "tag_engine_fl", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower);
        fl_push   = force_fromtag_normpower;
        //vehicles_sweap_collision(force_fromtag_origin, this.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier);
 
-       push_vector += racer_force_from_tag(this, "tag_engine_br", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower);
+       push_vector += this.racer_force_from_tag(this, "tag_engine_br", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower);
        br_push   = force_fromtag_normpower;
        //vehicles_sweap_collision(force_fromtag_origin, this.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier);
 
-       push_vector += racer_force_from_tag(this, "tag_engine_bl", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower);
+       push_vector += this.racer_force_from_tag(this, "tag_engine_bl", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower);
        bl_push   = force_fromtag_normpower;
        //vehicles_sweap_collision(force_fromtag_origin, this.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier);
 
@@ -109,7 +111,7 @@ void racer_align4point(entity this, float _delta)
        {
                uforce = autocvar_g_vehicle_racer_water_upforcedamper;
 
-               if(PHYS_INPUT_BUTTON_CROUCH(this.owner) && time < this.air_finished)
+               if(PHYS_INPUT_BUTTON_CROUCH(player) && time < this.air_finished)
                        this.velocity_z += 30;
                else
                        this.velocity_z += 200;
@@ -161,6 +163,8 @@ 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;
 
        if(IS_DEAD(vehic))
@@ -169,7 +173,7 @@ bool racer_frame(entity this, float dt)
                return;
        }
 
-       racer_align4point(vehic, dt);
+       racer_align4point(vehic, player, dt);
 
        PHYS_INPUT_BUTTON_ZOOM(player) = PHYS_INPUT_BUTTON_CROUCH(player) = false;
 
@@ -251,6 +255,7 @@ bool racer_frame(entity this, float dt)
                }
 
 #ifdef SVQC
+               // NOTE: reusing .invincible_finished here as delay counter for the smoke effect
                if(vehic.invincible_finished < time)
                {
                        traceline(vehic.origin, vehic.origin - '0 0 256', MOVE_NORMAL, vehic);
@@ -260,6 +265,7 @@ bool racer_frame(entity this, float dt)
                        vehic.invincible_finished = time + 0.1 + (random() * 0.1);
                }
 
+               // NOTE: reusing .strength_finished here as a sound delay counter
                if(vehic.strength_finished < time)
                {
                        vehic.strength_finished = time + 10.922667; //soundlength("vehicles/racer_boost.wav");
@@ -291,15 +297,6 @@ bool racer_frame(entity this, float dt)
        if (PHYS_INPUT_BUTTON_ATCK(player))
        if (wep1.wr_checkammo1(wep1, vehic, weaponentity))
        {
-               string tagname = (vehic.cnt)
-                   ? (vehic.cnt = 0, "tag_fire1")
-                   : (vehic.cnt = 1, "tag_fire2");
-               vector org = gettaginfo(vehic, gettagindex(vehic, tagname));
-               w_shotorg = org;
-               w_shotdir = v_forward;
-               // Fix z-aim (for chase mode)
-               crosshair_trace(player);
-               w_shotdir.z = normalize(trace_endpos - org).z * 0.5;
                wep1.wr_think(wep1, vehic, weaponentity, 1);
        }
 
@@ -380,7 +377,9 @@ bool racer_frame(entity this, float dt)
 
 void racer_think(entity this)
 {
-       this.nextthink = time + autocvar_g_vehicle_racer_thinkrate;
+       float dt = autocvar_g_vehicle_racer_thinkrate;
+
+       this.nextthink = time + dt;
 
        tracebox(this.origin, this.mins, this.maxs, this.origin - ('0 0 1' * autocvar_g_vehicle_racer_springlength), MOVE_NOMONSTERS, this);
 
@@ -398,12 +397,12 @@ void racer_think(entity this)
                this.velocity_z += 200;
        }
 
-       this.velocity += df * autocvar_g_vehicle_racer_thinkrate;
+       this.velocity += df * dt;
        if(this.velocity_z > 0)
-               this.velocity_z *= 1 - forced * autocvar_g_vehicle_racer_thinkrate;
+               this.velocity_z *= 1 - forced * dt;
 
-       this.angles_x *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * autocvar_g_vehicle_racer_thinkrate);
-       this.angles_z *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * autocvar_g_vehicle_racer_thinkrate);
+       this.angles_x *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * dt);
+       this.angles_z *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * dt);
 
        CSQCMODEL_AUTOUPDATE(this);
 }
@@ -483,7 +482,7 @@ void racer_blowup_think(entity this)
        if(time >= this.delay)
                racer_blowup(this);
 
-       CSQCMODEL_AUTOUPDATE(this);
+       //CSQCMODEL_AUTOUPDATE(this);
 }
 
 void racer_deadtouch(entity this, entity toucher)
@@ -512,35 +511,23 @@ METHOD(Racer, vr_impact, void(Racer thisveh, entity instance))
 
 METHOD(Racer, vr_enter, void(Racer thisveh, entity instance))
 {
-#ifdef SVQC
     set_movetype(instance, MOVETYPE_BOUNCE);
+#ifdef SVQC
     instance.owner.vehicle_health = (GetResource(instance, RES_HEALTH) / autocvar_g_vehicle_racer_health)  * 100;
     instance.owner.vehicle_shield = (instance.vehicle_shield / autocvar_g_vehicle_racer_shield)  * 100;
 
     if(instance.owner.flagcarried)
        setorigin(instance.owner.flagcarried, '-190 0 96');
-#elif defined(CSQC)
-    set_movetype(instance, MOVETYPE_BOUNCE);
 #endif
 }
 
 METHOD(Racer, vr_spawn, void(Racer thisveh, entity instance))
 {
 #ifdef SVQC
-    if(instance.scale != 0.5)
-    {
-        if(autocvar_g_vehicle_racer_hovertype != 0)
-            racer_force_from_tag = vehicles_force_fromtag_maglev;
-        else
-            racer_force_from_tag = vehicles_force_fromtag_hover;
-
-        // FIXME: this be hakkz, fix the models insted (scale body, add tag_viewport to the hudmodel).
-        instance.scale = 0.5;
-        setattachment(instance.vehicle_hudmodel, instance, "");
-        setattachment(instance.vehicle_viewport, instance, "tag_viewport");
-
-        instance.mass                     = 900;
-    }
+    if(autocvar_g_vehicle_racer_hovertype != 0)
+        instance.racer_force_from_tag = vehicles_force_fromtag_maglev;
+    else
+        instance.racer_force_from_tag = vehicles_force_fromtag_hover;
 
     setthink(instance, racer_think);
     instance.nextthink   = time;
@@ -550,7 +537,11 @@ METHOD(Racer, vr_spawn, void(Racer thisveh, entity instance))
     set_movetype(instance, MOVETYPE_TOSS);
     instance.solid               = SOLID_SLIDEBOX;
     instance.delay               = time;
-    instance.scale               = 0.5;
+    instance.scale               = 0.5; // FIXME: this be hakkz, fix the models insted (scale body, add tag_viewport to the hudmodel).
+    instance.mass                = 900;
+
+    setattachment(instance.vehicle_hudmodel, instance, "");
+    setattachment(instance.vehicle_viewport, instance, "tag_viewport");
 
     instance.PlayerPhysplug = racer_frame;
 
@@ -611,8 +602,7 @@ METHOD(Racer, vr_setup, void(Racer thisveh, entity instance))
     instance.vehicle_exit = racer_exit;
 
     // we have no need to network energy
-    if(autocvar_g_vehicle_racer_energy)
-    if(autocvar_g_vehicle_racer_energy_regen)
+    if(autocvar_g_vehicle_racer_energy && autocvar_g_vehicle_racer_energy_regen)
         instance.vehicle_flags |= VHF_ENERGYREGEN;
 
     if(autocvar_g_vehicle_racer_shield)
@@ -634,3 +624,5 @@ METHOD(Racer, vr_setup, void(Racer thisveh, entity instance))
     AuxiliaryXhair[0].axh_image = vCROSS_LOCK; // Rocket
 #endif
 }
+
+#endif
index 0e7222eb2403d847db29476e04fead2a60ad3829..473f9a7574a32c5cf54da9b0053db68461fd6a95 100644 (file)
@@ -14,10 +14,20 @@ METHOD(RacerAttack, wr_think, void(entity thiswep, entity actor, .entity weapone
             veh.vehicle_energy -= autocvar_g_vehicle_racer_cannon_cost;
             veh.wait = time;
         }
+        string tagname = (veh.cnt)
+            ? (veh.cnt = 0, "tag_fire1")
+            : (veh.cnt = 1, "tag_fire2");
+        vector vshotorg = gettaginfo(veh, gettagindex(veh, tagname));
+        w_shotorg = vshotorg;
+        w_shotdir = v_forward;
+        // Fix z-aim (for chase mode)
+        crosshair_trace(player);
+        w_shotdir.z = normalize(trace_endpos - vshotorg).z * 0.5;
+
         if (isPlayer) W_SetupShot_Dir(player, weaponentity, v_forward, false, 0, SND_Null, CH_WEAPON_B, 0, DEATH_VH_WAKI_GUN.m_id);
         vector org = w_shotorg;
         vector dir = w_shotdir;
-        entity bolt = vehicles_projectile(veh, EFFECT_RACER_MUZZLEFLASH.eent_eff_name, SND_LASERGUN_FIRE,
+        entity bolt = vehicles_projectile(veh, EFFECT_RACER_MUZZLEFLASH, SND_LASERGUN_FIRE,
                                org, normalize(v_forward + randomvec() * autocvar_g_vehicle_racer_cannon_spread) * autocvar_g_vehicle_racer_cannon_speed,
                                autocvar_g_vehicle_racer_cannon_damage, autocvar_g_vehicle_racer_cannon_radius, autocvar_g_vehicle_racer_cannon_force,  0,
                                DEATH_VH_WAKI_GUN.m_id, PROJECTILE_WAKICANNON, 0, true, true, player);
@@ -45,7 +55,7 @@ void racer_rocket_groundhugger(entity this);
 
 void racer_fire_rocket(entity player, vector org, vector dir, entity trg)
 {
-    entity rocket = vehicles_projectile(player.vehicle, EFFECT_RACER_ROCKETLAUNCH.eent_eff_name, SND_ROCKET_FIRE,
+    entity rocket = vehicles_projectile(player.vehicle, EFFECT_RACER_ROCKETLAUNCH, SND_ROCKET_FIRE,
                            org, dir * autocvar_g_vehicle_racer_rocket_speed,
                            autocvar_g_vehicle_racer_rocket_damage, autocvar_g_vehicle_racer_rocket_radius, autocvar_g_vehicle_racer_rocket_force, 3,
                            DEATH_VH_WAKI_ROCKET.m_id, PROJECTILE_WAKIROCKET, 20, false, false, player);
index e9f7f7333d17bc495a2f202983ce5378abeaf28f..015f947b2d62bf94ff1a0e4806edc076fa01703e 100644 (file)
@@ -1,5 +1,7 @@
 #include "raptor.qh"
 
+#ifdef GAMEQC
+
 #ifdef SVQC
 
 bool autocvar_g_vehicle_raptor = true;
@@ -453,7 +455,7 @@ bool raptor_takeoff(entity this, float dt)
        // Takeoff sequense
        if(vehic.frame < 25)
        {
-               vehic.frame += 25 / (autocvar_g_vehicle_raptor_takeofftime / PHYS_INPUT_FRAMETIME);
+               vehic.frame += 25 / (autocvar_g_vehicle_raptor_takeofftime / dt);
                vehic.velocity_z = min(vehic.velocity_z * 1.5, 256);
                vehic.bomb1.gun1.avelocity_y = 90 + ((vehic.frame / 25) * 25000);
                vehic.bomb1.gun2.avelocity_y = -vehic.bomb1.gun1.avelocity_y;
@@ -831,3 +833,5 @@ METHOD(Raptor, vr_setup, void(Raptor thisveh, entity instance))
 }
 
 #endif
+
+#endif
index 66b5bec883392c1527a1adb229e209c798355996..7d4a250f416e07b5a26aef7dbd69012c8b820525 100644 (file)
@@ -7,7 +7,7 @@ METHOD(RaptorCannon, wr_think, void(entity thiswep, entity actor, .entity weapon
     entity player = isPlayer ? actor : actor.owner;
     entity veh = player.vehicle;
     // 1 [wait] 1 [wait] 2 [wait] 2 [wait] [wait]
-    float t = autocvar_g_vehicle_raptor_cannon_refire * (1 + veh.misc_bulletcounter == 4);
+    float t = autocvar_g_vehicle_raptor_cannon_refire * (1 + ((veh.misc_bulletcounter + 1) >= 4));
     if (fire & 1)
     if (weapon_prepareattack(thiswep, player, weaponentity, false, t)) {
         if (isPlayer) W_SetupShot_Dir(player, weaponentity, v_forward, false, 0, SND_Null, CH_WEAPON_B, 0, DEATH_VH_RAPT_CANNON.m_id);
@@ -16,12 +16,12 @@ METHOD(RaptorCannon, wr_think, void(entity thiswep, entity actor, .entity weapon
         if (veh) {
             veh.misc_bulletcounter += 1;
             org = (veh.misc_bulletcounter <= 2) ? gettaginfo(veh.gun1, gettagindex(veh.gun1, "fire1"))
-              : (((veh.misc_bulletcounter == 4) ? veh.misc_bulletcounter = 0 : 0), gettaginfo(veh.gun2, gettagindex(veh.gun2, "fire1")));
+              : (((veh.misc_bulletcounter >= 4) ? veh.misc_bulletcounter = 0 : 0), gettaginfo(veh.gun2, gettagindex(veh.gun2, "fire1")));
             dir = v_forward;
             veh.vehicle_energy -= autocvar_g_vehicle_raptor_cannon_cost;
             actor.cnt = time;
         }
-        vehicles_projectile(veh, EFFECT_RAPTOR_MUZZLEFLASH.eent_eff_name, SND_LASERGUN_FIRE,
+        vehicles_projectile(veh, EFFECT_RAPTOR_MUZZLEFLASH, SND_LASERGUN_FIRE,
                                org, normalize(dir + randomvec() * autocvar_g_vehicle_raptor_cannon_spread) * autocvar_g_vehicle_raptor_cannon_speed,
                                autocvar_g_vehicle_raptor_cannon_damage, autocvar_g_vehicle_raptor_cannon_radius, autocvar_g_vehicle_raptor_cannon_force,  0,
                                DEATH_VH_RAPT_CANNON.m_id, PROJECTILE_RAPTORCANNON, 0, true, true, player);
@@ -59,6 +59,8 @@ METHOD(RaptorFlare, wr_think, void(entity thiswep, entity actor, .entity weapone
     entity veh = player.vehicle;
     if (fire & 2)
     if (!isPlayer || weapon_prepareattack(thiswep, player, weaponentity, true, autocvar_g_vehicle_raptor_flare_refire)) {
+        vector forward, right, up;
+        MAKE_VECTORS(player.v_angle, forward, right, up);
         for(int i = 0; i < 3; ++i) {
             entity _flare = spawn();
             setmodel(_flare, MDL_VEH_RAPTOR_FLARE);
@@ -67,7 +69,7 @@ METHOD(RaptorFlare, wr_think, void(entity thiswep, entity actor, .entity weapone
             setorigin(_flare, actor.origin - '0 0 16');
             set_movetype(_flare, MOVETYPE_TOSS);
             _flare.gravity = 0.15;
-            _flare.velocity = 0.25 * actor.velocity + (v_forward + randomvec() * 0.25)* -500;
+            _flare.velocity = 0.25 * actor.velocity + (forward + randomvec() * 0.25)* -500;
             setthink(_flare, raptor_flare_think);
             _flare.nextthink = time;
             _flare.owner = veh ? veh : player;
index 37b87bbada36ff97a675eed836914a9b650a7c58..c762acfa2309386816c7445dbd79e75a53b3565d 100644 (file)
@@ -30,7 +30,7 @@ REGISTER_WEAPON(RAPTOR_FLARE, NEW(RaptorFlare));
 float autocvar_g_vehicle_raptor_cannon_cost = 1;
 float autocvar_g_vehicle_raptor_cannon_damage = 10;
 float autocvar_g_vehicle_raptor_cannon_radius = 60;
-float autocvar_g_vehicle_raptor_cannon_refire = 0.03;
+float autocvar_g_vehicle_raptor_cannon_refire = 0.033333;
 float autocvar_g_vehicle_raptor_cannon_speed = 24000;
 float autocvar_g_vehicle_raptor_cannon_spread = 0.01;
 float autocvar_g_vehicle_raptor_cannon_force = 25;
index 68b422fad820bac87b4aaf2d276bf64458e82534..ca72ec1b23b034658bcb8617a9e60a2f9a4c9a21 100644 (file)
@@ -1,5 +1,7 @@
 #include "spiderbot.qh"
 
+#ifdef GAMEQC
+
 const int SBRM_FIRST = 1;
 const int SBRM_VOLLY = 1;
 const int SBRM_GUIDE = 2;
@@ -637,3 +639,5 @@ METHOD(Spiderbot, vr_setup, void(Spiderbot thisveh, entity instance))
 }
 
 #endif
+
+#endif
index 308a92fd87871bbe4972d441ef56ea40cd6ae0d1..fdeddc47bfbcb5d2956d7fa7c6125c94aa64130d 100644 (file)
@@ -183,7 +183,7 @@ void spiderbot_rocket_do(entity this)
     switch(STAT(VEHICLESTAT_W2MODE, this))
     {
         case SBRM_VOLLY:
-            rocket = vehicles_projectile(this, EFFECT_SPIDERBOT_ROCKETLAUNCH.eent_eff_name, SND_ROCKET_FIRE,
+            rocket = vehicles_projectile(this, EFFECT_SPIDERBOT_ROCKETLAUNCH, SND_ROCKET_FIRE,
                                    v, normalize(randomvec() * autocvar_g_vehicle_spiderbot_rocket_spread + v_forward) * autocvar_g_vehicle_spiderbot_rocket_speed,
                                    autocvar_g_vehicle_spiderbot_rocket_damage, autocvar_g_vehicle_spiderbot_rocket_radius, autocvar_g_vehicle_spiderbot_rocket_force, 1,
                                    DEATH_VH_SPID_ROCKET.m_id, PROJECTILE_SPIDERROCKET, autocvar_g_vehicle_spiderbot_rocket_health, false, true, this.owner);
@@ -197,7 +197,7 @@ void spiderbot_rocket_do(entity this)
                 this.wait = -10;
             break;
         case SBRM_GUIDE:
-            rocket = vehicles_projectile(this, EFFECT_SPIDERBOT_ROCKETLAUNCH.eent_eff_name, SND_ROCKET_FIRE,
+            rocket = vehicles_projectile(this, EFFECT_SPIDERBOT_ROCKETLAUNCH, SND_ROCKET_FIRE,
                                    v, normalize(v_forward) * autocvar_g_vehicle_spiderbot_rocket_speed,
                                    autocvar_g_vehicle_spiderbot_rocket_damage, autocvar_g_vehicle_spiderbot_rocket_radius, autocvar_g_vehicle_spiderbot_rocket_force, 1,
                                    DEATH_VH_SPID_ROCKET.m_id, PROJECTILE_SPIDERROCKET, autocvar_g_vehicle_spiderbot_rocket_health, false, false, this.owner);
@@ -209,7 +209,7 @@ void spiderbot_rocket_do(entity this)
 
         break;
         case SBRM_ARTILLERY:
-            rocket = vehicles_projectile(this, EFFECT_SPIDERBOT_ROCKETLAUNCH.eent_eff_name, SND_ROCKET_FIRE,
+            rocket = vehicles_projectile(this, EFFECT_SPIDERBOT_ROCKETLAUNCH, SND_ROCKET_FIRE,
                                    v, normalize(v_forward) * autocvar_g_vehicle_spiderbot_rocket_speed,
                                    autocvar_g_vehicle_spiderbot_rocket_damage, autocvar_g_vehicle_spiderbot_rocket_radius, autocvar_g_vehicle_spiderbot_rocket_force, 1,
                                    DEATH_VH_SPID_ROCKET.m_id, PROJECTILE_SPIDERROCKET, autocvar_g_vehicle_spiderbot_rocket_health, false, true, this.owner);
index f2fdf4407fb6307494ba7201e009c3c21f36091c..a8d1376d1d86b60781be17f990ff41f835f88996 100644 (file)
@@ -225,6 +225,20 @@ string GetAmmoPicture(int ammotype)
        }
 }
 
+string GetAmmoName(int ammotype)
+{
+       switch (ammotype)
+       {
+               case RES_SHELLS:  return ITEM_Shells.m_name;
+               case RES_BULLETS: return ITEM_Bullets.m_name;
+               case RES_ROCKETS: return ITEM_Rockets.m_name;
+               case RES_CELLS:   return ITEM_Cells.m_name;
+               case RES_PLASMA:  return ITEM_Plasma.m_name;
+               case RES_FUEL:    return ITEM_JetpackFuel.m_name;
+               default:          return "batteries";
+       }
+}
+
 #ifdef CSQC
 int GetAmmoTypeFromNum(int i)
 {
@@ -551,14 +565,27 @@ REGISTER_NET_TEMP(wframe)
 #ifdef CSQC
 NET_HANDLE(wframe, bool isNew)
 {
-       vector a = ReadVector();
+       int fr = ReadByte();
+       float t = ReadFloat();
     int slot = ReadByte();
        bool restartanim = ReadByte();
        entity wepent = viewmodels[slot];
-       if(a.x == wepent.anim_idle_x) // we don't need to enforce idle animation
-               wepent.animstate_looping = false;
+       if(fr == WFRAME_IDLE)
+               wepent.animstate_looping = false; // we don't need to enforce idle animation
        else
+       {
+               vector a = '0 0 0';
+               switch(fr)
+               {
+                       default:
+                       case WFRAME_IDLE: a = wepent.anim_idle; break;
+                       case WFRAME_FIRE1: a = wepent.anim_fire1; break;
+                       case WFRAME_FIRE2: a = wepent.anim_fire2; break;
+                       case WFRAME_RELOAD: a = wepent.anim_reload; break;
+               }
+               a.z *= t;
                anim_set(wepent, a, !restartanim, restartanim, restartanim);
+       }
        wepent.state = ReadByte();
        wepent.weapon_nextthink = ReadFloat();
        switch (wepent.state)
@@ -578,13 +605,14 @@ NET_HANDLE(wframe, bool isNew)
 #endif
 
 #ifdef SVQC
-void wframe_send(entity actor, entity weaponentity, vector a, bool restartanim)
+void wframe_send(entity actor, entity weaponentity, int wepframe, float attackrate, bool restartanim)
 {
        if (!IS_REAL_CLIENT(actor)) return;
        int channel = MSG_ONE;
        msg_entity = actor;
        WriteHeader(channel, wframe);
-       WriteVector(channel, a);
+       WriteByte(channel, wepframe);
+       WriteFloat(channel, attackrate);
        WriteByte(channel, weaponslot(weaponentity.weaponentity_fld));
        WriteByte(channel, restartanim);
        WriteByte(channel, weaponentity.state);
index 0be413f0fb0071fad8974f2022e50cea7a1bf838..26b40084bfe82b4013862d1d6c4fae03621c74ff 100644 (file)
@@ -38,7 +38,7 @@ STATIC_INIT(WeaponPickup) { FOREACH(Weapons, true, it.m_pickup = NEW(WeaponPicku
 #define WepSet_FromWeapon(it) ((it).m_wepset)
 WepSet _WepSet_FromWeapon(int i);
 
-GENERIC_COMMAND(dumpweapons, "Dump all weapons into weapons_dump.txt") // WEAPONTODO: make this work with other progs than just server
+GENERIC_COMMAND(dumpweapons, "Dump all weapons into weapons_dump.txt", false) // WEAPONTODO: make this work with other progs than just server
 {
     switch(request)
     {
@@ -392,6 +392,6 @@ REPLICATE(cvar_cl_accuracy_data_receive, bool, "cl_accuracy_data_receive");
 #endif
 
 #ifdef SVQC
-void wframe_send(entity actor, entity weaponentity, vector a, bool restartanim);
+void wframe_send(entity actor, entity weaponentity, int wepframe, float attackrate, bool restartanim);
 #endif
 #endif
index 3dd2a8048af45223f5ddaf383d1a649f262861ec..02fbdb536c283c669714f2ac754df048f3bacd9f 100644 (file)
@@ -216,6 +216,8 @@ WepSet W_RandomWeapons(entity e, WepSet remaining, int n);
 
 string GetAmmoPicture(int ammotype);
 
+string GetAmmoName(int ammotype);
+
 #ifdef CSQC
 int GetAmmoTypeFromNum(int i);
 int GetAmmoStat(int ammotype);
index 5948d6a12e2831e0fcaf2f340cd7ae781ee72ce7..ae2dbf07dfeda4f47c1b70d63ce7322364251c88 100644 (file)
@@ -809,7 +809,7 @@ void Draw_ArcBeam_callback(vector start, vector hit, vector end)
                Draw_CylindricLine(start, end, thickness, beam.beam_image, 0.25, -time * 3, beam.beam_color, beam.beam_alpha, DRAWFLAG_NORMAL, transformed_view_org);
        else
        {
-               R_BeginPolygon(beam.beam_image, DRAWFLAG_NORMAL); // DRAWFLAG_ADDITIVE
+               R_BeginPolygon(beam.beam_image, DRAWFLAG_NORMAL, false); // DRAWFLAG_ADDITIVE
                R_PolygonVertex(
                        top,
                        '0 0.5 0' + ('0 0.5 0' * (thickness / beam.beam_thickness)),
@@ -892,10 +892,9 @@ void Draw_ArcBeam(entity this)
                // into a weapon system for client code.
 
                // find where we are aiming
-               makevectors(((autocvar_chase_active) ? warpzone_save_view_angles : view_angles));
-               vector forward = v_forward;
-               vector right = v_right;
-               vector up = v_up;
+               vector myviewangle = ((autocvar_chase_active) ? warpzone_save_view_angles : view_angles);
+               vector forward, right, up;
+               MAKE_VECTORS(myviewangle, forward, right, up);
                entity wepent = viewmodels[this.beam_slot];
 
                if(autocvar_chase_active)
@@ -911,11 +910,6 @@ void Draw_ArcBeam(entity this)
                else
                        { start_pos = this.origin; }
 
-               int v_shot_idx;  // used later
-               (v_shot_idx = gettagindex(wepent, "shot")) || (v_shot_idx = gettagindex(wepent, "tag_shot"));
-               if(v_shot_idx && this.beam_usevieworigin == 2)
-                       start_pos = gettaginfo(wepent, v_shot_idx) - '0 0 2';
-
                // trace forward with an estimation
                WarpZone_TraceLine(
                        start_pos,
@@ -924,6 +918,11 @@ void Draw_ArcBeam(entity this)
                        this
                );
 
+               int v_shot_idx;  // used later
+               (v_shot_idx = gettagindex(wepent, "shot")) || (v_shot_idx = gettagindex(wepent, "tag_shot"));
+               if(v_shot_idx && this.beam_usevieworigin == 2)
+                       start_pos = gettaginfo(wepent, v_shot_idx) - '0 0 2';
+
                // untransform in case our trace went through a warpzone
                vector end_pos = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
 
@@ -956,6 +955,8 @@ void Draw_ArcBeam(entity this)
                {
                        this.beam_dir = wantdir;
                        this.beam_initialized = true;
+
+                       this.beam_muzzleentity.drawmask = MASK_NORMAL; // NOTE: this works around the muzzle entity flashing on the middle of the screen for a frame
                }
 
                if(this.beam_dir != wantdir)
@@ -972,7 +973,7 @@ void Draw_ArcBeam(entity this)
                                // if the angle is greater than maxangle, force the blendfactor to make this the maximum factor
                                float blendfactor = bound(
                                        0,
-                                       (1 - (this.beam_returnspeed * frametime)),
+                                       (1 - (this.beam_returnspeed * dt)),
                                        min(this.beam_maxangle / angle, 1)
                                );
                                this.beam_dir = normalize((wantdir * (1 - blendfactor)) + (this.beam_dir * blendfactor));
@@ -982,7 +983,7 @@ void Draw_ArcBeam(entity this)
                                // the radius is not too far yet, no worries :D
                                float blendfactor = bound(
                                        0,
-                                       (1 - (this.beam_returnspeed * frametime)),
+                                       (1 - (this.beam_returnspeed * dt)),
                                        1
                                );
                                this.beam_dir = normalize((wantdir * (1 - blendfactor)) + (this.beam_dir * blendfactor));
@@ -1132,7 +1133,7 @@ void Draw_ArcBeam(entity this)
                        this.beam_hiteffect,
                        last_origin,
                        beamdir * -1,
-                       frametime * 2
+                       dt * 2
                );
        }
        if(this.beam_hitlight[0])
@@ -1153,7 +1154,7 @@ void Draw_ArcBeam(entity this)
                        this.beam_muzzleeffect,
                        original_start_pos + wantdir * 20,
                        wantdir * 1000,
-                       frametime * 0.1
+                       dt * 0.1
                );
        }
        if(this.beam_muzzlelight[0])
@@ -1206,7 +1207,7 @@ NET_HANDLE(ENT_CLIENT_ARC_BEAM, bool isnew)
                flash = spawn();
                flash.owner = this;
                flash.effects = EF_ADDITIVE | EF_FULLBRIGHT;
-               flash.drawmask = MASK_NORMAL;
+               //flash.drawmask = MASK_NORMAL;
                flash.solid = SOLID_NOT;
                flash.avelocity_z = 5000;
                setattachment(flash, this, "");
index fce84c3b8eb88cc3d0b36a37861a361e5810f103..997f6eb36865648470cf398e2b78294a1ffe1ee1 100644 (file)
@@ -401,7 +401,7 @@ METHOD(Devastator, wr_aim, void(entity thiswep, entity actor, .entity weaponenti
         });
         float desirabledamage;
         desirabledamage = enemydamage;
-        if(time > actor.invincible_finished && time > actor.spawnshieldtime)
+        if(time > STAT(INVINCIBLE_FINISHED, actor) && time > actor.spawnshieldtime)
             desirabledamage = desirabledamage - selfdamage * autocvar_g_balance_selfdamagepercent;
         if(teamplay && actor.team)
             desirabledamage = desirabledamage - teamdamage;
index 2ba6b5da18628bc669f6de77668c32c23738ea11..69ccc4251bff69dbd7dacb70975cdf1966c62434 100644 (file)
@@ -154,27 +154,46 @@ void W_Electro_Bolt_Think(entity this)
                {
                        if(e.classname == "electro_orb")
                        {
-                               // change owner to whoever caused the combo explosion
-                               e.realowner = this.realowner;
-                               e.takedamage = DAMAGE_NO;
-                               e.classname = "electro_orb_chain";
-
-                               // now set the next one to trigger as well
-                               setthink(e, W_Electro_ExplodeCombo);
+                               bool explode;
+                               if (this.owner == e.owner)
+                               {
+                                       explode = WEP_CVAR_PRI(electro, midaircombo_own);
+                               }
+                               else if (SAME_TEAM(this.owner, e.owner))
+                               {
+                                       explode = WEP_CVAR_PRI(electro, midaircombo_teammate);
+                               }
+                               else
+                               {
+                                       explode = WEP_CVAR_PRI(electro, midaircombo_enemy);
+                               }
 
-                               // delay combo chains, looks cooler
-                               e.nextthink =
+                               if (explode)
+                               {
+                                       // change owner to whoever caused the combo explosion
+                                       e.realowner = this.realowner;
+                                       e.takedamage = DAMAGE_NO;
+                                       e.classname = "electro_orb_chain";
+
+                                       // Only first orb explosion uses midaircombo_speed, others use the normal combo_speed.
+                                       // This allows to avoid the delay on the first explosion which looks better
+                                       // (the bolt and orb should explode together because they interacted together)
+                                       // while keeping the chaining delay.
+                                       setthink(e, W_Electro_ExplodeCombo);
+                                       e.nextthink =
                                        (
                                                time
                                                +
-                                               (WEP_CVAR(electro, combo_speed) ?
-                                                       (vlen(e.WarpZone_findradius_dist) / WEP_CVAR(electro, combo_speed))
+                                               (WEP_CVAR_PRI(electro, midaircombo_speed) ?
+                                                       (vlen(e.WarpZone_findradius_dist) / WEP_CVAR_PRI(electro, midaircombo_speed))
                                                        :
                                                        0
                                                )
                                        );
 
-                               ++found;
+
+                                       ++found;
+                               }
                        }
                        e = e.chain;
                }
index 7dbed189b095e297a6a2805f1df2dda980c36045..4480812207defe79dfddd925c4589c1a57f09ea7 100644 (file)
@@ -40,9 +40,13 @@ CLASS(Electro, Weapon)
                P(class, prefix, force, float, BOTH) \
                P(class, prefix, health, float, SEC) \
                P(class, prefix, lifetime, float, BOTH) \
+               P(class, prefix, midaircombo_enemy, bool, PRI) \
                P(class, prefix, midaircombo_explode, float, PRI) \
                P(class, prefix, midaircombo_interval, float, PRI) \
+               P(class, prefix, midaircombo_own, bool, PRI) \
                P(class, prefix, midaircombo_radius, float, PRI) \
+               P(class, prefix, midaircombo_speed, float, PRI) \
+               P(class, prefix, midaircombo_teammate, float, PRI) \
                P(class, prefix, radius, float, BOTH) \
                P(class, prefix, refire2, float, SEC) \
                P(class, prefix, refire, float, BOTH) \
index 7f60c5b571d90c84b9d8ff52717c19462300d89d..90090077c1b4c63c3f8207406c82cf6cb3ff32f5 100644 (file)
@@ -389,7 +389,7 @@ METHOD(MineLayer, wr_aim, void(entity thiswep, entity actor, .entity weaponentit
 
         float desirabledamage;
         desirabledamage = enemydamage;
-        if(time > actor.invincible_finished && time > actor.spawnshieldtime)
+        if(time > STAT(INVINCIBLE_FINISHED, actor) && time > actor.spawnshieldtime)
             desirabledamage = desirabledamage - selfdamage * autocvar_g_balance_selfdamagepercent;
         if(teamplay && actor.team)
             desirabledamage = desirabledamage - teamdamage;
index 0e482d8ae82db239dbdd14160070da41befea332..fd33dacded56547632bda86e12359ae6187df06f 100644 (file)
@@ -43,7 +43,7 @@ void Porto_Draw(entity this)
                        dir = reflect(dir, trace_plane_normal);
                        pos = trace_endpos;
                        wepent.polyline[++idx] = pos;
-                       if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK || trace_dphitcontents & DPCONTENTS_PLAYERCLIP)
+                       if ((trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK) || (trace_dphitcontents & DPCONTENTS_PLAYERCLIP))
                        {
                                n += 1;
                                continue;
@@ -118,7 +118,7 @@ void W_Porto_Fail(entity this, float failhard)
 
        if(this.cnt < 0 && !failhard && this.realowner.playerid == this.playerid && !IS_DEAD(this.realowner) && !(STAT(WEAPONS, this.realowner) & WEPSET(PORTO)))
        {
-               setsize(this, '-16 -16 0', '16 16 32');
+               setsize(this, '-16 -16 0', '16 16 48');
                setorigin(this, this.origin + trace_plane_normal);
                if(move_out_of_solid(this))
                {
index 74986f9cc96be069154ee8c5dd35419cf07c6b85..f38c34b19791182d9127b58a6459d12d8cc332db 100644 (file)
@@ -712,14 +712,14 @@ void Draw_Shockwave(entity this)
                if(counter >= 1)
                {
                        // draw from shot origin to min spread radius
-                       R_BeginPolygon("", DRAWFLAG_NORMAL);
+                       R_BeginPolygon("", DRAWFLAG_NORMAL, false);
                        R_PolygonVertex(prev_min_end, '0 0 0', sw_color, a);
                        R_PolygonVertex(new_min_end, '0 0 0', sw_color, a);
                        R_PolygonVertex(this.sw_shotorg, '0 0 0', sw_color, a);
                        R_EndPolygon();
 
                        // draw from min spread radius to max spread radius
-                       R_BeginPolygon("", DRAWFLAG_NORMAL);
+                       R_BeginPolygon("", DRAWFLAG_NORMAL, false);
                        R_PolygonVertex(new_min_end, '0 0 0', sw_color, a);
                        R_PolygonVertex(prev_min_end, '0 0 0', sw_color, a);
                        R_PolygonVertex(prev_max_end, '0 0 0', sw_color, a);
@@ -734,14 +734,14 @@ void Draw_Shockwave(entity this)
                if((counter + 1) == divisions)
                {
                        // draw from shot origin to min spread radius
-                       R_BeginPolygon("", DRAWFLAG_NORMAL);
+                       R_BeginPolygon("", DRAWFLAG_NORMAL, false);
                        R_PolygonVertex(prev_min_end, '0 0 0', sw_color, a);
                        R_PolygonVertex(first_min_end, '0 0 0', sw_color, a);
                        R_PolygonVertex(this.sw_shotorg, '0 0 0', sw_color, a);
                        R_EndPolygon();
 
                        // draw from min spread radius to max spread radius
-                       R_BeginPolygon("", DRAWFLAG_NORMAL);
+                       R_BeginPolygon("", DRAWFLAG_NORMAL, false);
                        R_PolygonVertex(first_min_end, '0 0 0', sw_color, a);
                        R_PolygonVertex(prev_min_end, '0 0 0', sw_color, a);
                        R_PolygonVertex(prev_max_end, '0 0 0', sw_color, a);
index e2f4b640aa1b818f3a6b7640c9cf7be2d61c93b2..b8cae5fd5da0d66c0216c9806c788b1752cfab8d 100644 (file)
@@ -2,6 +2,9 @@
 
 #ifdef SVQC
 
+// enable to debug melee range
+//#define SHOTGUN_MELEEDEBUG
+
 METHOD(Shotgun, m_spawnfunc_hookreplace, Weapon(Shotgun this, entity e))
 {
        if (autocvar_sv_q3acompat_machineshotgunswap && !Item_IsLoot(e))
@@ -89,8 +92,10 @@ void W_Shotgun_Melee_Think(entity this)
                WarpZone_traceline_antilag(this.realowner, this.realowner.origin + this.realowner.view_ofs, targpos, false, this.realowner, ((IS_CLIENT(this.realowner)) ? ANTILAG_LATENCY(this.realowner) : 0));
 
                // draw lightning beams for debugging
-               //te_lightning2(NULL, targpos, this.realowner.origin + this.realowner.view_ofs + v_forward * 5 - v_up * 5);
-               //te_customflash(targpos, 40,  2, '1 1 1');
+       #ifdef SHOTGUN_MELEEDEBUG
+               te_lightning2(NULL, targpos, this.realowner.origin + this.realowner.view_ofs + v_forward * 5 - v_up * 5);
+               te_customflash(targpos, 40,  2, '1 1 1');
+       #endif
 
                is_player = (IS_PLAYER(trace_ent) || trace_ent.classname == "body" || IS_MONSTER(trace_ent));
 
@@ -116,7 +121,9 @@ void W_Shotgun_Melee_Think(entity this)
                        if(accuracy_isgooddamage(this.realowner, target_victim)) { accuracy_add(this.realowner, WEP_SHOTGUN, 0, swing_damage); }
 
                        // draw large red flash for debugging
-                       //te_customflash(targpos, 200, 2, '15 0 0');
+               #ifdef SHOTGUN_MELEEDEBUG
+                       te_customflash(targpos, 200, 2, '15 0 0');
+               #endif
 
                        if(WEP_CVAR_SEC(shotgun, melee_multihit)) // allow multiple hits with one swing, but not against the same player twice.
                        {
index dbf24c7964d94ff229b30ac068d4a0d315a251ba..e71ed7478a327227a021e91491aaf352bec50784 100644 (file)
@@ -33,7 +33,6 @@ void Draw_VaporizerBeam_trace_callback(vector start, vector hit, vector end)
 }
 
 .vector vorg1, vorg2;
-.float spawn_time;
 void VaporizerBeam_Draw(entity this)
 {
        //draw either the old v2.3 beam or the new beam
@@ -281,7 +280,7 @@ void W_RocketMinsta_Attack3 (entity actor, .entity weaponentity)
 
 METHOD(Vaporizer, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
 {
-    if(GetResource(actor, thiswep.ammo_type) > 0)
+    if((actor.items & IT_UNLIMITED_AMMO) || GetResource(actor, thiswep.ammo_type) > 0)
         PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, weaponentity, 1000000, 0, 1, false);
     else
         PHYS_INPUT_BUTTON_ATCK2(actor) = bot_aim(actor, weaponentity, WEP_CVAR_SEC(vaporizer, speed), 0, WEP_CVAR_SEC(vaporizer, lifetime), false); // WEAPONTODO: replace with proper vaporizer cvars
index 9453157f7000591bf273c07ed20aff7438404636..eaea70f5e9eb33d3fb45377a5d1c6e907aa5d119 100644 (file)
 #undef STAT_MOVEVARS_TIMESCALE
 #undef STAT_MOVEVARS_GRAVITY
 
-#pragma noref 0
-
 #define use use1
 .void(entity this, entity actor, entity trigger) use;
 #define touch move_touch
 
-// deglobalization:
-
 void(vector ang) _makevectors_hidden = #1;
-//#define makevectors DO_NOT_USE_GLOBALS_PREFER_MAKE_VECTORS_MACRO_INSTEAD
-
-#define makestatic DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
-
-#define skel_get_bonerel DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
-
 vector(float skel, float bonenum) _skel_get_boneabs_hidden = #270;
-//#define skel_get_boneabs DO_NOT_USE_GLOBALS_PREFER_SKEL_GET_BONE_ABS_MACRO_INSTEAD
-
 void(float skel, float bonenum, vector org) _skel_set_bone_hidden = #271;
-//#define skel_set_bone DO_NOT_USE_GLOBALS_PREFER_SKEL_SET_BONE_MACRO_INSTEAD
-
-#define skel_mul_bone DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
-
-#define skel_mul_bones DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
-
 void(vector org, float radius, vector lightcolours) _adddynamiclight_hidden = #305;
-//#define adddynamiclight DO_NOT_USE_GLOBALS_PREFER_ADD_DYNAMIC_LIGHT_MACRO_INSTEAD
-#define adddynamiclight2 DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
-
 void(vector dir) _vectorvectors_hidden = #432;
-#define vectorvectors DO_NOT_USE_GLOBALS_PREFER_VECTOR_VECTORS_MACRO_INSTEAD
-
 vector(entity ent, float tagindex) _gettaginfo_hidden = #452;
-//#define gettaginfo DO_NOT_USE_GLOBALS_PREFER_GET_TAG_INFO_MACRO_INSTEAD
 
-#define getentity DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
-#define getentityvec DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
+#pragma noref 0
index d6f6a072a0fea688e192219b28e21184a8c7b76b..578d58b27b3c2f68477973fa37035c7dd9cb8347 100644 (file)
@@ -62,21 +62,8 @@ int(string s1, string s2, int len) _strncasecmp = #230;
 int() _buf_create = #460;
 #define buf_create _buf_create
 
-#pragma noref 0
-
-// deglobalization:
-
-#define skel_get_bonerel DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
-
 vector(float skel, float bonenum) _skel_get_boneabs_hidden = #270;
-//#define skel_get_boneabs DO_NOT_USE_GLOBALS_PREFER_SKEL_GET_BONE_ABS_MACRO_INSTEAD
-
 void(float skel, float bonenum, vector org) _skel_set_bone_hidden = #271;
-//#define skel_set_bone DO_NOT_USE_GLOBALS_PREFER_SKEL_SET_BONE_MACRO_INSTEAD
-
-#define skel_mul_bone DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
-
-#define skel_mul_bones DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
-
 vector(entity ent, float tagindex) _gettaginfo_hidden = #452;
-//#define gettaginfo DO_NOT_USE_GLOBALS_PREFER_GET_TAG_INFO_MACRO_INSTEAD
+
+#pragma noref 0
index 70e5f378422af7850a91ec65cf8857d6c61ae0d8..93ea3612b7cc50e1fc19547f767a0ce077554b04 100644 (file)
 #else
        #define NULL (RVALUE, world)
 #endif
+
+// Shadow functions which use globals - see deglobalization.qh for details.
+#define makevectors DO_NOT_USE_GLOBALS_PREFER_MAKE_VECTORS_MACRO_INSTEAD
+#define aim DO_NOT_USE_GLOBALS
+#define makestatic DO_NOT_USE_GLOBALS
+#define skel_get_bonerel DO_NOT_USE_GLOBALS
+#define skel_get_boneabs DO_NOT_USE_GLOBALS_PREFER_SKEL_GET_BONE_ABS_MACRO_INSTEAD
+#define skel_set_bone DO_NOT_USE_GLOBALS_PREFER_SKEL_SET_BONE_MACRO_INSTEAD
+#define skel_mul_bone DO_NOT_USE_GLOBALS
+#define skel_mul_bones DO_NOT_USE_GLOBALS
+#define adddynamiclight DO_NOT_USE_GLOBALS_PREFER_ADD_DYNAMIC_LIGHT_MACRO_INSTEAD
+#define adddynamiclight2 DO_NOT_USE_GLOBALS
+#define vectorvectors DO_NOT_USE_GLOBALS_PREFER_VECTOR_VECTORS_MACRO_INSTEAD
+#define gettaginfo DO_NOT_USE_GLOBALS_PREFER_GET_TAG_INFO_MACRO_INSTEAD
+#define getentity DO_NOT_USE_GLOBALS
+#define getentityvec DO_NOT_USE_GLOBALS
index a8d8a4a486a0824cb200182a176ebf856762f8ed..f4e2bdaf7b182777ea2fdfcfb417112a19450b2b 100644 (file)
     if (IS_REAL_CLIENT(_cl)) stuffcmd(_cl, __VA_ARGS__); \
 MACRO_END
 
-#pragma noref 0
-
 #define use use1
 .void(entity this, entity actor, entity trigger) use;
 
-// deglobalization:
-
 void(vector ang) _makevectors_hidden = #1;
-//#define makevectors DO_NOT_USE_GLOBALS_PREFER_MAKE_VECTORS_MACRO_INSTEAD
 
-#define aim DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
-
-#define makestatic DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
+#pragma noref 0
index 2d48e577b8da2bf72b5ae3fa8cf19da46d8b89aa..192136b6253225e014490f4d4e100f2ddfca30e9 100644 (file)
@@ -1,24 +1,29 @@
 #pragma once
 
+IntrusiveList g_events;
+IntrusiveList g_components;
+STATIC_INIT(components) { g_events = IL_NEW(); g_components = IL_NEW(); }
+
 /** Components always interpolate from the previous state */
 #define COMPONENT(com) \
        void com_##com##_interpolate(entity it, float a); \
        .bool com_##com
 
-#define FOREACH_COMPONENT(com, body) FOREACH_ENTITY_FLOAT(com_##com, true, body)
+#define FOREACH_COMPONENT(com, body) IL_EACH(g_components, it.com_##com, body)
 
 
 #define EVENT(T, args) .bool evt_##T##_listener; .void args evt_##T
 
 #define emit(T, ...) \
        MACRO_BEGIN \
-       FOREACH_ENTITY_FLOAT_ORDERED(evt_##T##_listener, true, it.evt_##T(__VA_ARGS__)); \
+       IL_EACH(g_events, it.evt_##T##_listener, it.evt_##T(__VA_ARGS__)); \
        MACRO_END
 
 #define subscribe(listener, T, fn) \
        MACRO_BEGIN \
        listener.evt_##T = (fn); \
        listener.evt_##T##_listener = true; \
+       IL_PUSH(g_events, listener); \
        MACRO_END
 
 
index f73ade3d12ea58ea6f5652554909505c0a335f79..41506ec31778f41344218c81b42bf70d8cc711f9 100644 (file)
@@ -33,7 +33,12 @@ void sys_phys_update(entity this, float dt)
        if (IS_SVQC) {
                if (this.move_movetype == MOVETYPE_NONE) { return; }
                // when we get here, disableclientprediction cannot be 2
-               this.disableclientprediction = (this.move_qcphysics) ? -1 : 0;
+               if(this.move_movetype == MOVETYPE_FOLLOW) // not compatible with prediction
+                       this.disableclientprediction = 1;
+               else if(this.move_qcphysics)
+                       this.disableclientprediction = -1;
+               else
+                       this.disableclientprediction = 0;
        }
 
        viewloc_PlayerPhysics(this);
@@ -42,7 +47,7 @@ void sys_phys_update(entity this, float dt)
 
        PM_check_blocked(this);
 
-       float maxspeed_mod = (!this.in_swamp) ? 1 : this.swamp_slowdown;  // cvar("g_balance_swamp_moverate");
+       float maxspeed_mod = 1;
 
 // conveyors: first fix velocity
        if (this.conveyor.active) { this.velocity -= this.conveyor.movedir; }
@@ -126,7 +131,7 @@ void sys_phys_update(entity this, float dt)
                this.com_phys_gravity = '0 0 0';
        } else if (ITEMS_STAT(this) & IT_USING_JETPACK) {
                PM_jetpack(this, maxspeed_mod, dt);
-       } else if (IS_ONGROUND(this)) {
+       } else if (IS_ONGROUND(this) && (!IS_ONSLICK(this) || !PHYS_SLICK_APPLYGRAVITY(this))) {
                if (!WAS_ONGROUND(this)) {
                        emit(phys_land, this);
                        if (this.lastground < time - 0.3) {
@@ -360,11 +365,9 @@ void sys_phys_simulate(entity this, float dt)
                        // apply edge friction
                        const float f2 = vlen2(vec2(this.velocity));
                        if (f2 > 0) {
-                               trace_dphitq3surfaceflags = 0;
-                               tracebox(this.origin, this.mins, this.maxs, this.origin - '0 0 1', MOVE_NOMONSTERS, this);
                                // TODO: apply edge friction
                                // apply ground friction
-                               const int realfriction = (trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK)
+                               const int realfriction = (IS_ONSLICK(this))
                                    ? PHYS_FRICTION_SLICK(this)
                                        : PHYS_FRICTION(this);
 
index f2677fe3a3b5eabdc2acd394fbb5fc38deb659bc..2ada204dbfd39bdd235085b8a79cc55e379ed27b 100644 (file)
@@ -1,3 +1,6 @@
+For more information, see https://gitlab.com/xonotic/xonotic/-/wikis/Translating
+
+
 How to make the .po template:
 
 find . -type f -not -name \*.po -not -name \*.txt | xgettext -LC -k_ -f- --from-code utf-8
index 3bbb17ccf8715ddfced52d63453e41e7f40cc3e2..0bef0b6e0e944feebfe54c14fea8728a9bc6d295 100644 (file)
 
 #include "warpzone/mathlib.qc"
 
+// needs to be included before any of the functions which use globals are called
+#include "deglobalization.qh"
+
 #include "accumulate.qh"
 #include "angle.qc"
 #include "arraylist.qh"
 #include "counting.qh"
 #include "cvar.qh"
 #include "defer.qh"
-#include "deglobalization.qh"
 #include "draw.qh"
 #include "enumclass.qh"
 #include "file.qh"
index 04b96bc9974974cf98656754bf9aeb1b0583502a..a5610b3de4024428a748bb7aaf375376d569e827 100644 (file)
@@ -82,7 +82,7 @@ void CSQCPlayer_SetPredictionError(vector o, vector v, float onground_diff)
 
        csqcplayer_predictionerroro = CSQCPlayer_GetPredictionErrorO() + o;
        csqcplayer_predictionerrorv = CSQCPlayer_GetPredictionErrorV() + v;
-       csqcplayer_predictionerrorfactor = autocvar_cl_movement_errorcompensation / ticrate;
+       csqcplayer_predictionerrorfactor = autocvar_cl_movement_errorcompensation / ((ticrate) ? ticrate : 1);
        csqcplayer_predictionerrortime = time + 1.0 / csqcplayer_predictionerrorfactor;
 }
 
@@ -108,6 +108,8 @@ void CSQCPlayer_SetMinsMaxs(entity this)
        {
                this.mins = PHYS_PL_MIN(this);
                this.maxs = PHYS_PL_MAX(this);
+               if (IS_DEAD(this))
+                       this.maxs.z = 5;
                this.view_ofs = PHYS_PL_VIEWOFS(this);
        }
 }
@@ -207,6 +209,303 @@ bool CSQCPlayer_IsLocalPlayer(entity this)
        return (this == csqcplayer);
 }
 
+float stairsmoothz;
+float autocvar_cl_stairsmoothspeed = 200;
+float autocvar_cl_smoothviewheight = 0.05;
+float smooth_prevtime;
+float viewheightavg;
+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)
+               stairsmoothz = v.z;
+       else
+       {
+               if(stairsmoothz < v.z)
+                       v.z = stairsmoothz = bound(v.z - PHYS_STEPHEIGHT(this), stairsmoothz + smoothtime * autocvar_cl_stairsmoothspeed, v.z);
+               else if(stairsmoothz > v.z)
+                       v.z = stairsmoothz = bound(v.z, stairsmoothz - smoothtime * autocvar_cl_stairsmoothspeed, v.z + PHYS_STEPHEIGHT(this));
+       }
+
+       float viewheight = bound(0, (time - smooth_prevtime) / max(0.0001, autocvar_cl_smoothviewheight), 1);
+       viewheightavg = viewheightavg * (1 - viewheight) + this.view_ofs.z * viewheight;
+       v.z += viewheightavg;
+
+       smooth_prevtime = time;
+
+       return v;
+}
+
+bool autocvar_v_deathtilt;
+float autocvar_v_deathtiltangle;
+void CSQCPlayer_ApplyDeathTilt(entity this)
+{
+       if(!this.csqcmodel_isdead || !autocvar_v_deathtilt)
+               return;
+       view_angles.z = autocvar_v_deathtiltangle;
+}
+
+float autocvar_v_idlescale;
+float autocvar_v_ipitch_cycle;
+float autocvar_v_iyaw_cycle;
+float autocvar_v_iroll_cycle;
+float autocvar_v_ipitch_level;
+float autocvar_v_iyaw_level;
+float autocvar_v_iroll_level;
+void CSQCPlayer_ApplyIdleScaling(entity this)
+{
+       if(!autocvar_v_idlescale)
+               return;
+       view_angles.x += autocvar_v_idlescale * sin(time * autocvar_v_ipitch_cycle) * autocvar_v_ipitch_level;
+       view_angles.y += autocvar_v_idlescale * sin(time * autocvar_v_iyaw_cycle) * autocvar_v_iyaw_level;
+       view_angles.z += autocvar_v_idlescale * sin(time * autocvar_v_iroll_cycle) * autocvar_v_iroll_level;
+       //setproperty(VF_CL_VIEWANGLES, view_angles); // update view angles as well so we can aim
+}
+
+float autocvar_cl_bob = 0;
+float autocvar_cl_bobcycle = 0.5;
+float autocvar_cl_bob_limit = 7;
+float autocvar_cl_bob_limit_heightcheck = 0;
+float autocvar_cl_bob_velocity_limit = 400;
+float autocvar_cl_bobup = 0.5;
+float autocvar_cl_bobfall = 0.05;
+float autocvar_cl_bobfallcycle = 3;
+float autocvar_cl_bobfallminspeed = 200;
+float autocvar_cl_bob2 = 0;
+float autocvar_cl_bob2cycle = 1;
+float autocvar_cl_bob2smooth = 0.05;
+float bobfall_swing;
+float bobfall_speed;
+float bob2_smooth;
+vector CSQCPlayer_ApplyBobbing(entity this, vector v)
+{
+       if(this.csqcmodel_isdead)
+               return v;
+
+       // bounded XY speed, used by several effects below
+       float bob, cycle;
+
+       // vertical view bobbing code
+       if(autocvar_cl_bob && autocvar_cl_bobcycle)
+       {
+               float bob_limit = autocvar_cl_bob_limit;
+
+               if(autocvar_cl_bob_limit_heightcheck)
+               {
+                       // use traces to determine what range the view can bob in, and scale down the bob as needed
+                       vector bob_height_check_dest = v;
+                       bob_height_check_dest.z += autocvar_cl_bob_limit * 1.1;
+                       traceline(v, bob_height_check_dest, MOVE_NOMONSTERS, NULL);
+                       float trace1fraction = trace_fraction;
+
+                       bob_height_check_dest = v;
+                       bob_height_check_dest.z += autocvar_cl_bob_limit * -0.5;
+                       traceline(v, bob_height_check_dest, MOVE_NOMONSTERS, NULL);
+                       float trace2fraction = trace_fraction;
+
+                       bob_limit *= min(trace1fraction, trace2fraction);
+               }
+
+               // LordHavoc: figured out bobup: the time at which the sin is at 180
+               // degrees (which allows lengthening or squishing the peak or valley)
+               cycle = time / autocvar_cl_bobcycle;
+               cycle -= rint(cycle);
+               if(cycle < autocvar_cl_bobup)
+                       cycle = sin(M_PI * cycle / autocvar_cl_bobup);
+               else
+                       cycle = sin(M_PI + M_PI * (cycle - autocvar_cl_bobup) / (1.0 - autocvar_cl_bobup));
+               // bob is proportional to velocity in the xy plane
+               // (don't count Z, or jumping messes it up)
+               float xyspeed = bound(0, sqrt(this.velocity.x * this.velocity.x + this.velocity.y * this.velocity.y), autocvar_cl_bob_velocity_limit);
+               bob = xyspeed * autocvar_cl_bob;
+               bob = bound(0, bob, bob_limit);
+               bob = bob * 0.3 + bob * 0.7 * cycle;
+               v.z += bob;
+       }
+
+       // horizontal view bobbing code
+       if(autocvar_cl_bob2 && autocvar_cl_bob2cycle)
+       {
+               cycle = time / autocvar_cl_bob2cycle;
+               cycle -= rint(cycle);
+               if(cycle < 0.5)
+                       cycle = cos(M_PI * cycle / 0.5); // cos looks better here with the other view bobbing using sin
+               else
+                       cycle = cos(M_PI + M_PI * (cycle - 0.5) / 0.5);
+               bob = autocvar_cl_bob2 * cycle;
+
+               // this value slowly decreases from 1 to 0 when we stop touching the ground.
+               // The cycle is later multiplied with it so the view smooths back to normal
+               if(IS_ONGROUND(this) && !(input_buttons & BIT(1))) // also block the effect while the jump button is pressed, to avoid twitches when bunny-hopping
+                       bob2_smooth = 1;
+               else
+               {
+                       if(bob2_smooth > 0)
+                               bob2_smooth -= bound(0, autocvar_cl_bob2smooth, 1);
+                       else
+                               bob2_smooth = 0;
+               }
+
+               // calculate the front and side of the player between the X and Y axes
+               makevectors(view_angles);
+               // now get the speed based on those angles. The bounds should match the same value as xyspeed's
+               float side = bound(-autocvar_cl_bob_velocity_limit, (this.velocity * v_right) * bob2_smooth, autocvar_cl_bob_velocity_limit);
+               float front = bound(-autocvar_cl_bob_velocity_limit, (this.velocity * v_forward) * bob2_smooth, autocvar_cl_bob_velocity_limit);
+               v_forward = v_forward * bob;
+               v_right = v_right * bob;
+               // we use side with forward and front with right, so the bobbing goes
+               // to the side when we walk forward and to the front when we strafe
+               vector bob2vel;
+               bob2vel.x = side * v_forward.x + front * v_right.x + 0 * v_up.x;
+               bob2vel.y = side * v_forward.y + front * v_right.y + 0 * v_up.y;
+               bob2vel.z = side * v_forward.z + front * v_right.z + 0 * v_up.z;
+               v.x += bob2vel.x;
+               v.y += bob2vel.y;
+       }
+
+       // fall bobbing code
+       // causes the view to swing down and back up when touching the ground
+       if(autocvar_cl_bobfall && autocvar_cl_bobfallcycle)
+       {
+               if(!IS_ONGROUND(this))
+               {
+                       bobfall_speed = bound(-400, this.velocity.z, 0) * bound(0, autocvar_cl_bobfall, 0.1);
+                       if(this.velocity.z < -autocvar_cl_bobfallminspeed)
+                               bobfall_swing = 1;
+                       else
+                               bobfall_swing = 0; // really?
+               }
+               else
+               {
+                       bobfall_swing = max(0, bobfall_swing - autocvar_cl_bobfallcycle * frametime);
+                       float bobfall = sin(M_PI * bobfall_swing) * bobfall_speed;
+                       v.z += bobfall;
+               }
+       }
+
+       return v;
+}
+
+float autocvar_cl_rollangle;
+float autocvar_cl_rollspeed;
+float CSQCPlayer_CalcRoll(entity this)
+{
+       makevectors(view_angles);
+       float side = (this.velocity * v_right);
+       float sign = (side < 0) ? -1 : 1;
+       side = fabs(side);
+
+       if(side < autocvar_cl_rollspeed)
+               side = side * autocvar_cl_rollangle / autocvar_cl_rollspeed;
+       else
+               side = autocvar_cl_rollangle;
+
+       return side * sign;
+}
+
+float autocvar_chase_back;
+float autocvar_chase_up;
+bool autocvar_chase_overhead;
+float autocvar_chase_pitchangle;
+vector CSQCPlayer_ApplyChase(entity this, vector v)
+{
+       vector forward;
+       vector chase_dest;
+
+       if(autocvar_chase_overhead)
+       {
+               view_angles.x = 0;
+               makevectors(view_angles);
+               forward = v_forward;
+               vector up = v_up;
+               // trace a little further so it hits a surface more consistently (to avoid 'snapping' on the edge of the range)
+               chase_dest.x = v.x - forward.x * autocvar_chase_back + up.x * autocvar_chase_up;
+               chase_dest.y = v.y - forward.y * autocvar_chase_back + up.y * autocvar_chase_up;
+               chase_dest.z = v.z - forward.z * autocvar_chase_back + up.z * autocvar_chase_up;
+
+               // trace from first person view location to our chosen third person view location
+               traceline(v, chase_dest, MOVE_NOMONSTERS, NULL);
+
+               vector bestvieworg = trace_endpos;
+               vector offset = '0 0 0';
+               for(offset.x = -16; offset.x <= 16; offset.x += 8)
+               {
+                       for(offset.y = -16; offset.y <= 16; offset.y += 8)
+                       {
+                               makevectors(view_angles);
+                               up = v_up;
+                               chase_dest.x = v.x - forward.x * autocvar_chase_back + up.x * autocvar_chase_up + offset.x;
+                               chase_dest.y = v.y - forward.y * autocvar_chase_back + up.y * autocvar_chase_up + offset.y;
+                               chase_dest.z = v.z - forward.z * autocvar_chase_back + up.z * autocvar_chase_up + offset.z;
+                               traceline(v, chase_dest, MOVE_NOMONSTERS, NULL);
+                               if(bestvieworg.z > trace_endpos.z)
+                                       bestvieworg.z = trace_endpos.z;
+                       }
+               }
+               bestvieworg.z -= 8;
+               v = bestvieworg;
+
+               view_angles.x = autocvar_chase_pitchangle;
+               //setproperty(VF_CL_VIEWANGLES, view_angles); // update view angles as well so we can aim
+       }
+       else
+       {
+               makevectors(view_angles);
+               forward = v_forward;
+               // trace a little further so it hits a surface more consistently (to avoid 'snapping' on the edge of the range)
+               float cdist = -autocvar_chase_back - 8;
+               chase_dest.x = v.x + forward.x * cdist;
+               chase_dest.y = v.y + forward.y * cdist;
+               chase_dest.z = v.z + forward.z * cdist + autocvar_chase_up;
+               traceline(v, chase_dest, MOVE_NOMONSTERS, NULL);
+               v.x = 1 * trace_endpos.x + 8 * forward.x + 4 * trace_plane_normal.x;
+               v.y = 1 * trace_endpos.y + 8 * forward.y + 4 * trace_plane_normal.y;
+               v.z = 1 * trace_endpos.z + 8 * forward.z + 4 * trace_plane_normal.z;
+       }
+
+#if 0
+       tracebox(v, '-4 -4 -4', '4 4 4', v - v_forward * autocvar_chase_back, MOVE_NORMAL, this);
+       v = trace_endpos;
+       tracebox(v, '-4 -4 -4', '4 4 4', v + v_up * autocvar_chase_up, MOVE_NORMAL, this);
+       v = trace_endpos;
+#endif
+       return v;
+}
+
+void CSQCPlayer_CalcRefdef(entity this)
+{
+       vector vieworg = this.origin;
+       if(intermission)
+       {
+               // just update view offset, don't need to do anything else
+               vieworg.z += this.view_ofs.z;
+       }
+       else
+       {
+               vieworg = CSQCPlayer_ApplySmoothing(this, vieworg);
+               if(autocvar_chase_active)
+                       vieworg = CSQCPlayer_ApplyChase(this, vieworg);
+               else
+               {
+                       // angles
+                       CSQCPlayer_ApplyDeathTilt(this);
+                       view_angles = view_angles + view_punchangle;
+                       view_angles.z += CSQCPlayer_CalcRoll(this);
+                       // TODO? we don't have damage time accessible here
+                       // origin
+                       vieworg = vieworg + view_punchvector;
+                       vieworg = CSQCPlayer_ApplyBobbing(this, vieworg);
+               }
+               CSQCPlayer_ApplyIdleScaling(this);
+       }
+       setproperty(VF_ORIGIN, vieworg);
+       setproperty(VF_ANGLES, view_angles);
+}
+
+bool autocvar_cl_useenginerefdef = false;
+
 /** Called once per CSQC_UpdateView() */
 void CSQCPlayer_SetCamera()
 {
@@ -270,7 +569,8 @@ void CSQCPlayer_SetCamera()
 #endif
                        CSQCPlayer_SetMinsMaxs(e);
 
-                       e.angles_y = input_angles.y;
+                       if (!IS_DEAD(e))
+                               e.angles.y = input_angles.y;
                }
 
                // relink
@@ -285,13 +585,20 @@ void CSQCPlayer_SetCamera()
                        InterpolateOrigin_Do(view);
                        view.view_ofs = '0 0 1' * vh;
                }
-               int refdefflags = 0;
-               if (view.csqcmodel_teleported) refdefflags |= REFDEFFLAG_TELEPORTED;
-               if (input_buttons & BIT(1)) refdefflags |= REFDEFFLAG_JUMPING;
-               // note: these two only work in WIP2, but are harmless in WIP1
-               if (PHYS_HEALTH(NULL) <= 0 && PHYS_HEALTH(NULL) != -666 && PHYS_HEALTH(NULL) != -2342) refdefflags |= REFDEFFLAG_DEAD;
-               if (intermission) refdefflags |= REFDEFFLAG_INTERMISSION;
-               V_CalcRefdef(view, refdefflags); // TODO? uses .health stat in the engine when this isn't called here, may be broken!
+               if(autocvar_cl_useenginerefdef)
+               {
+                       int refdefflags = 0;
+                       if (view.csqcmodel_teleported) refdefflags |= REFDEFFLAG_TELEPORTED;
+                       if (input_buttons & BIT(1)) refdefflags |= REFDEFFLAG_JUMPING;
+                       // note: these two only work in WIP2, but are harmless in WIP1
+                       if (PHYS_HEALTH(NULL) <= 0 && PHYS_HEALTH(NULL) != -666 && PHYS_HEALTH(NULL) != -2342) refdefflags |= REFDEFFLAG_DEAD;
+                       if (intermission) refdefflags |= REFDEFFLAG_INTERMISSION;
+                       V_CalcRefdef(view, refdefflags); // TODO? uses .health stat in the engine when this isn't called here, may be broken!
+               }
+               else
+               {
+                       CSQCPlayer_CalcRefdef(view);
+               }
        }
        else
        {
index 297e2e69d648c1826289fa21c95e389f5a61b5f2..92948dc5a92d119b34485fe649823fa67f0960a6 100644 (file)
@@ -35,7 +35,7 @@ const int PMF_JUMP_HELD = 1;
 //const int PMF_DUCKED = 4;
 //const int PMF_ONGROUND = 8;
 
-const int FL_DUCKED = 524288;
+const int FL_DUCKED = BIT(19);
 
 void CSQCPlayer_SetCamera();
 float CSQCPlayer_PreUpdate(entity this);
index 7600fdde606f5d7a5c6733c0f2822b448140d806..831ce95e9eb34432f8082f7ad9be84ffa6166a7b 100644 (file)
@@ -48,11 +48,11 @@ void InterpolateOrigin_Note(entity this)
                this.iorigin2 = this.origin;
        }
 
-       if (this.iflags & IFLAG_AUTOANGLES
+       if ((this.iflags & IFLAG_AUTOANGLES)
            && this.iorigin2
            != this.iorigin1) this.angles = vectoangles(this.iorigin2 - this.iorigin1);
 
-       if (this.iflags & IFLAG_AUTOVELOCITY
+       if ((this.iflags & IFLAG_AUTOVELOCITY)
            && this.itime2
            != this.itime1) this.velocity = (this.iorigin2 - this.iorigin1) * (1.0 / (this.itime2 - this.itime1));
 
index e8e2c54880a1a29eed6c48d50a6ac0cd44c016ff..4b292a3a5b20a614b7d2fc3f9326c9e79758a8bf 100644 (file)
@@ -30,23 +30,12 @@ string MakeConsoleSafe(string input)
        return input;
 }
 
-ERASEABLE
-void cvar_describe(string name, string desc)
-{
-       localcmd(sprintf("\nset %1$s \"$%1$s\" \"%2$s\"\n", name, MakeConsoleSafe(desc)));
-}
-
-ERASEABLE
-void cvar_archive(string name)
-{
-       localcmd(sprintf("\nseta %1$s \"$%1$s\"\n", name));
-}
-
 ERASEABLE
 void RegisterCvars_Set(string name, string def, string desc, bool archive, string file)
 {
-       cvar_describe(name, desc);
-       if (archive) cvar_archive(name);
+       localcmd(sprintf("\nset %1$s \"$%1$s\" \"%2$s\"\n", name, MakeConsoleSafe(desc)));
+       if (archive)
+               localcmd(sprintf("\nseta %1$s \"$%1$s\"\n", name));
 }
 
 int RegisterCvars_Save_fd;
index 3d7f82067440137e64db91a8bc7c78cf53c5ca37..3f71fd8ace4cf920e5a036047208b14b20f8bdeb 100644 (file)
@@ -1,40 +1,85 @@
+#include "lib/accumulate.qh"
 #include "lib/float.qh"
+#include "lib/log.qh"
 #include "lib/misc.qh"
 #include "lib/static.qh"
 #include "lib/vector.qh"
 
-// These macros wrap functions which use globals so mutation only occurs inside them and is not visible from outside.
-// Functions for which all usages are replaced with these macros can be hidden by #defines inside our `*defs.qh` files
-// to prevent anyone from using them accidentally in the future
+// These macros wrap functions which use globals so mutation of global state only occurs inside them and is not visible from outside.
+// This helps prevent bugs where refactoring accidentally breaks implicit assumptions about global state ("pls call makevectors before calling this").
+// Currently only functions that use v_forward/v_right/v_up are wrapped since those are most common.
+// Some functions don't have wrappers because they're not used anywhere.
 
-// TODO stuff in the engine that uses the v_forward/v_right/v_up globals and is not wrapped yet:
-//  - RF_USEAXIS, addentities, predraw,
-//    - CL_GetEntityMatrix (in engine but is called from other functions so transitively any of them can use the globals - e.g. V_CalcRefdef, maybe others)
-//    - however RF_USEAXIS is only used if MF_ROTATE is used which is only set in one place
-//  - e.camera_transform / CL_VM_TransformView (in engine)
-//    - this is the only used function that both sets and gets the globals (aim does too but isn't used in our code)
+// Steps (slightly inspired by steps in self.qh):
+// 1) (done) Create alternative names for the builtins (e.g. _makevectors_hidden) to be used inside wrappers.
+//    Shadow the originals with macros that tell the user to use the wrappers instead. These are in the *defs.qh files.
+// 2) Create wrapper macros with the same name (e.g. makevectors) that still use globals but log their usage.
+//     - Would be nice to also log reads and writes to the globals themselves. Probably possible with macros, comma expressions and [[alias]].
+// 3) Create wrapper macros that use locals (e.g. MAKE_VECTORS).
+//    TODO stuff in the engine that uses the v_forward/v_right/v_up globals and is not wrapped yet:
+//     - RF_USEAXIS, addentities, predraw,
+//       - CL_GetEntityMatrix (in engine but is called from other functions so transitively any of them can use the globals - e.g. V_CalcRefdef, maybe others)
+//       - however RF_USEAXIS is only used if MF_ROTATE is used which is only set in one place
+//     - e.camera_transform / CL_VM_TransformView (in engine)
+//       - this is the only used function that both sets and gets the globals (aim does too but isn't used in our code)
+// 4) Gradually replace uses of each function with its wrapper.
+// 5) When a function is no longer used, remove the wrapper with the same name to cause compile errors that will prevent accidental use in the future.
 
-// convenience for deglobalization code - don't use these just to hide that globals are still used
-#define CLEAR_V_GLOBALS() v_forward = VEC_NAN; v_right = VEC_NAN; v_up = VEC_NAN
-#define GET_V_GLOBALS(forward, right, up) forward = v_forward; right = v_right; up = v_up
-#define SET_V_GLOBALS(forward, right, up) v_forward = forward; v_right = right; v_up = up
+// Final checking:
+// When all functions which use a global have been replaced with the wrappers,
+// the wrappers can check that the global contains NaN before its use and set it to NaN after its use.
+// This should detect if there is any remaining global mutation (even in the engine).
+// NaN is the most likely value to expose remaining usages - e.g. functions like traceline crash on it.
+
+#ifdef GAMEQC // menu doesn't use any globals
+
+// compile time switches in case perf is an issue
+#define DEGLOB_LOGGING 1
+#define DEGLOB_CLEAR 1
+
+const int DEGLOB_ORIGINAL = 1;
+const int DEGLOB_WRAPPED = 2;
+#if DEGLOB_LOGGING
+int autocvar_debug_deglobalization_logging = 0;
+// Varargs to this should already be stringized, otherwise they're expanded first which makes them less readable.
+// The downside is redundant quotes, fortunately none of these functions take strings.
+#define DEGLOB_LOG(kind, name, ...) deglob_log(kind, name, __FILE__, __LINE__, __FUNC__, #__VA_ARGS__)
+// This needs to be a function, not a macro,
+// because some wrappers of the old functions need to use comma expressions
+// because they return values.
+void deglob_log(int kind, string name, string file, int line, string func, string more_text) {
+       if (autocvar_debug_deglobalization_logging & kind) {
+               LOG_INFOF("%s %f %s %s:%d:%s args: %s", PROGNAME, time, name, file, line, func, more_text);
+       }
+}
+#else
+#define DEGLOB_LOG(kind, name, ...)
+void deglob_log(int kind, string name, string file, int line, string func, string more_text) {}
+#endif
 
-#ifdef GAMEQC
+// convenience for deglobalization code - don't use these just to hide that globals are still used
+#define GET_V_GLOBALS(forward, right, up) MACRO_BEGIN forward = v_forward; right = v_right; up = v_up; MACRO_END
+#define SET_V_GLOBALS(forward, right, up) MACRO_BEGIN v_forward = forward; v_right = right; v_up = up; MACRO_END
+#if DEGLOB_CLEAR
+bool autocvar_debug_deglobalization_clear = true;
+#define CLEAR_V_GLOBALS() MACRO_BEGIN \
+       if (autocvar_debug_deglobalization_clear) { \
+               v_forward = VEC_NAN; v_right = VEC_NAN; v_up = VEC_NAN \
+       } \
+MACRO_END
 STATIC_INIT(globals) {
        // set to NaN to more easily detect uninitialized use
-       // TODO when all functions are wrapped and the raw functions are not used anymore,
-       // uncomment the defines in *progs.qh files that hide the raw functions
-       // and assert that the global vectors are NaN before calling the raw functions here
-       // to make sure nobody (even builtins) is accidentally using them - NaN is the most likely value to expose remaining usages
-
        CLEAR_V_GLOBALS();
 }
+#else
+#define CLEAR_V_GLOBALS()
 #endif
 
 /// Same as the `makevectors` builtin but uses the provided locals instead of the `v_*` globals.
 /// Always use this instead of raw `makevectors` to make the data flow clear.
 /// Note that you might prefer `FIXED_MAKE_VECTORS` for new code.
 #define MAKE_VECTORS(angles, forward, right, up) MACRO_BEGIN \
+       DEGLOB_LOG(DEGLOB_WRAPPED, "MAKE_VECTORS", #angles); \
        _makevectors_hidden(angles); \
        GET_V_GLOBALS(forward, right, up); \
        CLEAR_V_GLOBALS(); \
@@ -42,24 +87,28 @@ MACRO_END
 
 /// Returns all 4 vectors by assigning to them (instead of returning a value) for consistency (and sanity)
 #define SKEL_GET_BONE_ABS(skel, bonenum, forward, right, up, origin) MACRO_BEGIN \
+       DEGLOB_LOG(DEGLOB_WRAPPED, "SKEL_GET_BONE_ABS", #skel, #bonenum); \
        origin = _skel_get_boneabs_hidden(skel, bonenum) \
        GET_V_GLOBALS(forward, right, up); \
        CLEAR_V_GLOBALS(); \
 MACRO_END
 
 #define SKEL_SET_BONE(skel, bonenum, org, forward, right, up) MACRO_BEGIN \
+       DEGLOB_LOG(DEGLOB_WRAPPED, "SKEL_SET_BONE", #skel, #bonenum, #org); \
        SET_V_GLOBALS(forward, right, up); \
        _skel_set_bone_hidden(skel, bonenum, org); \
        CLEAR_V_GLOBALS(); \
 MACRO_END
 
 #define ADD_DYNAMIC_LIGHT(org, radius, lightcolours, forward, right, up) MACRO_BEGIN \
+       DEGLOB_LOG(DEGLOB_WRAPPED, "ADD_DYNAMIC_LIGHT", #org, #radius, #lightcolours); \
        SET_V_GLOBALS(forward, right, up); \
        _adddynamiclight_hidden(org, radius, lightcolours); \
        CLEAR_V_GLOBALS(); \
 MACRO_END
 
 #define VECTOR_VECTORS(forward_in, forward, right, up) MACRO_BEGIN \
+       DEGLOB_LOG(DEGLOB_WRAPPED, "VECTOR_VECTORS", #forward_in); \
        _vectorvectors_hidden(forward_in); \
        GET_V_GLOBALS(forward, right, up); \
        CLEAR_V_GLOBALS(); \
@@ -67,7 +116,40 @@ MACRO_END
 
 /// Note that this only avoids the v_* globals, not the gettaginfo_* ones
 #define GET_TAG_INFO(ent, tagindex, forward, right, up, origin) MACRO_BEGIN \
+       DEGLOB_LOG(DEGLOB_WRAPPED, "GET_TAG_INFO", #ent, #tagindex); \
        origin = _gettaginfo_hidden(ent, tagindex); \
        GET_V_GLOBALS(forward, right, up); \
        CLEAR_V_GLOBALS(); \
 MACRO_END
+
+#undef makevectors
+#define makevectors(angles) MACRO_BEGIN \
+       DEGLOB_LOG(DEGLOB_ORIGINAL, "makevectors", #angles); \
+       _makevectors_hidden(angles); \
+MACRO_END
+
+#undef skel_get_boneabs
+#define skel_get_boneabs(skel, bonenum) ( \
+       deglob_log(DEGLOB_ORIGINAL, "skel_get_boneabs", __FILE__, __LINE__, __FUNC__, #skel ", " #bonenum), \
+       _skel_get_boneabs_hidden(skel, bonenum) \
+)
+
+#undef skel_set_bone
+#define skel_set_bone(skel, bonenum, org) MACRO_BEGIN \
+       DEGLOB_LOG(DEGLOB_ORIGINAL, "skel_set_bone", #skel, #bonenum, #org); \
+       _skel_set_bone_hidden(skel, bonenum, org); \
+MACRO_END
+
+#undef adddynamiclight
+#define adddynamiclight(org, radius, lightcolours) MACRO_BEGIN \
+       DEGLOB_LOG(DEGLOB_ORIGINAL, "adddynamiclight", #org, #radius, #lightcolours); \
+       _adddynamiclight_hidden(org, radius, lightcolours); \
+MACRO_END
+
+#undef gettaginfo
+#define gettaginfo(ent, tagindex) ( \
+       deglob_log(DEGLOB_ORIGINAL, "gettaginfo", __FILE__, __LINE__, __FUNC__, #ent ", " #tagindex), \
+       _gettaginfo_hidden(ent, tagindex) \
+)
+
+#endif // GAMEQC
index 2bf480a8782aed99c16167731c5f38efd1300fcd..dbac8b8b190f90a6923ee30239ba4a9b7429c185 100644 (file)
@@ -26,7 +26,7 @@
                C = to + thickdir * (thickness / 2);
                D = to - thickdir * (thickness / 2);
 
-               R_BeginPolygon(texture, drawflag);
+               R_BeginPolygon(texture, drawflag, false);
                R_PolygonVertex(A, '0 0 0' + shift * '1 0 0', rgb, theAlpha);
                R_PolygonVertex(B, '0 1 0' + shift * '1 0 0', rgb, theAlpha);
                R_PolygonVertex(C, '0 1 0' + (shift + length_tex) * '1 0 0', rgb, theAlpha);
index cbdf55375922de5420b3c81c51b244acf7f3c024..3069f519dc33454a5310a68a52e9ba16d2570fd8 100644 (file)
@@ -8,7 +8,7 @@
 string prvm_language;
 
 /**
- * @deprecated prefer _("translated")
+ * @deprecated prefer _("translatable text") - GMQCC's -ftranslatable-strings feature
  */
 ERASEABLE
 string language_filename(string s)
index 279210fb1808040aae9479d827fc43e5a3135ce4..be3fb00fa88ad72aad651d185bc974a4a518fd8e 100644 (file)
@@ -248,7 +248,7 @@ void ONREMOVE(entity this)
        if (this.il_lists) {
                for (int i = 0; i < IL_MAX; ++i) {
                        IntrusiveList list = il_links[i];
-                       if (this.il_lists & list.il_listmask && IL_CONTAINS(list, this)) {
+                       if ((this.il_lists & list.il_listmask) && IL_CONTAINS(list, this)) {
                                IL_REMOVE(list, this);
                        }
                }
index 94a58d0ca486636e9a917429b677f4aeb726f204..16875c8bc3e233224cc484b49a8efa63ed5f4932 100644 (file)
@@ -6,7 +6,7 @@ void print_assertfailed_severe(string expr);
 void print_assertfailed_fatal(string expr);
 
 #define assert(expr, ...) _assert(print_assertfailed_severe, expr, __VA_ARGS__)
-#define devassert(...) MACRO_BEGIN if (autocvar_developer) assert(__VA_ARGS__); MACRO_END
+#define devassert(...) MACRO_BEGIN if (autocvar_developer > 0) assert(__VA_ARGS__); MACRO_END
 
 #define assert_once(expr, ...) \
        MACRO_BEGIN \
@@ -17,10 +17,10 @@ void print_assertfailed_fatal(string expr);
                        __once = true; \
                } \
        MACRO_END
-#define devassert_once(...) MACRO_BEGIN if (autocvar_developer) assert_once(__VA_ARGS__); MACRO_END
+#define devassert_once(...) MACRO_BEGIN if (autocvar_developer > 0) assert_once(__VA_ARGS__); MACRO_END
 
 #define demand(expr, ...) _assert(print_assertfailed_fatal, expr, __VA_ARGS__)
-#define devdemand(...) MACRO_BEGIN if (autocvar_developer) demand(__VA_ARGS__); MACRO_END
+#define devdemand(...) MACRO_BEGIN if (autocvar_developer > 0) demand(__VA_ARGS__); MACRO_END
 
 #define _assert(f, expr, then) \
        MACRO_BEGIN \
index ea7f0e1fe26f62143774a14a217047780abb9e6c..d89dc2b6457ed51d632307c7d41c550646f61567 100644 (file)
@@ -69,7 +69,7 @@ ERASEABLE
 void db_dump(int db, string filename)
 {
        int fh = fopen(filename, FILE_WRITE);
-       if (fh < 0) LOG_FATALF("Can't dump DB to %s");
+       if (fh < 0) LOG_FATALF("Can't dump DB to %s", filename);
        fputs(fh, "0\n");
        for (int i = 0, n = buf_getsize(db); i < n; ++i)
        {
index 1b58eb1b9fcf75d0ddd7196843a6cb5be402d695..0cfe564f0792461ed0264663041eae2340cdc5f8 100644 (file)
@@ -2,7 +2,7 @@
 
 #include <common/command/_mod.qh>
 
-GENERIC_COMMAND(mx, "Send a matrix command") {
+GENERIC_COMMAND(mx, "Send a matrix command", false) {
     switch (argv(1)) {
         case "user":
             strcpy(matrix_user, substring(command, argv_start_index(2), -1));
index 57754d04e4334d05da4a3701217d7bf6e17d7cb4..3ce4fcfc8ec01a3506d69bc12ab7ae0f89b07afd 100644 (file)
@@ -147,7 +147,7 @@ void MX_JLF_(entity fh, entity pass, int status)
     switch (status) {
         case URL_READY_CANWRITE: {
             fh.url_content_type = "application/json";
-            url_fputs(fh, sprintf("{}", pass.message));
+            url_fputs(fh, sprintf("{%s}", pass.message));
             url_fclose(fh);
             break;
         }
index 9abeb1bcce330e1e20ede401e5e624c2d0370eae..70e17e6cf0b2ddc9146c3bbf52fec8d0d88f078b 100644 (file)
@@ -328,7 +328,7 @@ CLASS(Object)
        {
                TC(Object, this);
                string s = _("No description");
-               if (cvar("developer"))
+               if (cvar("developer") > 0)
                {
                        for (int i = 0, n = numentityfields(); i < n; ++i)
                        {
index a88bde462934134f3585707eff76e81303e8d6c2..019194a6d55df61e608e4fe9d6c126fb73ed08ad 100644 (file)
@@ -59,7 +59,7 @@
                                store.fld = field; \
                        }
        #elif defined(CSQC)
-               float ReplicateVars_time;
+               noref float ReplicateVars_time;
                #define ReplicateVars_NOT_SENDING() (time > ReplicateVars_time)
                #define ReplicateVars_DELAY(t) ReplicateVars_time = time + t
                #define ReplicateVars_DELAY_1FRAME() ReplicateVars_time = time
                        }
 
                #define REPLICATE_SIMPLE(field, cvarname) MACRO_BEGIN \
-                       if (ReplicateVars_NOT_SENDING() && field != cvar(cvarname)) \
+                       if (ReplicateVars_NOT_SENDING()) \
                        { \
-                               localcmd(strcat("cl_cmd sendcvar ", cvarname, "\n")); \
-                               ReplicateVars_DELAY_1FRAME(); \
-                               field = cvar(cvarname); \
-                               return; \
+                               float thecvar = cvar(cvarname); \
+                               if(field != thecvar) \
+                               { \
+                                       localcmd(strcat("cl_cmd sendcvar ", cvarname, "\n")); \
+                                       ReplicateVars_DELAY_1FRAME(); \
+                                       field = thecvar; \
+                                       return; \
+                               } \
                        } \
                MACRO_END
        #endif
index e0ec96b8ec0c43872992e12523329c0be74e8f5d..e1879890e8521dfe9c5173c209aee501c89da628 100644 (file)
@@ -17,8 +17,8 @@ void profile(string s)
 }
 
 #define _STATIC_INIT(func, where) \
-       ACCUMULATE void _static_##func##profile() { profile(#func); } \
-       ACCUMULATE_FUNCTION(where, _static_##func##profile) \
+       /* ACCUMULATE void _static_##func##profile() { profile(#func); } */ \
+       /* ACCUMULATE_FUNCTION(where, _static_##func##profile) */ \
        ACCUMULATE void _static_##func(); \
        ACCUMULATE_FUNCTION(where, _static_##func) \
        void _static_##func()
index b57f41af2b4927d466dd64f4533f0c7103db6511..5a2b53b69f3796da2c23802c617567d221ddbeb6 100644 (file)
@@ -11,7 +11,42 @@ USING(vectori, vector);
 const int STATS_ENGINE_RESERVE = 32;
 // must be listed in ascending order
 #define MAGIC_STATS(_, x) \
+       _(x, MOVEVARS_AIRACCEL_QW_STRETCHFACTOR, 220) \
+       _(x, MOVEVARS_AIRCONTROL_PENALTY, 221) \
+       _(x, MOVEVARS_AIRSPEEDLIMIT_NONQW, 222) \
+       _(x, MOVEVARS_AIRSTRAFEACCEL_QW, 223) \
+       _(x, MOVEVARS_AIRCONTROL_POWER, 224) \
+       _(x, MOVEFLAGS, 225) \
+       _(x, MOVEVARS_WARSOWBUNNY_AIRFORWARDACCEL, 226) \
+       _(x, MOVEVARS_WARSOWBUNNY_ACCEL, 227) \
+       _(x, MOVEVARS_WARSOWBUNNY_TOPSPEED, 228) \
+       _(x, MOVEVARS_WARSOWBUNNY_TURNACCEL, 229) \
+       _(x, MOVEVARS_WARSOWBUNNY_BACKTOSIDERATIO, 230) \
+       _(x, MOVEVARS_AIRSTOPACCELERATE, 231) \
+       _(x, MOVEVARS_AIRSTRAFEACCELERATE, 232) \
+       _(x, MOVEVARS_MAXAIRSTRAFESPEED, 233) \
+       _(x, MOVEVARS_AIRCONTROL, 234) \
+       _(x, FRAGLIMIT, 235) \
+       _(x, TIMELIMIT, 236) \
+       _(x, MOVEVARS_WALLFRICTION, 237) \
+       _(x, MOVEVARS_FRICTION, 238) \
+       _(x, MOVEVARS_WATERFRICTION, 239) \
+       _(x, MOVEVARS_TICRATE, 240) \
        _(x, MOVEVARS_TIMESCALE, 241) \
+       _(x, MOVEVARS_GRAVITY, 242) \
+       _(x, MOVEVARS_STOPSPEED, 243) \
+       _(x, MOVEVARS_MAXSPEED, 244) \
+       _(x, MOVEVARS_SPECTATORMAXSPEED, 245) \
+       _(x, MOVEVARS_ACCELERATE, 246) \
+       _(x, MOVEVARS_AIRACCELERATE, 247) \
+       _(x, MOVEVARS_WATERACCELERATE, 248) \
+       _(x, MOVEVARS_ENTGRAVITY, 249) \
+       _(x, MOVEVARS_JUMPVELOCITY, 250) \
+       _(x, MOVEVARS_EDGEFRICTION, 251) \
+       _(x, MOVEVARS_MAXAIRSPEED, 252) \
+       _(x, MOVEVARS_STEPHEIGHT, 253) \
+       _(x, MOVEVARS_AIRACCEL_QW, 254) \
+       _(x, MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION, 255) \
        /**/
 
 int g_magic_stats_hole = 0;
@@ -117,10 +152,12 @@ int g_magic_stats_hole = 0;
                        addstat_##T(STAT_##id.m_id, fld); \
                }
        void GlobalStats_update(entity this) {}
+       void GlobalStats_updateglobal() {}
     /** TODO: do we want the global copy to update? */
     #define REGISTER_STAT_3(id, T, expr) \
        REGISTER_STAT_2(id, T); \
        ACCUMULATE void GlobalStats_update(entity this) { STAT(id, this) = (expr); } \
+       ACCUMULATE void GlobalStats_updateglobal() { entity this = STATS; STAT(id, this) = (expr); } \
        STATIC_INIT(worldstat_##id) { entity this = STATS; STAT(id, this) = (expr); }
 #else
        #define REGISTER_STAT_2(id, type)
index c4b594d40fd846cf81b6e5e20de920abbb110642..a7508b8fb85c236f61619684dc1e692d5fec0859 100644 (file)
@@ -127,8 +127,6 @@ string autocvar_hud_colorset_background = "7";   // BG - White // neutral/unimpo
 /** color code replace, place inside of sprintf and parse the string */
 string CCR(string input)
 {
-       // See the autocvar declarations in util.qh for default values
-
        // foreground/normal colors
        input = strreplace("^F1", strcat("^", autocvar_hud_colorset_foreground_1), input);
        input = strreplace("^F2", strcat("^", autocvar_hud_colorset_foreground_2), input);
index ca0e84f67a95b4b8f118eac268d461a64ae6a8a7..6f419954cc5a333f18b856fc6882586debaa65d3 100644 (file)
@@ -69,18 +69,6 @@ float vlen_minnorm2d(vector v)
        return min(max(v.x, -v.x), max(v.y, -v.y));
 }
 
-ERASEABLE
-float dist_point_line(vector p, vector l0, vector ldir)
-{
-       ldir = normalize(ldir);
-
-       // remove the component in line direction
-       p = p - (p * ldir) * ldir;
-
-       // vlen of the remaining vector
-       return vlen(p);
-}
-
 /** requires that m2>m1 in all coordinates, and that m4>m3 */
 ERASEABLE
 float boxesoverlap(vector m1, vector m2, vector m3, vector m4) { return m2_x >= m3_x && m1_x <= m4_x && m2_y >= m3_y && m1_y <= m4_y && m2_z >= m3_z && m1_z <= m4_z; }
@@ -122,6 +110,19 @@ vector Rotate(vector v, float a)
 noref vector _yinvert;
 #define yinvert(v) (_yinvert = (v), _yinvert.y = 1 - _yinvert.y, _yinvert)
 
+/// \param[in] p point
+/// \param[in] l0 starting point of ldir
+/// \param[in] ldir line
+/// \return Vector starting from p perpendicular to ldir
+ERASEABLE
+vector point_line_vec(vector p, vector l0, vector ldir)
+{
+       ldir = normalize(ldir);
+       p = l0 - p;
+       // remove the component in line direction from p
+       return p - ((p * ldir) * ldir);
+}
+
 /**
  * @param dir the directional vector
  * @param norm the normalized normal
index cf86d97f9cb5e22e6a2123eaf6f7136630cd590e..2b1d00c2cccca49056f80f877d8574a483000cdf 100644 (file)
@@ -24,11 +24,12 @@ bool isinf(float e)
 }
 bool isnan(float e)
 {
-       // the sane way to detect NaN is broken because of a compiler bug
-       // (works with constants but breaks when assigned to variables)
-       // use conversion to string instead
-       //float f = e;
-       //return (e != f);
+       // The sane way to detect NaN is this:
+       // float f = e;
+       // return (e != f);
+       // but darkplaces used to be compiled with -ffinite-math-only which broke it.
+       // DP is fixed now but until all clients update (so after 0.8.3) we have to use the following workaround
+       // or they'd have issues when connecting to newer servers.
 
        // Negative NaN ("-nan") is much more common but plain "nan" can be created by negating *some* -nans so we need to check both.
        // DP's QCVM and GMQCC's QCVM behave differently - one needs ftos(-(0.0 / 0.0)), the other ftos(-sqrt(-1)).
@@ -225,7 +226,7 @@ float copysign(float e, float f)
 {
        return fabs(e) * ((f>0) ? 1 : -1);
 }
-/// Always use `isnan` function to compare because `float x = nan(); x == x;` gives true
+
 float nan(string tag)
 {
        return sqrt(-1);
index 0244b40a9d724c33713d95e4b694cce4b6f84849..66ee6b133c22b2ef98cc1e1e4aae614ed21ae79d 100644 (file)
        #include <server/utils.qh>
 #endif
 
+#ifdef SVQC
+bool autocvar_sv_warpzone_allow_selftarget;
+#endif
+
 #ifdef WARPZONELIB_KEEPDEBUG
 #define WARPZONELIB_REMOVEHACK
 #endif
@@ -213,19 +217,8 @@ void WarpZone_Touch(entity this, entity toucher)
        if(WarpZone_Teleport(this, toucher, f, 0))
        {
 #ifdef SVQC
-               string save1, save2;
-
-               save1 = this.target; this.target = string_null;
-               save2 = this.target3; this.target3 = string_null;
-               SUB_UseTargets(this, toucher, toucher); // use toucher too?
-               if (!this.target) this.target = save1;
-               if (!this.target3) this.target3 = save2;
-
-               save1 = this.target; this.target = string_null;
-               save2 = this.target2; this.target2 = string_null;
-               SUB_UseTargets(this.enemy, toucher, toucher); // use toucher too?
-               if (!this.target) this.target = save1;
-               if (!this.target2) this.target2 = save2;
+               SUB_UseTargets_SkipTargets(this, toucher, toucher, BIT(1) | BIT(3)); // use toucher too?
+               SUB_UseTargets_SkipTargets(this.enemy, toucher, toucher, BIT(1) | BIT(2)); // use toucher too?
 #endif
        }
        else
@@ -369,19 +362,8 @@ float WarpZone_CheckProjectileImpact(entity player)
        player.velocity = player.warpzone_oldvelocity;
        if(WarpZone_Teleport(wz, player, 0, 1))
        {
-               string save1, save2;
-
-               save1 = wz.target; wz.target = string_null;
-               save2 = wz.target3; wz.target3 = string_null;
-               SUB_UseTargets(wz, player, player);
-               if (!wz.target) wz.target = save1;
-               if (!wz.target3) wz.target3 = save2;
-
-               save1 = wz.enemy.target; wz.enemy.target = string_null;
-               save2 = wz.enemy.target2; wz.enemy.target2 = string_null;
-               SUB_UseTargets(wz.enemy, player, player);
-               if (!wz.enemy.target) wz.enemy.target = save1;
-               if (!wz.enemy.target2) wz.enemy.target2 = save2;
+               SUB_UseTargets_SkipTargets(wz, player, player, BIT(1) | BIT(3));
+               SUB_UseTargets_SkipTargets(wz.enemy, player, player, BIT(1) | BIT(2));
        }
        else
        {
@@ -648,7 +630,8 @@ void WarpZone_InitStep_FindTarget(entity this)
        // this way only one of the two ents needs to target
        if(this.target != "")
        {
-               this.enemy = this; // so the if(!e.enemy) check also skips this, saves one IF
+               if(!autocvar_sv_warpzone_allow_selftarget)
+                       this.enemy = this; // so the if(!e.enemy) check also skips this, saves one IF
 
                e2 = NULL;
                for(e = NULL, i = 0; (e = find(e, targetname, this.target)); )
index f195574449379ceec441847d1605267878b38789..891235def666700cc2a0865d8809d9512a1b43ac 100644 (file)
@@ -50,7 +50,7 @@ void m_gamestatus()
        gamestatus = 0;
        if (isserver()) gamestatus |= GAME_ISSERVER;
        if (clientstate() == CS_CONNECTED || isdemo()) gamestatus |= GAME_CONNECTED;
-       if (cvar("developer")) gamestatus |= GAME_DEVELOPER;
+       if (cvar("developer") > 0) gamestatus |= GAME_DEVELOPER;
 }
 
 void m_init()
@@ -73,7 +73,7 @@ void m_init()
 #endif
 
        // list all game dirs (TEST)
-       if (cvar("developer"))
+       if (cvar("developer") > 0)
        {
                for (int i = 0; ; ++i)
                {
index a3ad36355d9cece13deb37c750054cfe8794d0d2..6f1d5111b84ea5c6c2af47e48e7430704293278a 100644 (file)
@@ -183,6 +183,9 @@ void XonoticCampaignList_resizeNotify(entity me, vector relOrigin, vector relSiz
 
        me.checkMarkOrigin = eY + eX * (me.columnCheckMarkOrigin + me.columnCheckMarkSize) - me.checkMarkSize;
 
+       me.typeIconOrigin = vec3(me.columnPreviewSize - me.checkMarkSize.x, me.checkMarkOrigin.y, 0);
+       me.typeIconSize = me.checkMarkSize;
+
        rewrapCampaign(me.columnNameSize, me.rowsPerItem - 3, me.emptyLineHeight, me.realFontSize);
 }
 void XonoticCampaignList_doubleClickListBoxItem(entity me, float i, vector where)
@@ -226,13 +229,19 @@ void XonoticCampaignList_drawListBoxItem(entity me, int i, vector absSize, bool
        else
                draw_Picture(me.columnPreviewOrigin * eX, strcat("/maps/", campaign_mapname[i]), me.columnPreviewSize * eX + eY, '1 1 1', theAlpha);
 
+       s = strcat("/gfx/menu/", cvar_string("menu_skin"), "/gametype_", campaign_gametype[i]);
+       if(i <= me.campaignIndex && draw_PictureSize(s) != '0 0 0')
+               draw_Picture(me.typeIconOrigin, s, me.typeIconSize, '1 1 1', 1);
+
        if(i < me.campaignIndex)
                draw_Picture(me.checkMarkOrigin, "checkmark", me.checkMarkSize, '1 1 1', 1);
        if(i <= me.campaignIndex)
                s = campaign_shortdesc[i]; // fteqcc sucks
        else
                s = "???";
-       s = draw_TextShortenToWidth(sprintf(_("Level %d: %s"), i+1, s), me.columnNameSize, 0, me.realFontSize);
+       // NOTE the following string is equal to the one used in the campaign level notification
+       // (CAMPAIGN_MESSAGE) to avoid adding another duplicate string to translate
+       s = draw_TextShortenToWidth(strcat(sprintf(_("Level %s: "), itos(i+1)), s), me.columnNameSize, 0, me.realFontSize);
        draw_Text(me.realUpperMargin1 * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, theColor, theAlpha, 0);
 
        if(i <= me.campaignIndex)
index 298e27587466697572311d048684b11a2dc21db9..d6c674e8d6343ef21cf9722ebecd0cab9e1d2290 100644 (file)
@@ -23,6 +23,8 @@ CLASS(XonoticCampaignList, XonoticListBox)
        ATTRIB(XonoticCampaignList, columnCheckMarkSize, float, 0);
        ATTRIB(XonoticCampaignList, checkMarkOrigin, vector, '0 0 0');
        ATTRIB(XonoticCampaignList, checkMarkSize, vector, '0 0 0');
+       ATTRIB(XonoticCampaignList, typeIconOrigin, vector, '0 0 0');
+       ATTRIB(XonoticCampaignList, typeIconSize, vector, '0 0 0');
        ATTRIB(XonoticCampaignList, realUpperMargin1, float, 0);
        ATTRIB(XonoticCampaignList, realUpperMargin2, float, 0);
 
index b50f4bd83a043a0cc281e34c7c0d918783cd7954..df19ef2784b5dd5c9c95d913b7e15fbb4ac53994 100644 (file)
@@ -22,4 +22,4 @@ void XonoticDisconnectDialog_fill(entity me)
                me.TD(me, 1, 1, e = makeXonoticButton_T(_("No"), '0 1 0', _("I would play more!")));
                        e.onClick = Dialog_Close;
                        e.onClickEntity = me;
-}
\ No newline at end of file
+}
index e4ea22be0b0a4320d9cd2641f45615bc0d29127f..a61dd775526527a7b7e374f5a311e2afe1c48f76 100644 (file)
@@ -10,4 +10,4 @@ CLASS(XonoticDisconnectDialog, XonoticDialog)
        ATTRIB(XonoticDisconnectDialog, rows, float, 3);
        ATTRIB(XonoticDisconnectDialog, colums, float, 2);
        ATTRIB(XonoticDisconnectDialog, name, string, "Disconnect");
-ENDCLASS(XonoticDisconnectDialog)
\ No newline at end of file
+ENDCLASS(XonoticDisconnectDialog)
index 33fe3575a8bde07be1326970f232e4087667cf6d..eac6f754d8082755219a8ce81c3f91ba0fad97c6 100644 (file)
@@ -161,17 +161,19 @@ void XonoticMutatorsDialog_fill(entity me)
        me.TR(me);
                me.TDempty(me, 0.2);
                me.TD(me, 1, 1.8, e = makeXonoticCheckBox_T(0, "g_dodging", _("Dodging"),
-                       _("Enable dodging")));
+                       _("Enable dodging (quick acceleration in a given direction). Double-tap a directional key to dodge")));
        me.TR(me);
                me.TDempty(me, 0.2);
-               me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_touchexplode", _("Touch explode")));
+               me.TD(me, 1, 1.8, e = makeXonoticCheckBox_T(0, "g_touchexplode", _("Touch explode"),
+                        _("An explosion occurs when two players collide")));
        me.TR(me);
                me.TDempty(me, 0.2);
                me.TD(me, 1, 1.8, e = makeXonoticCheckBox_T(0, "g_cloaked", _("Cloaked"),
                        _("All players are almost invisible")));
        me.TR(me);
                me.TDempty(me, 0.2);
-               me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_buffs", _("Buffs")));
+               me.TD(me, 1, 1.8, e = makeXonoticCheckBox_T(0, "g_buffs", _("Buffs"),
+                        _("Enable buff pickups (random bonuses like Medic, Invisible, etc.) on the maps that support it")));
                        e.cvarOffValue = "-1"; // TODO: make this a radio button?
        me.TR(me);
                me.TDempty(me, 0.2);
@@ -185,7 +187,7 @@ void XonoticMutatorsDialog_fill(entity me)
        me.TR(me);
                me.TDempty(me, 0.2);
                s = makeXonoticSlider_T(10, 50, 1, "g_bloodloss",
-                       _("Amount of health below which your player gets stunned because of blood loss"));
+                       _("Amount of health below which players start bleeding out (health rots and they can't jump)"));
                me.TD(me, 1, 1.8, e = makeXonoticSliderCheckBox(0, 1, s, _("Blood loss")));
                        setDependent(e, "g_instagib", 0, 0);
        me.TR(me);
@@ -194,7 +196,7 @@ void XonoticMutatorsDialog_fill(entity me)
        me.TR(me);
                me.TDempty(me, 0.2);
                s = makeXonoticSlider_T(80, 400, 8, "sv_gravity",
-                       _("Make things fall to the ground slower, lower value means lower gravity"));
+                       _("Make things fall to the ground slower (percentage of normal gravity)"));
                        s.valueDigits = 0;
                        s.valueDisplayMultiplier = 0.125; // show gravity in percent
                me.TD(me, 1, 1.8, e = makeXonoticSliderCheckBox(800, 1, s, _("Low gravity")));
@@ -207,22 +209,25 @@ void XonoticMutatorsDialog_fill(entity me)
        me.TR(me);
                me.TDempty(me, 0.2);
                me.TD(me, 1, 1.8, e = makeXonoticCheckBox_T(0, "g_grappling_hook", _("Grappling hook"),
-                       _("Players spawn with the grappling hook")));
+                       _("Players spawn with the grappling hook. Press the 'hook' key to use it")));
        me.TR(me);
                me.TDempty(me, 0.2);
                me.TD(me, 1, 1.8, e = makeXonoticCheckBox_T(0, "g_jetpack", _("Jetpack"),
-                       _("Players spawn with the jetpack")));
+                       _("Players spawn with the jetpack. Double-tap 'jump' or press the 'jetpack' key to use it")));
        me.TR(me);
                me.TDempty(me, 0.2);
-               me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_invincible_projectiles", _("Invincible Projectiles")));
+               me.TD(me, 1, 1.8, e = makeXonoticCheckBox_T(0, "g_invincible_projectiles", _("Invincible Projectiles"),
+                        _("Projectiles can't be destroyed. However, Electro combos still work")));
                        setDependent(e, "g_instagib", 0, 0);
        me.TR(me);
                me.TDempty(me, 0.2);
-               me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_new_toys", _("New Toys")));
+               me.TD(me, 1, 1.8, e = makeXonoticCheckBox_T(0, "g_new_toys", _("New Toys"),
+                        _("Some weapon spawns will be randomly replaced with new weapons: Heavy Laser Assault Cannon, Mine Layer, Rifle, T.A.G. Seeker")));
                        setDependentWeird(e, checkCompatibility_newtoys);
        me.TR(me);
                me.TDempty(me, 0.2);
-               me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_rocket_flying", _("Rocket Flying")));
+               me.TD(me, 1, 1.8, e = makeXonoticCheckBox_T(0, "g_rocket_flying", _("Rocket Flying"),
+                        _("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")));
                        setDependent(e, "g_instagib", 0, 0);
        me.TR(me);
                me.TDempty(me, 0.2);
index e68b967a0f69a06b888beb214920dbcfd6373eac..3f5b18712ea8263b277e72a4624a2ae0af65dd21 100644 (file)
@@ -11,7 +11,7 @@ void XonoticQuitDialog_fill(entity me)
                me.TD(me, 1, 2, makeXonoticTextLabel(0.5, _("Are you sure you want to quit?")));
        me.TR(me);
        me.TR(me);
-               me.TD(me, 1, 1, e = makeXonoticCommandButton_T(_("Yes"), '1 0 0', "echo ]quit\nquit", 0,
+               me.TD(me, 1, 1, e = makeXonoticCommandButton_T(_("Yes"), '1 0 0', "echo ]quitquit", 0,
                        _("Back to work...")));
                me.TD(me, 1, 1, e = makeXonoticButton_T(_("No"), '0 1 0',
                        _("I got some more fragging to do!")));
index 7af8c550032b3dec7e6368f19b6ada4cfe8099d7..1f8c6d81cffc6cb9f8460358a67a2b2f35075412 100644 (file)
@@ -172,7 +172,7 @@ void XonoticAudioSettingsTab_fill(entity me)
                        e.sendCvars = true;
        me.TR(me);
        me.TR(me);
-               if(cvar("developer"))
+               if(cvar("developer") > 0)
                        me.TD(me, 1, 3, makeXonoticCheckBox(0, "showsound", _("Debug info about sounds")));
 
        me.gotoRC(me, me.rows - 1, 0);
index a9375327ec2e9735b2ea65db1e1632cc44edc5e1..9841f66ff3f83313b093daa686083838b0e8b967 100644 (file)
@@ -39,8 +39,8 @@ void XonoticEffectsSettingsTab_fill(entity me)
        float n;
        me.TR(me);
                me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Quality preset:")));
-               n = 5 + 2 * boolean(cvar("developer"));
-               if(cvar("developer"))
+               n = 5 + 2 * boolean(cvar("developer") > 0);
+               if(cvar("developer") > 0)
                {
                        me.TD(me, 1, 5 / n, e = makeXonoticCommandButton(ZCTX(_("PRE^OMG!")), '1 0 1', "exec effects-omg.cfg", 0));
                                e.applyButton = effectsApplyButton;
@@ -55,7 +55,7 @@ void XonoticEffectsSettingsTab_fill(entity me)
                        e.applyButton = effectsApplyButton;
                me.TD(me, 1, 5 / n, e = makeXonoticCommandButton(ZCTX(_("PRE^Ultra")), '0 0 0', "exec effects-ultra.cfg", 0));
                        e.applyButton = effectsApplyButton;
-               if(cvar("developer"))
+               if(cvar("developer") > 0)
                {
                        me.TD(me, 1, 5 / n, e = makeXonoticCommandButton(ZCTX(_("PRE^Ultimate")), '0.5 0 0', "exec effects-ultimate.cfg", 0));
                                e.applyButton = effectsApplyButton;
@@ -87,7 +87,7 @@ void XonoticEffectsSettingsTab_fill(entity me)
                me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Texture resolution:")));
                        setDependent(e, "r_showsurfaces", 0, 0);
                me.TD(me, 1, 2, e = makeXonoticPicmipSlider());
-                       if(cvar("developer"))
+                       if(cvar("developer") > 0)
                                e.addValue(e, ZCTX(_("RES^Leet")), "1337");
                        e.addValue(e, ZCTX(_("RES^Lowest")), "3");
                        e.addValue(e, ZCTX(_("RES^Very low")), "2");
@@ -125,10 +125,11 @@ void XonoticEffectsSettingsTab_fill(entity me)
                        }
                }
        me.TR(me);
-               if(cvar("developer"))
+               me.TDempty(me, 0.2);
+               me.TD(me, 1, 1, e = makeXonoticCheckBoxEx_T(1, 0, "r_sky", _("Show skyboxes"), _("Disable skyboxes for performance and visibility")));
+               if(cvar("developer") > 0)
                {
-                       me.TDempty(me, 0.2);
-                       me.TD(me, 1, 2.8, e = makeXonoticCheckBoxEx_T(3, 0, "r_showsurfaces", _("Show surfaces"),
+                       me.TD(me, 1, 1, e = makeXonoticCheckBoxEx_T(3, 0, "r_showsurfaces", _("Show surfaces"),
                                _("Disable textures completely for very slow hardware. This gives a huge performance boost, but looks very ugly.")));
                }
        me.TR(me);
index 0b3a9ff6c4402253b2a30fb8ab277ab41b6a3c3d..b4c170280c652febf3435542d8bd57073f81601f 100644 (file)
@@ -24,10 +24,9 @@ void XonoticGameViewSettingsTab_fill(entity me)
 
        me.TR(me);
                me.TD(me, 1, 3, e = makeXonoticRadioButton(1, "chase_active", "0", _("1st person perspective")));
-               makeMulti(e, "crosshair_hittest_showimpact");
        me.TR(me);
                me.TDempty(me, 0.2);
-               me.TD(me, 1, 2.8, e = makeXonoticCheckBox(0, "cl_eventchase_death", _("Slide to third person upon death")));
+               me.TD(me, 1, 2.8, e = makeXonoticCheckBoxEx(2, 0, "cl_eventchase_death", _("Slide to third person upon death")));
                setDependent(e, "chase_active", -1, 0);
        me.TR(me);
                me.TDempty(me, 0.2);
@@ -49,7 +48,6 @@ void XonoticGameViewSettingsTab_fill(entity me)
        me.TR(me);
        me.TR(me);
                me.TD(me, 1, 3, e = makeXonoticRadioButton(1, "chase_active", "1", _("3rd person perspective")));
-               makeMulti(e, "crosshair_hittest_showimpact");
        me.TR(me);
                me.TDempty(me, 0.2);
                me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Back distance")));
index 8eac7301abc705df0d96c214107ddb7683b5957a..5c77faffb501ed0ca2aebf740dd8d559548b94d4 100644 (file)
@@ -3,6 +3,7 @@
 #include "weaponslist.qh"
 #include "commandbutton.qh"
 #include "textlabel.qh"
+#include "textslider.qh"
 #include "checkbox.qh"
 #include "button.qh"
 #include "radiobutton.qh"
@@ -72,6 +73,18 @@ void XonoticGameWeaponsSettingsTab_fill(entity me)
                me.TD(me, 1, 1.0, e = makeXonoticRadioButton_T(1, "cl_gunalign", "3", _("Right align"),
                        _("Position of the weapon model; requires reconnect")));
                        setDependent(e, "r_drawviewmodel", 1, 1);
+       me.TR(me);
+                       me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Weapon model opacity:")));
+                               setDependent(e, "r_drawviewmodel", 1, 1);
+
+                       me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_viewmodel_alpha"));
+                               setDependent(e, "r_drawviewmodel", 1, 1);
+                               e.addValue(e, "15%", "0.15");
+                               e.addValue(e, "25%", "0.25");
+                               e.addValue(e, "50%", "0.5");
+                               e.addValue(e, "75%", "0.75");
+                               e.addValue(e, "100%", "1");
+                               e.configureXonoticTextSliderValues(e);
        me.TR(me);
        me.TR(me);
                me.TDempty(me, 0.2);
index ca812d30415bd23c46802c36c0359cc41e0e3bd2..1033919f4f7a2e3ce2490c7444512c2670a20b65 100644 (file)
@@ -40,10 +40,6 @@ void XonoticMiscSettingsTab_fill(entity me)
                        e.addValue(e, _("Fast ADSL"), "40000");
                        e.addValue(e, _("Broadband"), "66666");
                        e.configureXonoticTextSliderValues(e);
-       me.TR(me);
-               me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Input packets/s:")));
-               me.TD(me, 1, 2, e = makeXonoticSlider_T(30, 180, 5, "cl_netfps",
-                       _("How many input packets to send to the server each second")));
        me.TR(me);
                me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Server queries/s:")));
                me.TD(me, 1, 2, e = makeXonoticSlider(20, 100, 10, "net_slist_queriespersecond"));
@@ -64,7 +60,7 @@ void XonoticMiscSettingsTab_fill(entity me)
                e.addValue(e, strzone(_("Unlimited")), "0");
                e.configureXonoticTextSliderValues(e);
        me.TR(me);
-               if(cvar("developer"))
+               if(cvar("developer") > 0)
                {
                        me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Local latency:")));
                        me.TD(me, 1, 2, e = makeXonoticSlider(0, 1000, 25, "cl_netlocalping"));
index 0e524b6e23852cedf80e6c5c3e66e3841ac430ef..77f2602a1958091fb55dec083089de4cbf973ddc 100644 (file)
@@ -62,7 +62,7 @@ void XonoticVideoSettingsTab_fill(entity me)
                        _("Enable vertical synchronization to prevent tearing, will cap your fps to the screen refresh rate")));
 
        me.TR(me);
-               if(cvar("developer"))
+               if(cvar("developer") > 0)
                {
                        me.TD(me, 1, 3, e = makeXonoticCheckBox_T(0, "v_flipped", _("Flip view horizontally"),
                                _("Poor man's left handed mode")));
@@ -125,16 +125,16 @@ void XonoticVideoSettingsTab_fill(entity me)
                        _("Brightness of white")));
        me.TR(me);
                me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Gamma:")));
-                       setDependentAND(e, "vid_gl20", 1, 1, "v_glslgamma", 1, 1);
+                       setDependent(e, "vid_gl20", 1, 1);
                me.TD(me, 1, 2, e = makeXonoticSlider_T(0.5, 2.0, 0.05, "v_gamma",
                        _("Inverse gamma correction value, a brightness effect that does not affect white or black")));
-                       setDependentAND(e, "vid_gl20", 1, 1, "v_glslgamma", 1, 1);
+                       setDependent(e, "vid_gl20", 1, 1);
        me.TR(me);
                me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Contrast boost:")));
-                       setDependentAND(e, "vid_gl20", 1, 1, "v_glslgamma", 1, 1);
+                       setDependent(e, "vid_gl20", 1, 1);
                me.TD(me, 1, 2, e = makeXonoticSlider_T(1.0, 5.0, 0.1, "v_contrastboost",
                        _("By how much to multiply the contrast in dark areas")));
-                       setDependentAND(e, "vid_gl20", 1, 1, "v_glslgamma", 1, 1);
+                       setDependent(e, "vid_gl20", 1, 1);
        me.TR(me);
                me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Saturation:")));
                        setDependent(e, "vid_gl20", 1, 1);
@@ -157,12 +157,7 @@ void XonoticVideoSettingsTab_fill(entity me)
        me.TR(me);
                me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "vid_gl20", _("Use OpenGL 2.0 shaders (GLSL)")));
                        e.applyButton = videoApplyButton;
-       me.TR(me);
-               me.TDempty(me, 0.2);
-               me.TD(me, 1, 2.8, e = makeXonoticCheckBox_T(0, "v_glslgamma", _("Use GLSL to handle color control"),
-                       _("Enable use of GLSL to apply gamma correction, note that it might decrease performance by a lot")));
-                       setDependent(e, "vid_gl20", 1, 1);
-       if(cvar("developer"))
+       if(cvar("developer") > 0)
        {
                me.TR(me);
                        me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "v_psycho", _("Psycho coloring (easter egg)")));
index dc39346aa61f962f323964e81b05eccec083dc4f..b2ae8c0ba9269752bbeddf82c4beb723d5cf8e70 100644 (file)
@@ -128,8 +128,8 @@ void XonoticSingleplayerDialog_fill(entity me)
        me.gotoRC(me, me.rows - 2, 0);
                me.TD(me, 1, 2, e = makeXonoticTextLabel(0.5, _("Campaign Difficulty:")));
                me.TD(me, 1, 1, e = makeXonoticRadioButton(1, "g_campaign_skill", "-2", ZCTX(_("CSKL^Easy"))));
-               me.TD(me, 1, 1, e = makeXonoticRadioButton(1, "g_campaign_skill", "-1", ZCTX(_("CSKL^Medium"))));
-               me.TD(me, 1, 1, e = makeXonoticRadioButton(1, "g_campaign_skill", "0", ZCTX(_("CSKL^Hard"))));
+               me.TD(me, 1, 1, e = makeXonoticRadioButton(1, "g_campaign_skill", "0", ZCTX(_("CSKL^Medium"))));
+               me.TD(me, 1, 1, e = makeXonoticRadioButton(1, "g_campaign_skill", "2", ZCTX(_("CSKL^Hard"))));
                me.TR(me);
                me.TD(me, 1, me.columns, e = makeXonoticButton(_("Start Singleplayer!"), '0 0 0'));
                        e.onClick = CampaignList_LoadMap;
index 4f6e4a04a6dbe3201e43430975b00ede72e53c6b..f9b2be71cf770feb9efedcdc0be4de699f3d94aa 100644 (file)
@@ -14,7 +14,7 @@ string KeyBinds_Functions[MAX_KEYBINDS];
 string KeyBinds_Descriptions[MAX_KEYBINDS];
 int KeyBinds_Count = -1;
 
-void KeyBinds_Read()
+void KeyBinds_BuildList()
 {
        KeyBinds_Count = 0;
 
@@ -30,7 +30,7 @@ void KeyBinds_Read()
        #define KEYBIND_HEADER(str) KEYBIND_DEF("", str)
 
        #define KEYBIND_IS_SPECIAL(func) (substring(func, 0 ,1) == "*")
-       #define KEYBIND_SPECIAL_DEF(key) KEYBIND_DEF(strcat("*", key), "")
+       #define KEYBIND_SPECIAL_DEF(key, desc) KEYBIND_DEF(strcat("*", key), desc)
 
        KEYBIND_HEADER(_("Moving"));
        KEYBIND_DEF("+forward"                              , _("forward"));
@@ -56,8 +56,6 @@ void KeyBinds_Read()
        KEYBIND_DEF("reload"                                , _("reload"));
        KEYBIND_DEF("dropweapon"                            , _("drop weapon / throw nade"));
 
-       int i;
-
        #define ADD_TO_W_LIST(pred) \
                FOREACH(Weapons, it != WEP_Null, { \
                        if (it.impulse != imp) continue; \
@@ -92,7 +90,7 @@ void KeyBinds_Read()
        KEYBIND_DEF("spec"                                  , _("enter spectator mode"));
        KEYBIND_EMPTY_LINE();
 
-       KEYBIND_HEADER(_("Communicate"));
+       KEYBIND_HEADER(_("Communication"));
        KEYBIND_DEF("messagemode"                           , _("public chat"));
        KEYBIND_DEF("messagemode2"                          , _("team chat"));
        KEYBIND_DEF("+con_chat_maximize"                    , _("show chat history"));
@@ -106,31 +104,36 @@ void KeyBinds_Read()
        // display the hardcoded shortcut to open the console as it works for all
        // non-English keyboard layouts, unlike default keys (` and ~)
        KEYBIND_DEF("toggleconsole"                         , _("enter console"));
-               KEYBIND_SPECIAL_DEF(strcat(translate_key("SHIFT"), "+", translate_key("ESCAPE")));
+               string console_shortcut = strcat(translate_key("SHIFT"), "+", translate_key("ESCAPE"));
+               KEYBIND_SPECIAL_DEF(console_shortcut, _("enter console"));
        KEYBIND_DEF("disconnect"                            , _("disconnect"));
        KEYBIND_DEF("menu_showquitdialog"                   , _("quit"));
        KEYBIND_EMPTY_LINE();
 
        KEYBIND_HEADER(_("Teamplay"));
-       KEYBIND_DEF("messagemode2"                          , _("team chat"));
        KEYBIND_DEF("team_auto"                             , _("auto-join team"));
        KEYBIND_DEF("menu_showteamselect"                   , _("team menu"));
-       KEYBIND_DEF("+use"                                  , _("drop key / drop flag"));
+       KEYBIND_DEF("spec"                                  , _("spectate"));
        KEYBIND_EMPTY_LINE();
 
        KEYBIND_HEADER(_("Misc"));
-       KEYBIND_DEF("kill"                                  , _("respawn"));
+       KEYBIND_DEF("+use"                                  , _("drop key/flag, exit vehicle"));
+       KEYBIND_DEF("kill"                                  , _("suicide / respawn"));
        KEYBIND_DEF("quickmenu"                             , _("quick menu"));
-       KEYBIND_DEF("menu_showsandboxtools"                 , _("sandbox menu"));
-       KEYBIND_DEF("wpeditor_menu"                         , _("waypoint editor menu"));
-       KEYBIND_DEF("+button8"                              , _("drag object"));
        KEYBIND_EMPTY_LINE();
 
        KEYBIND_HEADER(_("User defined"));
 
-       for(i = 1; i <= 32; ++i)
+       for(int i = 1; i <= 32; ++i)
                KEYBIND_DEF(strcat("+userbind ", itos(i)), strcat("$userbind", itos(i)));
 
+       KEYBIND_EMPTY_LINE();
+
+       KEYBIND_HEADER(_("Development"));
+       KEYBIND_DEF("menu_showsandboxtools"                 , _("sandbox menu"));
+       KEYBIND_DEF("+button8"                              , _("drag object (sandbox)"));
+       KEYBIND_DEF("wpeditor_menu"                         , _("waypoint editor menu"));
+
        #undef KEYBIND_DEF
 }
 
@@ -177,7 +180,7 @@ void XonoticKeyBinder_loadKeyBinds(entity me)
        bool force_initial_selection = false;
        if(KeyBinds_Count < 0) // me.handle not loaded yet?
                force_initial_selection = true;
-       KeyBinds_Read();
+       KeyBinds_BuildList();
        me.nItems = KeyBinds_Count;
        if(force_initial_selection)
                me.setSelected(me, 0);
@@ -246,8 +249,10 @@ void XonoticKeyBinder_keyGrabbed(entity me, int key, bool ascii)
                {
                        k = stof(argv(j));
                        if(k != -1)
-                               //localcmd("\nunbind \"", keynumtostring(k), "\"\n");
+                       {
+                               // bind to empty cmd instead of using unbind so it gets saved in config and overrides any default binds
                                localcmd("\nbind \"", keynumtostring(k), "\" \"", KEY_NOT_BOUND_CMD, "\"\n");
+                       }
                }
        }
        m_play_click_sound(MENU_SOUND_SELECT);
@@ -318,8 +323,10 @@ void KeyBinder_Bind_Clear(entity btn, entity me)
        {
                k = stof(argv(j));
                if(k != -1)
-                       //localcmd("\nunbind \"", keynumtostring(k), "\"\n");
+               {
+                       // bind to empty cmd instead of using unbind so it gets saved in config and overrides any default binds
                        localcmd("\nbind \"", keynumtostring(k), "\" \"", KEY_NOT_BOUND_CMD, "\"\n");
+               }
        }
        m_play_click_sound(MENU_SOUND_CLEAR);
        localcmd("-zoom\n"); // to make sure we aren't in togglezoom'd state
@@ -393,9 +400,6 @@ float XonoticKeyBinder_keyDown(entity me, int key, bool ascii, float shift)
 
 void XonoticKeyBinder_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
 {
-       string s;
-       int j, n;
-       float k;
        vector theColor;
        float theAlpha;
        float extraMargin;
@@ -405,7 +409,6 @@ void XonoticKeyBinder_drawListBoxItem(entity me, int i, vector absSize, bool isS
 
        if(func == "")
        {
-               theAlpha = 1;
                theColor = SKINCOLOR_KEYGRABBER_TITLES;
                theAlpha = SKINALPHA_KEYGRABBER_TITLES;
                extraMargin = 0;
@@ -432,7 +435,7 @@ void XonoticKeyBinder_drawListBoxItem(entity me, int i, vector absSize, bool isS
 
        if(substring(descr, 0, 1) == "$")
        {
-               s = substring(descr, 1, strlen(descr) - 1);
+               string s = substring(descr, 1, strlen(descr) - 1);
                descr = cvar_string(strcat(s, "_description"));
                if(descr == "")
                        descr = s;
@@ -441,7 +444,7 @@ void XonoticKeyBinder_drawListBoxItem(entity me, int i, vector absSize, bool isS
                                theAlpha *= SKINALPHA_DISABLED;
        }
 
-       s = draw_TextShortenToWidth(descr, me.columnFunctionSize, 0, me.realFontSize);
+       string s = draw_TextShortenToWidth(descr, me.columnFunctionSize, 0, me.realFontSize);
        draw_Text(me.realUpperMargin * eY + extraMargin * eX, s, me.realFontSize, theColor, theAlpha, 0);
 
        if (func == "")
@@ -452,15 +455,19 @@ void XonoticKeyBinder_drawListBoxItem(entity me, int i, vector absSize, bool isS
                s = substring(func, 1, -1);
        else
        {
-               n = tokenize(findkeysforcommand(func, 0)); // uses '...' strings
-               for(j = 0; j < n; ++j)
+               bool joy_active = cvar("joy_active");
+               int n = tokenize(findkeysforcommand(func, 0)); // uses '...' strings
+               for(int j = 0; j < n; ++j)
                {
-                       k = stof(argv(j));
+                       float k = stof(argv(j));
                        if(k != -1)
                        {
+                               string key = keynumtostring(k);
+                               if (!joy_active && startsWith(key, "JOY"))
+                                       continue;
                                if(s != "")
                                        s = strcat(s, ", ");
-                               s = strcat(s, translate_key(keynumtostring(k)));
+                               s = strcat(s, translate_key(key));
                        }
                }
        }
index 5184ee1fd546a0f90ad3838462a57c005b7b4a9e..a18037db63178830a7e85d675a66564cf01a7a47 100644 (file)
@@ -365,11 +365,11 @@ float XonoticMapList_keyDown(entity me, float scan, float ascii, float shift)
                if(MapInfo_FindName_firstResult >= 0)
                        me.setSelected(me, MapInfo_FindName_firstResult);
        }
-       else if(shift & S_CTRL && scan == 'f') // ctrl-f (as in "F"ind)
+       else if((shift & S_CTRL) && scan == 'f') // ctrl-f (as in "F"ind)
        {
                me.parent.setFocus(me.parent, me.stringFilterBox);
        }
-       else if(shift & S_CTRL && scan == 'u') // ctrl-u (remove stringFilter line
+       else if((shift & S_CTRL) && scan == 'u') // ctrl-u (remove stringFilter line
        {
                me.stringFilterBox.setText(me.stringFilterBox, "");
                MapList_StringFilterBox_Change(me.stringFilterBox, me);
index 021e9765119d7bf70861a5cdccca8d99c1108280..21278f720cc6e37c1ed13d78dc5eca8280885c33 100644 (file)
@@ -8,10 +8,9 @@
 
 void SL_ProcessCategoryOverrides(.string override_field_string, .float override_field)
 {
-       string s;
        for (int i = 0; i < category_ent_count; ++i)
        {
-               s = categories[i].override_field_string;
+               string s = categories[i].override_field_string;
                if (s != "" && s != categories[i].cat_name)
                {
                        int catnum = 0;
@@ -70,22 +69,19 @@ entity RetrieveCategoryEnt(int catnum)
 
 bool IsServerInList(string list, string srv)
 {
-       string p;
-       int i, n;
        if(srv == "")
                return false;
        srv = netaddress_resolve(srv, 26000);
        if(srv == "")
                return false;
-       p = crypto_getidfp(srv);
-       n = tokenize_console(list);
-       for(i = 0; i < n; ++i)
+       string p = crypto_getidfp(srv);
+       int n = tokenize_console(list);
+       for(int i = 0; i < n; ++i)
        {
                if(substring(argv(i), 0, 1) != "[" && strlen(argv(i)) == 44 && strstrofs(argv(i), ".", 0) < 0)
                {
-                       if(p)
-                               if(argv(i) == p)
-                                       return true;
+                       if(p && argv(i) == p)
+                               return true;
                }
                else
                {
@@ -96,7 +92,7 @@ bool IsServerInList(string list, string srv)
        return false;
 }
 
-int CheckCategoryOverride(int cat)
+int CategoryOverride(int cat)
 {
        entity catent = RetrieveCategoryEnt(cat);
        if(catent)
@@ -107,12 +103,12 @@ int CheckCategoryOverride(int cat)
        }
        else
        {
-               error(sprintf("CheckCategoryOverride(%d): Improper category number!\n", cat));
+               error(sprintf("CategoryOverride(%d): Improper category number!\n", cat));
                return cat;
        }
 }
 
-int CheckCategoryForEntry(int entry)
+int CategoryForEntry(int entry)
 {
        string s, k, v, modtype = "";
        int j, m, impure = 0, freeslots = 0, sflags = 0;
@@ -199,8 +195,6 @@ int CheckCategoryForEntry(int entry)
                        case "minstagib":
                        case "instagib": { return CAT_INSTAGIB; }
                        case "overkill": { return CAT_OVERKILL; }
-                       //case "nix": { return CAT_NIX; }
-                       //case "newtoys": { return CAT_NEWTOYS; }
 
                        // "cts" is allowed as compat, xdf is replacement
                        case "cts":
@@ -259,8 +253,8 @@ void ServerList_Update_favoriteButton(entity btn, entity me)
        entity e = me.favoriteButton;
        if(IsFavorite(me.ipAddressBox.text))
        {
-               e.setText(e, _("Remove"));
-               clearTooltip(e);
+               e.setText(e, _("Remove favorite"));
+               setZonedTooltip(e, _("Remove the currently highlighted server from bookmarks"), string_null);
        }
        else
        {
@@ -314,14 +308,10 @@ void XonoticServerList_refreshServerList(entity me, int mode)
 
        if(mode >= REFRESHSERVERLIST_REFILTER)
        {
-               float m;
-               int i, n;
-               int listflags = 0;
-               string s, typestr, modstr;
-
-               s = me.filterString;
+               string s = me.filterString;
 
-               m = strstrofs(s, ":", 0);
+               string typestr;
+               int m = strstrofs(s, ":", 0);
                if(m >= 0)
                {
                        typestr = substring(s, 0, m);
@@ -332,7 +322,7 @@ void XonoticServerList_refreshServerList(entity me, int mode)
                else
                        typestr = "";
 
-               modstr = cvar_string("menu_slist_modfilter");
+               string modstr = cvar_string("menu_slist_modfilter");
 
                m = SLIST_MASK_AND - 1;
                resethostcachemasks();
@@ -365,8 +355,8 @@ void XonoticServerList_refreshServerList(entity me, int mode)
                }
 
                // server banning
-               n = tokenizebyseparator(_Nex_ExtResponseSystem_BannedServers, " ");
-               for(i = 0; i < n; ++i)
+               int n = tokenizebyseparator(_Nex_ExtResponseSystem_BannedServers, " ");
+               for(int i = 0; i < n; ++i)
                        if(argv(i) != "")
                                sethostcachemaskstring(++m, SLIST_FIELD_CNAME, argv(i), SLIST_TEST_NOTSTARTSWITH);
 
@@ -379,11 +369,11 @@ void XonoticServerList_refreshServerList(entity me, int mode)
                        sethostcachemaskstring(++m, SLIST_FIELD_QCSTATUS, strcat(s, ":"), SLIST_TEST_STARTSWITH);
                }
 
-               // sorting flags
-               //listflags |= SLSF_FAVORITES;
-               listflags |= SLSF_CATEGORIES;
-               if(me.currentSortOrder < 0) { listflags |= SLSF_DESCENDING; }
-               sethostcachesort(me.currentSortField, listflags);
+               int sorting_flags = 0;
+               //sorting_flags |= SLSF_FAVORITES;
+               sorting_flags |= SLSF_CATEGORIES;
+               if(me.currentSortOrder < 0) { sorting_flags |= SLSF_DESCENDING; }
+               sethostcachesort(me.currentSortField, sorting_flags);
        }
 
        resorthostcache();
@@ -404,9 +394,6 @@ void XonoticServerList_focusEnter(entity me)
 
 void XonoticServerList_draw(entity me)
 {
-       int i;
-       bool found = false, owned;
-
        if(_Nex_ExtResponseSystem_BannedServersNeedsRefresh)
        {
                if(!me.needsRefresh)
@@ -448,9 +435,9 @@ void XonoticServerList_draw(entity me)
                me.refreshServerList(me, REFRESHSERVERLIST_RESORT);
        }
 
-       owned = ((me.selectedServer == me.ipAddressBox.text) && (me.ipAddressBox.text != ""));
+       bool owned = ((me.selectedServer == me.ipAddressBox.text) && (me.ipAddressBox.text != ""));
 
-       for(i = 0; i < category_draw_count; ++i) { category_name[i] = -1; category_item[i] = -1; }
+       for(int i = 0; i < category_draw_count; ++i) { category_name[i] = -1; category_item[i] = -1; }
        category_draw_count = 0;
 
        if(autocvar_menu_slist_categories >= 0) // if less than 0, don't even draw a category heading for favorites
@@ -541,11 +528,12 @@ void XonoticServerList_draw(entity me)
        }
        else { me.nItems = gethostcachevalue(SLIST_HOSTCACHEVIEWCOUNT); }
 
-       me.connectButton.disabled = (me.lockedSelectedItem || (me.nItems == 0 && me.ipAddressBox.text == ""));
+       me.connectButton.disabled = (me.ipAddressBox.text == "");
        //me.disconnectButton.disabled = (!(gamestatus & (GAME_ISSERVER | GAME_CONNECTED)));
-       me.infoButton.disabled = (me.lockedSelectedItem || me.nItems == 0 || !owned);
-       me.favoriteButton.disabled = (me.lockedSelectedItem || (me.nItems == 0 && me.ipAddressBox.text == ""));
+       me.infoButton.disabled = !owned;
+       me.favoriteButton.disabled = (me.ipAddressBox.text == "");
 
+       bool found = false;
        if(me.lockedSelectedItem)
        {
                if(me.nItems > 0)
@@ -559,7 +547,7 @@ void XonoticServerList_draw(entity me)
        }
        else if(me.selectedServer)
        {
-               for(i = 0; i < me.nItems; ++i)
+               for(int i = 0; i < me.nItems; ++i)
                {
                        if(gethostcachestring(SLIST_FIELD_CNAME, i) == me.selectedServer)
                        {
@@ -708,13 +696,11 @@ void XonoticServerList_setSortOrder(entity me, int fld, int direction)
 }
 void XonoticServerList_positionSortButton(entity me, entity btn, float theOrigin, float theSize, string theTitle, void(entity, entity) theFunc)
 {
-       vector originInLBSpace, sizeInLBSpace;
-       originInLBSpace = eY * (-me.itemHeight);
-       sizeInLBSpace = eY * me.itemHeight + eX * (1 - me.controlWidth);
+       vector originInLBSpace = eY * (-me.itemHeight);
+       vector sizeInLBSpace = eY * me.itemHeight + eX * (1 - me.controlWidth);
 
-       vector originInDialogSpace, sizeInDialogSpace;
-       originInDialogSpace = boxToGlobal(originInLBSpace, me.Container_origin, me.Container_size);
-       sizeInDialogSpace = boxToGlobalSize(sizeInLBSpace, me.Container_size);
+       vector originInDialogSpace = boxToGlobal(originInLBSpace, me.Container_origin, me.Container_size);
+       vector sizeInDialogSpace = boxToGlobalSize(sizeInLBSpace, me.Container_size);
 
        btn.Container_origin_x = originInDialogSpace.x + sizeInDialogSpace.x * theOrigin;
        btn.Container_size_x   =                         sizeInDialogSpace.x * theSize;
@@ -759,10 +745,8 @@ void XonoticServerList_resizeNotify(entity me, vector relOrigin, vector relSize,
 }
 void ServerList_Connect_Click(entity btn, entity me)
 {
-       if (me.lockedSelectedItem)
-               return;
-       string sv = (me.ipAddressBox.text != "") ? me.ipAddressBox.text : me.selectedServer;
-       localcmd(sprintf("connect %s\n", sv));
+       if (me.ipAddressBox.text != "")
+               localcmd(sprintf("connect %s\n", me.ipAddressBox.text));
 }
 void ServerList_Favorite_Click(entity btn, entity this)
 {
@@ -788,33 +772,22 @@ void XonoticServerList_doubleClickListBoxItem(entity me, int i, vector where)
 }
 void XonoticServerList_drawListBoxItem(entity me, int i, vector absSize, bool isSelected, bool isFocused)
 {
-       // layout: Ping, Server name, Map name, NP, TP, MP
-       float p;
-       int q;
-       bool isv4, isv6;
-       vector theColor;
-       float theAlpha;
-       bool pure = false, pure_available = false;
-       int freeslots = -1, sflags = -1, j, m;
-       string s, typestr, versionstr, k, v, modname;
-
-       //printf("time: %f, i: %d, item: %d, nitems: %d\n", time, i, item, me.nItems);
-
        vector oldscale = draw_scale;
        vector oldshift = draw_shift;
 #define SET_YRANGE(start,end) \
        draw_scale = boxToGlobalSize(eX + eY * (end - start), oldscale); \
        draw_shift = boxToGlobal(eY * start, oldshift, oldscale);
 
-       for (j = 0; j < category_draw_count; ++j) {
+       int c;
+       for (c = 0; c < category_draw_count; ++c) {
                // Matches exactly the headings with increased height.
-               if (i == category_item[j])
+               if (i == category_item[c])
                        break;
        }
 
-       if (j < category_draw_count)
+       if (c < category_draw_count)
        {
-               entity catent = RetrieveCategoryEnt(category_name[j]);
+               entity catent = RetrieveCategoryEnt(category_name[c]);
                if(catent)
                {
                        SET_YRANGE(
@@ -848,33 +821,34 @@ void XonoticServerList_drawListBoxItem(entity me, int i, vector absSize, bool is
                draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_FOCUSED, me.focusedItemAlpha);
        }
 
-       s = gethostcachestring(SLIST_FIELD_QCSTATUS, i);
-       m = tokenizebyseparator(s, ":");
-       typestr = "";
+       string s = gethostcachestring(SLIST_FIELD_QCSTATUS, i);
+       int m = tokenizebyseparator(s, ":");
+       string typestr = "", versionstr = "";
        if(m >= 2)
        {
                typestr = argv(0);
                versionstr = argv(1);
        }
-       freeslots = -1;
-       modname = "";
-       for(j = 2; j < m; ++j)
+       bool pure = false, pure_available = false;
+       int freeslots = -1, sflags = -1;
+       string modname = "";
+       for(int j = 2; j < m; ++j)
        {
                if(argv(j) == "")
                        break;
-               k = substring(argv(j), 0, 1);
-               v = substring(argv(j), 1, -1);
-               if(k == "P")
+               string key = substring(argv(j), 0, 1);
+               string value = substring(argv(j), 1, -1);
+               if(key == "P")
                {
-                       pure = (stof(v) == 0);
+                       pure = (stof(value) == 0);
                        pure_available = true;
                }
-               else if(k == "S")
-                       freeslots = stof(v);
-               else if(k == "F")
-                       sflags = stoi(v);
-               else if(k == "M")
-                       modname = v;
+               else if(key == "S")
+                       freeslots = stof(value);
+               else if(key == "F")
+                       sflags = stoi(value);
+               else if(key == "M")
+                       modname = value;
        }
 
 #ifdef COMPAT_NO_MOD_IS_XONOTIC
@@ -901,6 +875,7 @@ void XonoticServerList_drawListBoxItem(entity me, int i, vector absSize, bool is
        if(modname != "newtoys")
                pure_available = false;
 
+       float theAlpha;
        if(gethostcachenumber(SLIST_FIELD_FREESLOTS, i) <= 0)
                theAlpha = SKINALPHA_SERVERLIST_FULL;
        else if(freeslots == 0)
@@ -910,18 +885,19 @@ void XonoticServerList_drawListBoxItem(entity me, int i, vector absSize, bool is
        else
                theAlpha = 1;
 
-       p = gethostcachenumber(SLIST_FIELD_PING, i);
+       float ping = gethostcachenumber(SLIST_FIELD_PING, i);
        const int PING_LOW = 75;
        const int PING_MED = 200;
        const int PING_HIGH = 500;
-       if(p < PING_LOW)
-               theColor = SKINCOLOR_SERVERLIST_LOWPING + (SKINCOLOR_SERVERLIST_MEDPING - SKINCOLOR_SERVERLIST_LOWPING) * (p / PING_LOW);
-       else if(p < PING_MED)
-               theColor = SKINCOLOR_SERVERLIST_MEDPING + (SKINCOLOR_SERVERLIST_HIGHPING - SKINCOLOR_SERVERLIST_MEDPING) * ((p - PING_LOW) / (PING_MED - PING_LOW));
-       else if(p < PING_HIGH)
+       vector theColor;
+       if(ping < PING_LOW)
+               theColor = SKINCOLOR_SERVERLIST_LOWPING + (SKINCOLOR_SERVERLIST_MEDPING - SKINCOLOR_SERVERLIST_LOWPING) * (ping / PING_LOW);
+       else if(ping < PING_MED)
+               theColor = SKINCOLOR_SERVERLIST_MEDPING + (SKINCOLOR_SERVERLIST_HIGHPING - SKINCOLOR_SERVERLIST_MEDPING) * ((ping - PING_LOW) / (PING_MED - PING_LOW));
+       else if(ping < PING_HIGH)
        {
                theColor = SKINCOLOR_SERVERLIST_HIGHPING;
-               theAlpha *= 1 + (SKINALPHA_SERVERLIST_HIGHPING - 1) * ((p - PING_MED) / (PING_HIGH - PING_MED));
+               theAlpha *= 1 + (SKINALPHA_SERVERLIST_HIGHPING - 1) * ((ping - PING_MED) / (PING_HIGH - PING_MED));
        }
        else
        {
@@ -937,7 +913,7 @@ void XonoticServerList_drawListBoxItem(entity me, int i, vector absSize, bool is
 
        s = gethostcachestring(SLIST_FIELD_CNAME, i);
 
-       isv4 = isv6 = false;
+       bool isv4 = false, isv6 = false;
        if(substring(s, 0, 1) == "[")
        {
                isv6 = true;
@@ -949,27 +925,27 @@ void XonoticServerList_drawListBoxItem(entity me, int i, vector absSize, bool is
                me.seenIPv4 += 1;
        }
 
-       q = stof(substring(crypto_getencryptlevel(s), 0, 1));
-       if((q <= 0 && cvar("crypto_aeslevel") >= 3) || (q >= 3 && cvar("crypto_aeslevel") <= 0))
+       int crypto = stof(substring(crypto_getencryptlevel(s), 0, 1));
+       if((crypto <= 0 && cvar("crypto_aeslevel") >= 3) || (crypto >= 3 && cvar("crypto_aeslevel") <= 0))
        {
                theColor = SKINCOLOR_SERVERLIST_IMPOSSIBLE;
                theAlpha = SKINALPHA_SERVERLIST_IMPOSSIBLE;
        }
 
-       if(q == 1)
+       if(crypto == 1)
        {
                if(cvar("crypto_aeslevel") >= 2)
-                       q |= 4;
+                       crypto |= 4;
        }
-       if(q == 2)
+       if(crypto == 2)
        {
                if(cvar("crypto_aeslevel") >= 1)
-                       q |= 4;
+                       crypto |= 4;
        }
-       if(q == 3)
-               q = 5;
-       else if(q >= 3)
-               q -= 2;
+       if(crypto == 3)
+               crypto = 5;
+       else if(crypto >= 3)
+               crypto -= 2;
        // possible status:
        // 0: crypto off
        // 1: AES possible
@@ -1001,8 +977,8 @@ void XonoticServerList_drawListBoxItem(entity me, int i, vector absSize, bool is
        iconPos.x += iconSize.x;
 
        // AES
-       if(q > 0)
-               draw_Picture(iconPos, strcat("icon_aeslevel", ftos(q)), iconSize, '1 1 1', 1);
+       if(crypto > 0)
+               draw_Picture(iconPos, strcat("icon_aeslevel", ftos(crypto)), iconSize, '1 1 1', 1);
 
        iconPos.x += iconSize.x;
 
@@ -1040,7 +1016,7 @@ void XonoticServerList_drawListBoxItem(entity me, int i, vector absSize, bool is
                string t = "";
                if(me.seenIPv4 && me.seenIPv6)
                        t = strcat(t, (isv6) ? "IPv6, " : "IPv4, ");
-               t = strcat(t, _("encryption:"), " ", (q ? sprintf(_("AES level %d"), q) : ZCTX(_("ENC^none"))), ", ");
+               t = strcat(t, _("encryption:"), " ", (crypto ? sprintf(_("AES level %d"), crypto) : ZCTX(_("ENC^none"))), ", ");
                t = strcat(t, sprintf(_("mod: %s"), ((modname == "xonotic") ? ZCTX(_("MOD^Default")) : original_modname)));
                if(pure_available)
                        t = strcat(t, sprintf(" (%s)", (pure) ? _("official settings") : _("modified settings")));
@@ -1053,7 +1029,7 @@ void XonoticServerList_drawListBoxItem(entity me, int i, vector absSize, bool is
        // --------------
 
        // ping
-       s = ftos(p);
+       s = ftos(ping);
        draw_Text(me.realUpperMargin * eY + (me.columnPingOrigin + me.columnPingSize - draw_TextWidth(s, 0, me.realFontSize)) * eX, s, me.realFontSize, theColor, theAlpha, 0);
 
        // server name
@@ -1140,8 +1116,7 @@ float XonoticServerList_getTotalHeight(entity me)
 int XonoticServerList_getItemAtPos(entity me, float pos)
 {
        pos = pos / me.itemHeight;
-       int i;
-       for (i = category_draw_count - 1; i >= 0; --i) {
+       for (int i = category_draw_count - 1; i >= 0; --i) {
                int itemidx = category_item[i];
                float itempos = i * me.categoriesHeight + category_item[i];
                if (pos >= itempos + me.categoriesHeight + 1)
@@ -1154,8 +1129,7 @@ int XonoticServerList_getItemAtPos(entity me, float pos)
 }
 float XonoticServerList_getItemStart(entity me, int item)
 {
-       int i;
-       for (i = category_draw_count - 1; i >= 0; --i) {
+       for (int i = category_draw_count - 1; i >= 0; --i) {
                int itemidx = category_item[i];
                float itempos = i * me.categoriesHeight + category_item[i];
                if (item >= itemidx + 1)
@@ -1168,8 +1142,7 @@ float XonoticServerList_getItemStart(entity me, int item)
 }
 float XonoticServerList_getItemHeight(entity me, int item)
 {
-       int i;
-       for (i = 0; i < category_draw_count; ++i) {
+       for (int i = 0; i < category_draw_count; ++i) {
                // Matches exactly the headings with increased height.
                if (item == category_item[i])
                        return me.itemHeight * (me.categoriesHeight + 1);
index 01b065df78b302d31d160590b7c76489ed19c189..8ad1856b07986ba5477b1f5a6b104e7ed486cab4 100644 (file)
@@ -71,7 +71,7 @@ ENDCLASS(XonoticServerList)
 entity makeXonoticServerList();
 
 void RegisterSLCategories();
-float CheckCategoryForEntry(float entry);
+float CategoryForEntry(float entry);
 void ServerList_Filter_Change(entity box, entity me);
 void ServerList_Categories_Click(entity box, entity me);
 void ServerList_ShowEmpty_Click(entity box, entity me);
@@ -127,8 +127,8 @@ float IsServerInList(string list, string srv);
 
 entity RetrieveCategoryEnt(float catnum);
 
-float CheckCategoryOverride(float cat);
-float m_gethostcachecategory(float entry) { return CheckCategoryOverride(CheckCategoryForEntry(entry)); }
+float CategoryOverride(float cat);
+float m_gethostcachecategory(float entry) { return CategoryOverride(CategoryForEntry(entry)); }
 
 
 // fields for category entities
index 72639fcb1ca93ddd504d34c262d3a5d8854ace78..5e2b1bf81785df0b4f9189345b7d9f718567a1a1 100644 (file)
@@ -11,13 +11,13 @@ void XonoticParticlesSlider_configureXonoticParticlesSlider(entity me)
 {
        me.configureXonoticTextSlider(me, "cl_particles_quality",
                _("Multiplier for amount of particles. Less means less particles, which in turn gives for better performance"));
-       if(cvar("developer")) { me.addValue(me, ZCTX(_("PART^OMG")),      "0.25 250 0"); }
+       if(cvar("developer") > 0) { me.addValue(me, ZCTX(_("PART^OMG")),      "0.25 250 0"); }
        me.addValue(me,                         ZCTX(_("PART^Low")),      "0.5 500 0");
        me.addValue(me,                         ZCTX(_("PART^Medium")),   "0.75 750 0");
        me.addValue(me,                         ZCTX(_("PART^Normal")),   "1.0 1000 1");
        me.addValue(me,                         ZCTX(_("PART^High")),     "1.5 1500 1");
        me.addValue(me,                         ZCTX(_("PART^Ultra")),    "2.0 2000 2");
-       if(cvar("developer")) { me.addValue(me, ZCTX(_("PART^Ultimate")), "3.0 3000 2"); }
+       if(cvar("developer") > 0) { me.addValue(me, ZCTX(_("PART^Ultimate")), "3.0 3000 2"); }
        me.configureXonoticTextSliderValues(me);
 }
 void XonoticParticlesSlider_loadCvars(entity me)
index c203a93030a6e986ca646ee5298a9cf6ba891c36..5e9fdb03d96d9a0ab079810d52fe799fdbf41625 100644 (file)
@@ -127,6 +127,7 @@ void makeCallback(entity e, entity cbent, void(entity, entity) cbfunc)
 .bool disabled;
 void setDependent_Check(entity e)
 {
+       bool disabled_prev = e.disabled;
        float f;
        string s;
        if(e.func_setDependent)
@@ -165,6 +166,8 @@ void setDependent_Check(entity e)
                                e.disabled = (e.disabled + ((f >= e.cvar3Max_setDependent) && (f <= e.cvar3Min_setDependent)) > e.op_setDependent);
                }
        }
+       if (disabled_prev != e.disabled && e.loadCvars)
+               e.loadCvars(e);
 }
 void setDependent_Draw(entity e)
 {
@@ -705,7 +708,7 @@ int GameType_GetCount()
        #define GAMETYPE(id) ++i;
        GAMETYPES
        #undef GAMETYPE
-       #define GAMETYPE(it) { if (dev) ++i; }
+       #define GAMETYPE(it) { if (dev > 0) ++i; }
        HIDDEN_GAMETYPES
        #undef GAMETYPE
        return i;
index a783d72314a7a1c571014ce6b5cbe70d2d0ac440..79989cc176d1a3e70200cd3fe03f60da91458817 100644 (file)
@@ -39,6 +39,7 @@ float autocvar_g_balance_falldamage_deadminspeed;
 float autocvar_g_balance_falldamage_factor;
 int autocvar_g_balance_falldamage_maxdamage;
 float autocvar_g_balance_falldamage_minspeed;
+bool autocvar_g_balance_falldamage_onlyvertical;
 int autocvar_g_balance_firetransfer_damage;
 int autocvar_g_balance_firetransfer_time;
 float autocvar_g_balance_fuel_limit;
@@ -92,7 +93,7 @@ float autocvar_g_ballistics_density_corpse;
 float autocvar_g_ballistics_density_player;
 float autocvar_g_ballistics_mindistance;
 bool autocvar_g_ballistics_penetrate_clips = true;
-float autocvar_g_ballistics_solidpenetration_exponent = 0.25;
+float autocvar_g_ballistics_solidpenetration_exponent = 1;
 float autocvar_g_ban_default_bantime;
 float autocvar_g_ban_default_masksize;
 float autocvar_g_ban_sync_interval;
@@ -158,6 +159,7 @@ bool autocvar_g_maplist_votable_suggestions;
 bool autocvar_g_maplist_votable_suggestions_override_mostrecent;
 float autocvar_g_maplist_votable_timeout;
 bool autocvar_g_maplist_ignore_sizes;
+bool autocvar_g_maplist_sizes_count_maxplayers = true;
 bool autocvar_g_maplist_sizes_count_bots = true;
 int autocvar_g_maxplayers;
 float autocvar_g_maxplayers_spectator_blocktime;
@@ -300,6 +302,7 @@ int autocvar_sv_eventlog_files_counter;
 string autocvar_sv_eventlog_files_nameprefix;
 string autocvar_sv_eventlog_files_namesuffix;
 bool autocvar_sv_eventlog_files_timestamps;
+bool autocvar_sv_eventlog_ipv6_delimiter = false;
 float autocvar_sv_friction_on_land;
 var float autocvar_sv_friction_slick = 0.5;
 float autocvar_sv_gameplayfix_q2airaccelerate = 1;
@@ -528,4 +531,4 @@ bool autocvar_sv_showspectators;
 bool autocvar_g_weaponswitch_debug;
 bool autocvar_g_weaponswitch_debug_alternate;
 bool autocvar_g_allow_checkpoints;
-bool autocvar_sv_vq3compat_changehitbox = false;
+bool autocvar_sv_q3defragcompat_changehitbox = false;
index 40afed17990b7e93c40e41e194b5893054c54911..7b30b62dfabbd720111f6cafad9296c231ce7a66 100644 (file)
@@ -104,7 +104,8 @@ void bot_think(entity this)
 
        // clear buttons
        PHYS_INPUT_BUTTON_ATCK(this) = false;
-       PHYS_INPUT_BUTTON_JUMP(this) = false;
+       // keep jump button pressed for a short while, useful with ramp jumps
+       PHYS_INPUT_BUTTON_JUMP(this) = (!IS_DEAD(this) && time < this.bot_jump_time + 0.2);
        PHYS_INPUT_BUTTON_ATCK2(this) = false;
        PHYS_INPUT_BUTTON_ZOOM(this) = false;
        PHYS_INPUT_BUTTON_CROUCH(this) = false;
@@ -145,21 +146,7 @@ void bot_think(entity this)
 void bot_setnameandstuff(entity this)
 {
        string readfile, s;
-       float file, tokens, prio;
-
-       string bot_name, bot_model, bot_skin, bot_shirt, bot_pants;
-       string name, prefix, suffix;
-
-       if(autocvar_g_campaign)
-       {
-               prefix = "";
-               suffix = "";
-       }
-       else
-       {
-               prefix = autocvar_bot_prefix;
-               suffix = autocvar_bot_suffix;
-       }
+       int file, tokens, prio;
 
        file = fopen(autocvar_bot_config_file, FILE_READ);
 
@@ -170,6 +157,26 @@ void bot_setnameandstuff(entity this)
        }
        else
        {
+               entity balance = TeamBalance_CheckAllowedTeams(NULL);
+               TeamBalance_GetTeamCounts(balance, NULL);
+               int smallest_team = -1;
+               int smallest_count = -1;
+               if (teamplay)
+               {
+                       for (int i = 1; i <= AvailableTeams(); ++i)
+                       {
+                               // NOTE if (autocvar_g_campaign && autocvar_g_campaign_forceteam == i)
+                               // TeamBalance_GetNumberOfPlayers(balance, i); returns the number of players + 1
+                               // since it keeps a spot for the real player in the desired team
+                               int count = TeamBalance_GetNumberOfPlayers(balance, i);
+                               if (smallest_count < 0 || count < smallest_count)
+                               {
+                                       smallest_team = i;
+                                       smallest_count = count;
+                               }
+                       }
+               }
+               TeamBalance_Destroy(balance);
                RandomSelection_Init();
                while((readfile = fgets(file)))
                {
@@ -177,24 +184,41 @@ void bot_setnameandstuff(entity this)
                                continue;
                        if(substring(readfile, 0, 1) == "#")
                                continue;
+                       // NOTE if the line is empty tokenizebyseparator(readfile, "\t")
+                       // will create 1 empty token because there's no separator (bug?)
+                       if (readfile == "")
+                               continue;
                        tokens = tokenizebyseparator(readfile, "\t");
                        if(tokens == 0)
                                continue;
                        s = argv(0);
-                       prio = 1;
+                       prio = 0;
+                       bool conflict = false;
                        FOREACH_CLIENT(IS_BOT_CLIENT(it), {
-                               if(s == it.cleanname)
+                               if (s == it.cleanname)
                                {
-                                       prio = 0;
+                                       conflict = true;
                                        break;
                                }
                        });
+                       if (!conflict)
+                               prio += 1;
+                       if (teamplay && !(autocvar_bot_vs_human && AvailableTeams() == 2))
+                       {
+                               int forced_team = stof(argv(5));
+                               if (!Team_IsValidIndex(forced_team))
+                                       forced_team = 0;
+                               if (!forced_team || forced_team == smallest_team)
+                                       prio += 2;
+                       }
                        RandomSelection_AddString(readfile, 1, prio);
                }
                readfile = RandomSelection_chosen_string;
                fclose(file);
        }
 
+       string bot_name, bot_model, bot_skin, bot_shirt, bot_pants;
+
        tokens = tokenizebyseparator(readfile, "\t");
        if(argv(0) != "") bot_name = argv(0);
        else bot_name = "Bot";
@@ -211,7 +235,10 @@ void bot_setnameandstuff(entity this)
        if(argv(4) != "" && stof(argv(4)) >= 0) bot_pants = argv(4);
        else bot_pants = ftos(floor(random() * 15));
 
-       this.bot_forced_team = stof(argv(5));
+       if (teamplay && !(autocvar_bot_vs_human && AvailableTeams() == 2))
+               this.bot_forced_team = stof(argv(5));
+       else
+               this.bot_forced_team = 0;
 
        prio = 6;
 
@@ -250,13 +277,10 @@ void bot_setnameandstuff(entity this)
        setcolor(this, stof(bot_shirt) * 16 + stof(bot_pants));
        this.bot_preferredcolors = this.clientcolors;
 
-       // pick the name
-       if (autocvar_bot_usemodelnames)
-               name = bot_model;
-       else
-               name = bot_name;
+       string prefix = (autocvar_g_campaign ? "" : autocvar_bot_prefix);
+       string suffix = (autocvar_g_campaign ? "" : autocvar_bot_suffix);
+       string name = (autocvar_bot_usemodelnames ? bot_model : bot_name);
 
-       // number bots with identical names
        if (name == "")
        {
                name = ftos(etof(this));
@@ -264,6 +288,7 @@ void bot_setnameandstuff(entity this)
        }
        else
        {
+               // number bots with identical names
                int j = 0;
                FOREACH_CLIENT(IS_BOT_CLIENT(it), {
                        if(it.cleanname == name)
@@ -285,6 +310,10 @@ void bot_setnameandstuff(entity this)
 
 void bot_custom_weapon_priority_setup()
 {
+       static string bot_priority_far_prev;
+       static string bot_priority_mid_prev;
+       static string bot_priority_close_prev;
+       static string bot_priority_distances_prev;
        float tokens, i, w;
 
        bot_custom_weapon = false;
@@ -292,70 +321,50 @@ void bot_custom_weapon_priority_setup()
        if(     autocvar_bot_ai_custom_weapon_priority_far == "" ||
                autocvar_bot_ai_custom_weapon_priority_mid == "" ||
                autocvar_bot_ai_custom_weapon_priority_close == "" ||
-               autocvar_bot_ai_custom_weapon_priority_distances == ""
+               autocvar_bot_ai_custom_weapon_priority_distances == ""
        )
                return;
 
-       // Parse distances
-       tokens = tokenizebyseparator(autocvar_bot_ai_custom_weapon_priority_distances," ");
-
-       if (tokens!=2)
-               return;
-
-       bot_distance_far = stof(argv(0));
-       bot_distance_close = stof(argv(1));
-
-       if(bot_distance_far < bot_distance_close){
-               bot_distance_far = stof(argv(1));
-               bot_distance_close = stof(argv(0));
-       }
-
-       // Initialize list of weapons
-       bot_weapons_far[0] = -1;
-       bot_weapons_mid[0] = -1;
-       bot_weapons_close[0] = -1;
+       if (bot_priority_distances_prev != autocvar_bot_ai_custom_weapon_priority_distances)
+       {
+               strcpy(bot_priority_distances_prev, autocvar_bot_ai_custom_weapon_priority_distances);
+               tokens = tokenizebyseparator(autocvar_bot_ai_custom_weapon_priority_distances," ");
 
-       // Parse far distance weapon priorities
-       tokens = tokenizebyseparator(W_NumberWeaponOrder(autocvar_bot_ai_custom_weapon_priority_far)," ");
+               if (tokens!=2)
+                       return;
 
-       int c = 0;
-       for(i=0; i < tokens && c < Weapons_COUNT; ++i){
-               w = stof(argv(i));
-               if ( w >= WEP_FIRST && w <= WEP_LAST) {
-                       bot_weapons_far[c] = w;
-                       ++c;
-               }
-       }
-       if(c < Weapons_COUNT)
-               bot_weapons_far[c] = -1;
+               bot_distance_far = stof(argv(0));
+               bot_distance_close = stof(argv(1));
 
-       // Parse mid distance weapon priorities
-       tokens = tokenizebyseparator(W_NumberWeaponOrder(autocvar_bot_ai_custom_weapon_priority_mid)," ");
-
-       c = 0;
-       for(i=0; i < tokens && c < Weapons_COUNT; ++i){
-               w = stof(argv(i));
-               if ( w >= WEP_FIRST && w <= WEP_LAST) {
-                       bot_weapons_mid[c] = w;
-                       ++c;
+               if(bot_distance_far < bot_distance_close){
+                       bot_distance_far = stof(argv(1));
+                       bot_distance_close = stof(argv(0));
                }
        }
-       if(c < Weapons_COUNT)
-               bot_weapons_mid[c] = -1;
 
-       // Parse close distance weapon priorities
-       tokens = tokenizebyseparator(W_NumberWeaponOrder(autocvar_bot_ai_custom_weapon_priority_close)," ");
+       int c;
+
+       #define PARSE_WEAPON_PRIORITIES(dist) MACRO_BEGIN \
+               if (bot_priority_##dist##_prev != autocvar_bot_ai_custom_weapon_priority_##dist) { \
+                       strcpy(bot_priority_##dist##_prev, autocvar_bot_ai_custom_weapon_priority_##dist); \
+                       tokens = tokenizebyseparator(W_NumberWeaponOrder(autocvar_bot_ai_custom_weapon_priority_##dist)," "); \
+                       bot_weapons_##dist[0] = -1; \
+                       c = 0; \
+                       for(i = 0; i < tokens && c < Weapons_COUNT; ++i) { \
+                               w = stof(argv(i)); \
+                               if (w >= WEP_FIRST && w <= WEP_LAST) { \
+                                       bot_weapons_##dist[c] = w; \
+                                       ++c; \
+                               } \
+                       } \
+                       if (c < Weapons_COUNT) \
+                               bot_weapons_##dist[c] = -1; \
+               } \
+       MACRO_END
 
-       c = 0;
-       for(i=0; i < tokens && i < Weapons_COUNT; ++i){
-               w = stof(argv(i));
-               if ( w >= WEP_FIRST && w <= WEP_LAST) {
-                       bot_weapons_close[c] = w;
-                       ++c;
-               }
-       }
-       if(c < Weapons_COUNT)
-               bot_weapons_close[c] = -1;
+       PARSE_WEAPON_PRIORITIES(far);
+       PARSE_WEAPON_PRIORITIES(mid);
+       PARSE_WEAPON_PRIORITIES(close);
 
        bot_custom_weapon = true;
 }
@@ -822,10 +831,6 @@ void bot_serverframe()
        if (autocvar_g_waypointeditor_auto)
                botframe_autowaypoints();
 
-       if(time > bot_cvar_nextthink)
-       {
-               if(currentbots>0)
-                       bot_custom_weapon_priority_setup();
-               bot_cvar_nextthink = time + 5;
-       }
+       if (currentbots > 0)
+               bot_custom_weapon_priority_setup();
 }
index 98b2ae3df78fb4d970ffd60528d65339b834f687..88dba449d5fe245d9a63b05c019f9c1ffd1009ec 100644 (file)
@@ -65,6 +65,7 @@ entity bot_list;
 .bool bot_pickup_respawning;
 .float bot_canfire;
 .float bot_strategytime;
+.float bot_jump_time;
 
 .float bot_forced_team;
 .float bot_config_loaded;
@@ -75,7 +76,6 @@ entity bot_strategytoken;
 float botframe_spawnedwaypoints;
 float botframe_nextthink;
 float botframe_nextdangertime;
-float bot_cvar_nextthink;
 
 int _content_type;
 #define IN_LAVA(pos) (_content_type = pointcontents(pos), (_content_type == CONTENT_LAVA || _content_type == CONTENT_SLIME))
index 55bc9c8f3f1ce218751bf1c57fdf5e6c3b6e86bc..269cd68044fe5902009a8fe610b3e67da8472985 100644 (file)
@@ -19,10 +19,12 @@ float autocvar_bot_ai_aimskill_order_mix_3th;
 float autocvar_bot_ai_aimskill_order_mix_4th;
 float autocvar_bot_ai_aimskill_order_mix_5th;
 float autocvar_bot_ai_aimskill_think;
-float autocvar_bot_ai_bunnyhop_firstjumpdelay;
 float autocvar_bot_ai_bunnyhop_skilloffset;
-float autocvar_bot_ai_bunnyhop_startdistance;
-float autocvar_bot_ai_bunnyhop_stopdistance;
+float autocvar_bot_ai_bunnyhop_dir_deviation_max;
+float autocvar_bot_ai_bunnyhop_downward_pitch_max;
+float autocvar_bot_ai_bunnyhop_turn_angle_min;
+float autocvar_bot_ai_bunnyhop_turn_angle_max;
+float autocvar_bot_ai_bunnyhop_turn_angle_reduction;
 float autocvar_bot_ai_chooseweaponinterval;
 string autocvar_bot_ai_custom_weapon_priority_close;
 string autocvar_bot_ai_custom_weapon_priority_distances;
@@ -31,6 +33,7 @@ string autocvar_bot_ai_custom_weapon_priority_mid;
 float autocvar_bot_ai_dangerdetectioninterval;
 float autocvar_bot_ai_dangerdetectionupdates;
 float autocvar_bot_ai_enemydetectioninterval;
+float autocvar_bot_ai_enemydetectioninterval_stickingtoenemy;
 float autocvar_bot_ai_enemydetectionradius;
 float autocvar_bot_ai_friends_aware_pickup_radius;
 float autocvar_bot_ai_ignoregoal_timeout;
index 477d1ec464c9c4af95f10f6dd3d2b260bd5bc6e3..6515cc44efad6bdcbb63a6f11c55f16586ed7bab 100644 (file)
@@ -47,8 +47,12 @@ void havocbot_ai(entity this)
                }
                else
                {
-                       if (!this.jumppadcount && !STAT(FROZEN, this))
+                       if (!this.jumppadcount && !STAT(FROZEN, this)
+                               && !(this.goalcurrent_prev && (this.goalcurrent_prev.wpflags & WAYPOINTFLAG_JUMP) && !IS_ONGROUND(this)))
+                       {
+                               // find a new goal
                                this.havocbot_role(this); // little too far down the rabbit hole
+                       }
                }
 
                // if we don't have a goal and we're under water look for a waypoint near the "shore" and push it
@@ -100,6 +104,8 @@ void havocbot_ai(entity this)
        {
                if (this.goalcurrent)
                        navigation_clearroute(this);
+               this.enemy = NULL;
+               this.bot_aimtarg = NULL;
                return;
        }
 
@@ -198,6 +204,63 @@ void havocbot_ai(entity this)
        }
 }
 
+void havocbot_bunnyhop(entity this, vector dir)
+{
+       bool can_run = false;
+       if (!(this.aistatus & AI_STATUS_ATTACKING) && this.goalcurrent && !IS_PLAYER(this.goalcurrent)
+               && vdist(vec2(this.velocity), >=, autocvar_sv_maxspeed) && !(this.aistatus & AI_STATUS_DANGER_AHEAD)
+               && this.waterlevel <= WATERLEVEL_WETFEET && !IS_DUCKED(this)
+               && IS_ONGROUND(this) && !(this.goalcurrent_prev && (this.goalcurrent_prev.wpflags & WAYPOINTFLAG_JUMP)))
+       {
+               vector vel_angles = vectoangles(this.velocity);
+               vector deviation = vel_angles - vectoangles(dir);
+               while (deviation.y < -180) deviation.y = deviation.y + 360;
+               while (deviation.y > 180) deviation.y = deviation.y - 360;
+               if (fabs(deviation.y) < autocvar_bot_ai_bunnyhop_dir_deviation_max)
+               {
+                       vector gco = get_closer_dest(this.goalcurrent, this.origin);
+                       float vel = vlen(vec2(this.velocity));
+
+                       // with the current physics, jump distance grows linearly with the speed
+                       float jump_distance = 52.661 + 0.606 * vel;
+                       jump_distance += this.origin.z - gco.z; // roughly take into account vertical distance too
+                       if (vdist(vec2(gco - this.origin), >, max(0, jump_distance)))
+                               can_run = true;
+                       else if (!(this.goalcurrent.wpflags & WAYPOINTFLAG_JUMP)
+                               && !(this.goalcurrent.wpflags & WAYPOINTFLAG_TELEPORT)
+                               && this.goalstack01 && !wasfreed(this.goalstack01) && !(this.goalstack01.wpflags & WAYPOINTFLAG_JUMP)
+                               && vdist(vec2(gco - this.goalstack01.origin), >, 70))
+                       {
+                               vector gno = (this.goalstack01.absmin + this.goalstack01.absmax) * 0.5;
+                               vector ang = vectoangles(gco - this.origin);
+                               deviation = vectoangles(gno - gco) - vel_angles;
+                               while (deviation.y < -180) deviation.y = deviation.y + 360;
+                               while (deviation.y > 180) deviation.y = deviation.y - 360;
+
+                               float max_turn_angle = autocvar_bot_ai_bunnyhop_turn_angle_max;
+                               max_turn_angle -= autocvar_bot_ai_bunnyhop_turn_angle_reduction * ((vel - autocvar_sv_maxspeed) / autocvar_sv_maxspeed);
+                               if ((ang.x < 90 || ang.x > 360 - autocvar_bot_ai_bunnyhop_downward_pitch_max)
+                                       && fabs(deviation.y) < max(autocvar_bot_ai_bunnyhop_turn_angle_min, max_turn_angle))
+                               {
+                                       can_run = true;
+                               }
+                       }
+               }
+       }
+
+       if (can_run)
+       {
+               PHYS_INPUT_BUTTON_JUMP(this) = true;
+               this.bot_jump_time = time;
+               this.aistatus |= AI_STATUS_RUNNING;
+       }
+       else
+       {
+               if (IS_ONGROUND(this) || this.waterlevel > WATERLEVEL_WETFEET)
+                       this.aistatus &= ~AI_STATUS_RUNNING;
+       }
+}
+
 void havocbot_keyboard_movement(entity this, vector destorg)
 {
        if(time <= this.havocbot_keyboardtime)
@@ -268,114 +331,6 @@ void havocbot_keyboard_movement(entity this, vector destorg)
        CS(this).movement = CS(this).movement + (keyboard - CS(this).movement) * blend;
 }
 
-void havocbot_bunnyhop(entity this, vector dir)
-{
-       // Don't jump when attacking
-       if(this.aistatus & AI_STATUS_ATTACKING)
-               return;
-
-       if (!this.goalcurrent || IS_PLAYER(this.goalcurrent))
-               return;
-
-       if((this.aistatus & AI_STATUS_RUNNING) && vdist(this.velocity, <, autocvar_sv_maxspeed * 0.75)
-               || (this.aistatus & AI_STATUS_DANGER_AHEAD))
-       {
-               this.aistatus &= ~AI_STATUS_RUNNING;
-               PHYS_INPUT_BUTTON_JUMP(this) = false;
-               this.bot_canruntogoal = 0;
-               this.bot_timelastseengoal = 0;
-               return;
-       }
-
-       if(this.waterlevel > WATERLEVEL_WETFEET || IS_DUCKED(this))
-       {
-               this.aistatus &= ~AI_STATUS_RUNNING;
-               return;
-       }
-
-       if(this.bot_lastseengoal != this.goalcurrent && !(this.aistatus & AI_STATUS_RUNNING))
-       {
-               this.bot_canruntogoal = 0;
-               this.bot_timelastseengoal = 0;
-       }
-
-       // Run only to visible goals
-       if(IS_ONGROUND(this))
-       if(vdist(vec2(this.velocity), >=, autocvar_sv_maxspeed))
-       if(checkpvs(this.origin + this.view_ofs, this.goalcurrent))
-       {
-               this.bot_lastseengoal = this.goalcurrent;
-
-               // seen it before
-               if(this.bot_timelastseengoal)
-               {
-                       vector gco = get_closer_dest(this.goalcurrent, this.origin);
-                       // for a period of time
-                       if(time - this.bot_timelastseengoal > autocvar_bot_ai_bunnyhop_firstjumpdelay)
-                       {
-                               bool checkdistance = true;
-
-                               // don't run if it is too close
-                               if(this.bot_canruntogoal==0)
-                               {
-                                       if(vdist(this.origin - gco, >, autocvar_bot_ai_bunnyhop_startdistance))
-                                               this.bot_canruntogoal = 1;
-                                       else
-                                               this.bot_canruntogoal = -1;
-                               }
-
-                               if(this.bot_canruntogoal != 1)
-                                       return;
-
-                               if(this.aistatus & AI_STATUS_ROAMING)
-                               if(this.goalcurrent.classname == "waypoint")
-                               if (!(this.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL))
-                               if(fabs(gco.z - this.origin.z) < this.maxs.z - this.mins.z)
-                               if (this.goalstack01 && !wasfreed(this.goalstack01))
-                               if (!(this.goalstack01.wpflags & WAYPOINTFLAG_JUMP))
-                               {
-                                       vector gno = (this.goalstack01.absmin + this.goalstack01.absmax) * 0.5;
-                                       vector deviation = vectoangles(gno - this.origin) - vectoangles(gco - this.origin);
-                                       while (deviation.y < -180) deviation.y = deviation.y + 360;
-                                       while (deviation.y > 180) deviation.y = deviation.y - 360;
-
-                                       if(fabs(deviation.y) < 20)
-                                       if(vlen2(this.origin - gco) < vlen2(this.origin - gno))
-                                       if(fabs(gno.z - gco.z) < this.maxs.z - this.mins.z)
-                                       {
-                                               if(vdist(gco - gno, >, autocvar_bot_ai_bunnyhop_startdistance))
-                                               if(checkpvs(this.origin + this.view_ofs, this.goalstack01))
-                                               {
-                                                       checkdistance = false;
-                                               }
-                                       }
-                               }
-
-                               if(checkdistance)
-                               {
-                                       this.aistatus &= ~AI_STATUS_RUNNING;
-                                       // increase stop distance in case the goal is on a slope or a lower platform
-                                       if(vdist(this.origin - gco, >, autocvar_bot_ai_bunnyhop_stopdistance + (this.origin.z - gco.z)))
-                                               PHYS_INPUT_BUTTON_JUMP(this) = true;
-                               }
-                               else
-                               {
-                                       this.aistatus |= AI_STATUS_RUNNING;
-                                       PHYS_INPUT_BUTTON_JUMP(this) = true;
-                               }
-                       }
-               }
-               else
-               {
-                       this.bot_timelastseengoal = time;
-               }
-       }
-       else
-       {
-               this.bot_timelastseengoal = 0;
-       }
-}
-
 // return true when bot isn't getting closer to the current goal
 bool havocbot_checkgoaldistance(entity this, vector gco)
 {
@@ -436,8 +391,6 @@ void havocbot_movetogoal(entity this)
        vector diff;
        vector dir;
        vector flatdir;
-       vector evadeobstacle;
-       vector evadelava;
        float dodge_enemy_factor = 1;
        float maxspeed;
        //float dist;
@@ -608,12 +561,31 @@ void havocbot_movetogoal(entity this)
        if (skill > 6 && !(IS_ONGROUND(this)))
        {
                #define ROCKETJUMP_DAMAGE() WEP_CVAR(devastator, damage) * 0.8 \
-                       * ((this.strength_finished > time) ? autocvar_g_balance_powerup_strength_selfdamage : 1) \
-                       * ((this.invincible_finished > time) ? autocvar_g_balance_powerup_invincible_takedamage : 1)
+                       * ((STAT(STRENGTH_FINISHED, this) > time) ? autocvar_g_balance_powerup_strength_selfdamage : 1) \
+                       * ((STAT(INVINCIBLE_FINISHED, this) > time) ? autocvar_g_balance_powerup_invincible_takedamage : 1)
+
+               // save some CPU cycles by checking trigger_hurt after checking
+               // that something can be done to evade it (cheaper checks)
+               int action_for_trigger_hurt = 0;
+               if (this.items & IT_JETPACK)
+                       action_for_trigger_hurt = 1;
+               else if (!this.jumppadcount && !waypoint_is_hardwiredlink(this.goalcurrent_prev, this.goalcurrent)
+                       && !(this.goalcurrent_prev && this.goalcurrent_prev.wpflags & WAYPOINTFLAG_JUMP)
+                       && GetResource(this, RES_HEALTH) + GetResource(this, RES_ARMOR) > ROCKETJUMP_DAMAGE())
+               {
+                       action_for_trigger_hurt = 2;
+               }
+               else if (!this.goalcurrent)
+                       action_for_trigger_hurt = 3;
 
-               tracebox(this.origin, this.mins, this.maxs, this.origin + '0 0 -65536', MOVE_NOMONSTERS, this);
-               if(tracebox_hits_trigger_hurt(this.origin, this.mins, this.maxs, trace_endpos ))
-               if(this.items & IT_JETPACK)
+               if (action_for_trigger_hurt)
+               {
+                       tracebox(this.origin, this.mins, this.maxs, this.origin + '0 0 -65536', MOVE_NOMONSTERS, this);
+                       if(!tracebox_hits_trigger_hurt(this.origin, this.mins, this.maxs, trace_endpos))
+                               action_for_trigger_hurt = 0;
+               }
+
+               if(action_for_trigger_hurt == 1) // jetpack
                {
                        tracebox(this.origin, this.mins, this.maxs, this.origin + '0 0 65536', MOVE_NOMONSTERS, this);
                        if(tracebox_hits_trigger_hurt(this.origin, this.mins, this.maxs, trace_endpos + '0 0 1' ))
@@ -651,9 +623,7 @@ void havocbot_movetogoal(entity this)
 
                        return;
                }
-               else if(!this.jumppadcount && !waypoint_is_hardwiredlink(this.goalcurrent_prev, this.goalcurrent)
-                       && !(this.goalcurrent_prev && this.goalcurrent_prev.wpflags & WAYPOINTFLAG_JUMP)
-                       && GetResource(this, RES_HEALTH) + GetResource(this, RES_ARMOR) > ROCKETJUMP_DAMAGE())
+               else if(action_for_trigger_hurt == 2) // rocketjump
                {
                        if(this.velocity.z < 0)
                        {
@@ -687,11 +657,10 @@ void havocbot_movetogoal(entity this)
                                }
                        }
                }
-               else
+               else if(action_for_trigger_hurt == 3) // no goal
                {
                        // If there is no goal try to move forward
-                       if(this.goalcurrent==NULL)
-                               CS(this).movement_x = maxspeed;
+                       CS(this).movement_x = maxspeed;
                }
        }
 
@@ -703,8 +672,6 @@ void havocbot_movetogoal(entity this)
                        dir.z = 1;
                else if(this.velocity.z >= 0 && !(this.waterlevel == WATERLEVEL_WETFEET && this.watertype == CONTENT_WATER))
                        PHYS_INPUT_BUTTON_JUMP(this) = true;
-               else
-                       PHYS_INPUT_BUTTON_JUMP(this) = false;
                makevectors(this.v_angle.y * '0 1 0');
                vector v = dir * maxspeed;
                CS(this).movement.x = v * v_forward;
@@ -910,12 +877,13 @@ void havocbot_movetogoal(entity this)
                dir = normalize(diff);
        flatdir = (diff.z == 0) ? dir : normalize(vec2(diff));
 
+       bool danger_detected = false;
+       vector do_break = '0 0 0';
+
        //if (this.bot_dodgevector_time < time)
        {
                //this.bot_dodgevector_time = time + cvar("bot_ai_dodgeupdateinterval");
                //this.bot_dodgevector_jumpbutton = 1;
-               evadeobstacle = '0 0 0';
-               evadelava = '0 0 0';
 
                this.aistatus &= ~AI_STATUS_DANGER_AHEAD;
                makevectors(this.v_angle.y * '0 1 0');
@@ -938,7 +906,6 @@ void havocbot_movetogoal(entity this)
                                }
                                else
                                {
-                                       PHYS_INPUT_BUTTON_JUMP(this) = false;
                                        if (destorg.z > this.origin.z)
                                                dir = flatdir;
                                }
@@ -982,15 +949,14 @@ void havocbot_movetogoal(entity this)
                                )
                                {
                                        PHYS_INPUT_BUTTON_JUMP(this) = true;
-                                       // avoid changing route while bot is jumping a gap
-                                       navigation_goalrating_timeout_extend_if_needed(this, 1.5);
+                                       this.bot_jump_time = time;
                                }
                        }
                        else if (!this.goalstack01 || (this.goalcurrent.wpflags & (WAYPOINTFLAG_TELEPORT | WAYPOINTFLAG_LADDER)))
                        {
                                if (vlen2(flat_diff) < vlen2(offset))
                                {
-                                       if (this.goalcurrent.wpflags & WAYPOINTFLAG_JUMP && this.goalstack01)
+                                       if ((this.goalcurrent.wpflags & WAYPOINTFLAG_JUMP) && this.goalstack01)
                                        {
                                                // oblique warpzones need a jump otherwise bots gets stuck
                                                PHYS_INPUT_BUTTON_JUMP(this) = true;
@@ -1059,13 +1025,19 @@ void havocbot_movetogoal(entity this)
                                                vector jump_height = (IS_ONGROUND(this)) ? stepheightvec + jumpheight_vec : jumpstepheightvec;
                                                tracebox(this.origin + jump_height, this.mins, this.maxs, actual_destorg + jump_height, false, this);
                                                if (trace_fraction > s)
+                                               {
                                                        PHYS_INPUT_BUTTON_JUMP(this) = true;
+                                                       this.bot_jump_time = time;
+                                               }
                                                else
                                                {
                                                        jump_height = stepheightvec + jumpheight_vec / 2;
                                                        tracebox(this.origin + jump_height, this.mins, this.maxs, actual_destorg + jump_height, false, this);
                                                        if (trace_fraction > s)
+                                                       {
                                                                PHYS_INPUT_BUTTON_JUMP(this) = true;
+                                                               this.bot_jump_time = time;
+                                                       }
                                                }
                                        }
                                }
@@ -1099,15 +1071,15 @@ void havocbot_movetogoal(entity this)
                                this.goalcurrent_distance_time = -time; // mark second try
                        }
 
-                       // Check for water/slime/lava and dangerous edges
-                       // (only when the bot is on the ground or jumping intentionally)
-
                        if (skill + this.bot_moveskill <= 3 && time > this.bot_stop_moving_timeout
                                && current_speed > maxspeed * 0.9 && fabs(deviation.y) > 70)
                        {
                                this.bot_stop_moving_timeout = time + 0.4 + random() * 0.2;
                        }
 
+                       // Check for water/slime/lava and dangerous edges
+                       // (only when the bot is on the ground or jumping intentionally)
+
                        offset = (vdist(this.velocity, >, 32) ? this.velocity * 0.2 : flatdir * 32);
                        vector dst_ahead = this.origin + this.view_ofs + offset;
                        vector dst_down = dst_ahead - '0 0 3000';
@@ -1126,37 +1098,42 @@ void havocbot_movetogoal(entity this)
                                //te_lightning2(NULL, dst_ahead, trace_endpos); // Draw "downwards" look
                                if(trace_endpos.z < this.origin.z + this.mins.z)
                                {
-                                       s = pointcontents(trace_endpos + '0 0 1');
-                                       if (s != CONTENT_SOLID)
-                                       if (s == CONTENT_LAVA || s == CONTENT_SLIME)
-                                               evadelava = normalize(this.velocity) * -1;
-                                       else if (s == CONTENT_SKY)
-                                               evadeobstacle = normalize(this.velocity) * -1;
-                                       else if (tracebox_hits_trigger_hurt(dst_ahead, this.mins, this.maxs, trace_endpos))
+                                       if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
+                                               danger_detected = true;
+                                       else if (trace_endpos.z < min(this.origin.z + this.mins.z, this.goalcurrent.origin.z) - 100)
+                                               danger_detected = true;
+                                       else
                                        {
-                                               // the traceline check isn't enough but is good as optimization,
-                                               // when not true (most of the time) this tracebox call is avoided
-                                               tracebox(dst_ahead, this.mins, this.maxs, dst_down, true, this);
-                                               if (tracebox_hits_trigger_hurt(dst_ahead, this.mins, this.maxs, trace_endpos))
+                                               s = pointcontents(trace_endpos + '0 0 1');
+                                               if (s != CONTENT_SOLID)
                                                {
-                                                       if (destorg.z > this.origin.z + jumpstepheightvec.z)
+                                                       if (s == CONTENT_LAVA || s == CONTENT_SLIME)
+                                                               danger_detected = true;
+                                                       else if (tracebox_hits_trigger_hurt(dst_ahead, this.mins, this.maxs, trace_endpos))
                                                        {
-                                                               // the goal is probably on an upper platform, assume bot can't get there
-                                                               unreachable = true;
+                                                               // the traceline check isn't enough but is good as optimization,
+                                                               // when not true (most of the time) this tracebox call is avoided
+                                                               tracebox(dst_ahead, this.mins, this.maxs, dst_down, true, this);
+                                                               if (tracebox_hits_trigger_hurt(dst_ahead, this.mins, this.maxs, trace_endpos))
+                                                               {
+                                                                       if (destorg.z > this.origin.z + jumpstepheightvec.z)
+                                                                       {
+                                                                               // the goal is probably on an upper platform, assume bot can't get there
+                                                                               unreachable = true;
+                                                                       }
+                                                                       else
+                                                                               danger_detected = true;
+                                                               }
                                                        }
-                                                       else
-                                                               evadelava = normalize(this.velocity) * -1;
                                                }
                                        }
                                }
                        }
 
                        dir = flatdir;
-                       evadeobstacle.z = 0;
-                       evadelava.z = 0;
                        makevectors(this.v_angle.y * '0 1 0');
 
-                       if(evadeobstacle || evadelava || (s == CONTENT_WATER))
+                       if (danger_detected || (s == CONTENT_WATER))
                        {
                                this.aistatus |= AI_STATUS_DANGER_AHEAD;
                                if(IS_PLAYER(this.goalcurrent))
@@ -1171,7 +1148,7 @@ void havocbot_movetogoal(entity this)
                                // tracebox wouldn't work when bot is still on the ledge
                                traceline(this.origin, this.origin - '0 0 200', true, this);
                                if (this.origin.z - trace_endpos.z > 120)
-                                       evadeobstacle = normalize(this.velocity) * -1;
+                                       do_break = normalize(this.velocity) * -1;
                        }
 
                        if(unreachable)
@@ -1186,8 +1163,6 @@ void havocbot_movetogoal(entity this)
                dodge = havocbot_dodge(this);
                if (dodge)
                        dodge *= bound(0, 0.5 + (skill + this.bot_dodgeskill) * 0.1, 1);
-               dodge += evadeobstacle + evadelava;
-               evadelava = evadelava * bound(1,3-(skill+this.bot_dodgeskill),3); //Noobs fear lava a lot and take more distance from it
                if (this.enemy)
                {
                        traceline(this.origin, (this.enemy.absmin + this.enemy.absmax) * 0.5, true, NULL);
@@ -1240,10 +1215,27 @@ void havocbot_movetogoal(entity this)
                        bot_aimdir(this, dir, 0);
        }
 
+       vector evadedanger = '0 0 0';
        if (!ladder_zdir)
        {
                dir *= dodge_enemy_factor;
-               dir = normalize(dir + dodge);
+               if (danger_detected && vdist(this.velocity, >, maxspeed * 0.8) && this.goalcurrent_prev
+                       && this.goalcurrent.classname == "waypoint")
+               {
+                       vector p = this.origin + this.velocity * 0.2;
+                       vector evadedanger = point_line_vec(p, vec2(this.goalcurrent_prev.origin) + eZ * p.z,
+                               vec2(destorg - this.goalcurrent_prev.origin));
+                       if (vdist(evadedanger, >, 20))
+                       {
+                               if (vdist(evadedanger, >, 40))
+                                       do_break = normalize(this.velocity) * -1;
+                               evadedanger = normalize(evadedanger);
+                               evadedanger *= bound(1, 3 - (skill + this.bot_dodgeskill), 3); // Noobs fear dangers a lot and take more distance from them
+                       }
+                       else
+                               evadedanger = '0 0 0';
+               }
+               dir = normalize(dir + dodge + do_break + evadedanger);
        }
 
        makevectors(this.v_angle);
@@ -1259,7 +1251,7 @@ void havocbot_movetogoal(entity this)
                havocbot_keyboard_movement(this, destorg);
 
        // Bunnyhop!
-       if (!bunnyhop_forbidden && skill + this.bot_moveskill >= autocvar_bot_ai_bunnyhop_skilloffset)
+       if (!bunnyhop_forbidden && !evadedanger && !do_break && skill + this.bot_moveskill >= autocvar_bot_ai_bunnyhop_skilloffset)
                havocbot_bunnyhop(this, dir);
 
        if (dir * v_up >= autocvar_sv_jumpvelocity * 0.5 && IS_ONGROUND(this))
@@ -1300,6 +1292,7 @@ void havocbot_chooseenemy(entity this)
                this.enemy = NULL;
                return;
        }
+
        if (this.enemy)
        {
                if (!bot_shouldattack(this, this.enemy))
@@ -1308,26 +1301,21 @@ void havocbot_chooseenemy(entity this)
                        this.enemy = NULL;
                        this.havocbot_chooseenemy_finished = time;
                }
-               else if (this.havocbot_stickenemy)
+               else if (this.havocbot_stickenemy_time && time < this.havocbot_stickenemy_time)
                {
                        // tracking last chosen enemy
-                       // if enemy is visible
-                       // and not really really far away
-                       // and we're not severely injured
-                       // then keep tracking for a half second into the future
-                       traceline(this.origin+this.view_ofs, ( this.enemy.absmin + this.enemy.absmax ) * 0.5,false,NULL);
+                       vector targ_pos = (this.enemy.absmin + this.enemy.absmax) * 0.5;
+                       traceline(this.origin + this.view_ofs, targ_pos, false, NULL);
                        if (trace_ent == this.enemy || trace_fraction == 1)
-                       if (vdist(((this.enemy.absmin + this.enemy.absmax) * 0.5) - this.origin, <, 1000))
-                       if (GetResource(this, RES_HEALTH) > 30)
+                       if (vdist(targ_pos - this.origin, <, 1000))
                        {
                                // remain tracking him for a shot while (case he went after a small corner or pilar
                                this.havocbot_chooseenemy_finished = time + 0.5;
                                return;
                        }
-                       // enemy isn't visible, or is far away, or we're injured severely
-                       // so stop preferring this enemy
-                       // (it will still take a half second until a new one is chosen)
-                       this.havocbot_stickenemy = 0;
+
+                       // stop preferring this enemy
+                       this.havocbot_stickenemy_time = 0;
                }
        }
        if (time < this.havocbot_chooseenemy_finished)
@@ -1335,7 +1323,7 @@ void havocbot_chooseenemy(entity this)
        this.havocbot_chooseenemy_finished = time + autocvar_bot_ai_enemydetectioninterval;
        vector eye = this.origin + this.view_ofs;
        entity best = NULL;
-       float bestrating = 100000000;
+       float bestrating = autocvar_bot_ai_enemydetectionradius ** 2;
 
        // Backup hit flags
        int hf = this.dphitcontentsmask;
@@ -1366,9 +1354,7 @@ LABEL(scan_targets)
 
                        vector v = (it.absmin + it.absmax) * 0.5;
                        float rating = vlen2(v - eye);
-                       if (vdist(v - eye, <, autocvar_bot_ai_enemydetectionradius))
-                       if (bestrating > rating)
-                       if (bot_shouldattack(this, it))
+                       if (rating < bestrating && bot_shouldattack(this, it))
                        {
                                traceline(eye, v, true, this);
                                if (trace_ent == it || trace_fraction >= 1)
@@ -1383,7 +1369,7 @@ LABEL(scan_targets)
                {
                        scan_secondary_targets = true;
                        // restart the loop
-                       bestrating = 100000000;
+                       bestrating = autocvar_bot_ai_enemydetectionradius ** 2;
                        goto scan_targets;
                }
 
@@ -1404,9 +1390,9 @@ LABEL(scan_targets)
        this.dphitcontentsmask = hf;
 
        this.enemy = best;
-       this.havocbot_stickenemy = true;
+       this.havocbot_stickenemy_time = time + autocvar_bot_ai_enemydetectioninterval_stickingtoenemy;
        if(best && best.classname == "misc_breakablemodel")
-               this.havocbot_stickenemy = false;
+               this.havocbot_stickenemy_time = 0;
 }
 
 float havocbot_chooseweapon_checkreload(entity this, .entity weaponentity, int new_weapon)
index d1a36a117260027569b229cb291cc78e2cd0a70a..02c0f3e7d76b3d8912afcea77f8f0ea5fb779df1 100644 (file)
 
 .float havocbot_keyboardtime;
 .float havocbot_ducktime;
-.float bot_timelastseengoal;
-.float bot_canruntogoal;
 .float bot_chooseweapontime;
 .float rocketjumptime;
 .float nextaim;
 .float havocbot_personal_waypoint_searchtime;
 .float havocbot_personal_waypoint_failcounter;
 .float havocbot_chooseenemy_finished;
-.float havocbot_stickenemy;
+.float havocbot_stickenemy_time;
 .float havocbot_role_timeout;
 
 .float bot_stop_moving_timeout;
index 84c597329ea5fda0eb0930dfec079be15e7edb22..d078cae8604903d461bf824bb3a8b4283f0b7755 100644 (file)
@@ -200,10 +200,10 @@ void havocbot_goalrating_enemyplayers(entity this, float ratingscale, vector org
                t = bound(0, 1 + t, 3);
                if (skill > 3)
                {
-                       if (time < this.strength_finished - 1) t += 0.5;
-                       if (time < it.strength_finished - 1) t -= 0.5;
-                       if (time < this.invincible_finished - 1) t += 0.2;
-                       if (time < it.invincible_finished - 1) t -= 0.4;
+                       if (time < STAT(STRENGTH_FINISHED, this) - 1) t += 0.5;
+                       if (time < STAT(STRENGTH_FINISHED, it) - 1) t -= 0.5;
+                       if (time < STAT(INVINCIBLE_FINISHED, this) - 1) t += 0.2;
+                       if (time < STAT(INVINCIBLE_FINISHED, it) - 1) t -= 0.4;
                }
                t += max(0, 8 - skill) * 0.05; // less skilled bots attack more mindlessly
                ratingscale *= t;
index 01352d0e4d94ba4702fdb727a8818dc1e946d02b..ebc18a6875353a2306ea07c6304d989860b76cac 100644 (file)
@@ -47,6 +47,7 @@ bool navigation_goalrating_timeout(entity this)
        return this.bot_strategytime < time;
 }
 
+ERASEABLE
 void navigation_goalrating_timeout_extend_if_needed(entity this, float seconds)
 {
        this.bot_strategytime = max(this.bot_strategytime, time + seconds);
@@ -239,6 +240,9 @@ bool navigation_checkladders(entity e, vector org, vector m1, vector m2, vector
        return false;
 }
 
+// Unfortuntely we can't use trace_inwater since it doesn't hold the fraction of the total
+// distance that was traveled before impact as the description in the engine (collision.h) says.
+// It would have helped to speed up tracewalk underwater
 vector resurface_limited(vector org, float lim, vector m1)
 {
        if (WETFEET(org + eZ * (lim - org.z)))
@@ -940,10 +944,7 @@ entity navigation_findnearestwaypoint_withdist_except(entity ent, float walkfrom
                        if(boxesoverlap(pm1, pm2, it.absmin, it.absmax))
                        {
                                if(walkfromwp && !ent.navigation_dynamicgoal)
-                               {
                                        waypoint_clearlinks(ent); // initialize wpXXmincost fields
-                                       navigation_item_addlink(it, ent);
-                               }
                                return it;
                        }
                });
@@ -962,24 +963,6 @@ entity navigation_findnearestwaypoint_withdist_except(entity ent, float walkfrom
                org.z = ent.origin.z + ent.mins.z - PL_MIN_CONST.z; // player height
        }
 
-       if(!autocvar_g_waypointeditor && walkfromwp && !ent.navigation_dynamicgoal)
-       {
-               waypoint_clearlinks(ent); // initialize wpXXmincost fields
-               IL_EACH(g_waypoints, it != ent,
-               {
-                       if (walkfromwp && (it.wpflags & WPFLAGMASK_NORELINK))
-                               continue;
-
-                       set_tracewalk_dest(ent, it.origin, false);
-                       if (vdist(tracewalk_dest - it.origin, <, 1050)
-                               && tracewalk(ent, it.origin, PL_MIN_CONST, PL_MAX_CONST,
-                               tracewalk_dest, tracewalk_dest_height, bot_navigation_movemode))
-                       {
-                               navigation_item_addlink(it, ent);
-                       }
-               });
-       }
-
        // box check failed, try walk
        IL_EACH(g_waypoints, it != ent,
        {
@@ -1504,7 +1487,7 @@ bool navigation_routetogoal(entity this, entity e, vector startposition)
        if(e == NULL)
                return false;
 
-       if(nearest_wp && nearest_wp.enemy)
+       if(nearest_wp && nearest_wp.enemy && !(nearest_wp.enemy.wpflags & WPFLAGMASK_NORELINK))
        {
                // often path can be optimized by not adding the nearest waypoint
                if (this.goalentity.navigation_dynamicgoal || autocvar_g_waypointeditor)
@@ -1526,8 +1509,35 @@ bool navigation_routetogoal(entity this, entity e, vector startposition)
                                }
                        }
                }
-               else if(navigation_item_islinked(nearest_wp.enemy, this.goalentity))
-                       e = nearest_wp.enemy;
+               else
+               {
+                       // NOTE unlike waypoints, items hold incoming links
+                       navigation_item_initlinks_ifneeded(this.goalentity);
+                       int link_num = navigation_item_getlinknum(this.goalentity, nearest_wp.enemy);
+                       if (link_num >= 0)
+                       {
+                               if (navigation_item_iswalkablelink(this.goalentity, link_num))
+                                       e = nearest_wp.enemy;
+                       }
+                       else // untested link
+                       {
+                               entity wp = nearest_wp.enemy;
+                               entity goal = this.goalentity;
+                               bool walkable = false;
+                               if (checkpvs(wp.origin, goal))
+                               {
+                                       set_tracewalk_dest(goal, wp.origin, false);
+                                       if (vdist(tracewalk_dest - wp.origin, <, 1050)
+                                               && tracewalk(goal, wp.origin, PL_MIN_CONST, PL_MAX_CONST,
+                                               tracewalk_dest, tracewalk_dest_height, bot_navigation_movemode))
+                                       {
+                                               walkable = true;
+                                               e = nearest_wp.enemy;
+                                       }
+                               }
+                               navigation_item_add_link(wp, goal, walkable);
+                       }
+               }
        }
 
        for (;;)
@@ -1644,7 +1654,7 @@ int navigation_poptouchedgoals(entity this)
                if(this.lastteleporttime > 0 && TELEPORT_USED(this, this.goalcurrent))
                {
                        if(this.aistatus & AI_STATUS_WAYPOINT_PERSONAL_GOING)
-                       if(this.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL && this.goalcurrent.owner==this)
+                       if((this.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL) && this.goalcurrent.owner==this)
                        {
                                this.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_GOING;
                                this.aistatus |= AI_STATUS_WAYPOINT_PERSONAL_REACHED;
@@ -1686,7 +1696,7 @@ int navigation_poptouchedgoals(entity this)
                if (tele_ent && TELEPORT_USED(this, tele_ent))
                {
                        if (this.aistatus & AI_STATUS_WAYPOINT_PERSONAL_GOING)
-                       if (tele_ent.wpflags & WAYPOINTFLAG_PERSONAL && tele_ent.owner == this)
+                       if ((tele_ent.wpflags & WAYPOINTFLAG_PERSONAL) && tele_ent.owner == this)
                        {
                                this.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_GOING;
                                this.aistatus |= AI_STATUS_WAYPOINT_PERSONAL_REACHED;
@@ -1707,18 +1717,23 @@ int navigation_poptouchedgoals(entity this)
        }
 
        // Loose goal touching check when running
-       if(this.aistatus & AI_STATUS_RUNNING)
-       if(this.goalcurrent.classname=="waypoint")
-       if(vdist(vec2(this.velocity), >=, autocvar_sv_maxspeed)) // if -really- running
-       {
-               if(vdist(this.origin - this.goalcurrent.origin, <, 150))
+       // check goalstack01 to make sure waypoint isn't the final goal
+       if((this.aistatus & AI_STATUS_RUNNING) && this.goalcurrent.classname == "waypoint" && !(this.goalcurrent.wpflags & WAYPOINTFLAG_JUMP)
+               && this.goalstack01 && !wasfreed(this.goalstack01) && vdist(vec2(this.velocity), >=, autocvar_sv_maxspeed))
+       {
+               vector gco = this.goalcurrent.origin;
+               float min_dist = BOT_BUNNYHOP_WP_DETECTION_RANGE;
+               // also detect waypoints when bot is way above them but with a narrower horizontal range
+               // so to increase chances bot ends up in the standard range (optimizes nearest waypoint finding)
+               if(vdist(this.origin - gco, <, min_dist)
+                       || (vdist(vec2(this.origin - gco), <, min_dist * 0.5) && vdist(this.origin - eZ * 1.5 * min_dist - gco, <, min_dist)))
                {
                        traceline(this.origin + this.view_ofs , this.goalcurrent.origin, true, NULL);
                        if(trace_fraction==1)
                        {
                                // Detect personal waypoints
                                if(this.aistatus & AI_STATUS_WAYPOINT_PERSONAL_GOING)
-                               if(this.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL && this.goalcurrent.owner==this)
+                               if((this.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL) && this.goalcurrent.owner==this)
                                {
                                        this.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_GOING;
                                        this.aistatus |= AI_STATUS_WAYPOINT_PERSONAL_REACHED;
@@ -1739,7 +1754,7 @@ int navigation_poptouchedgoals(entity this)
                if(this.goalcurrent.classname == "waypoint" && !this.goalcurrent.wpisbox)
                {
                        gc_min = this.goalcurrent.origin - '1 1 1' * 12;
-                       gc_max = this.goalcurrent.origin + '1 1 1' * 12;
+                       gc_max = this.goalcurrent.origin + '1 1 1' * 12 + eZ * (jumpheight_vec.z + STAT(PL_MIN, this).z);
                }
                if (time < this.ladder_time)
                {
@@ -1754,7 +1769,7 @@ int navigation_poptouchedgoals(entity this)
 
                // Detect personal waypoints
                if(this.aistatus & AI_STATUS_WAYPOINT_PERSONAL_GOING)
-               if(this.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL && this.goalcurrent.owner==this)
+               if((this.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL) && this.goalcurrent.owner==this)
                {
                        this.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_GOING;
                        this.aistatus |= AI_STATUS_WAYPOINT_PERSONAL_REACHED;
@@ -1775,7 +1790,8 @@ entity navigation_get_really_close_waypoint(entity this)
                wp = this.goalcurrent_prev;
        if(!wp)
                return NULL;
-       if(wp != this.goalcurrent_prev && vdist(wp.origin - this.origin, >, 50))
+       float min_dist = ((this.aistatus & AI_STATUS_RUNNING) ? BOT_BUNNYHOP_WP_DETECTION_RANGE : 50);
+       if(wp != this.goalcurrent_prev && vdist(wp.origin - this.origin, >, min_dist))
        {
                wp = this.goalcurrent_prev;
                if(!wp)
@@ -1787,12 +1803,12 @@ entity navigation_get_really_close_waypoint(entity this)
                if(!wp)
                        return NULL;
        }
-       if(vdist(wp.origin - this.origin, >, 50))
+       if(vdist(wp.origin - this.origin, >, min_dist))
        {
                wp = NULL;
                IL_EACH(g_waypoints, !(it.wpflags & (WAYPOINTFLAG_TELEPORT | WAYPOINTFLAG_JUMP)),
                {
-                       if(vdist(it.origin - this.origin, <, 50))
+                       if(vdist(it.origin - this.origin, <, min_dist))
                        {
                                wp = it;
                                break;
index 026d326b9e6fba8524b95a73862eb284e3f06d86..07eacc1860f4d4176a77f2a8bfaf07df1ada6e9d 100644 (file)
@@ -41,6 +41,9 @@ entity navigation_bestgoal;
 /*
 // item it is linked from waypoint it.wpXX (INCOMING link)
 // links are sorted by their cost (wpXXmincost)
+// one of these links is added in game every time a bot heads to an item
+// even links that are not walkable are added (marked with a high cost)
+// so that bots next time know if they can walk it or not saving a tracewalk call
 .entity wp00, wp01, wp02, wp03, wp04, wp05, wp06, wp07, wp08, wp09, wp10, wp11, wp12, wp13, wp14, wp15;
 .entity wp16, wp17, wp18, wp19, wp20, wp21, wp22, wp23, wp24, wp25, wp26, wp27, wp28, wp29, wp30, wp31;
 
@@ -50,9 +53,12 @@ entity navigation_bestgoal;
 .float wp24mincost, wp25mincost, wp26mincost, wp27mincost, wp28mincost, wp29mincost, wp30mincost, wp31mincost;
 */
 
-#define navigation_item_islinked(from_wp, to_item) waypoint_islinked(to_item, from_wp)
-#define navigation_item_addlink(from_wp, to_item) \
-       waypoint_addlink_customcost(to_item, from_wp, waypoint_getlinkcost(from_wp, to_item))
+#define navigation_item_initlinks_ifneeded(e) MACRO_BEGIN if (!e.wp00) waypoint_clearlinks(e); MACRO_END // initialize wpXXmincost fields
+#define navigation_item_getlinknum(to_item, from_wp) waypoint_getlinknum(to_item, from_wp)
+#define navigation_item_iswalkablelink(to_item, from_wp) (waypoint_get_assigned_link_cost(to_item, from_wp) < 999)
+
+#define navigation_item_add_link(from_wp, to_item, walkable) \
+       waypoint_addlink_customcost(to_item, from_wp, (walkable ? waypoint_getlinkcost(from_wp, to_item) : 999))
 
 #define TELEPORT_USED(pl, tele_wp) \
        boxesoverlap(tele_wp.absmin, tele_wp.absmax, pl.lastteleport_origin + STAT(PL_MIN, pl), pl.lastteleport_origin + STAT(PL_MAX, pl))
@@ -82,6 +88,8 @@ entity bot_waypoint_queue_goal;               // Head of the temporary list of goals
 entity bot_waypoint_queue_bestgoal;
 float bot_waypoint_queue_bestgoalrating;
 
+const float BOT_BUNNYHOP_WP_DETECTION_RANGE = 100;
+
 .entity bot_basewaypoint;
 .bool navigation_dynamicgoal;
 void navigation_dynamicgoal_init(entity this, bool initially_static);
index 176b6361de30bb83ca0870475a3b49b00bfab804..9c2c6825db0342164159eef90cd99c0e59f8ca91 100644 (file)
@@ -1211,12 +1211,12 @@ float bot_execute_commands_once(entity this)
 
        // Handle conditions
        if (!(bot_cmd.bot_cmd_type==BOT_CMD_FI||bot_cmd.bot_cmd_type==BOT_CMD_ELSE))
-       if(this.bot_cmd_condition_status & CMD_CONDITION_true && this.bot_cmd_condition_status & CMD_CONDITION_false_BLOCK)
+       if((this.bot_cmd_condition_status & CMD_CONDITION_true) && this.bot_cmd_condition_status & CMD_CONDITION_false_BLOCK)
        {
                bot_command_executed(this, true);
                return -1;
        }
-       else if(this.bot_cmd_condition_status & CMD_CONDITION_false && this.bot_cmd_condition_status & CMD_CONDITION_true_BLOCK)
+       else if((this.bot_cmd_condition_status & CMD_CONDITION_false) && this.bot_cmd_condition_status & CMD_CONDITION_true_BLOCK)
        {
                bot_command_executed(this, true);
                return -1;
index 7a40f18e8df56f6e1eacf6e0f242b08b316ee9e6..da407cbbc8673d7cfd2be4603898c0bf5aa1f120 100644 (file)
@@ -470,7 +470,7 @@ entity waypoint_spawn(vector m1, vector m2, float f)
                        }
                        else
                        {
-                               if(autocvar_developer)
+                               if(autocvar_developer > 0)
                                {
                                        LOG_INFO("A generated waypoint is stuck in solid at ", vtos(w.origin));
                                        backtrace("Waypoint stuck");
@@ -1572,6 +1572,46 @@ void waypoint_load_hardwiredlinks()
        LOG_TRACE("loaded ", ftos(c), " waypoint links from maps/", mapname, ".waypoints.hardwired");
 }
 
+float waypoint_get_assigned_link_cost(entity w, float i)
+{
+       switch(i)
+       {
+               case  0: return w.wp00mincost;
+               case  1: return w.wp01mincost;
+               case  2: return w.wp02mincost;
+               case  3: return w.wp03mincost;
+               case  4: return w.wp04mincost;
+               case  5: return w.wp05mincost;
+               case  6: return w.wp06mincost;
+               case  7: return w.wp07mincost;
+               case  8: return w.wp08mincost;
+               case  9: return w.wp09mincost;
+               case 10: return w.wp10mincost;
+               case 11: return w.wp11mincost;
+               case 12: return w.wp12mincost;
+               case 13: return w.wp13mincost;
+               case 14: return w.wp14mincost;
+               case 15: return w.wp15mincost;
+               case 16: return w.wp16mincost;
+               case 17: return w.wp17mincost;
+               case 18: return w.wp18mincost;
+               case 19: return w.wp19mincost;
+               case 20: return w.wp20mincost;
+               case 21: return w.wp21mincost;
+               case 22: return w.wp22mincost;
+               case 23: return w.wp23mincost;
+               case 24: return w.wp24mincost;
+               case 25: return w.wp25mincost;
+               case 26: return w.wp26mincost;
+               case 27: return w.wp27mincost;
+               case 28: return w.wp28mincost;
+               case 29: return w.wp29mincost;
+               case 30: return w.wp30mincost;
+               case 31: return w.wp31mincost;
+               default: return -1;
+       }
+}
+
 entity waypoint_get_link(entity w, float i)
 {
        switch(i)
index 25356446a4d1c05d40ece80c5e6f81f64cbfab7e..e9aa1ee12a64213aa9fb8af5feb11347495ba02e 100644 (file)
@@ -67,6 +67,8 @@ void waypoint_think(entity this);
 void waypoint_clearlinks(entity wp);
 void waypoint_schedulerelink(entity wp);
 
+float waypoint_get_assigned_link_cost(entity w, float i);
+
 float waypoint_getlinkcost(entity from, entity to);
 float waypoint_gettravelcost(vector from, vector to, entity from_ent, entity to_ent);
 float waypoint_getlinearcost(float dist);
index 76e2cdeb8480069230118925719d77d9e105ae5b..110704f2bbd9b2d80cfba1f6325faa321b53f378 100644 (file)
@@ -75,10 +75,19 @@ float Campaign_Invalid()
        return 0;
 }
 
+int Campaign_GetLevelNum()
+{
+       return campaign_level + 1;
+}
+
+string Campaign_GetMessage()
+{
+       return strcat(campaign_shortdesc[0], "\n^3\n", campaign_longdesc[0]);
+}
+
 void CampaignPreInit()
 {
        float baseskill;
-       string title;
        campaign_level = autocvar__campaign_index;
        campaign_name = strzone(autocvar__campaign_name);
        campaign_index_var = strzone(strcat("g_campaign", campaign_name, "_index"));
@@ -98,11 +107,7 @@ void CampaignPreInit()
                return;
        }
 
-       baseskill = autocvar_g_campaign_skill;
-       baseskill = baseskill + campaign_botskill[0];
-       if(baseskill < 0)
-               baseskill = 0;
-
+       baseskill = max(0, autocvar_g_campaign_skill + campaign_botskill[0]);
        campaign_forcewin = false;
 
        cvar_set("sv_public", "0");
@@ -119,7 +124,7 @@ void CampaignPreInit()
                {
                        string arg = argv(j);
                        if(arg == "") continue;
-                       _MapInfo_Parse_Settemp(mapname, MAPINFO_SETTEMP_ACL_USER, 0, arg, 0); // no recursion!
+                       _MapInfo_Parse_Settemp(mapname, MAPINFO_SETTEMP_ACL_USER, 0, arg, 1);
                }
        }
 #endif
@@ -146,11 +151,6 @@ void CampaignPreInit()
 
        if(Campaign_Invalid())
                return;
-
-       title = campaign_shortdesc[0];
-       title = strzone(strcat("Level ", ftos(campaign_level + 1), ": ", title));
-       campaign_message = strzone(strcat(title, "\n^3\n", campaign_longdesc[0], "\n\n^1press jump to enter the game"));
-       strunzone(title);
 }
 
 void CampaignPostInit()
@@ -161,16 +161,28 @@ void CampaignPostInit()
        if(autocvar__campaign_testrun)
        {
                cvar_set("fraglimit", "0");
+               cvar_set("leadlimit", "0");
                cvar_set("timelimit", "0.01");
                cvar_set_normal("fraglimit", "0");
+               cvar_set_normal("leadlimit", "0");
                cvar_set_normal("timelimit", "0.01");
        }
        else
        {
-               cvar_set("fraglimit", ftos(campaign_fraglimit[0]));
-               cvar_set("timelimit", ftos(campaign_timelimit[0]));
-               cvar_set_normal("fraglimit", ftos(campaign_fraglimit[0]));
-               cvar_set_normal("timelimit", ftos(campaign_timelimit[0]));
+               // "default" uses implicit values, "" or "0" means no limit
+               tokenizebyseparator(campaign_fraglimit[0], "+");
+               if(argv(0) != "default") {
+                       cvar_set("fraglimit", argv(0));
+                       cvar_set_normal("fraglimit", argv(0));
+               }
+               if(argv(1) != "default") {
+                       cvar_set("leadlimit", argv(1));
+                       cvar_set_normal("leadlimit", argv(1));
+               }
+               if(campaign_timelimit[0] != "default") {
+                       cvar_set("timelimit", campaign_timelimit[0]);
+                       cvar_set_normal("timelimit", campaign_timelimit[0]);
+               }
        }
 }
 
@@ -301,7 +313,6 @@ void CampaignPostIntermission()
 
        CampaignSetup(campaign_won);
        CampaignFile_Unload();
-       strunzone(campaign_message);
        strunzone(campaign_index_var);
        strunzone(campaign_name);
        campaign_name = "";
index df25c6c6ac5430581e13b7bb293446159e38b1d6..0662a3704f1eeaa0b0ea0a3560477f10c9d3579a 100644 (file)
@@ -3,7 +3,8 @@
 // this must be included BEFORE campaign_common.h to make this a memory saving
 #define CAMPAIGN_MAX_ENTRIES 2
 
-string campaign_message;
+int Campaign_GetLevelNum();
+string Campaign_GetMessage();
 
 void CampaignPreInit();
 void CampaignPostInit();
index 1acab9c00535d647e18a26f1ba35ff55d0ba7cf2..186677df9492f4caf1fa7c7d22711a62692ed133 100644 (file)
@@ -168,8 +168,8 @@ float CheatImpulse(entity this, int imp)
                        this.personal.pauserothealth_finished = this.pauserothealth_finished;
                        this.personal.pauserotfuel_finished = this.pauserotfuel_finished;
                        this.personal.pauseregen_finished = this.pauseregen_finished;
-                       this.personal.strength_finished = this.strength_finished;
-                       this.personal.invincible_finished = this.invincible_finished;
+                       STAT(STRENGTH_FINISHED, this.personal) = STAT(STRENGTH_FINISHED, this);
+                       STAT(INVINCIBLE_FINISHED, this.personal) = STAT(INVINCIBLE_FINISHED, this);
                        this.personal.teleport_time = time;
                        break; // this part itself doesn't cheat, so let's not count this
                case CHIMPULSE_CLONE_MOVING.impulse:
@@ -229,8 +229,8 @@ float CheatImpulse(entity this, int imp)
                                this.pauserothealth_finished = time + this.personal.pauserothealth_finished - this.personal.teleport_time;
                                this.pauserotfuel_finished = time + this.personal.pauserotfuel_finished - this.personal.teleport_time;
                                this.pauseregen_finished = time + this.personal.pauseregen_finished - this.personal.teleport_time;
-                               this.strength_finished = time + this.personal.strength_finished - this.personal.teleport_time;
-                               this.invincible_finished = time + this.personal.invincible_finished - this.personal.teleport_time;
+                               STAT(STRENGTH_FINISHED, this) = time + STAT(STRENGTH_FINISHED, this.personal) - this.personal.teleport_time;
+                               STAT(INVINCIBLE_FINISHED, this) = time + STAT(INVINCIBLE_FINISHED, this.personal) - this.personal.teleport_time;
 
                                if(!autocvar_g_allow_checkpoints)
                                        DID_CHEAT();
index 98616a76341f76ac901e838fdd7b81cb39478911..2f45c06aed9adbab7ebd8d499e1bf4ee3d6e768b 100644 (file)
@@ -25,6 +25,7 @@
 #include "campaign.qh"
 #include "command/common.qh"
 #include "scores_rules.qh"
+#include "weapons/common.qh"
 
 #include "bot/api.qh"
 
@@ -333,9 +334,10 @@ void PutObserverInServer(entity this)
        this.fade_time = 0;
        this.pain_frame = 0;
        this.pain_finished = 0;
-       this.strength_finished = 0;
-       this.invincible_finished = 0;
-       this.superweapons_finished = 0;
+       STAT(STRENGTH_FINISHED, this) = 0;
+       STAT(INVINCIBLE_FINISHED, this) = 0;
+       STAT(SUPERWEAPONS_FINISHED, this) = 0;
+       this.air_finished = 0;
        //this.dphitcontentsmask = 0;
        this.dphitcontentsmask = DPCONTENTS_SOLID;
        if (autocvar_g_playerclip_collisions)
@@ -587,7 +589,7 @@ void PutPlayerInServer(entity this)
 
        PS(this).dual_weapons = '0 0 0';
 
-       this.superweapons_finished = (STAT(WEAPONS, this) & WEPSET_SUPERWEAPONS) ? time + autocvar_g_balance_superweapons_time : 0;
+       STAT(SUPERWEAPONS_FINISHED, this) = (STAT(WEAPONS, this) & WEPSET_SUPERWEAPONS) ? time + autocvar_g_balance_superweapons_time : 0;
 
        this.items = start_items;
 
@@ -610,7 +612,8 @@ void PutPlayerInServer(entity this)
        this.respawn_flags = 0;
        this.respawn_time = 0;
        STAT(RESPAWN_TIME, this) = 0;
-       this.scale = autocvar_sv_player_scale;
+       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;
@@ -635,8 +638,8 @@ void PutPlayerInServer(entity this)
        this.punchangle = '0 0 0';
        this.punchvector = '0 0 0';
 
-       this.strength_finished = 0;
-       this.invincible_finished = 0;
+       STAT(STRENGTH_FINISHED, this) = 0;
+       STAT(INVINCIBLE_FINISHED, this) = 0;
        this.fire_endtime = -1;
        STAT(REVIVE_PROGRESS, this) = 0;
        this.revival_time = 0;
@@ -645,7 +648,7 @@ void PutPlayerInServer(entity this)
        STAT(BUFFS, this) = 0;
        STAT(BUFF_TIME, this) = 0;
 
-       this.air_finished = time + 12;
+       this.air_finished = 0;
        this.waterlevel = WATERLEVEL_NONE;
        this.watertype = CONTENT_EMPTY;
 
@@ -684,8 +687,13 @@ void PutPlayerInServer(entity this)
                IL_REMOVE(g_conveyed, this);
        this.conveyor = NULL; // prevent conveyors at the previous location from moving a freshly spawned player
        if(this.swampslug)
-               delete(this.swampslug);
-       this.in_swamp = false;
+               IL_REMOVE(g_swamped, this);
+       this.swampslug = NULL;
+       this.swamp_interval = 0;
+       IL_EACH(g_counters, it.realowner == this,
+       {
+               delete(it);
+       });
        STAT(HUD, this) = HUD_NORMAL;
 
        this.event_damage = PlayerDamage;
@@ -713,10 +721,7 @@ void PutPlayerInServer(entity this)
        for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
        {
                .entity weaponentity = weaponentities[slot];
-               entity oldwep = this.(weaponentity);
                CL_SpawnWeaponentity(this, weaponentity);
-               if(oldwep && oldwep.owner == this)
-                       this.(weaponentity).m_gunalign = oldwep.m_gunalign;
        }
        this.alpha = default_player_alpha;
        this.colormod = '1 1 1' * autocvar_g_player_brightness;
@@ -778,6 +783,7 @@ void PutPlayerInServer(entity this)
 
        if (CS(this).impulse) ImpulseCommands(this);
 
+       W_ResetGunAlign(this, CS(this).cvar_cl_gunalign);
        for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
        {
                .entity weaponentity = weaponentities[slot];
@@ -1041,7 +1047,9 @@ string getwelcomemessage(entity this)
        modifications = substring(modifications, 2, strlen(modifications) - 2);
 
        string versionmessage = GetClientVersionMessage(this);
-       string s = strcat(versionmessage, "^8\n^8\nmatch type is ^1", gamemode_name, "^8\n");
+       string s = strcat(versionmessage, "^8\n^8\nhost is ^9", autocvar_hostname, "^8\n");
+
+       s = strcat(s, "^8\nmatch type is ^1", gamemode_name, "^8\n");
 
        if(modifications != "")
                s = strcat(s, "^8\nactive modifications: ^3", modifications, "^8\n");
@@ -1069,7 +1077,7 @@ string getwelcomemessage(entity this)
        return s;
 }
 
-bool autocvar_sv_qcphysics = false; // TODO this is for testing - remove when qcphysics work
+bool autocvar_sv_qcphysics = true; // TODO this is for testing - remove when qcphysics work
 
 /**
 =============
@@ -1108,7 +1116,7 @@ void ClientConnect(entity this)
                CS(this).allowed_timeouts = autocvar_sv_timeout_number;
 
        if (autocvar_sv_eventlog)
-               GameLogEcho(strcat(":join:", ftos(this.playerid), ":", ftos(etof(this)), ":", ((IS_REAL_CLIENT(this)) ? this.netaddress : "bot"), ":", playername(this, false)));
+               GameLogEcho(strcat(":join:", ftos(this.playerid), ":", ftos(etof(this)), ":", ((IS_REAL_CLIENT(this)) ? GameLog_ProcessIP(this.netaddress) : "bot"), ":", playername(this, false)));
 
        CS(this).just_joined = true;  // stop spamming the eventlog with additional lines when the client connects
 
@@ -1229,6 +1237,11 @@ void ClientDisconnect(entity this)
        if (this.chatbubbleentity) delete(this.chatbubbleentity);
        if (this.killindicator) delete(this.killindicator);
 
+       IL_EACH(g_counters, it.realowner == this,
+       {
+               delete(it);
+       });
+
        WaypointSprite_PlayerGone(this);
 
        bot_relinkplayerlist();
@@ -1339,7 +1352,7 @@ void PrintToChat(entity client, string text)
 ERASEABLE
 void DebugPrintToChat(entity client, string text)
 {
-       if (autocvar_developer)
+       if (autocvar_developer > 0)
        {
                PrintToChat(client, text);
        }
@@ -1355,7 +1368,7 @@ void PrintToChatAll(string text)
 ERASEABLE
 void DebugPrintToChatAll(string text)
 {
-       if (autocvar_developer)
+       if (autocvar_developer > 0)
        {
                PrintToChatAll(text);
        }
@@ -1377,7 +1390,7 @@ void PrintToChatTeam(int team_num, string text)
 ERASEABLE
 void DebugPrintToChatTeam(int team_num, string text)
 {
-       if (autocvar_developer)
+       if (autocvar_developer > 0)
        {
                PrintToChatTeam(team_num, text);
        }
@@ -1414,9 +1427,9 @@ void player_powerups(entity this)
        {
                if (this.items & ITEM_Strength.m_itemid)
                {
-                       play_countdown(this, this.strength_finished, SND_POWEROFF);
+                       play_countdown(this, STAT(STRENGTH_FINISHED, this), SND_POWEROFF);
                        this.effects = this.effects | (EF_BLUE | EF_ADDITIVE | EF_FULLBRIGHT);
-                       if (time > this.strength_finished)
+                       if (time > STAT(STRENGTH_FINISHED, this))
                        {
                                this.items = this.items - (this.items & ITEM_Strength.m_itemid);
                                //Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_POWERDOWN_STRENGTH, this.netname);
@@ -1425,7 +1438,7 @@ void player_powerups(entity this)
                }
                else
                {
-                       if (time < this.strength_finished)
+                       if (time < STAT(STRENGTH_FINISHED, this))
                        {
                                this.items = this.items | ITEM_Strength.m_itemid;
                                if(!g_cts)
@@ -1435,9 +1448,9 @@ void player_powerups(entity this)
                }
                if (this.items & ITEM_Shield.m_itemid)
                {
-                       play_countdown(this, this.invincible_finished, SND_POWEROFF);
+                       play_countdown(this, STAT(INVINCIBLE_FINISHED, this), SND_POWEROFF);
                        this.effects = this.effects | (EF_RED | EF_ADDITIVE | EF_FULLBRIGHT);
-                       if (time > this.invincible_finished)
+                       if (time > STAT(INVINCIBLE_FINISHED, this))
                        {
                                this.items = this.items - (this.items & ITEM_Shield.m_itemid);
                                //Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_POWERDOWN_SHIELD, this.netname);
@@ -1446,7 +1459,7 @@ void player_powerups(entity this)
                }
                else
                {
-                       if (time < this.invincible_finished)
+                       if (time < STAT(INVINCIBLE_FINISHED, this))
                        {
                                this.items = this.items | ITEM_Shield.m_itemid;
                                if(!g_cts)
@@ -1458,7 +1471,7 @@ void player_powerups(entity this)
                {
                        if (!(STAT(WEAPONS, this) & WEPSET_SUPERWEAPONS))
                        {
-                               this.superweapons_finished = 0;
+                               STAT(SUPERWEAPONS_FINISHED, this) = 0;
                                this.items = this.items - (this.items & IT_SUPERWEAPON);
                                //Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_SUPERWEAPON_LOST, this.netname);
                                Send_Notification(NOTIF_ONE, this, MSG_CENTER, CENTER_SUPERWEAPON_LOST);
@@ -1469,8 +1482,8 @@ void player_powerups(entity this)
                        }
                        else
                        {
-                               play_countdown(this, this.superweapons_finished, SND_POWEROFF);
-                               if (time > this.superweapons_finished)
+                               play_countdown(this, STAT(SUPERWEAPONS_FINISHED, this), SND_POWEROFF);
+                               if (time > STAT(SUPERWEAPONS_FINISHED, this))
                                {
                                        this.items = this.items - (this.items & IT_SUPERWEAPON);
                                        STAT(WEAPONS, this) &= ~WEPSET_SUPERWEAPONS;
@@ -1481,7 +1494,7 @@ void player_powerups(entity this)
                }
                else if(STAT(WEAPONS, this) & WEPSET_SUPERWEAPONS)
                {
-                       if (time < this.superweapons_finished || (this.items & IT_UNLIMITED_SUPERWEAPONS))
+                       if (time < STAT(SUPERWEAPONS_FINISHED, this) || (this.items & IT_UNLIMITED_SUPERWEAPONS))
                        {
                                this.items = this.items | IT_SUPERWEAPON;
                                if(!(this.items & IT_UNLIMITED_SUPERWEAPONS))
@@ -1493,13 +1506,13 @@ void player_powerups(entity this)
                        }
                        else
                        {
-                               this.superweapons_finished = 0;
+                               STAT(SUPERWEAPONS_FINISHED, this) = 0;
                                STAT(WEAPONS, this) &= ~WEPSET_SUPERWEAPONS;
                        }
                }
                else
                {
-                       this.superweapons_finished = 0;
+                       STAT(SUPERWEAPONS_FINISHED, this) = 0;
                }
        }
 
@@ -1536,8 +1549,10 @@ float CalcRot(float current, float stable, float rotfactor, float rotframetime)
                return max(stable, current + (stable - current) * rotfactor * rotframetime);
 }
 
-float CalcRotRegen(float current, float regenstable, float regenfactor, float regenlinear, float regenframetime, float rotstable, float rotfactor, float rotlinear, float rotframetime, float limit)
+void RotRegen(entity this, int res, float regenstable, float regenfactor, float regenlinear, float regenframetime, float rotstable, float rotfactor, float rotlinear, float rotframetime, float limit_mod)
 {
+       float old = GetResource(this, res);
+       float current = old;
        if(current > rotstable)
        {
                if(rotframetime > 0)
@@ -1555,10 +1570,12 @@ float CalcRotRegen(float current, float regenstable, float regenfactor, float re
                }
        }
 
+       float limit = GetResourceLimit(this, res) * limit_mod;
        if(current > limit)
                current = limit;
 
-       return current;
+       if (current != old)
+               SetResource(this, res, current);
 }
 
 void player_regen(entity this)
@@ -1588,23 +1605,16 @@ void player_regen(entity this)
        if(!mutator_returnvalue)
        if(!STAT(FROZEN, this))
        {
-               float mina, maxa, limith, limita;
-               maxa = autocvar_g_balance_armor_rotstable;
-               mina = autocvar_g_balance_armor_regenstable;
-               limith = GetResourceLimit(this, RES_HEALTH);
-               limita = GetResourceLimit(this, RES_ARMOR);
+               float maxa = autocvar_g_balance_armor_rotstable;
+               float mina = autocvar_g_balance_armor_regenstable;
 
-               regen_health_rotstable = regen_health_rotstable * max_mod;
-               regen_health_stable = regen_health_stable * max_mod;
-               limith = limith * limit_mod;
-               limita = limita * limit_mod;
+               RotRegen(this, RES_ARMOR, mina, autocvar_g_balance_armor_regen, autocvar_g_balance_armor_regenlinear,
+                       regen_mod * frametime * (time > this.pauseregen_finished), maxa, autocvar_g_balance_armor_rot, autocvar_g_balance_armor_rotlinear,
+                       rot_mod * frametime * (time > this.pauserotarmor_finished), limit_mod);
 
-               SetResource(this, RES_ARMOR, CalcRotRegen(GetResource(this, RES_ARMOR), mina, autocvar_g_balance_armor_regen, autocvar_g_balance_armor_regenlinear, 
-                                                                       regen_mod * frametime * (time > this.pauseregen_finished), maxa, autocvar_g_balance_armor_rot, autocvar_g_balance_armor_rotlinear,
-                                                                       rot_mod * frametime * (time > this.pauserotarmor_finished), limita));
-               SetResource(this, RES_HEALTH, CalcRotRegen(GetResource(this, RES_HEALTH), regen_health_stable, regen_health, regen_health_linear,
-                                                                       regen_mod * frametime * (time > this.pauseregen_finished), regen_health_rotstable, regen_health_rot, regen_health_rotlinear,
-                                                                       rot_mod * frametime * (time > this.pauserothealth_finished), limith));
+               RotRegen(this, RES_HEALTH, regen_health_stable * max_mod, regen_health, regen_health_linear,
+                       regen_mod * frametime * (time > this.pauseregen_finished), regen_health_rotstable * max_mod, regen_health_rot, regen_health_rotlinear,
+                       rot_mod * frametime * (time > this.pauserothealth_finished), limit_mod);
        }
 
        // if player rotted to death...  die!
@@ -1619,15 +1629,12 @@ void player_regen(entity this)
 
        if (!(this.items & IT_UNLIMITED_AMMO))
        {
-               float minf, maxf, limitf;
-
-               maxf = autocvar_g_balance_fuel_rotstable;
-               minf = autocvar_g_balance_fuel_regenstable;
-               limitf = GetResourceLimit(this, RES_FUEL);
+               float maxf = autocvar_g_balance_fuel_rotstable;
+               float minf = autocvar_g_balance_fuel_regenstable;
 
-               SetResource(this, RES_FUEL, CalcRotRegen(GetResource(this, RES_FUEL), minf, autocvar_g_balance_fuel_regen, autocvar_g_balance_fuel_regenlinear, 
-                                                                               frametime * (time > this.pauseregen_finished) * ((this.items & ITEM_JetpackRegen.m_itemid) != 0),
-                                                                               maxf, autocvar_g_balance_fuel_rot, autocvar_g_balance_fuel_rotlinear, frametime * (time > this.pauserotfuel_finished), limitf));
+               RotRegen(this, RES_FUEL, minf, autocvar_g_balance_fuel_regen, autocvar_g_balance_fuel_regenlinear,
+                       frametime * (time > this.pauseregen_finished) * ((this.items & ITEM_JetpackRegen.m_itemid) != 0),
+                       maxf, autocvar_g_balance_fuel_rot, autocvar_g_balance_fuel_rotlinear, frametime * (time > this.pauserotfuel_finished), 1);
        }
 }
 
@@ -1687,9 +1694,10 @@ void SpectateCopy(entity this, entity spectatee)
        this.items = spectatee.items;
        STAT(LAST_PICKUP, this) = STAT(LAST_PICKUP, spectatee);
        STAT(HIT_TIME, this) = STAT(HIT_TIME, spectatee);
-       this.strength_finished = spectatee.strength_finished;
-       this.invincible_finished = spectatee.invincible_finished;
-       this.superweapons_finished = spectatee.superweapons_finished;
+       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(PRESSED_KEYS, this) = STAT(PRESSED_KEYS, spectatee);
        STAT(WEAPONS, this) = STAT(WEAPONS, spectatee);
        this.punchangle = spectatee.punchangle;
@@ -1781,6 +1789,11 @@ void SetSpectatee_status(entity this, int spectatee_num)
 
        if (CS(this).spectatee_status != oldspectatee_status)
        {
+               if (STAT(PRESSED_KEYS, this))
+               {
+                       CS(this).pressedkeys = 0;
+                       STAT(PRESSED_KEYS, this) = 0;
+               }
                ClientData_Touch(this);
                if (g_race || g_cts) race_InitSpectator();
        }
@@ -1942,6 +1955,8 @@ void Join(entity this)
 
 int GetPlayerLimit()
 {
+       if(g_duel)
+               return 2; // TODO: this workaround is needed since the mutator hook from duel can't be activated before the gametype is loaded (e.g. switching modes via gametype vote screen)
        int player_limit = autocvar_g_maxplayers;
        MUTATOR_CALLHOOK(GetPlayerLimit, player_limit);
        player_limit = M_ARGV(0, int);
@@ -1988,11 +2003,11 @@ int nJoinAllowed(entity this, entity ignore)
        else if(currentlyPlaying < player_limit)
                free_slots = min(maxclients - totalClients, player_limit - currentlyPlaying);
 
-       static float join_prevent_msg_time = 0;
-       if(this && ignore && !free_slots && time > join_prevent_msg_time)
+       static float msg_time = 0;
+       if(this && !this.caplayer && ignore && !free_slots && time > msg_time)
        {
                Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_JOIN_PREVENT);
-               join_prevent_msg_time = time + 3;
+               msg_time = time + 0.5;
        }
 
        return free_slots;
@@ -2022,7 +2037,7 @@ void PrintWelcomeMessage(entity this)
                if (autocvar_g_campaign) {
                        if ((IS_PLAYER(this) && PHYS_INPUT_BUTTON_INFO(this)) || (!IS_PLAYER(this))) {
                                CS(this).motd_actived_time = time;
-                               Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_MOTD, campaign_message);
+                               Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_CAMPAIGN_MESSAGE, Campaign_GetMessage(), Campaign_GetLevelNum());
                        }
                } else {
                        if (PHYS_INPUT_BUTTON_INFO(this)) {
@@ -2038,7 +2053,7 @@ void PrintWelcomeMessage(entity this)
                                CS(this).motd_actived_time = time;
                        else if ((time - CS(this).motd_actived_time > 2) && IS_PLAYER(this)) { // hide it some seconds after BUTTON_INFO has been released
                                CS(this).motd_actived_time = 0;
-                               Kill_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CPID_MOTD);
+                               Kill_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CPID_CAMPAIGN_MESSAGE);
                        }
                } else {
                        if (PHYS_INPUT_BUTTON_INFO(this))
@@ -2057,7 +2072,10 @@ void PrintWelcomeMessage(entity this)
                {
                        // instantly hide MOTD
                        CS(this).motd_actived_time = 0;
-                       Kill_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CPID_MOTD);
+                       if (autocvar_g_campaign)
+                               Kill_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CPID_CAMPAIGN_MESSAGE);
+                       else
+                               Kill_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CPID_MOTD);
                }
                else if (IS_PLAYER(this) || IS_SPEC(this))
                {
@@ -2085,6 +2103,7 @@ bool joinAllowed(entity this)
 
 .int items_added;
 .string shootfromfixedorigin;
+.bool dualwielding_prev;
 bool PlayerThink(entity this)
 {
        if (game_stopped || intermission_running) {
@@ -2187,6 +2206,15 @@ bool PlayerThink(entity this)
                stuffcmd(this, sprintf("\ncl_shootfromfixedorigin \"%s\"\n", autocvar_g_shootfromfixedorigin));
        }
 
+       // reset gun alignment when dual wielding status changes
+       // to ensure guns are always aligned right and left
+       bool dualwielding = W_DualWielding(this);
+       if(this.dualwielding_prev != dualwielding)
+       {
+               W_ResetGunAlign(this, CS(this).cvar_cl_gunalign);
+               this.dualwielding_prev = dualwielding;
+       }
+
        // LordHavoc: allow firing on move frames (sub-ticrate), this gives better timing on slow servers
        //if(frametime)
        {
@@ -2207,27 +2235,25 @@ bool PlayerThink(entity this)
                this.items |= this.items_added;
        }
 
-       player_regen(this);
-
-       // WEAPONTODO: Add a weapon request for this
-       // rot vortex charge to the charge limit
-       for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+       if (frametime)
        {
-               .entity weaponentity = weaponentities[slot];
-               if (WEP_CVAR(vortex, charge_rot_rate) && this.(weaponentity).vortex_charge > WEP_CVAR(vortex, charge_limit) && this.(weaponentity).vortex_charge_rottime < time)
-                       this.(weaponentity).vortex_charge = bound(WEP_CVAR(vortex, charge_limit), this.(weaponentity).vortex_charge - WEP_CVAR(vortex, charge_rot_rate) * frametime / W_TICSPERFRAME, 1);
-       }
+               // WEAPONTODO: Add a weapon request for this
+               // rot vortex charge to the charge limit
+               for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+               {
+                       .entity weaponentity = weaponentities[slot];
+                       if (WEP_CVAR(vortex, charge_rot_rate) && this.(weaponentity).vortex_charge > WEP_CVAR(vortex, charge_limit) && this.(weaponentity).vortex_charge_rottime < time)
+                               this.(weaponentity).vortex_charge = bound(WEP_CVAR(vortex, charge_limit), this.(weaponentity).vortex_charge - WEP_CVAR(vortex, charge_rot_rate) * frametime / W_TICSPERFRAME, 1);
+               }
 
-       if (frametime) player_anim(this);
+               player_regen(this);
+               player_anim(this);
+               this.dmg_team = max(0, this.dmg_team - autocvar_g_teamdamage_resetspeed * frametime);
+       }
 
-       // secret status
        secrets_setstatus(this);
-
-       // monsters status
        monsters_setstatus(this);
 
-       this.dmg_team = max(0, this.dmg_team - autocvar_g_teamdamage_resetspeed * frametime);
-
        return true;
 }
 
@@ -2259,7 +2285,8 @@ void ObserverThink(entity this)
                        if(this.flags & FL_SPAWNING)
                        {
                                this.flags &= ~FL_SPAWNING;
-                               Join(this);
+                               if(joinAllowed(this))
+                                       Join(this);
                                return;
                        }
                }
@@ -2457,7 +2484,7 @@ void PlayerPreThink (entity this)
                this.max_armorvalue = 0;
        }
 
-       if(IS_PLAYER(this))
+       if (frametime && IS_PLAYER(this))
        {
                if (STAT(FROZEN, this) == FROZEN_TEMP_REVIVING)
                {
@@ -2593,21 +2620,30 @@ void PlayerPreThink (entity this)
 
 void DrownPlayer(entity this)
 {
-       if(IS_DEAD(this) || game_stopped || time < game_starttime)
+       if(IS_DEAD(this) || game_stopped || time < game_starttime || this.vehicle
+               || STAT(FROZEN, this) || this.watertype != CONTENT_WATER)
+       {
+               this.air_finished = 0;
                return;
+       }
 
-       if (this.waterlevel != WATERLEVEL_SUBMERGED || this.vehicle)
+       if (this.waterlevel != WATERLEVEL_SUBMERGED)
        {
-               if(this.air_finished < time)
+               if(this.air_finished && this.air_finished < time)
                        PlayerSound(this, playersound_gasp, CH_PLAYER, VOL_BASE, VOICETYPE_PLAYERSOUND);
-               this.air_finished = time + autocvar_g_balance_contents_drowndelay;
+               this.air_finished = 0;
        }
-       else if (this.air_finished < time)
-       {       // drown!
-               if (this.pain_finished < time)
-               {
-                       Damage (this, NULL, NULL, autocvar_g_balance_contents_playerdamage_drowning * autocvar_g_balance_contents_damagerate, DEATH_DROWN.m_id, DMG_NOWEP, this.origin, '0 0 0');
-                       this.pain_finished = time + 0.5;
+       else
+       {
+               if (!this.air_finished)
+                       this.air_finished = time + autocvar_g_balance_contents_drowndelay;
+               if (this.air_finished < time)
+               {       // drown!
+                       if (this.pain_finished < time)
+                       {
+                               Damage (this, NULL, NULL, autocvar_g_balance_contents_playerdamage_drowning * autocvar_g_balance_contents_damagerate, DEATH_DROWN.m_id, DMG_NOWEP, this.origin, '0 0 0');
+                               this.pain_finished = time + 0.5;
+                       }
                }
        }
 }
@@ -2712,6 +2748,11 @@ void PlayerPostThink (entity this)
                }
                GetPressedKeys(this);
        }
+       else if (IS_OBSERVER(this) && STAT(PRESSED_KEYS, this))
+       {
+               CS(this).pressedkeys = 0;
+               STAT(PRESSED_KEYS, this) = 0;
+       }
 
        if (this.waypointsprite_attachedforcarrier) {
                float hp = healtharmor_maxdamage(GetResource(this, RES_HEALTH), GetResource(this, RES_ARMOR), autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id).x;
index b20a8af93cdd5a72539e334adaefabf7b47ae3ac..20148933cbc5421d5a87fb56b105c6c022885ef3 100644 (file)
@@ -141,6 +141,7 @@ CLASS(Client, Object)
     ATTRIB(Client, autoswitch, bool, this.autoswitch);
     ATTRIB(Client, cvar_cl_casings, bool, this.cvar_cl_casings);
     ATTRIB(Client, cvar_cl_dodging_timeout, float, this.cvar_cl_dodging_timeout);
+    ATTRIB(Client, cvar_cl_dodging, float, this.cvar_cl_dodging);
     ATTRIB(Client, cvar_cl_multijump, bool, this.cvar_cl_multijump);
     ATTRIB(Client, cvar_cl_accuracy_data_share, bool, this.cvar_cl_accuracy_data_share);
     ATTRIB(Client, cvar_cl_accuracy_data_receive, bool, this.cvar_cl_accuracy_data_receive);
@@ -265,7 +266,7 @@ void DebugPrintToChatTeam(int team_num, string text);
 
 void play_countdown(entity this, float finished, Sound samp);
 
-float CalcRotRegen(float current, float regenstable, float regenfactor, float regenlinear, float regenframetime, float rotstable, float rotfactor, float rotlinear, float rotframetime, float limit);
+void RotRegen(entity this, float current, float regenstable, float regenfactor, float regenlinear, float regenframetime, float rotstable, float rotfactor, float rotlinear, float rotframetime, float limit_mod);
 
 bool Spectate(entity this, entity pl);
 
index 6928957d6d812e6f15511d2b82e421d8f0c7f877..ad9cab8e72301cbc7735ebea4a5e9b19c8bc4070 100644 (file)
@@ -635,15 +635,22 @@ void ClientCommand_spectate(entity caller, int request)
                {
                        if (!intermission_running && IS_CLIENT(caller))
                        {
-                               if((IS_SPEC(caller) || IS_OBSERVER(caller)) && argv(1) != "")
+                               if(argv(1) != "")
                                {
-                                       entity client = GetFilteredEntity(argv(1));
-                                       int spec_accepted = VerifyClientEntity(client, false, false);
-                                       if(spec_accepted > 0 && IS_PLAYER(client))
+                                       if(IS_SPEC(caller) || IS_OBSERVER(caller))
                                        {
-                                               if(Spectate(caller, client))
-                                                       return; // fall back to regular handling
+                                               entity client = GetFilteredEntity(argv(1));
+                                               int spec_accepted = VerifyClientEntity(client, false, false);
+                                               if(spec_accepted > 0 && IS_PLAYER(client))
+                                               {
+                                                       Spectate(caller, client);
+                                               }
+                                               else
+                                                       sprint(caller, "can't spectate ", argv(1), "^7\n");
                                        }
+                                       else
+                                               sprint(caller, "cmd spectate client only works when you are spectator/observer\n");
+                                       return;
                                }
 
                                int mutator_returnvalue = MUTATOR_CALLHOOK(ClientCommand_Spectate, caller);
@@ -660,7 +667,7 @@ void ClientCommand_spectate(entity caller, int request)
                default:
                case CMD_REQUEST_USAGE:
                {
-                       sprint(caller, "\nUsage:^3 cmd spectate <client>\n");
+                       sprint(caller, "\nUsage:^3 cmd spectate [client]\n");
                        sprint(caller, "  Where 'client' can be the player to spectate.\n");
                        return;
                }
index 5ff2d3472ae22ebbf2d3d898e0ecbd5f4ae4c910..2383669547fc0e12c0114b0da239424bb828f244 100644 (file)
@@ -1025,23 +1025,22 @@ void GameCommand_moveplayer(int request, int argc)
                                                        if (teamplay)
                                                        {
                                                                // set up
-                                                               float team_id;
                                                                int save = Player_GetForcedTeamIndex(client);
                                                                Player_SetForcedTeamIndex(client, TEAM_FORCE_DEFAULT);
 
                                                                // find the team to move the player to
-                                                               team_id = Team_ColorToTeam(destination);
+                                                               int team_num = Team_ColorToTeam(destination);
                                                                entity balance;
-                                                               if (team_id == client.team)  // already on the destination team
+                                                               if (team_num == client.team)  // already on the destination team
                                                                {
                                                                        // keep the forcing undone
                                                                        LOG_INFO("Player ", ftos(GetFilteredNumber(t)), " (", playername(client, false), ") is already on the ", Team_ColoredFullName(client.team), (targets ? "^7, skipping to next player.\n" : "^7."));
                                                                        continue;
                                                                }
-                                                               else if (team_id == 0)  // auto team
+                                                               else if (team_num == 0)  // auto team
                                                                {
                                                                        balance = TeamBalance_CheckAllowedTeams(client);
-                                                                       team_id = Team_IndexToTeam(TeamBalance_FindBestTeam(balance, client, false));
+                                                                       team_num = Team_IndexToTeam(TeamBalance_FindBestTeam(balance, client, false));
                                                                }
                                                                else
                                                                {
@@ -1050,62 +1049,24 @@ void GameCommand_moveplayer(int request, int argc)
                                                                Player_SetForcedTeamIndex(client, save);
 
                                                                // Check to see if the destination team is even available
-                                                               switch (team_id)
+                                                               int team_id = Team_TeamToIndex(team_num);
+                                                               if (team_id == -1)
                                                                {
-                                                                       case NUM_TEAM_1:
-                                                                       {
-                                                                               if (!TeamBalance_IsTeamAllowed(balance, 1))
-                                                                               {
-                                                                                       LOG_INFO("Sorry, can't move player to red team if it doesn't exist.");
-                                                                                       TeamBalance_Destroy(balance);
-                                                                                       return;
-                                                                               }
-                                                                               TeamBalance_Destroy(balance);
-                                                                               break;
-                                                                       }
-                                                                       case NUM_TEAM_2:
-                                                                       {
-                                                                               if (!TeamBalance_IsTeamAllowed(balance, 2))
-                                                                               {
-                                                                                       LOG_INFO("Sorry, can't move player to blue team if it doesn't exist.");
-                                                                                       TeamBalance_Destroy(balance);
-                                                                                       return;
-                                                                               }
-                                                                               TeamBalance_Destroy(balance);
-                                                                               break;
-                                                                       }
-                                                                       case NUM_TEAM_3:
-                                                                       {
-                                                                               if (!TeamBalance_IsTeamAllowed(balance, 3))
-                                                                               {
-                                                                                       LOG_INFO("Sorry, can't move player to yellow team if it doesn't exist.");
-                                                                                       TeamBalance_Destroy(balance);
-                                                                                       return;
-                                                                               }
-                                                                               TeamBalance_Destroy(balance);
-                                                                               break;
-                                                                       }
-                                                                       case NUM_TEAM_4:
-                                                                       {
-                                                                               if (!TeamBalance_IsTeamAllowed(balance, 4))
-                                                                               {
-                                                                                       LOG_INFO("Sorry, can't move player to pink team if it doesn't exist.");
-                                                                                       TeamBalance_Destroy(balance);
-                                                                                       return;
-                                                                               }
-                                                                               TeamBalance_Destroy(balance);
-                                                                               break;
-                                                                       }
-                                                                       default:
-                                                                       {
-                                                                               LOG_INFO("Sorry, can't move player here if team ", destination, " doesn't exist.");
-                                                                               return;
-                                                                       }
+                                                                       LOG_INFO("Sorry, can't move player here if team ", destination, " doesn't exist.");
+                                                                       TeamBalance_Destroy(balance);
+                                                                       return;
+                                                               }
+                                                               if (!TeamBalance_IsTeamAllowed(balance, team_id))
+                                                               {
+                                                                       LOG_INFOF("Sorry, can't move player to %s team if it doesn't exist.", destination);
+                                                                       TeamBalance_Destroy(balance);
+                                                                       return;
                                                                }
+                                                               TeamBalance_Destroy(balance);
 
                                                                // If so, lets continue and finally move the player
                                                                Player_SetForcedTeamIndex(client, TEAM_FORCE_DEFAULT);
-                                                               if (MoveToTeam(client, Team_TeamToIndex(team_id), 6))
+                                                               if (MoveToTeam(client, team_id, 6))
                                                                {
                                                                        successful = strcat(successful, (successful ? ", " : ""), playername(client, false));
                                                                        LOG_INFO("Player ", ftos(GetFilteredNumber(t)), " (", playername(client, false), ") has been moved to the ", Team_ColoredFullName(team_id), "^7.");
@@ -1145,8 +1106,8 @@ void GameCommand_moveplayer(int request, int argc)
                        LOG_INFO("  'clients' is a list (separated by commas) of player entity ID's or nicknames");
                        LOG_INFO("  'destination' is what to send the player to, be it team or spectating");
                        LOG_INFO("  Full list of destinations here: \"spec, spectator, red, blue, yellow, pink, auto.\"");
-                       LOG_INFO("Examples: sv_cmd moveplayer 1,3,5 red 3");
-                       LOG_INFO("          sv_cmd moveplayer 2 spec ");
+                       LOG_INFO("Examples: sv_cmd moveplayer 1,3,5 red");
+                       LOG_INFO("          sv_cmd moveplayer 2 spec");
                        LOG_INFO("See also: ^2allspec, shuffleteams^7");
                        return;
                }
index b611ab2665896975ab0b4ce15c24da2480f61190..1869a15a898dc51a15ccbe25f8abe9d0714fee64 100644 (file)
@@ -477,7 +477,7 @@ void ReadyRestart_force()
 void ReadyRestart()
 {
        if (MUTATOR_CALLHOOK(ReadyRestart_Deny) || game_stopped || race_completing) localcmd("restart\n");
-       else localcmd("\nsv_hook_gamerestart\n");
+       else localcmd("\nsv_hook_readyrestart\n");
 
        // Reset ALL scores, but only do that at the beginning of the countdown if sv_ready_restart_after_countdown is off!
        // Otherwise scores could be manipulated during the countdown.
@@ -542,11 +542,21 @@ float VoteCommand_checknasty(string vote_command)
        return true;
 }
 
+// NOTE: requires input to be surrounded by spaces
+string VoteCommand_checkreplacements(string input)
+{
+       string output = input;
+       // allow gotomap replacements
+       output = strreplace(" map ", " gotomap ", output);
+       output = strreplace(" chmap ", " gotomap ", output);
+       return output;
+}
+
 float VoteCommand_checkinlist(string vote_command, string list)
 {
-       string l = strcat(" ", list, " ");
+       string l = VoteCommand_checkreplacements(strcat(" ", list, " "));
 
-       if (strstrofs(l, strcat(" ", vote_command, " "), 0) >= 0) return true;
+       if (strstrofs(l, VoteCommand_checkreplacements(strcat(" ", vote_command, " ")), 0) >= 0) return true;
 
        return false;
 }
index 8205b81284d2811d618b38e6c8675aca3942482b..4d469b455dc1919c1061c238e10d8be061afc8fc 100644 (file)
@@ -59,10 +59,7 @@ SPAWNFUNC_ITEM(item_armor_shard, ITEM_ArmorSmall)
 SPAWNFUNC_ITEM(item_enviro, ITEM_Shield)
 
 // medkit -> armor (we have no holdables)
-SPAWNFUNC_ITEM(holdable_medkit, ITEM_ArmorMega)
-
-// doubler -> strength
-SPAWNFUNC_ITEM(item_doubler, ITEM_Strength)
+SPAWNFUNC_ITEM(holdable_medkit, ITEM_ArmorBig)
 
 .float wait;
 .float delay;
@@ -103,24 +100,34 @@ void target_init_use(entity this, entity actor, entity trigger)
 
        if (!(this.spawnflags & 4))
        {
-               SetResource(actor, RES_SHELLS, start_ammo_shells);
-               SetResource(actor, RES_BULLETS, start_ammo_nails);
-               SetResource(actor, RES_ROCKETS, start_ammo_rockets);
-               SetResource(actor, RES_CELLS, start_ammo_cells);
-               SetResource(actor, RES_PLASMA, start_ammo_plasma);
-               SetResource(actor, RES_FUEL, start_ammo_fuel);
-
-               STAT(WEAPONS, actor) = start_weapons;
-               if (this.spawnflags & 32)
+               if(this.spawnflags & 32) // spawn with only melee
+               {
+                       SetResource(actor, RES_SHELLS, 0);
+                       SetResource(actor, RES_BULLETS, 0);
+                       SetResource(actor, RES_ROCKETS, 0);
+                       SetResource(actor, RES_CELLS, 0);
+                       SetResource(actor, RES_PLASMA, 0);
+                       SetResource(actor, RES_FUEL, 0);
+
+                       STAT(WEAPONS, actor) = WEPSET(SHOTGUN);
+               }
+               else
                {
-                       // TODO
+                       SetResource(actor, RES_SHELLS, start_ammo_shells);
+                       SetResource(actor, RES_BULLETS, start_ammo_nails);
+                       SetResource(actor, RES_ROCKETS, start_ammo_rockets);
+                       SetResource(actor, RES_CELLS, start_ammo_cells);
+                       SetResource(actor, RES_PLASMA, start_ammo_plasma);
+                       SetResource(actor, RES_FUEL, start_ammo_fuel);
+
+                       STAT(WEAPONS, actor) = start_weapons;
                }
        }
 
        if (!(this.spawnflags & 8))
        {
-               actor.strength_finished = 0;
-               actor.invincible_finished = 0;
+               STAT(STRENGTH_FINISHED, actor) = 0;
+               STAT(INVINCIBLE_FINISHED, actor) = 0;
                if(STAT(BUFFS, actor)) // TODO: make a dropbuffs function to handle this
                {
                        int buffid = buff_FirstFromFlags(STAT(BUFFS, actor)).m_id;
@@ -176,6 +183,10 @@ void target_give_init(entity this)
                        SetResourceExplicit(this, RES_ROCKETS, GetResource(this, RES_ROCKETS) + it.count * WEP_CVAR_PRI(mortar, ammo)); // WEAPONTODO
                        this.netname = cons(this.netname, "mortar");
                }
+               else if (it.classname == "weapon_shotgun") {
+                       SetResourceExplicit(this, RES_SHELLS, GetResource(this, RES_SHELLS) + it.count * WEP_CVAR_PRI(shotgun, ammo)); // WEAPONTODO
+                       this.netname = cons(this.netname, "shotgun");
+               }
                else if (it.classname == "item_armor_mega")
                        SetResourceExplicit(this, RES_ARMOR, 100);
                else if (it.classname == "item_health_mega")
@@ -233,6 +244,7 @@ spawnfunc(target_fragsFilter)
 }
 
 //spawnfunc(item_flight)       /* handled by buffs mutator */
+//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 */
index b1d73f6a3124c87110d254d1f2bc73f739003d38..9d7421987c1ce254c5ce4da58139214d594a6d53 100644 (file)
@@ -50,7 +50,8 @@ float server_is_dedicated;
 .float pain_frame;                     //"
 .float  crouch;        // Crouching or not?
 
-const .float superweapons_finished = _STAT(SUPERWEAPONS_FINISHED);
+.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;
@@ -92,7 +93,6 @@ const float MAX_DAMAGEEXTRARADIUS = 16;
 .float railgunhitsolidbackup;
 .vector railgunhitloc;
 
-.float         air_finished;
 .float         dmgtime;
 
 .float         killcount;
@@ -140,7 +140,6 @@ float blockSpectators; //if set, new or existing spectators or observers will be
 .float spectatortime; //point in time since the client is spectating or observing
 void checkSpectatorBlock(entity this);
 
-float game_completion_ratio; // 0 at start, 1 near end
 .float winning;
 .float jointime; // time of connecting
 .float startplaytime; // time of switching from spectator to player
@@ -412,6 +411,7 @@ 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();
@@ -433,4 +433,5 @@ STATIC_INIT(defs)
        g_saved_team = IL_NEW();
        g_monster_targets = IL_NEW();
        g_pathlib_nodes = IL_NEW();
+       g_moveables = IL_NEW();
 }
index e14ecd6ce7808ebeeca7dd436dc1aa4d41db2127..555a73472fb35cff23435bc2c9b7f2cdfbc66525 100644 (file)
@@ -85,9 +85,9 @@ string AppendItemcodes(string s, entity player)
                if(w != 0 || slot == 0)
                        s = strcat(s, ftos(w));
        }
-       if(time < player.strength_finished)
+       if(time < STAT(STRENGTH_FINISHED, player))
                s = strcat(s, "S");
-       if(time < player.invincible_finished)
+       if(time < STAT(INVINCIBLE_FINISHED, player))
                s = strcat(s, "I");
        if(PHYS_INPUT_BUTTON_CHAT(player))
                s = strcat(s, "T");
@@ -199,9 +199,9 @@ float Obituary_WeaponDeath(
        else
        {
                LOG_TRACEF(
-                       "Obituary_WeaponDeath(): ^1Deathtype ^7(%d)^1 has no notification for weapon %d!\n",
+                       "Obituary_WeaponDeath(): ^1Deathtype ^7(%d)^1 has no notification for weapon %s!\n",
                        deathtype,
-                       death_weapon
+                       death_weapon.netname
                );
        }
 
@@ -683,7 +683,8 @@ void Damage(entity targ, entity inflictor, entity attacker, float damage, int de
                    }
                }
 
-               if(deathtype != DEATH_HURTTRIGGER.m_id && deathtype != DEATH_TEAMCHANGE.m_id && deathtype != DEATH_AUTOTEAMCHANGE.m_id && STAT(FROZEN, targ))
+               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)
                        {
@@ -698,12 +699,12 @@ void Damage(entity targ, entity inflictor, entity attacker, float damage, int de
                        force *= autocvar_g_frozen_force;
                }
 
-               if(IS_PLAYER(targ) && STAT(FROZEN, targ) && deathtype == DEATH_HURTTRIGGER.m_id && !autocvar_g_frozen_damage_trigger)
+               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);
-
+                       entity spot = SelectSpawnPoint(targ, false);
                        if(spot)
                        {
                                damage = 0;
index b2b91bc02baf71cea1adf089e8236eea2a397667..aa970f4be3626a6ef4187417ad8c6f4a3f84769a 100644 (file)
@@ -359,9 +359,13 @@ void FireGrapplingHook(entity actor, .entity weaponentity)
        if(weaponLocked(actor)) return;
        if(actor.vehicle) return;
 
-       // TODO: offhand hook shoots from eye
+       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);
        Send_Effect(EFFECT_HOOK_MUZZLEFLASH, w_shotorg, '0 0 0', 1);
+       actor.(weaponentity).movedir = oldmovedir;
 
        entity missile = WarpZone_RefSys_SpawnSameRefSys(actor);
        missile.owner = missile.realowner = actor;
index 0c44a95f17bf5385372fb106e1dd4e37114930ee..bee939d9ac55fc5da8766fb70d0510123d1b71f3 100644 (file)
@@ -330,11 +330,13 @@ void cvar_changes_init()
                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_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");
                BADCVAR("g_domination_point_leadlimit");
                BADCVAR("g_forced_respawn");
@@ -396,6 +398,7 @@ void cvar_changes_init()
                //   :%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");
@@ -492,6 +495,7 @@ void cvar_changes_init()
                BADCVAR("g_ca_weaponarena");
                BADCVAR("g_freezetag_weaponarena");
                BADCVAR("g_lms_weaponarena");
+               BADCVAR("g_ctf_stalemate_time");
 
                if(cvar_string("g_mod_balance") == "Testing")
                {
@@ -810,8 +814,6 @@ spawnfunc(worldspawn)
                if(this.spawnflags & SPAWNFLAG_NO_WAYPOINTS_FOR_ITEMS)
                        bot_waypoints_for_items = 0;
 
-       precache();
-
        WaypointSprite_Init();
 
        GameLogInit(); // prepare everything
@@ -821,7 +823,7 @@ spawnfunc(worldspawn)
        // character set: ASCII 33-126 without the following characters: : ; ' " \ $
        if(autocvar_sv_eventlog)
        {
-               string s = sprintf("%d.%s.%06d", itos(autocvar_sv_eventlog_files_counter), strftime(false, "%s"), floor(random() * 1000000));
+               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));
@@ -872,6 +874,12 @@ spawnfunc(worldspawn)
        MapInfo_Enumerate();
        MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 1);
 
+       if(fexists(strcat("scripts/", mapname, ".arena")))
+               cvar_settemp("sv_q3acompat_machineshotgunswap", "1");
+
+       if(fexists(strcat("scripts/", mapname, ".defi")))
+               cvar_settemp("sv_q3defragcompat", "1");
+
        if(whichpack(strcat("maps/", mapname, ".cfg")) != "")
        {
                int fd = fopen(strcat("maps/", mapname, ".cfg"), FILE_READ);
@@ -1064,7 +1072,8 @@ bool MapHasRightSize(string map)
        // open map size restriction file
        string opensize_msg = strcat("opensize ", map);
        float fh = fopen(strcat("maps/", map, ".sizes"), FILE_READ);
-       int pcount = player_count;
+       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)
@@ -1097,7 +1106,7 @@ string Map_Filename(float position)
 
 void Map_MarkAsRecent(string m)
 {
-       cvar_set("g_maplist_mostrecent", strwords(strcat(m, " ", autocvar_g_maplist_mostrecent), max(0, autocvar_g_maplist_mostrecent_count)));
+       cvar_set("g_maplist_mostrecent", strwords(cons(m, autocvar_g_maplist_mostrecent), max(0, autocvar_g_maplist_mostrecent_count)));
 }
 
 float Map_IsRecent(string m)
@@ -1251,7 +1260,7 @@ void Maplist_Init()
                                break;
                }
        }
-       
+
        if (i == Map_Count)
        {
                bprint( "Maplist contains no usable maps!  Resetting it to default map list.\n" );
@@ -1409,54 +1418,6 @@ void IntermissionThink(entity this)
        MapVote_Start();
 }
 
-/*
-============
-FindIntermission
-
-Returns the entity to view from
-============
-*/
-/*
-entity FindIntermission()
-{
-       local   entity spot;
-       local   float cyc;
-
-// look for info_intermission first
-       spot = find(NULL, classname, "info_intermission");
-       if (spot)
-       {       // pick a random one
-               cyc = random() * 4;
-               while (cyc > 1)
-               {
-                       spot = find(spot, classname, "info_intermission");
-                       if (!spot)
-                               spot = find(spot, classname, "info_intermission");
-                       cyc = cyc - 1;
-               }
-               return spot;
-       }
-
-// then look for the start position
-       spot = find(NULL, classname, "info_player_start");
-       if (spot)
-               return spot;
-
-// testinfo_player_start is only found in regioned levels
-       spot = find(NULL, classname, "testplayerstart");
-       if (spot)
-               return spot;
-
-// then look for the start position
-       spot = find(NULL, classname, "info_player_deathmatch");
-       if (spot)
-               return spot;
-
-       //objerror ("FindIntermission: no spot");
-       return NULL;
-}
-*/
-
 /*
 ===============================================================================
 
@@ -1746,11 +1707,9 @@ void ShuffleMaplist()
        cvar_set("g_maplist", shufflewords(autocvar_g_maplist));
 }
 
-float leaderfrags;
+int fragsleft_last;
 float WinningCondition_Scores(float limit, float leadlimit)
 {
-       float limitreached;
-
        // TODO make everything use THIS winning condition (except LMS)
        WinningConditionHelper(NULL);
 
@@ -1780,42 +1739,43 @@ float WinningCondition_Scores(float limit, float leadlimit)
                leadlimit = 0; // not supported in this mode
 
        if(MUTATOR_CALLHOOK(Scores_CountFragsRemaining))
-       // these modes always score in increments of 1, thus this makes sense
        {
-               if(leaderfrags != WinningConditionHelper_topscore)
-               {
-                       leaderfrags = WinningConditionHelper_topscore;
+               float fragsleft = FLOAT_MAX, leadingfragsleft = FLOAT_MAX;
+               if (limit)
+                       fragsleft = limit - WinningConditionHelper_topscore;
+               if (leadlimit)
+                       leadingfragsleft = WinningConditionHelper_secondscore + leadlimit - WinningConditionHelper_topscore;
 
-                       if (limit)
-                       {
-                               if (leaderfrags == limit - 1)
-                                       Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_REMAINING_FRAG_1);
-                               else if (leaderfrags == limit - 2)
-                                       Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_REMAINING_FRAG_2);
-                               else if (leaderfrags == limit - 3)
-                                       Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_REMAINING_FRAG_3);
-                       }
+               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;
                }
        }
 
-       limitreached = false;
-       if (limit && WinningConditionHelper_topscore >= limit)
-               limitreached = true;
-       if(leadlimit)
-       {
-               float leadlimitreached;
-               leadlimitreached = (WinningConditionHelper_topscore - WinningConditionHelper_secondscore >= leadlimit);
-               if(autocvar_leadlimit_and_fraglimit)
-                       limitreached = (limitreached && leadlimitreached);
-               else
-                       limitreached = (limitreached || leadlimitreached);
-       }
+       bool fraglimit_reached = (limit && WinningConditionHelper_topscore >= limit);
+       bool leadlimit_reached = (leadlimit && WinningConditionHelper_topscore - WinningConditionHelper_secondscore >= leadlimit);
 
-       if(limit)
-               game_completion_ratio = max(game_completion_ratio, bound(0, WinningConditionHelper_topscore / limit, 1));
+       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 && limitreached,
+               WinningConditionHelper_topscore && limit_reached,
                WinningConditionHelper_equality
        );
 }
@@ -1906,10 +1866,6 @@ Exit deathmatch games upon conditions
 */
 void CheckRules_World()
 {
-       float timelimit;
-       float fraglimit;
-       float leadlimit;
-
        VoteThink();
        MapVote_Think();
 
@@ -1924,9 +1880,10 @@ void CheckRules_World()
                return;
        }
 
-       timelimit = autocvar_timelimit * 60;
-       fraglimit = autocvar_fraglimit;
-       leadlimit = autocvar_leadlimit;
+       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
        {
@@ -1951,11 +1908,6 @@ void CheckRules_World()
        float wantovertime;
        wantovertime = 0;
 
-       if(timelimit > game_starttime)
-               game_completion_ratio = (time - game_starttime) / (timelimit - game_starttime);
-       else
-               game_completion_ratio = 0;
-
        if(checkrules_suddendeathend)
        {
                if(!checkrules_suddendeathwarning)
@@ -2101,7 +2053,7 @@ void Physics_Frame()
        if(autocvar_sv_freezenonclients)
                return;
 
-       FOREACH_ENTITY_FLOAT(pure_data, false,
+       IL_EACH(g_moveables, true,
        {
                if(IS_CLIENT(it) || it.classname == "" || it.move_movetype == MOVETYPE_PUSH || it.move_movetype == MOVETYPE_FAKEPUSH || it.move_movetype == MOVETYPE_PHYSICS)
                        continue;
@@ -2127,7 +2079,7 @@ void Physics_Frame()
        if(autocvar_sv_gameplayfix_delayprojectiles >= 0)
                return;
 
-       FOREACH_ENTITY_FLOAT(move_qcphysics, true,
+       IL_EACH(g_moveables, it.move_qcphysics,
        {
                if(IS_CLIENT(it) || is_pure(it) || it.classname == "" || it.move_movetype == MOVETYPE_NONE)
                        continue;
@@ -2262,7 +2214,7 @@ void Shutdown()
                        else
                                db_save(ServerProgsDB, strcat("server.db", autocvar_sessionid));
                }
-               if(autocvar_developer)
+               if(autocvar_developer > 0)
                {
                        if(autocvar_sv_db_saveasdump)
                                db_dump(TemporaryDB, "server-temp.db");
index 9d74477b4846525c3d84dc020a58340c75b2e11e..a7786f6b660eac467b1d7ea689dfb0f4dac98f92 100644 (file)
@@ -453,11 +453,16 @@ bool Ban_MaybeEnforceBan(entity client)
 {
        if (Ban_IsClientBanned(client, -1))
        {
-               string s = sprintf("^1NOTE:^7 banned client %s just tried to enter\n", client.netaddress);
+               if (!client.crypto_idfp)
+                       LOG_INFOF("^1NOTE:^7 banned client %s just tried to enter\n",
+                               client.netaddress);
+               else
+                       LOG_INFOF("^1NOTE:^7 banned client %s (%s) just tried to enter\n",
+                               client.netaddress, client.crypto_idfp);
+
                if(autocvar_g_ban_telluser)
                        sprint(client, "You are banned from this server.\n");
                dropclient(client);
-               bprint(s);
                return true;
        }
        return false;
@@ -489,7 +494,7 @@ string Ban_Enforce(float j, string reason)
                                        reason = strcat(reason, ", ");
                                reason = strcat(reason, it.netname);
                        }
-                       s = strcat(s, "^1NOTE:^7 banned client ", it.netaddress, "^7 has to go\n");
+                       s = strcat(s, "^1NOTE:^7 banned client ", it.netname, "^7 has to go\n");
                        dropclient(it);
                }
        });
index ceb2cdd07850a884875e4895d71f614e3de7867e..acac831d76a181940782c1b074d7b5e0ef0b3d61 100644 (file)
@@ -525,7 +525,7 @@ bool MapVote_CheckRules_2()
                        }
                }
        firstPlaceVotes = RandomSelection_best_priority;
-       if ( autocvar_sv_vote_gametype_default_current && currentVotes == firstPlaceVotes )
+       if ( autocvar_sv_vote_gametype_default_current && firstPlaceVotes == 0 )
                firstPlace = currentPlace;
        else
                firstPlace = RandomSelection_chosen_float;
index ded47a6387f97920ce32f2fa41851a7b8ec32dea..9dd468c2d74982c15a6e83691debb4b4c9254bcb 100644 (file)
@@ -7,6 +7,7 @@
 #include "ipban.qh"
 #include <server/mutators/_mod.qh>
 #include "../common/t_items.qh"
+#include "mapvoting.qh"
 #include "resources.qh"
 #include "items.qh"
 #include "player.qh"
@@ -32,6 +33,7 @@
 #include "../common/state.qh"
 #include "../common/effects/qc/globalsound.qh"
 #include "../common/wepent.qh"
+#include <common/weapons/weapon.qh>
 #include "../lib/csqcmodel/sv_model.qh"
 #include "../lib/warpzone/anglestransform.qh"
 #include "../lib/warpzone/server.qh"
@@ -82,6 +84,13 @@ void dedicated_print(string input)
        if (server_is_dedicated) print(input);
 }
 
+string GameLog_ProcessIP(string s)
+{
+       if(!autocvar_sv_eventlog_ipv6_delimiter)
+               return s;
+       return strreplace(":", "_", s);
+}
+
 void GameLogEcho(string s)
 {
     string fn;
@@ -213,19 +222,28 @@ string NearestLocation(vector p)
     return ret;
 }
 
-string AmmoNameFromWeaponentity(Weapon wep)
+string PlayerHealth(entity this)
 {
-       string ammoitems = "batteries";
-       switch (wep.ammo_type)
-       {
-               case RES_SHELLS:  ammoitems = ITEM_Shells.m_name;      break;
-               case RES_BULLETS: ammoitems = ITEM_Bullets.m_name;     break;
-               case RES_ROCKETS: ammoitems = ITEM_Rockets.m_name;     break;
-               case RES_CELLS:   ammoitems = ITEM_Cells.m_name;       break;
-               case RES_PLASMA:  ammoitems = ITEM_Plasma.m_name;      break;
-               case RES_FUEL:    ammoitems = ITEM_JetpackFuel.m_name; break;
-       }
-       return ammoitems;
+       float myhealth = floor(GetResource(this, RES_HEALTH));
+       if(myhealth == -666)
+               return "spectating";
+       else if(myhealth == -2342 || (myhealth == 2342 && mapvote_initialized))
+               return "observing";
+       else if(myhealth <= 0 || IS_DEAD(this))
+               return "dead";
+       return ftos(myhealth);
+}
+
+string WeaponNameFromWeaponentity(entity this, .entity weaponentity)
+{
+       entity wepent = this.(weaponentity);
+       if(!wepent)
+               return "none";
+       else if(wepent.m_weapon != WEP_Null)
+               return wepent.m_weapon.m_name;
+       else if(wepent.m_switchweapon != WEP_Null)
+               return wepent.m_switchweapon.m_name;
+       return "none"; //Weapons_from(wepent.cnt).m_name;
 }
 
 string formatmessage(entity this, string msg)
@@ -281,12 +299,12 @@ string formatmessage(entity this, string msg)
                        case "\\":replacement = "\\"; break;
                        case "n": replacement = "\n"; break;
                        case "a": replacement = ftos(floor(GetResource(this, RES_ARMOR))); break;
-                       case "h": replacement = ftos(floor(GetResource(this, RES_HEALTH))); break;
+                       case "h": replacement = PlayerHealth(this); break;
                        case "l": replacement = NearestLocation(this.origin); break;
                        case "y": replacement = NearestLocation(cursor); break;
                        case "d": replacement = NearestLocation(this.death_origin); break;
-                       case "w": replacement = ((this.(weaponentity).m_weapon == WEP_Null) ? ((this.(weaponentity).m_switchweapon == WEP_Null) ? Weapons_from(this.(weaponentity).cnt) : this.(weaponentity).m_switchweapon) : this.(weaponentity).m_weapon).m_name; break;
-                       case "W": replacement = AmmoNameFromWeaponentity(this.(weaponentity).m_weapon); break;
+                       case "w": replacement = WeaponNameFromWeaponentity(this, weaponentity); break;
+                       case "W": replacement = GetAmmoName(this.(weaponentity).m_weapon.ammo_type); break;
                        case "x": replacement = ((cursor_ent.netname == "" || !cursor_ent) ? "nothing" : cursor_ent.netname); break;
                        case "s": replacement = ftos(vlen(this.velocity - this.velocity_z * '0 0 1')); break;
                        case "S": replacement = ftos(vlen(this.velocity)); break;
@@ -475,6 +493,8 @@ void GetCvars(entity this, entity store, int f)
                }
                if (s == "cl_allow_uidtracking")
                        PlayerStats_GameReport_AddPlayer(this);
+               //if (s == "cl_gunalign")
+                       //W_ResetGunAlign(this, store.cvar_cl_gunalign);
        }
 }
 
@@ -611,8 +631,6 @@ void weaponarena_available_most_update(entity this)
 
 void readplayerstartcvars()
 {
-       float i, t;
-
        // initialize starting values for players
        start_weapons = '0 0 0';
        start_weapons_default = '0 0 0';
@@ -696,11 +714,11 @@ void readplayerstartcvars()
        else
        {
                g_weaponarena = 1;
-               t = tokenize_console(s);
+               float t = tokenize_console(s);
                g_weaponarena_list = "";
-               for (i = 0; i < t; ++i)
+               for (int j = 0; j < t; ++j)
                {
-                       s = argv(i);
+                       s = argv(j);
                        Weapon wep = Weapons_fromstr(s);
                        if(wep != WEP_Null)
                        {
@@ -838,9 +856,14 @@ void readplayerstartcvars()
 
 void precache_playermodel(string m)
 {
-       float globhandle, i, n;
+       int globhandle, i, n;
        string f;
 
+       // remove :<skinnumber> suffix
+       int j = strstrofs(m, ":", 0);
+       if(j >= 0)
+               m = substring(m, 0, j);
+
        if(substring(m, -9, 5) == "_lod1")
                return;
        if(substring(m, -9, 5) == "_lod2")
@@ -883,10 +906,8 @@ void precache_playermodels(string s)
        FOREACH_WORD(s, true, { precache_playermodel(it); });
 }
 
-void precache()
+PRECACHE(PlayerModels)
 {
-    // gamemode related things
-
     // Precache all player models if desired
     if (autocvar_sv_precacheplayermodels)
     {
@@ -906,20 +927,6 @@ void precache()
                precache_playermodels(autocvar_sv_defaultplayermodel_pink);
                precache_playermodels(autocvar_sv_defaultplayermodel);
     }
-
-#if 0
-    // Disabled this code because it simply does not work (e.g. ignores bgmvolume, overlaps with "cd loop" controlled tracks).
-
-    if (!this.noise && this.music) // quake 3 uses the music field
-        this.noise = this.music;
-
-    // plays music for the level if there is any
-    if (this.noise)
-    {
-        precache_sound (this.noise);
-        ambientsound ('0 0 0', this.noise, VOL_BASE, ATTEN_NONE);
-    }
-#endif
 }
 
 
@@ -1184,11 +1191,10 @@ bool SUB_NoImpactCheck(entity this, entity toucher)
     return false;
 }
 
-#define SUB_OwnerCheck(ent,oth) ((oth) && ((oth) == (ent).owner))
-
 bool WarpZone_Projectile_Touch_ImpactFilter_Callback(entity this, entity toucher)
 {
-       if(SUB_OwnerCheck(this, toucher))
+       // owner check
+       if(toucher && toucher == this.owner)
                return true;
        if(SUB_NoImpactCheck(this, toucher))
        {
@@ -1236,9 +1242,9 @@ void URI_Get_Callback(float id, float status, string data)
        }
 }
 
-string uid2name(string myuid) {
-       string s;
-       s = db_get(ServerProgsDB, strcat("/uid2name/", myuid));
+string uid2name(string myuid)
+{
+       string s = db_get(ServerProgsDB, strcat("/uid2name/", myuid));
 
        // FIXME remove this later after 0.6 release
        // convert old style broken records to correct style
@@ -1257,20 +1263,18 @@ string uid2name(string myuid) {
        return s;
 }
 
-float MoveToRandomLocationWithinBounds(entity e, vector boundmin, vector boundmax, float goodcontents, float badcontents, float badsurfaceflags, float attempts, float maxaboveground, float minviewdistance)
+bool MoveToRandomLocationWithinBounds(entity e, vector boundmin, vector boundmax, float goodcontents, float badcontents, float badsurfaceflags, int attempts, float maxaboveground, float minviewdistance)
 {
-    float m, i;
-    vector start, org, delta, end, enddown, mstart;
-
-    m = e.dphitcontentsmask;
+    float m = e.dphitcontentsmask;
     e.dphitcontentsmask = goodcontents | badcontents;
 
-    org = boundmin;
-    delta = boundmax - boundmin;
+    vector org = boundmin;
+    vector delta = boundmax - boundmin;
 
+    vector start, end;
     start = end = org;
-
-    for (i = 0; i < attempts; ++i)
+    int j; // used after the loop
+    for(j = 0; j < attempts; ++j)
     {
         start.x = org.x + random() * delta.x;
         start.y = org.y + random() * delta.y;
@@ -1292,13 +1296,13 @@ float MoveToRandomLocationWithinBounds(entity e, vector boundmin, vector boundma
         // rule 2: if we are too high, lower the point
         if (trace_fraction * delta.z > maxaboveground)
             start = trace_endpos + '0 0 1' * maxaboveground;
-        enddown = trace_endpos;
+        vector enddown = trace_endpos;
 
         // rule 3: make sure we aren't outside the map. This only works
         // for somewhat well formed maps. A good rule of thumb is that
         // the map should have a convex outside hull.
         // these can be traceLINES as we already verified the starting box
-        mstart = start + 0.5 * (e.mins + e.maxs);
+        vector mstart = start + 0.5 * (e.mins + e.maxs);
         traceline(mstart, mstart + '1 0 0' * delta.x, MOVE_NORMAL, e);
         if (trace_fraction >= 1 || trace_dphittexturename == "common/caulk")
             continue;
@@ -1315,35 +1319,35 @@ float MoveToRandomLocationWithinBounds(entity e, vector boundmin, vector boundma
         if (trace_fraction >= 1 || trace_dphittexturename == "common/caulk")
             continue;
 
-       // rule 4: we must "see" some spawnpoint or item
-    entity sp = NULL;
-    IL_EACH(g_spawnpoints, checkpvs(mstart, it),
-    {
-       if((traceline(mstart, it.origin, MOVE_NORMAL, e), trace_fraction) >= 1)
-       {
-               sp = it;
-               break;
-       }
-    });
-       if(!sp)
-       {
-               int items_checked = 0;
-               IL_EACH(g_items, checkpvs(mstart, it),
+               // rule 4: we must "see" some spawnpoint or item
+           entity sp = NULL;
+           IL_EACH(g_spawnpoints, checkpvs(mstart, it),
+           {
+               if((traceline(mstart, it.origin, MOVE_NORMAL, e), trace_fraction) >= 1)
+               {
+                       sp = it;
+                       break;
+               }
+           });
+               if(!sp)
                {
-                       if((traceline(mstart, it.origin + (it.mins + it.maxs) * 0.5, MOVE_NORMAL, e), trace_fraction) >= 1)
+                       int items_checked = 0;
+                       IL_EACH(g_items, checkpvs(mstart, it),
                        {
-                               sp = it;
-                               break;
-                       }
+                               if((traceline(mstart, it.origin + (it.mins + it.maxs) * 0.5, MOVE_NORMAL, e), trace_fraction) >= 1)
+                               {
+                                       sp = it;
+                                       break;
+                               }
 
-                       ++items_checked;
-                       if(items_checked >= attempts)
-                               break; // sanity
-               });
+                               ++items_checked;
+                               if(items_checked >= attempts)
+                                       break; // sanity
+                       });
 
-               if(!sp)
-                       continue;
-       }
+                       if(!sp)
+                               continue;
+               }
 
         // find a random vector to "look at"
         end.x = org.x + random() * delta.x;
@@ -1353,17 +1357,17 @@ float MoveToRandomLocationWithinBounds(entity e, vector boundmin, vector boundma
 
         // rule 4: start TO end must not be too short
         tracebox(start, e.mins, e.maxs, end, MOVE_NORMAL, e);
-        if (trace_startsolid)
+        if(trace_startsolid)
             continue;
-        if (trace_fraction < minviewdistance / vlen(delta))
+        if(trace_fraction < minviewdistance / vlen(delta))
             continue;
 
         // rule 5: don't want to look at sky
-        if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
+        if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
             continue;
 
         // rule 6: we must not end up in trigger_hurt
-        if (tracebox_hits_trigger_hurt(start, e.mins, e.maxs, enddown))
+        if(tracebox_hits_trigger_hurt(start, e.mins, e.maxs, enddown))
             continue;
 
         break;
@@ -1371,15 +1375,14 @@ float MoveToRandomLocationWithinBounds(entity e, vector boundmin, vector boundma
 
     e.dphitcontentsmask = m;
 
-    if (i < attempts)
+    if(j < attempts)
     {
         setorigin(e, start);
         e.angles = vectoangles(end - start);
-        LOG_DEBUG("Needed ", ftos(i + 1), " attempts");
+        LOG_DEBUG("Needed ", ftos(j + 1), " attempts");
         return true;
     }
-    else
-        return false;
+    return false;
 }
 
 float MoveToRandomMapLocation(entity e, float goodcontents, float badcontents, float badsurfaceflags, float attempts, float maxaboveground, float minviewdistance)
@@ -1461,24 +1464,13 @@ void follow_sameorigin(entity e, entity to)
     e.v_angle = e.angles - to.angles; // relative angles
 }
 
+#if 0
+// TODO: unused, likely for a reason, possibly needs extensions (allow setting the new movetype as a parameter?)
 void unfollow_sameorigin(entity e)
 {
     set_movetype(e, MOVETYPE_NONE);
 }
-
-entity gettaginfo_relative_ent;
-vector gettaginfo_relative(entity e, float tag)
-{
-    if (!gettaginfo_relative_ent)
-    {
-        gettaginfo_relative_ent = spawn();
-        gettaginfo_relative_ent.effects = EF_NODRAW;
-    }
-    gettaginfo_relative_ent.model = e.model;
-    gettaginfo_relative_ent.modelindex = e.modelindex;
-    gettaginfo_relative_ent.frame = e.frame;
-    return gettaginfo(gettaginfo_relative_ent, tag);
-}
+#endif
 
 .string aiment_classname;
 .float aiment_deadflag;
index 2374b4869bc6c5415c08c319a162850ca9871440..cb11057eff97d8c5167600c17a97d5ccd740ba9c 100644 (file)
@@ -11,7 +11,7 @@
 #include <common/mapinfo.qh>
 #include <common/turrets/all.qh>
 
-#ifdef RELEASE
+#if 1
 #define cvar_string_normal builtin_cvar_string
 #define cvar_normal builtin_cvar
 #else
@@ -74,6 +74,8 @@ string formatmessage(entity this, string msg);
 /** print(), but only print if the server is not local */
 void dedicated_print(string input);
 
+string GameLog_ProcessIP(string s);
+
 void GameLogEcho(string s);
 
 void GameLogInit();
@@ -90,20 +92,16 @@ float LostMovetypeFollow(entity ent);
 
 string uid2name(string myuid);
 
-float MoveToRandomLocationWithinBounds(entity e, vector boundmin, vector boundmax, float goodcontents, float badcontents, float badsurfaceflags, float attempts, float maxaboveground, float minviewdistance);
+bool MoveToRandomLocationWithinBounds(entity e, vector boundmin, vector boundmax, float goodcontents, float badcontents, float badsurfaceflags, int attempts, float maxaboveground, float minviewdistance);
 
 float MoveToRandomMapLocation(entity e, float goodcontents, float badcontents, float badsurfaceflags, float attempts, float maxaboveground, float minviewdistance);
 
 string NearestLocation(vector p);
 
-string AmmoNameFromWeaponentity(Weapon wep);
-
 void play2(entity e, string filename);
 
 string playername(entity p, bool team_colorize);
 
-void precache();
-
 void remove_safely(entity e);
 
 void remove_unsafely(entity e);
index fc550fa636f029bd2f0b1e596c44dbd0b15a6a2e..4cb8a3806c6883f32cb8550abc9388eda50cef5a 100644 (file)
@@ -289,7 +289,7 @@ void pathlib_cleanup()
 
 float Cosine_Interpolate(float a, float b, float c)
 {
-       float ft = c * 3.1415927;
+       float ft = c * M_PI;
        float f = (1 - cos(ft)) * 0.5;
 
        return a*(1-f) + b*f;
index 9e67050cb654b23c9847c8b2e94bda0f1898b106..e5a8f47f90f859908e0ba951776cbd71a3bbf854 100644 (file)
@@ -369,7 +369,7 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage,
 
        if(attacker == this)
        {
-               // don't reset pushltime for this damage as it may be an attempt to
+               // don't reset pushltime for self damage as it may be an attempt to
                // escape a lava pit or similar
                //this.pushltime = 0;
                this.istypefrag = 0;
@@ -468,6 +468,7 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage,
 
                        float realdmg = damage - excess;
                        if (this != attacker && realdmg)
+                       if (!(round_handler_IsActive() && !round_handler_IsRoundStarted()) && time >= game_starttime)
                        {
                                if (IS_PLAYER(attacker) && DIFF_TEAM(attacker, this)) {
                                        GameRules_scoring_add(attacker, DMG, realdmg);
@@ -490,6 +491,7 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage,
        bool valid_damage_for_weaponstats = false;
        Weapon awep = WEP_Null;
 
+       if (!(round_handler_IsActive() && !round_handler_IsRoundStarted()) && time >= game_starttime)
        if(vbot || IS_REAL_CLIENT(this))
        if(abot || IS_REAL_CLIENT(attacker))
        if(attacker && this != attacker)
index 6f128716365933599e271f4294ef295a779ef8b8..0eb325699d8f05716456d332685ab665c21e7ec4 100644 (file)
@@ -16,6 +16,7 @@
 #include "../lib/warpzone/common.qh"
 #include "../common/vehicles/vehicle.qh"
 #include "../common/vehicles/sv_vehicles.qh"
+#include <server/player.qh>
 
 #define PORTALS_ARE_NOT_SOLID
 
@@ -30,11 +31,10 @@ const vector SAFERNUDGE = '8 8 8';
 
 float PlayerEdgeDistance(entity p, vector v)
 {
-       vector vbest;
-
-       if(v.x < 0) vbest.x = p.mins.x; else vbest.x = p.maxs.x;
-       if(v.y < 0) vbest.y = p.mins.y; else vbest.y = p.maxs.y;
-       if(v.z < 0) vbest.z = p.mins.z; else vbest.z = p.maxs.z;
+       vector vbest = vec3(
+               ((v.x < 0) ? p.mins.x : p.maxs.x),
+               ((v.y < 0) ? p.mins.y : p.maxs.y),
+               ((v.z < 0) ? p.mins.z : p.maxs.z));
 
        return vbest * v;
 }
@@ -103,7 +103,7 @@ vector Portal_ApplyTransformToPlayerAngle(vector transform, vector vangle)
 }
 
 .vector right_vector;
-float Portal_TeleportPlayer(entity teleporter, entity player)
+float Portal_TeleportPlayer(entity teleporter, entity player, entity portal_owner)
 {
        vector from, to, safe, step, transform, ang, newvel;
        float planeshift, s, t;
@@ -189,6 +189,12 @@ float Portal_TeleportPlayer(entity teleporter, entity player)
                if(time < teleporter.teleport_time + 1)
                        Send_Notification(NOTIF_ONE, player, MSG_ANNCE, ANNCE_ACHIEVEMENT_AMAZING);
        }
+       else if(player != portal_owner && IS_PLAYER(portal_owner) && IS_PLAYER(player))
+       {
+               player.pusher = portal_owner;
+               player.pushltime = time + autocvar_g_maxpushtime;
+               player.istypefrag = PHYS_INPUT_BUTTON_CHAT(player);
+       }
 
        if (!teleporter.enemy)
        {
@@ -317,7 +323,7 @@ void Portal_Touch(entity this, entity toucher)
        }
        */
 
-       if(Portal_TeleportPlayer(this, toucher))
+       if(Portal_TeleportPlayer(this, toucher, this.aiment))
                if(toucher.classname == "porto")
                        if(toucher.effects & EF_RED)
                                toucher.effects += EF_BLUE - EF_RED;
@@ -440,7 +446,7 @@ void Portal_Damage(entity this, entity inflictor, entity attacker, float damage,
                Portal_Remove(this, 1);
 }
 
-void Portal_Think_TryTeleportPlayer(entity this, entity e, vector g)
+void Portal_Think_TryTeleportPlayer(entity this, entity e, vector g, entity portal_owner)
 {
        if(!Portal_WillHitPlane(e.origin, e.mins, e.maxs, e.velocity + g, this.origin, v_forward, this.maxs.x))
                return;
@@ -449,7 +455,7 @@ void Portal_Think_TryTeleportPlayer(entity this, entity e, vector g)
        // already teleport him
        tracebox(e.origin, e.mins, e.maxs, e.origin + e.velocity * 2 * frametime, MOVE_NORMAL, e);
        if(trace_ent == this)
-               Portal_TeleportPlayer(this, e);
+               Portal_TeleportPlayer(this, e, portal_owner);
 }
 
 void Portal_Think(entity this)
@@ -479,13 +485,13 @@ void Portal_Think(entity this)
                                continue; // cannot go through someone else's portal
 
                if(it != o || time >= this.portal_activatetime)
-                       Portal_Think_TryTeleportPlayer(this, it, g);
+                       Portal_Think_TryTeleportPlayer(this, it, g, o);
 
                for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
            {
                .entity weaponentity = weaponentities[slot];
                if(it.(weaponentity).hook)
-                       Portal_Think_TryTeleportPlayer(this, it.(weaponentity).hook, g);
+                       Portal_Think_TryTeleportPlayer(this, it.(weaponentity).hook, g, o);
            }
        });
        this.solid = SOLID_TRIGGER;
index af2f4b574f43a57f0c098d19c47b5fe2754428ac..69b18ba2a206d8685dd1ef33bf18604007a971fb 100644 (file)
@@ -5,6 +5,7 @@
 #include <server/g_world.qh>
 #include <server/miscfunctions.qh>
 #include <server/mutators/_mod.qh>
+#include <server/round_handler.qh>
 #include <common/net_linked.qh>
 #include "../common/playerstats.qh"
 #include "../common/teams.qh"
@@ -107,8 +108,11 @@ float TeamScore_AddToTeam(int t, float scorefield, float score)
 {
        entity s;
 
-       if(game_stopped)
+       if(game_stopped || time < game_starttime
+               || (round_handler_IsActive() && !round_handler_IsRoundStarted()))
+       {
                score = 0;
+       }
 
        if(!scores_initialized) return 0; // FIXME remove this when everything uses this system
        if(t <= 0 || t >= 16)
@@ -334,9 +338,11 @@ float PlayerScore_Add(entity player, PlayerScoreField scorefield, float score)
        bool mutator_returnvalue = MUTATOR_CALLHOOK(AddPlayerScore, scorefield, score, player);
        score = M_ARGV(1, float);
 
-       if(game_stopped)
-       if(!mutator_returnvalue)
+       if((!mutator_returnvalue && game_stopped) || time < game_starttime
+               || (round_handler_IsActive() && !round_handler_IsRoundStarted()))
+       {
                score = 0;
+       }
 
        if(!scores_initialized) return 0; // FIXME remove this when everything uses this system
        entity s = CS(player).scorekeeper;
index 5aa81a2a73b0e9ad3fae1304237f863e71c9a2ed..e2c5ab307aa7743dedc878cc89f0b2254f4ae8bc 100644 (file)
@@ -65,10 +65,16 @@ void spawnpoint_use(entity this, entity actor, entity trigger)
        {
                this.team = actor.team;
                some_spawn_has_been_used = true;
+               this.SendFlags |= 1; // update team on the client side
        }
        //LOG_INFO("spawnpoint was used!\n");
 }
 
+void spawnpoint_reset(entity this)
+{
+       this.SendFlags |= 1; // update team since it was restored during reset
+}
+
 void relocate_spawnpoint(entity this)
 {
     // nudge off the floor
@@ -106,6 +112,7 @@ void relocate_spawnpoint(entity this)
     this.use = spawnpoint_use;
     setthink(this, spawnpoint_think);
     this.nextthink = time + 0.5 + random() * 2; // shouldn't need it for a little second
+    this.reset2 = spawnpoint_reset; // restores team, allows re-sending the spawnpoint
     this.team_saved = this.team;
     IL_PUSH(g_saved_team, this);
     if (!this.cnt)
index 54c9744332d5033ccbd5518f4f79b29dca36606c..531a1537bf14a6efa183f66fc82a60bbe84cc5a4 100644 (file)
@@ -46,7 +46,14 @@ void CreatureFrame_hotliquids(entity this)
        }
        else
        {
-               if (this.watertype == CONTENT_LAVA)
+               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)
                        {
@@ -89,7 +96,6 @@ void CreatureFrame_Liquids(entity this)
                        this.flags &= ~FL_INWATER;
                        this.dmgtime = 0;
                }
-               this.air_finished = time + 12;
        }
 }
 
@@ -101,7 +107,6 @@ void CreatureFrame_FallDamage(entity this)
                return; // if the entity hasn't moved and isn't moving, then don't do anything
 
        // check for falling damage
-       float velocity_len = vlen(this.velocity);
        bool have_hook = false;
        for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
        {
@@ -114,16 +119,24 @@ void CreatureFrame_FallDamage(entity this)
        }
        if(!have_hook)
        {
-               float dm = vlen(this.oldvelocity) - velocity_len; // dm is now the velocity DECREASE. Velocity INCREASE should never cause a sound or any damage.
+               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)
-                       Damage (this, NULL, NULL, dm, DEATH_FALL.m_id, DMG_NOWEP, this.origin, '0 0 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 && velocity_len > autocvar_g_maxspeed)
+       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');
 }
 
@@ -239,6 +252,7 @@ void StartFrame()
        anticheat_startframe();
        MUTATOR_CALLHOOK(SV_StartFrame);
 
+       GlobalStats_updateglobal();
     FOREACH_CLIENT(true, GlobalStats_update(it));
     IL_EACH(g_players, IS_FAKE_CLIENT(it), PlayerPostThink(it));
 }
index ff9438e76d84b205679a05982d5b8bc1eb0b57f3..a7c7205c1fb5781bec8edf30adc0dfa5a2a3fc12 100644 (file)
@@ -496,8 +496,7 @@ entity TeamBalance_CheckAllowedTeams(entity for_whom)
        }
 
        // TODO: Balance quantity of bots across > 2 teams when bot_vs_human is set (and remove next line)
-       if (AvailableTeams() == 2)
-       if (autocvar_bot_vs_human && for_whom)
+       if (autocvar_bot_vs_human && AvailableTeams() == 2 && for_whom)
        {
                if (autocvar_bot_vs_human > 0)
                {
index 23a3ee67d6aa5ab8d2ba95d302f2b7514ecbdc39..93c49af9bddb7c7fe02cdd47018d5ce34a3758dd 100644 (file)
@@ -34,7 +34,7 @@ void weapon_defaultspawnfunc(entity this, Weapon wpn)
        {
                if (wpn.spawnflags & WEP_FLAG_MUTATORBLOCKED)
                {
-                       LOG_WARNF("Attempted to spawn a mutator-blocked weapon rejected: prvm_edict server %i", this);
+                       //LOG_WARNF("Attempted to spawn a mutator-blocked weapon rejected: prvm_edict server %i", this);
                        startitem_failed = true;
                        return;
                }
index 7e8a061f049b1ebc552308c796219c1b716eedbd..ba039fc1055baf6655a3bc91724635df4d69281f 100644 (file)
@@ -67,15 +67,15 @@ float W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vector
                        });
                        if(superweapons <= 1)
                        {
-                               wep.superweapons_finished = own.superweapons_finished;
-                               own.superweapons_finished = 0;
+                               wep.superweapons_finished = STAT(SUPERWEAPONS_FINISHED, own);
+                               STAT(SUPERWEAPONS_FINISHED, own) = 0;
                        }
                        else
                        {
-                               float timeleft = own.superweapons_finished - time;
+                               float timeleft = STAT(SUPERWEAPONS_FINISHED, own) - time;
                                float weptimeleft = timeleft / superweapons;
                                wep.superweapons_finished = time + weptimeleft;
-                               own.superweapons_finished -= weptimeleft;
+                               STAT(SUPERWEAPONS_FINISHED, own) -= weptimeleft;
                        }
                }
        }
index 6e74738c738eaf5a1bbabcf155bef94c74416ad2..5f4f6f8332deb1d0b4d171c31a839922b4267bd3 100644 (file)
@@ -366,6 +366,9 @@ void weapon_thinkf(entity actor, .entity weaponentity, WFRAME fr, float t, void(
        bool restartanim;
        if (fr == WFRAME_DONTCHANGE)
        {
+               // this can happen when the weapon entity is newly spawned, since it has a clear state and no previous weapon frame
+               if (this.wframe == WFRAME_DONTCHANGE)
+                       this.wframe = WFRAME_IDLE;
                fr = this.wframe;
                restartanim = false;
        }
@@ -374,14 +377,7 @@ void weapon_thinkf(entity actor, .entity weaponentity, WFRAME fr, float t, void(
                restartanim = fr != WFRAME_IDLE;
        }
 
-       vector a = '0 0 0';
     this.wframe = fr;
-    if (fr == WFRAME_IDLE) a = this.anim_idle;
-    else if (fr == WFRAME_FIRE1) a = this.anim_fire1;
-    else if (fr == WFRAME_FIRE2) a = this.anim_fire2;
-    else  // if (fr == WFRAME_RELOAD)
-        a = this.anim_reload;
-    a.z *= g_weaponratefactor;
 
        if (this.weapon_think == w_ready && func != w_ready && this.state == WS_RAISE) backtrace(
                        "Tried to override initial weapon think function - should this really happen?");
@@ -408,7 +404,7 @@ void weapon_thinkf(entity actor, .entity weaponentity, WFRAME fr, float t, void(
        {
                FOREACH_CLIENT(true, {
                        if(it == actor || (IS_SPEC(it) && it.enemy == actor))
-                               wframe_send(it, this, a, restartanim);
+                               wframe_send(it, this, fr, g_weaponratefactor, restartanim);
                });
        }
 
@@ -445,6 +441,28 @@ bool weaponLocked(entity player)
        return false;
 }
 
+void W_ResetGunAlign(entity player, int preferred_alignment)
+{
+       if(W_DualWielding(player))
+               preferred_alignment = 3; // right align, the second gun will default to left
+
+       // clear current weapon slots' alignments so we can redo the calculations!
+       for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+       {
+               .entity weaponentity = weaponentities[slot];
+               if (player.(weaponentity))
+                       player.(weaponentity).m_gunalign = 0;
+       }
+
+       // now set the new values
+       for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+       {
+               .entity weaponentity = weaponentities[slot];
+               if (player.(weaponentity))
+                       player.(weaponentity).m_gunalign = W_GunAlign(player.(weaponentity), preferred_alignment);
+       }
+}
+
 .bool hook_switchweapon;
 
 void W_WeaponFrame(Player actor, .entity weaponentity)
@@ -783,6 +801,8 @@ void W_Reload(entity actor, .entity weaponentity, float sent_ammo_min, Sound sen
                {
                        if (!(actor.items & IT_UNLIMITED_AMMO))
                        {
+                               if (autocvar_g_weaponswitch_debug == 2 && weaponslot(weaponentity) > 0)
+                                       return; // in this case the primary weapon will do the switching when it runs out of ammo (TODO: do this same check but for other slots)
                                if (IS_REAL_CLIENT(actor) && actor.reload_complain < time)
                                {
                                        play2(actor, SND(UNAVAILABLE));
index 91879feb2a9a95548eb6008c500498bc79a07a09..986756aa510344405c4f27e9db7f9b57effef938 100644 (file)
@@ -23,6 +23,8 @@ void W_DropEvent(.void(Weapon, entity actor, .entity) event, entity player, floa
 
 void W_Reload(entity actor, .entity weaponentity, float sent_ammo_min, Sound sent_sound);
 
+void W_ResetGunAlign(entity player, int preferred_alignment);
+
 void W_WeaponFrame(Player actor, .entity weaponentity);
 
 float W_WeaponRateFactor(entity this);
index cb39b2a10ce1a16c1b5cb554be256a42e01c52f5..8b3f70a9414db5e046c8e240d40dcfc6d9a285bc 100644 (file)
@@ -34,3 +34,5 @@ g_spawn_near_teammate "!g_assault !g_freezetag"
 g_spawn_near_teammate_ignore_spawnpoint 1
 g_spawnshieldtime 0.5
 g_respawn_delay_forced 2
+
+g_ballistics_solidpenetration_exponent 0.25
index f87b86c8d99c4d4680e3497f194e90a28b219e8b..8901438e85a28e983c05eab5ffdff2b703871bc3 100644 (file)
@@ -10,7 +10,7 @@ electro_plasma_hull
 {
         {
        map textures/electro_plasma_hull.tga
-       alphaFunc GT0
+       alphaFunc GE128
        rgbGen Vertex
         }
 }
@@ -22,4 +22,4 @@ electro
                map textures/electronew.tga
                rgbgen lightingDiffuse
        }
-}
\ No newline at end of file
+}
index da045a45c8524dbea21d069b402ad6b46ea20b37..e0e1a852c0e230e2c4e94df1393dd287003ad28e 100644 (file)
Binary files a/sound/weapons/hagar_fire.ogg and b/sound/weapons/hagar_fire.ogg differ
index f0d6b5fbffdd4aea4cbe8986a802b42162f9f5f7..7d6ad35f7bd3da4ede1394e723986a2850235dac 100644 (file)
Binary files a/sound/weapons/rocket_fire.ogg and b/sound/weapons/rocket_fire.ogg differ
diff --git a/testing.cfg b/testing.cfg
new file mode 100644 (file)
index 0000000..f000a08
--- /dev/null
@@ -0,0 +1,15 @@
+// https://forums.xonotic.org/showthread.php?tid=8190
+// https://gitlab.com/xonotic/xonotic-data.pk3dir/merge_requests/738
+alias test_blaster_switch "settemp g_balance_blaster_primary_animtime 0.1 ; settemp g_balance_blaster_switchdelay_drop 0.1 ; settemp g_balance_blaster_switchdelay_raise 0.1"
+
+alias test_crylink_sec_horizontal "settemp g_balance_crylink_secondary_linkexplode 0 ; settemp g_balance_crylink_secondary_other_fadetime 2 ; settemp g_balance_crylink_secondary_other_lifetime 2 ; settemp g_balance_crylink_secondary_speed 4000 ; settemp g_balance_crylink_secondary_spread 0.08 ; settemp g_balance_crylink_secondary_spreadtype 0"
+
+alias test_rocket_flying "settemp g_balance_devastator_remote_jump 1"
+
+// https://forums.xonotic.org/showthread.php?tid=8192
+// https://gitlab.com/xonotic/xonotic-data.pk3dir/merge_requests/736
+alias test_ctf_stalemate90 "settemp g_ctf_stalemate_time 90"
+alias test_ctf_stalemate120 "settemp g_ctf_stalemate_time 120"
+
+alias testing_enable "addvote test_blaster_switch ; addvote test_crylink_sec_horizontal ; addvote test_rocket_flying ; addvote test_ctf_stalemate90 ; addvote test_ctf_stalemate120"
+alias testing_disable "delvote test_blaster_switch ; delvote test_crylink_sec_horizontal ; delvote test_rocket_flying ; delvote test_ctf_stalemate90 ; delvote test_ctf_stalemate120"
index d3a2c0bc5658e578f14f4236f97530ddfd5f18cb..7aa6e888f9f0fb4007421595b3fc96ea1b7d7b76 100644 (file)
@@ -226,7 +226,7 @@ set g_vehicle_raptor_bouncepain "1 4 1000"
 set g_vehicle_raptor_cannon_cost 1
 set g_vehicle_raptor_cannon_damage 10
 set g_vehicle_raptor_cannon_radius 60
-set g_vehicle_raptor_cannon_refire 0.03
+set g_vehicle_raptor_cannon_refire 0.033333
 set g_vehicle_raptor_cannon_speed 24000
 set g_vehicle_raptor_cannon_spread 0.01
 set g_vehicle_raptor_cannon_force 25
index a6494cc088a0551d2856b8cfc8c4c3539cc49657..389da6f74cb35b5340e0644530f2ce2291da9bcd 100644 (file)
@@ -67,8 +67,8 @@ seta cl_spawn_event_particles 1 "pointparticles effect whenever a player spawns"
 seta cl_spawn_event_sound 1 "sound effect whenever a player spawns"
 //seta cl_spawn_point_model 0 "place a model at all spawn points" // still needs a model
 seta cl_spawn_point_particles 1 "pointparticles effect at all spawn points" // managed by effects-.cfg files
-seta cl_spawn_point_dist_min 1200
-seta cl_spawn_point_dist_max 1600
+seta cl_spawn_point_dist_min 800
+seta cl_spawn_point_dist_max 1200
 
 freelook 1
 sensitivity 6
@@ -200,9 +200,9 @@ seta cl_hitsound_min_pitch 0.75 "minimum pitch of hit sound"
 seta cl_hitsound_max_pitch 1.5 "maximum pitch of hit sound"
 seta cl_hitsound_nom_damage 25 "damage amount at which hitsound bases pitch off"
 
-seta cl_eventchase_spectated_change 1 "camera goes into 3rd person mode for a moment when changing spectated player"
+seta cl_eventchase_spectated_change 0 "camera goes into 3rd person mode for a moment when changing spectated player"
 seta cl_eventchase_spectated_change_time 1 "how much time the effect lasts when changing spectated player"
-seta cl_eventchase_death 1 "camera goes into 3rd person mode when the player is dead; set to 2 to active the effect only when the corpse doesn't move anymore"
+seta cl_eventchase_death 2 "camera goes into 3rd person mode when the player is dead; set to 2 to active the effect only when the corpse doesn't move anymore"
 seta cl_eventchase_frozen 0 "camera goes into 3rd person mode when the player is frozen"
 seta cl_eventchase_nexball 1 "camera goes into 3rd person mode when in nexball game-mode"
 seta cl_eventchase_distance 140 "final camera distance"
@@ -228,7 +228,8 @@ seta cl_damageeffect_lifetime 0.1 "how much a damage effect lasts, based on dama
 seta cl_damageeffect_lifetime_min 3 "minimum lifetime a damage effect may have"
 seta cl_damageeffect_lifetime_max 6 "maximum lifetime a damage effect may have"
 
-set cl_deathglow 0.8 "number of seconds during which dead bodies glow out"
+set cl_deathglow 2 "number of seconds during which dead bodies glow out"
+set cl_deathglow_min 0.5 "glow out up to this glow factor"
 
 cl_movement 1
 cl_movement_track_canjump 0
@@ -735,7 +736,7 @@ seta cl_forcemyplayercolors 0 "set to the color value (encoding is same as _cl_c
 seta cl_movement_errorcompensation 1 "try to compensate for prediction errors and reduce perceived lag"
 seta cl_movement_intermissionrunning 0 "keep velocity after the match ends, players may appear to continue running while stationary"
 
-seta cl_viewmodel_alpha 0 "Maximum transparency of the view model, set to 0 to disable"
+seta cl_viewmodel_alpha 1 "Maximum opacity of the view model, use a value between 0 and 1"
 
 set debugdraw 0
 set debugdraw_filter ""
@@ -745,6 +746,9 @@ set debugtrace 0
 // FIXME remove this when the engine feature FINALLY MAYBE works
 r_glsl_skeletal 0
 
+// FIXME engine description mentions the default should be 1, but sets it to 2 anyway, breaks some maps
+r_useportalculling 1
+
 // animation tuning
 set cl_lerpanim_maxdelta_framegroups 0.05 // must be faster than fastest weapon refire
 set cl_lerpanim_maxdelta_server 0.1 // must be slower than slowest server controlled anim (e.g. animinfo stuff)
@@ -796,9 +800,9 @@ r_shadow_glossintensity 1
 r_fullbright_directed 1
 
 r_water_hideplayer 1 // hide your own feet/player model in refraction views, this way you don't see half of your body under water
-r_water_refractdistort 0.019
+r_water_refractdistort 0.003
 
-set cl_rainsnow_maxdrawdist 2048
+set cl_rainsnow_maxdrawdist 1000
 
 // safe font defaults
 r_font_hinting 1
@@ -854,7 +858,6 @@ seta cl_ghost_items 0.45 "enable ghosted items (when between 0 and 1, overrides
 seta cl_ghost_items_color "-1 -1 -1" "color of ghosted items (colormod format: 0 0 0 leaves the color unchanged, negative values allowed)"
 seta cl_simple_items 0 "enable simple items (if server allows)"
 set cl_simpleitems_postfix "_luma" "posfix to add fo model name when simple items are enabled"
-set cl_fullbright_items 0 "enable fullbright items (if server allows, controlled by g_fullbrightitems) - items are more visible in shadows"
 set cl_weapon_stay_color "2 0.5 0.5" "Color of picked up weapons when g_weapon_stay > 0 (colormod format: 0 0 0 leaves the color unchanged, negative values allowed)"
 set cl_weapon_stay_alpha 0.75 "Alpha of picked up weapons when g_weapon_stay > 0"
 
index f44d9c96f969fa5853216a289a2d8c7e0bdeffb9..7a2c4611ad2ce287500b5cf3aa91827621f7c4ca 100644 (file)
@@ -48,7 +48,7 @@ fs_empty_files_in_pack_mark_deletions 1 // makes patches able to delete files
 set g_campaign 0
 set g_campaign_forceteam 0 "Forces the player to a given team in campaign mode, 1 = red, 2 = blue, 3 = yellow, 4 = pink"
 seta g_campaign_name "xonoticbeta"
-seta g_campaign_skill -1 // -2 easy -1 medium 0 hard
+seta g_campaign_skill 0 // -2 easy, 0 medium, 2 hard
 
 alias singleplayer_start "g_campaign_index 0; set scmenu_campaign_goto 0"
 alias singleplayer_continue "set scmenu_campaign_goto -1"
@@ -144,6 +144,9 @@ seta snd_channel9volume 1 "QuakeC controlled ambient sound volume"
 snd_identicalsoundrandomization_time -0.1
 snd_identicalsoundrandomization_tics    1
 
+set debug_deglobalization_logging 0 "bitfield: 1 logs usage of the old functions which use globals implicitly, 2 logs usage of the new wrappers; support for this can be disabled at compile time for better performance"
+set debug_deglobalization_clear 0 "make the new wrappers set globals to NaN after use, this helps find bugs but can result in crashes; support for this can be disabled at compile time for better performance"
+
 // load console command aliases and settings
 exec commands.cfg
 
index e66f051cd848ab7ae05a5544adc6c3f90e9b9cea..d4a97d7da54f872b631665fe9c0fad750faf00c2 100644 (file)
@@ -19,6 +19,8 @@ set sv_ready_restart 0 "allow a map to be restarted once all players pressed the
 set sv_ready_restart_after_countdown 0 "reset players and map items after the countdown ended, instead of at the beginning of the countdown"
 set sv_ready_restart_repeatable 0 "allows the players to restart the game as often as needed"
 
+alias sv_hook_readyrestart
+
 //nifreks lockonrestart feature, used in team-based game modes, if set to 1 and all players readied up no other player can then join the game anymore, useful to block spectators from joining
 set teamplay_lockonrestart 0 "lock teams once all players readied up and the game restarted (no new players can join after restart unless using the server-command unlockteams)"
 
@@ -124,7 +126,8 @@ set bot_typefrag 0 "Allow bots to shoot players while they're typing"
 set bot_ai_thinkinterval 0.05 "Frame rate at which bots update their navigation and aiming, scales by skill"
 set bot_ai_strategyinterval 7 "How often a new objective is chosen"
 set bot_ai_strategyinterval_movingtarget 5.5 "How often a new objective is chosen when current objective can move"
-set bot_ai_enemydetectioninterval 2 "How often bots pick a new target"
+set bot_ai_enemydetectioninterval 2 "How often bots try to pick a new target if no suitable target is found"
+set bot_ai_enemydetectioninterval_stickingtoenemy 4 "How often bots try to pick a new target while targetting an enemy"
 set bot_ai_enemydetectionradius 10000 "How far bots can see enemies"
 set bot_ai_dodgeupdateinterval 0.2 "How often scan for items to dodge. Currently not in use."
 set bot_ai_chooseweaponinterval 0.5 "How often the best weapon according to the situation will be chosen"
@@ -150,9 +153,11 @@ set bot_ai_weapon_combo_threshold 0.4 "Try to make a combo N seconds after the l
 set bot_ai_friends_aware_pickup_radius "500" "Bots will not pickup items if a team mate is this distance near the item"
 set bot_ai_ignoregoal_timeout 3 "Ignore goals making bots to get stuck in front of a wall for N seconds"
 set bot_ai_bunnyhop_skilloffset 7 "Bots with skill equal or greater than this value will perform the \"bunnyhop\" technique"
-set bot_ai_bunnyhop_startdistance 200 "Run to goals located further than this distance"
-set bot_ai_bunnyhop_stopdistance 300 "Stop jumping after reaching this distance to the goal"
-set bot_ai_bunnyhop_firstjumpdelay 0.2 "Start running to the goal only if it was seen for more than N seconds"
+set bot_ai_bunnyhop_dir_deviation_max 20 "bunnyhop if speed - direction deviation is <= this amount"
+set bot_ai_bunnyhop_downward_pitch_max 30 "bunnyhop if downard pitch towards the next waypoint is <= this amount"
+set bot_ai_bunnyhop_turn_angle_max 80 "bunnyhop if next turn angle is <= this amount at walk speed (sv_maxspeed)"
+set bot_ai_bunnyhop_turn_angle_min 4 "bunnyhop regardless of speed if next turn angle is <= this amount"
+set bot_ai_bunnyhop_turn_angle_reduction 40 "linearly reduce max turn angle by this amount when speed increases by sv_maxspeed"
 set bot_god 0 "god mode for bots"
 set bot_ai_navigation_jetpack 0 "Enable bots to navigate maps using the jetpack"
 set bot_ai_navigation_jetpack_mindistance 3500 "Bots will try fly to objects located farther than this distance"
@@ -189,7 +194,6 @@ set g_antilag_nudge 0 "don't touch"
 set g_shootfromeye 0 "shots are fired from your eye/crosshair; visual gun position can still be influenced by cl_gunalign 1 and 2"
 set g_shootfromcenter 0 "weapon gets moved to the center, shots still come from the barrel of your weapon; visual gun position can still be influenced by cl_gunalign 1 and 2"
 set g_shootfromfixedorigin "" "if set to a string like 0 y z, the gun is moved to the given y and z coordinates. If set to a string like x y z, the whole shot origin is used"
-set g_pinata 0 "if set to 1 you will not only drop your current weapon when you are killed, but you will drop all weapons that you possessed"
 set g_weapon_stay 0 "1: ghost weapons can be picked up but give no ammo, thrown guns have ammo 2: ghost weapons can be picked up and refill ammo to one pickup size, thrown guns have no ammo (to prevent infinite ammo abuse)"
 set g_weapon_throwable 1 "if set to 1, weapons can be dropped"
 set g_powerups -1 "if set to 0 the strength and shield (invincibility) will not spawn on the map, if 1 they will spawn in all game modes, -1 is game mode default"
@@ -204,7 +208,7 @@ set g_weaponarena_random_with_blaster "1" "additionally, always provide the blas
 set g_spawnpoints_auto_move_out_of_solid 0 "if set to 1 you will see a warning if a spawn point was placed inside a solid"
 set g_forced_respawn 0 "if set to 1 and a player died, that player gets automatically respawned once <g_respawn_delay> seconds are over"
 set g_fullbrightplayers 0 "brightens up player models (note that the color, skin or model of the players does not change!)"
-set g_fullbrightitems 0 "allows players to use cl_fullbright_items"
+set g_fullbrightitems 0 "disables lighting effects on items, making them appear bright for visibility"
 set g_nodepthtestplayers 0 "disables depth testing on players"
 set g_nodepthtestitems 0 "disables depth testing on items"
 set g_casings 2 "specifies which casings (0: none, 1: only shotgun casings, 2: shotgun and machine gun casings) are sent to the client"
@@ -216,6 +220,7 @@ set g_maplist_selectrandom 0 "if 1, a random map will be chosen as next map - DE
 set g_maplist_shuffle 1 "new randomization method: like selectrandom, but avoid playing the same maps in short succession. This works by taking out the first element and inserting it into g_maplist with a bias to the end of the list"
 set g_maplist_check_waypoints 0 "when 1, maps are skipped if there currently are bots, but the map has no waypoints"
 set g_maplist_ignore_sizes 0 "when 1, all maps are shown in the map list regardless of player count"
+set g_maplist_sizes_count_maxplayers 1 "check the player limit when getting the player count so forced spectators don't affect the size restrictions"
 set g_maplist_sizes_count_bots 1 "include the number of bots currently in the server when counting the number of players for size restrictions"
 
 set g_items_mindist 4000 "starting distance for the fading of items"
@@ -312,6 +317,7 @@ set sv_eventlog_files_timestamps 1 "include timestamps in the log file names"
 set sv_eventlog_files_counter 0 "internal counter cvar, do not modify"
 set sv_eventlog_files_nameprefix xonotic "prefix of individual log file names"
 set sv_eventlog_files_namesuffix .log "suffix of individual log file names"
+set sv_eventlog_ipv6_delimiter 0 "use a _ delimiter for IPV6 IPs, so that they can be easily detected in scripts"
 
 set nextmap "" "override the maplist when switching to the next map"
 set lastlevel "" "for singleplayer use, shows the menu once the match has ended"
@@ -343,7 +349,7 @@ set g_maplist_votable_timeout 30 "timeout for the map voting; must be below 50 s
 set g_maplist_votable_suggestions 2 "number of maps a player is allowed to suggest for the map voting screen using 'suggestmap'"
 set g_maplist_votable_suggestions_override_mostrecent 0 "allow players to suggest maps that have been played recently"
 set g_maplist_votable_nodetail 0 "hide per-map vote counts (to avoid influential first votes)"
-set g_maplist_votable_abstain 0 "offer a "\don't care\" option on the voting screen"
+set g_maplist_votable_abstain 0 "offer a \"don't care\" option on the voting screen"
 set g_maplist_votable_screenshot_dir "maps levelshots" "where to look for map screenshots"
 
 set sv_vote_gametype 0 "show a vote screen for gametypes before map vote screen"
@@ -391,6 +397,8 @@ sv_gameplayfix_delayprojectiles 0
 sv_gameplayfix_q2airaccelerate 1
 sv_gameplayfix_stepmultipletimes 1
 sv_gameplayfix_stepdown 2
+// only available in qc physics
+set sv_gameplayfix_stepdown_maxspeed 0 "maximum speed walking entities can be moving for stepping down to apply - requires sv_qcphysics 1"
 
 // delay for "kill" to prevent abuse
 set g_balance_kill_delay 2 "timer before death when using the kill command"
@@ -428,7 +436,7 @@ set g_ballistics_mindistance 2 "when shooting through walls thinner than this, t
 set g_ballistics_density_player 0.50 "how hard players are to shoot through compared to walls"
 set g_ballistics_density_corpse 0.10 "how hard corpses are to shoot through compared to walls"
 set g_ballistics_penetrate_clips 1 "allow ballistics to pass through weapon clips"
-set g_ballistics_solidpenetration_exponent 0.25 "how fast damage falls off when bullets pass through walls - 1 means linear, lower values mean slower initial falloff but faster once there's little solidpenetration left (damage_fraction = solidpen_fraction^exp for solidpen_fraction between 0 and 1)"
+set g_ballistics_solidpenetration_exponent 1 "how fast damage falls off when bullets pass through walls - 1 means linear, lower values mean slower initial falloff but faster once there's little solidpenetration left (damage_fraction = solidpen_fraction^exp for solidpen_fraction between 0 and 1)"
 
 sv_status_show_qcstatus 1 "Xonotic uses this field instead of frags"
 set g_full_getstatus_responses 0 "this currently breaks qstat"
@@ -485,7 +493,7 @@ sv_gameplayfix_gravityunaffectedbyticrate 1
 sv_gameplayfix_nogravityonground 1
 
 set sv_q3acompat_machineshotgunswap 0 "shorthand for swapping machinegun and shotgun (for Q3A map compatibility in mapinfo files)"
-set sv_vq3compat 0 "toggle for some compatibility hacks (for VQ3 and CPM map compatibility in mapinfo files)"
+set sv_q3defragcompat 0 "toggle for some compatibility hacks (for Q3DF map compatibility)"
 
 set g_movement_highspeed 1 "multiplier scale for movement speed (applies to sv_maxspeed and sv_maxairspeed, also applies to air acceleration when g_movement_highspeed_q3_compat is set to 0)"
 set g_movement_highspeed_q3_compat 0 "apply speed modifiers to air movement in a more Q3-compatible way (only apply speed buffs and g_movement_highspeed to max air speed, not to acceleration)"
@@ -526,7 +534,7 @@ alias g_forced_team_matchsetup "map $1; settemp g_forced_team_red \"$2\"; settem
 // frozen
 set g_frozen_revive_falldamage 0 "Enable reviving from this amount of fall damage"
 set g_frozen_revive_falldamage_health 40 "Amount of health player has if they revived from falling"
-set g_frozen_damage_trigger 1 "if 1, frozen players falling into the void will die instead of teleporting to spawn"
+set g_frozen_damage_trigger 1 "if 1, frozen players falling into the void/lava/slime will die instead of teleporting to spawn"
 set g_frozen_force 0.6 "How much to multiply the force on a frozen player with"
 
 // player statistics
@@ -546,7 +554,8 @@ set g_mod_balance "" "Current balance config name"
 set g_mod_config  "" "Current config mod name"
 
 // other config files
-exec balance-xonotic.cfg
+exec testing.cfg
+exec balance-xonotic.cfg // depends on testing.cfg
 exec physicsX.cfg
 exec turrets.cfg
 exec vehicles.cfg
@@ -567,4 +576,6 @@ set sv_showspectators 1 "Show who's spectating who in the player info panel when
 set sv_damagetext 2 "<= 0: disabled, >= 1: visible to spectators, >= 2: visible to attacker, >= 3: all players see everyone's damage"
 
 set sv_showfps 5 "Show player's FPS counters in the scoreboard. This setting acts as a delay in seconds between updates"
-set autocvar_sv_doors_always_open 0 "If set to 1 don't close doors which after they were open"
+set sv_doors_always_open 0 "If set to 1 don't close doors which after they were open"
+
+set sv_warpzone_allow_selftarget 0 "do not touch"