Merge branch 'martin-t/keybinder' into 'master'
authorterencehill <piuntn@gmail.com>
Wed, 15 Apr 2020 13:33:26 +0000 (13:33 +0000)
committerterencehill <piuntn@gmail.com>
Wed, 15 Apr 2020 13:33:26 +0000 (13:33 +0000)
Keybinder cleanup

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

107 files changed:
.gitlab-ci.yml
.tx/merge-base
_hud_descriptions.cfg
bal-wep-overkill-nerfed.cfg [deleted file]
bal-wep-testing.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
check-cvars.sh
commands.cfg
common.ast.po
common.he.po
common.pl.po
effectinfo.txt
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
qcsrc/client/autocvars.qh
qcsrc/client/hud/hud_config.qc
qcsrc/client/hud/panel/healtharmor.qc
qcsrc/client/hud/panel/pressedkeys.qc
qcsrc/client/hud/panel/scoreboard.qc
qcsrc/client/main.qc
qcsrc/client/miscfunctions.qc
qcsrc/client/miscfunctions.qh
qcsrc/client/view.qc
qcsrc/common/debug.qh
qcsrc/common/effects/effectinfo.inc
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/keyhunt/sv_keyhunt.qc
qcsrc/common/mutators/mutator/buffs/sv_buffs.qc
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/itemstime/itemstime.qc
qcsrc/common/mutators/mutator/multijump/multijump.qc
qcsrc/common/mutators/mutator/overkill/okhmg.qc
qcsrc/common/mutators/mutator/overkill/okmachinegun.qc
qcsrc/common/mutators/mutator/pinata/sv_pinata.qc
qcsrc/common/mutators/mutator/superspec/sv_superspec.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/walk.qc
qcsrc/common/physics/player.qc
qcsrc/common/state.qc
qcsrc/common/stats.qh
qcsrc/common/t_items.qc
qcsrc/common/vehicles/vehicle/racer.qc
qcsrc/common/weapons/all.qc
qcsrc/common/weapons/weapon/vaporizer.qc
qcsrc/ecs/systems/physics.qc
qcsrc/lib/csqcmodel/cl_player.qc
qcsrc/lib/csqcmodel/cl_player.qh
qcsrc/lib/i18n.qh
qcsrc/lib/string.qh
qcsrc/lib/vector.qh
qcsrc/lib/warpzone/mathlib.qc
qcsrc/menu/xonotic/campaign.qc
qcsrc/menu/xonotic/dialog_settings_game_view.qc
qcsrc/menu/xonotic/dialog_settings_video.qc
qcsrc/menu/xonotic/serverlist.qc
qcsrc/menu/xonotic/serverlist.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/navigation.qc
qcsrc/server/bot/default/navigation.qh
qcsrc/server/bot/default/waypoints.qc
qcsrc/server/bot/default/waypoints.qh
qcsrc/server/campaign.qc
qcsrc/server/campaign.qh
qcsrc/server/client.qc
qcsrc/server/client.qh
qcsrc/server/command/sv_cmd.qc
qcsrc/server/command/vote.qc
qcsrc/server/defs.qh
qcsrc/server/g_world.qc
qcsrc/server/ipban.qc
qcsrc/server/mapvoting.qc
qcsrc/server/pathlib/main.qc
qcsrc/server/sv_main.qc
qcsrc/server/weapons/weaponsystem.qc
testing.cfg [new file with mode: 0644]
xonotic-client.cfg
xonotic-server.cfg

index 15ea0ec..4906ab6 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=6535600492e1cb63af8e449570bffe4a
+    - EXPECT=a98e5e5ee0cc3d2e80ee0ad812786703
     - HASH=$(${ENGINE} -noconfig -nohome +exec serverbench.cfg
       | tee /dev/stderr
       | grep '^:'
index d89ad5c..15b91cc 100644 (file)
@@ -1 +1 @@
-Sat Feb  8 07:24:17 CET 2020
+Wed Apr  8 07:24:18 CEST 2020
index 30e5a8b..9bb1b84 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"
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
-// }}}
diff --git a/bal-wep-testing.cfg b/bal-wep-testing.cfg
deleted file mode 100644 (file)
index abee0b6..0000000
+++ /dev/null
@@ -1,974 +0,0 @@
-// {{{ #1: Blaster
-set g_balance_blaster_primary_animtime 0.1
-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.1
-set g_balance_blaster_switchdelay_raise 0.1
-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_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
-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 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 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
-// }}}
index de22d1f..ea4c4db 100644 (file)
@@ -1,4 +1,5 @@
 g_mod_balance Mario
+testing_disable
 
 // {{{ starting gear
 set g_balance_health_start 100
index 81c786e..b3d856c 100644 (file)
@@ -1,4 +1,5 @@
 g_mod_balance Nexuiz25
+testing_disable
 
 // {{{ starting gear
 set g_balance_health_start 150
index 28f8f17..7aea6f8 100644 (file)
@@ -1,4 +1,5 @@
 g_mod_balance Overkill
+testing_disable
 
 // {{{ starting gear
 set g_balance_health_start 100
index f98731e..c177f30 100644 (file)
@@ -1,4 +1,5 @@
 g_mod_balance Samual
+testing_disable
 
 // {{{ starting gear
 set g_balance_health_start 100
index 9602116..9baac18 100644 (file)
@@ -1,244 +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_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
-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 4ee3f36..93cdc11 100644 (file)
@@ -1,244 +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_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
-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
+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 e866bd1..5ba025a 100644 (file)
@@ -1,4 +1,5 @@
 g_mod_balance XDF
+testing_disable
 
 // {{{ starting gear
 set g_balance_health_start 100
index 2666108..8c36402 100644 (file)
@@ -1,4 +1,5 @@
 g_mod_balance Xonotic
+testing_disable
 
 // {{{ starting gear
 set g_balance_health_start 100
index bcd5848..46e04a9 100644 (file)
@@ -1,4 +1,5 @@
 g_mod_balance XPM
+testing_disable
 
 // {{{ starting gear
 set g_balance_health_start 100
index 43683fe..387d937 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 5a5667c..1375a78 100644 (file)
@@ -88,7 +88,9 @@ 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 68a14f4..2e397ca 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 ee357ff..6cbefcf 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 5b07262..f7f4fd9 100644 (file)
 # Jakub P. <pedziszewski@gmail.com>, 2015
 # Jakub P. <pedziszewski@gmail.com>, 2015
 # John Smith <myrangd@gmail.com>, 2016
-# karol kosek <krkkx@protonmail.com>, 2020
-# karol kosek <krkkx@protonmail.com>, 2020
+# 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
@@ -22,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: 2020-02-08 00:07+0000\n"
-"Last-Translator: karol kosek <krkkx@protonmail.com>\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"
@@ -63,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."
@@ -2614,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
@@ -4266,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
@@ -4276,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 ""
@@ -6361,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:"
@@ -8855,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"
index 129dba3..f7ee697 100644 (file)
@@ -3418,6 +3418,30 @@ effect TE_TEI_G3PINK_HIT
        sizeincrease -6
        size 10 10
        trailspacing 40
+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
 effect particlegibs_damage_hit
        type blood
        airfriction 3
index 501f07f..b1631b2 100644 (file)
@@ -76,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)"
index 813ecba..84e7340 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"
index c5cfe4a..2b0d14a 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"
index b728258..be4a87a 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"
index 3bfd694..db0fc51 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"
index c808f62..4baea48 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"
index b0b02d0..7266205 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"
index 389aa27..27c977d 100644 (file)
@@ -9,7 +9,7 @@ ga    "Irish" "Irish" 32%
 it    "Italian" "Italiano" 100%
 hu    "Hungarian" "Magyar" 48%
 nl    "Dutch" "Nederlands" 63%
-pl    "Polish" "Polski" 73%
+pl    "Polish" "Polski" 74%
 pt    "Portuguese" "Português" 86%
 pt_BR "Portuguese (Brazil)" "Português (Brasil)" 100%
 ro    "Romanian" "Romana" 75%
index b6ad346..2d52893 100644 (file)
@@ -9,6 +9,7 @@
 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"
 
 
 // ===========
@@ -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"
 
 
 // ==========
@@ -443,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
@@ -522,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 80b26a9..41f0706 100644 (file)
@@ -351,11 +351,12 @@ seta notification_INFO_WEAPON_TUBA_SUICIDE "1" "0 = off, 1 = print to console, 2
 seta notification_INFO_WEAPON_VAPORIZER_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
 seta notification_INFO_WEAPON_VORTEX_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
 
-// MSG_CENTER notifications (count = 239):
+// MSG_CENTER notifications (count = 240):
 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"
@@ -753,4 +754,4 @@ seta notification_show_sprees_info "3" "Show spree information in MSG_INFO messa
 seta notification_show_sprees_info_newline "1" "Show attacker spree information for MSG_INFO messages on a separate line than the death notification itself"
 seta notification_show_sprees_info_specialonly "1" "Don't show attacker spree information in MSG_INFO messages if it isn't an achievement"
 
-// Notification counts (total = 846): MSG_ANNCE = 89, MSG_INFO = 334, MSG_CENTER = 239, MSG_MULTI = 156, MSG_CHOICE = 28
+// Notification counts (total = 847): MSG_ANNCE = 89, MSG_INFO = 334, MSG_CENTER = 240, MSG_MULTI = 156, MSG_CHOICE = 28
index f87b94e..234f9b0 100644 (file)
@@ -363,6 +363,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;
@@ -415,7 +416,7 @@ float autocvar_cl_hitsound_nom_damage = 25;
 float autocvar_cl_hitsound_antispam_time;
 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;
index a6c22c7..27a33c4 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");
index 1e124dd..1a61a96 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 0bf9b8d..3c87a1c 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 a6d1cc9..08a1a73 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))
@@ -1635,7 +1635,14 @@ void Scoreboard_Draw()
                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),
index b7b7e53..72ee803 100644 (file)
@@ -136,7 +136,7 @@ void CSQC_Init()
 
        registercvar("cl_shootfromfixedorigin", "");
 
-       registercvar("cl_multijump", "1");
+       registercvar("cl_multijump", "-1");
 
        registercvar("cl_spawn_near_teammate", "1");
 
index bb0bfe1..d801cea 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';
index d259efe..3397ab7 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 eb341d5..57cd15a 100644 (file)
@@ -1420,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) \
index c95bb2d..e5012f8 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,8 +192,8 @@ bool autocvar_debugdraw;
                        }
                }
        }
-#endif
-#endif
+#endif // SVQC
+#endif // ENABLE_DEBUGDRAW
 
 
 GENERIC_COMMAND(bufstr_get, "Examine a string buffer object", false)
@@ -225,7 +224,7 @@ GENERIC_COMMAND(version, "Print the current version", false)
        {
                case CMD_REQUEST_COMMAND:
                {
-                       LOG_INFO(WATERMARK);
+                       LOG_INFO(PROGNAME, " version: ", WATERMARK);
                        return;
                }
                default:
@@ -241,6 +240,7 @@ GENERIC_COMMAND(version, "Print the current version", false)
 #ifdef CSQC
 void(float bufhandle, string pattern, string antipattern) buf_cvarlist = #517;
 #endif
+
 GENERIC_COMMAND(cvar_localchanges, "Print locally changed cvars", false)
 {
        switch (request)
@@ -275,6 +275,7 @@ GENERIC_COMMAND(cvar_localchanges, "Print locally changed cvars", false)
 
 #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,7 +330,8 @@ STATIC_INIT(TRACE_ENT)
        e.draw2d = Trace_draw2d;
        IL_PUSH(g_drawables_2d, e);
 }
-#endif
+#endif // CSQC
+
 #endif
 
 
@@ -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 d45bdf3..7c2dde1 100644 (file)
@@ -5154,6 +5154,49 @@ TE_TEI_G3(YELLOW, "0xffff00", "0xffff11", "0x202000", "0x404000")
 TE_TEI_G3(PINK, "0xFF00FF", "0xFF11FF", "0x200020", "0x400040")
 #undef TE_TEI_G3
 
+// 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";
+}
+
 #include "effectinfo_gentle_particlegibs.inc"
 
 #include "effectinfo_onslaught.inc"
index c82e0bc..cbbe9af 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 11bbaea..cfe8d40 100644 (file)
@@ -438,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, "");
index 8906069..eaa60f8 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)
        {
@@ -620,6 +620,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;
@@ -628,6 +634,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 3eb7530..b77318c 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 b2d0874..660a551 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 1240ee4..5d52ed7 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
index f1a1491..83b471c 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);
index 40f19d6..38a687f 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 97e6316..f53d8c3 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 84f7731..696a2d9 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 66d18ac..3651e9a 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 8d2bb31..5add006 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 0efd856..40bc9a3 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 a0a8962..68d69ab 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))
index 17e71f0..817e369 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))
index 779e562..fa80451 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 eb20082..5fe52b2 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 || it.invincible_finished > 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;
@@ -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 036a8b5..ca63d9f 100644 (file)
     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"), "")
index 7c34129..192c224 100644 (file)
@@ -62,6 +62,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)
@@ -423,6 +424,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)) : ""))*/ \
index 68d4c36..63aa3dd 100644 (file)
@@ -413,6 +413,30 @@ 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
 {
@@ -421,13 +445,12 @@ bool _Movetype_TestEntityPosition(vector ofs)  // SV_TestEntityPosition
 
        //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);
+       tracebox(org, this.mins, this.maxs, this.origin, ((this.move_movetype == MOVETYPE_FLY_WORLDONLY) ? MOVE_WORLDONLY : MOVE_NOMONSTERS), this);
        //this.dphitcontentsmask = cont;
-
-       if(trace_startsolid)
+       if(trace_dpstartcontents & _Movetype_ContentsMask(this))
                return true;
 
-       if(vdist(trace_endpos - this.origin, >, 0.0001))
+       if(vlen2(trace_endpos - this.origin) >= 0.0001)
        {
                tracebox(trace_endpos, this.mins, this.maxs, trace_endpos, MOVE_NOMONSTERS, this);
                if(!trace_startsolid)
@@ -436,6 +459,23 @@ bool _Movetype_TestEntityPosition(vector ofs)  // SV_TestEntityPosition
        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;
@@ -450,13 +490,7 @@ int _Movetype_UnstickEntity(entity this)  // SV_UnstickEntity
        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(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));
index 0c8bc69..52610c5 100644 (file)
@@ -16,6 +16,7 @@ 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)
index 13224f8..e0d05d7 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 16cb27a..5dce802 100644 (file)
@@ -359,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))
@@ -693,11 +693,7 @@ void PM_check_slick(entity this)
        trace_dphitq3surfaceflags = 0;
        tracebox(this.origin, this.mins, this.maxs, this.origin - '0 0 1', MOVE_NOMONSTERS, this);
        if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK)
-       {
-               if(PHYS_SLICK_APPLYGRAVITY(this))
-                       UNSET_ONGROUND(this);
                SET_ONSLICK(this);
-       }
        else
                UNSET_ONSLICK(this);
 }
index 0f40acf..14b22e9 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 7d2aae5..c77ca16 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,6 +191,7 @@ 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;
@@ -201,6 +203,7 @@ int autocvar_sv_gameplayfix_noairborncorpse_allowsuspendeditems = 1;
 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)
@@ -240,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
@@ -259,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)
index df3bb9b..d9bd7bd 100644 (file)
@@ -735,7 +735,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)
@@ -1474,10 +1478,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
        {
@@ -1545,27 +1550,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)
@@ -1663,17 +1670,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)
index 21069a9..b3cac72 100644 (file)
@@ -163,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))
index b8d2428..a8d1376 100644 (file)
@@ -577,10 +577,10 @@ NET_HANDLE(wframe, bool isNew)
                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;
-                       default:
                        case WFRAME_RELOAD: a = wepent.anim_reload; break;
                }
                a.z *= t;
index dbf24c7..cfdbe7b 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
index a5af98d..cd59c51 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);
@@ -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) {
index 04a3c2b..25fd5cd 100644 (file)
@@ -596,7 +596,6 @@ void CSQCPlayer_SetCamera()
                {
                        CSQCPlayer_CalcRefdef(view);
                }
-                       
        }
        else
        {
index 297e2e6..92948dc 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 0f609ca..3069f51 100644 (file)
@@ -8,7 +8,7 @@
 string prvm_language;
 
 /**
- * @deprecated prefer _("translated") - GMQCC's -ftranslatable-strings feature
+ * @deprecated prefer _("translatable text") - GMQCC's -ftranslatable-strings feature
  */
 ERASEABLE
 string language_filename(string s)
index c4b594d..a7508b8 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 ca0e84f..6f41995 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 cf86d97..2b1d00c 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 0f64aef..6f1d511 100644 (file)
@@ -239,7 +239,9 @@ void XonoticCampaignList_drawListBoxItem(entity me, int i, vector absSize, bool
                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 ed21eea..b4c1702 100644 (file)
@@ -26,7 +26,7 @@ void XonoticGameViewSettingsTab_fill(entity me)
                me.TD(me, 1, 3, e = makeXonoticRadioButton(1, "chase_active", "0", _("1st person perspective")));
        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);
index 305567b..77f2602 100644 (file)
@@ -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,11 +157,6 @@ 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") > 0)
        {
                me.TR(me);
index 021e976..b301bea 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
@@ -546,6 +533,7 @@ void XonoticServerList_draw(entity me)
        me.infoButton.disabled = (me.lockedSelectedItem || me.nItems == 0 || !owned);
        me.favoriteButton.disabled = (me.lockedSelectedItem || (me.nItems == 0 && 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;
@@ -788,33 +774,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 +823,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 +877,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 +887,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 +915,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 +927,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 +979,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 +1018,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 +1031,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 +1118,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 +1131,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 +1144,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 01b065d..8ad1856 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 cb83896..7b30b62 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);
 
@@ -230,6 +217,8 @@ void bot_setnameandstuff(entity this)
                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";
@@ -288,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));
@@ -302,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)
@@ -323,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;
@@ -330,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));
-       }
+       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," ");
 
-       // Initialize list of weapons
-       bot_weapons_far[0] = -1;
-       bot_weapons_mid[0] = -1;
-       bot_weapons_close[0] = -1;
+               if (tokens!=2)
+                       return;
 
-       // Parse far distance weapon priorities
-       tokens = tokenizebyseparator(W_NumberWeaponOrder(autocvar_bot_ai_custom_weapon_priority_far)," ");
+               bot_distance_far = stof(argv(0));
+               bot_distance_close = stof(argv(1));
 
-       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(bot_distance_far < bot_distance_close){
+                       bot_distance_far = stof(argv(1));
+                       bot_distance_close = stof(argv(0));
                }
        }
-       if(c < Weapons_COUNT)
-               bot_weapons_far[c] = -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(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;
 }
@@ -860,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 98b2ae3..88dba44 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 55bc9c8..269cd68 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 477d1ec..619d08d 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)))
+                       {
+                               // 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;
@@ -611,9 +564,28 @@ void havocbot_movetogoal(entity this)
                        * ((this.strength_finished > time) ? autocvar_g_balance_powerup_strength_selfdamage : 1) \
                        * ((this.invincible_finished > time) ? autocvar_g_balance_powerup_invincible_takedamage : 1)
 
-               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)
+               // 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;
+
+               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,8 +949,7 @@ 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)))
@@ -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 d1a36a1..02c0f3e 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 5457211..1f5377b 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);
@@ -943,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;
                        }
                });
@@ -965,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,
        {
@@ -1507,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)
@@ -1529,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 (;;)
@@ -1710,11 +1717,16 @@ 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)
@@ -1742,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)
                {
@@ -1778,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)
@@ -1790,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 026d326..07eacc1 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 c09d8f8..da407cb 100644 (file)
@@ -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 2535644..e9aa1ee 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 f0fcea6..336d825 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"));
@@ -142,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()
@@ -309,7 +313,6 @@ void CampaignPostIntermission()
 
        CampaignSetup(campaign_won);
        CampaignFile_Unload();
-       strunzone(campaign_message);
        strunzone(campaign_index_var);
        strunzone(campaign_name);
        campaign_name = "";
index df25c6c..0662a37 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 887e00c..271c803 100644 (file)
@@ -337,6 +337,7 @@ void PutObserverInServer(entity this)
        this.strength_finished = 0;
        this.invincible_finished = 0;
        this.superweapons_finished = 0;
+       this.air_finished = 0;
        //this.dphitcontentsmask = 0;
        this.dphitcontentsmask = DPCONTENTS_SOLID;
        if (autocvar_g_playerclip_collisions)
@@ -647,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;
 
@@ -1536,8 +1537,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 +1558,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 +1593,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 +1617,12 @@ void player_regen(entity this)
 
        if (!(this.items & IT_UNLIMITED_AMMO))
        {
-               float minf, maxf, limitf;
+               float maxf = autocvar_g_balance_fuel_rotstable;
+               float minf = autocvar_g_balance_fuel_regenstable;
 
-               maxf = autocvar_g_balance_fuel_rotstable;
-               minf = autocvar_g_balance_fuel_regenstable;
-               limitf = GetResourceLimit(this, RES_FUEL);
-
-               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);
        }
 }
 
@@ -1690,6 +1685,7 @@ void SpectateCopy(entity this, entity spectatee)
        this.strength_finished = spectatee.strength_finished;
        this.invincible_finished = spectatee.invincible_finished;
        this.superweapons_finished = spectatee.superweapons_finished;
+       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 +1777,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();
        }
@@ -2022,7 +2023,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 +2039,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);
+                     &nb