]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge remote-tracking branch 'origin/master' into samual/lightning_gun
authorSamual Lenks <samual@xonotic.org>
Mon, 10 Jun 2013 01:24:23 +0000 (21:24 -0400)
committerSamual Lenks <samual@xonotic.org>
Mon, 10 Jun 2013 01:24:23 +0000 (21:24 -0400)
Conflicts:
balanceLeeStricklin.cfg
balanceXonotic.cfg
qcsrc/client/hook.qc
qcsrc/client/hud.qc
qcsrc/common/constants.qh
qcsrc/server/autocvars.qh

15 files changed:
1  2 
balance25.cfg
balanceFruitieX.cfg
balanceXPM.cfg
balanceXonotic.cfg
qcsrc/client/Defs.qc
qcsrc/client/Main.qc
qcsrc/client/hook.qc
qcsrc/common/constants.qh
qcsrc/server/autocvars.qh
qcsrc/server/cl_client.qc
qcsrc/server/g_world.qc
qcsrc/server/progs.src
qcsrc/server/t_quake3.qc
qcsrc/server/w_all.qc
qcsrc/server/w_electro.qc

diff --combined balance25.cfg
index 85e61f217296add289cfa455bb37c9a63da839aa,343891810adf6b8494361761137676bc31e831d1..f1ef007387f9760dd58111055b586f9b94d17cd6
@@@ -1,9 -1,10 +1,10 @@@
+ g_mod_balance Nexuiz25
  // {{{ starting gear
  set g_start_weapon_laser -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
  set g_start_weapon_shotgun -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
  set g_start_weapon_uzi -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
  set g_start_weapon_grenadelauncher -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
- set g_start_weapon_minelayer -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
  set g_start_weapon_electro -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
  set g_start_weapon_crylink -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
  set g_start_weapon_nex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
@@@ -12,11 -13,8 +13,8 @@@ set g_start_weapon_rocketlauncher -1 "
  set g_start_weapon_minstanex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
  set g_start_weapon_porto -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
  set g_start_weapon_hook -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
- set g_start_weapon_hlac -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
- set g_start_weapon_sniperrifle -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
  set g_start_weapon_tuba -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
  set g_start_weapon_fireball -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
- set g_start_weapon_seeker -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
  set g_balance_health_start 150
  set g_balance_armor_start 0
  set g_start_ammo_shells 40
@@@ -100,12 -98,14 +98,14 @@@ set g_pickup_respawntime_medium 2
  set g_pickup_respawntime_long 30
  set g_pickup_respawntime_powerup 120
  set g_pickup_respawntime_weapon 15
+ set g_pickup_respawntime_superweapon 120
  set g_pickup_respawntime_ammo 15
  set g_pickup_respawntimejitter_short 0
  set g_pickup_respawntimejitter_medium 0
  set g_pickup_respawntimejitter_long 0
  set g_pickup_respawntimejitter_powerup 10
  set g_pickup_respawntimejitter_weapon 0
+ set g_pickup_respawntimejitter_superweapon 10
  set g_pickup_respawntimejitter_ammo 0
  // }}}
  
@@@ -145,7 -145,6 +145,6 @@@ set g_balance_fuel_limit 99
  
  // {{{ misc
  set g_balance_selfdamagepercent 0.6
- set g_balance_weaponswitchdelay 0.15
  set g_weaponspeedfactor 1 "weapon projectile speed multiplier"
  set g_weaponratefactor 1 "weapon fire rate multiplier"
  set g_weapondamagefactor 1 "weapon damage multiplier"
@@@ -155,13 -154,19 +154,19 @@@ set g_balance_firetransfer_time 0.
  set g_balance_firetransfer_damage 0.8
  set g_throughfloor_damage 1
  set g_throughfloor_force 1
+ 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 0
  set g_projectiles_newton_style 2
  // 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)
- // 3: absolute velocity + player velocity component in shot direction (note: does NOT yield the right relative velocity, but may be good enough, but it is somewhat prone to sniper rockets)
- // 4: just add the player velocity length to the absolute velocity (tZork's sniper rockets)
  set g_projectiles_newton_style_2_minfactor 0.7
  set g_projectiles_newton_style_2_maxfactor 5
  set g_projectiles_spread_style 0
@@@ -178,6 -183,14 +183,14 @@@ set g_balance_falldamage_deadminspeed 1
  set g_balance_falldamage_minspeed 1400
  set g_balance_falldamage_factor 0.15
  set g_balance_falldamage_maxdamage 25
+ set g_balance_damagepush_speedfactor 0
+ set g_balance_contents_damagerate 0.2 // ticrate interval for applying damage with playerdamage/projectiledamage
+ set g_balance_contents_drowndelay 10 // time under water before a player begins drowning
+ 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_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
@@@ -188,6 -201,7 +201,7 @@@ set g_balance_powerup_strength_force 
  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
@@@ -208,6 -222,7 +222,7 @@@ set g_balance_grapplehook_length_min 5
  set g_balance_grapplehook_stretch 50
  set g_balance_grapplehook_airfriction 0.2
  set g_balance_grapplehook_health 130
+ set g_balance_grapplehook_damagedbycontents 0
  // }}}
  
  // {{{ weapon properties
@@@ -243,6 -258,10 +258,10 @@@ set g_balance_laser_secondary_gauntlet 
  set g_balance_laser_secondary_force_zscale 1
  set g_balance_laser_secondary_force_velocitybias 0
  set g_balance_laser_secondary_force_other_scale 1
+ set g_balance_laser_switchdelay_drop 0.15
+ set g_balance_laser_switchdelay_raise 0.15
+ set g_balance_laser_reload_ammo 0 //default: 6
+ set g_balance_laser_reload_time 2
  // }}}
  // {{{ shotgun
  set g_balance_shotgun_primary_bullets 6
@@@ -255,14 -274,23 +274,23 @@@ set g_balance_shotgun_primary_ammo 
  set g_balance_shotgun_primary_speed 12000
  set g_balance_shotgun_primary_bulletconstant 75 // 3.8qu
  set g_balance_shotgun_secondary 1
- set g_balance_shotgun_secondary_melee_delay 0.35 // match the anim
- set g_balance_shotgun_secondary_melee_range 60
- set g_balance_shotgun_secondary_melee_swing 50
- set g_balance_shotgun_secondary_melee_time 0.1
+ set g_balance_shotgun_secondary_melee_delay 0.25 // 0.35 was too slow
+ 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_melee_no_doubleslap 1
+ set g_balance_shotgun_secondary_melee_nonplayerdamage 0
+ set g_balance_shotgun_secondary_melee_multihit 1
  set g_balance_shotgun_secondary_damage 115
  set g_balance_shotgun_secondary_force 150
  set g_balance_shotgun_secondary_refire 1.1
  set g_balance_shotgun_secondary_animtime 1
+ set g_balance_shotgun_switchdelay_drop 0.15
+ set g_balance_shotgun_switchdelay_raise 0.15
+ set g_balance_shotgun_reload_ammo 0 //default: 5
+ set g_balance_shotgun_reload_time 2
  // }}}
  // {{{ uzi
  set g_balance_uzi_mode 0                              // Activates varible spread for sustained & burst mode secondary
@@@ -294,6 -322,12 +322,12 @@@ set g_balance_uzi_sustained_ammo 
  
  set g_balance_uzi_speed 18000
  set g_balance_uzi_bulletconstant 115 // 13.1qu
+ set g_balance_uzi_switchdelay_drop 0.15
+ set g_balance_uzi_switchdelay_raise 0.15
+ set g_balance_uzi_reload_ammo 0 //default: 30
+ set g_balance_uzi_reload_time 2
  // }}}
  // {{{ mortar
  set g_balance_grenadelauncher_primary_type 0
@@@ -324,7 -358,8 +358,8 @@@ set g_balance_grenadelauncher_secondary
  set g_balance_grenadelauncher_secondary_speed_z 0
  set g_balance_grenadelauncher_secondary_spread 0
  set g_balance_grenadelauncher_secondary_lifetime 2.5
- set g_balance_grenadelauncher_secondary_lifetime2 0
+ set g_balance_grenadelauncher_secondary_lifetime_bounce 0
+ set g_balance_grenadelauncher_secondary_lifetime_stick 0
  set g_balance_grenadelauncher_secondary_refire 0.7
  set g_balance_grenadelauncher_secondary_animtime 0.3
  set g_balance_grenadelauncher_secondary_ammo 2
@@@ -334,29 -369,12 +369,12 @@@ set g_balance_grenadelauncher_secondary
  
  set g_balance_grenadelauncher_bouncefactor 0.5
  set g_balance_grenadelauncher_bouncestop 0.075
- // }}}
- // {{{ minelayer
- set g_balance_minelayer_damage 35
- set g_balance_minelayer_edgedamage 30
- set g_balance_minelayer_force 250
- set g_balance_minelayer_radius 175
- set g_balance_minelayer_proximityradius 150
- set g_balance_minelayer_speed 750
- set g_balance_minelayer_lifetime 60
- set g_balance_minelayer_lifetime_countdown 0
- set g_balance_minelayer_refire 1.5
- set g_balance_minelayer_animtime 0.4
- set g_balance_minelayer_ammo 5
- set g_balance_minelayer_health 15
- set g_balance_minelayer_limit 4 // 0 disables the limit
- set g_balance_minelayer_protection 1 // don't explode if the mine would hurt the owner or a team mate
- set g_balance_minelayer_damageforcescale 0
- set g_balance_minelayer_detonatedelay -1 // positive: timer till detonation is allowed, negative: "security device" that prevents ANY remote detonation if it could hurt its owner, zero: detonatable at any time
- set g_balance_minelayer_time 0.5
- set g_balance_minelayer_remote_damage 45
- set g_balance_minelayer_remote_edgedamage 40
- set g_balance_minelayer_remote_radius 200
- set g_balance_minelayer_remote_force 300
+ set g_balance_grenadelauncher_switchdelay_drop 0.15
+ set g_balance_grenadelauncher_switchdelay_raise 0.15
+ set g_balance_grenadelauncher_reload_ammo 0 //default: 12
+ set g_balance_grenadelauncher_reload_time 2
  // }}}
  // {{{ electro
  set g_balance_electro_lightning 0
@@@ -391,6 -409,7 +409,7 @@@ set g_balance_electro_secondary_animtim
  set g_balance_electro_secondary_ammo 2
  set g_balance_electro_secondary_health 5
  set g_balance_electro_secondary_damageforcescale 4
+ set g_balance_electro_secondary_damagedbycontents 0
  set g_balance_electro_secondary_count 1
  set g_balance_electro_secondary_bouncefactor 0.5
  set g_balance_electro_secondary_bouncestop 0.075
@@@ -400,37 -419,12 +419,42 @@@ set g_balance_electro_combo_force 20
  set g_balance_electro_combo_radius 250
  set g_balance_electro_combo_comboradius 0
  set g_balance_electro_combo_speed 2000
+ set g_balance_electro_combo_safeammocheck 0
+ set g_balance_electro_switchdelay_drop 0.15
+ set g_balance_electro_switchdelay_raise 0.15
+ set g_balance_electro_reload_ammo 0 //default: 20
+ set g_balance_electro_reload_time 2
  // }}}
 +// {{{ lightning
 +set g_balance_lightning_primary_ammo 5
 +set g_balance_lightning_primary_animtime 0.2
 +set g_balance_lightning_primary_damage 100
 +set g_balance_lightning_primary_edgedamage 0
 +set g_balance_lightning_primary_falloff_mindist 0
 +set g_balance_lightning_primary_falloff_maxdist 0
 +set g_balance_lightning_primary_falloff_halflifedist 0
 +set g_balance_lightning_primary_force 425
 +set g_balance_lightning_primary_lifetime 0
 +set g_balance_lightning_primary_radius 850
 +set g_balance_lightning_primary_range 800
 +set g_balance_lightning_primary_refire 0.4
 +set g_balance_lightning_primary_speed 0
 +set g_balance_lightning_primary_spread 0
 +set g_balance_lightning_secondary_ammo 5
 +set g_balance_lightning_secondary_animtime 0.5
 +set g_balance_lightning_secondary_damage 100
 +set g_balance_lightning_secondary_damageforcescale 4
 +set g_balance_lightning_secondary_edgedamage 80
 +set g_balance_lightning_secondary_flyingdamage 1
 +set g_balance_lightning_secondary_flyingforce -80
 +set g_balance_lightning_secondary_flyingradius 200
 +set g_balance_lightning_secondary_force -200
 +set g_balance_lightning_secondary_health 1
 +set g_balance_lightning_secondary_lifetime 30
 +set g_balance_lightning_secondary_radius 300
 +set g_balance_lightning_secondary_refire 5
 +set g_balance_lightning_secondary_speed 600
 +// }}}
  // {{{ crylink
  set g_balance_crylink_primary_damage 18
  set g_balance_crylink_primary_edgedamage 0
@@@ -466,6 -460,7 +490,7 @@@ set g_balance_crylink_secondary_force -
  set g_balance_crylink_secondary_radius 3
  set g_balance_crylink_secondary_speed 7000
  set g_balance_crylink_secondary_spread 0.08
+ set g_balance_crylink_secondary_spreadtype 0
  set g_balance_crylink_secondary_shots 7
  set g_balance_crylink_secondary_bounces 0
  set g_balance_crylink_secondary_refire 0.5
@@@ -486,6 -481,12 +511,12 @@@ set g_balance_crylink_secondary_middle_
  set g_balance_crylink_secondary_middle_fadetime 5
  set g_balance_crylink_secondary_line_lifetime 2 // range: 35000 full, fades to 70000
  set g_balance_crylink_secondary_line_fadetime 2
+ set g_balance_crylink_switchdelay_drop 0.15
+ set g_balance_crylink_switchdelay_raise 0.15
+ set g_balance_crylink_reload_ammo 0 //default: 10
+ set g_balance_crylink_reload_time 2
  // }}}
  // {{{ nex
  set g_balance_nex_primary_damage 100
@@@ -522,21 -523,36 +553,36 @@@ set g_balance_nex_charge_rate 0.
  set g_balance_nex_charge_animlimit 0.5
  set g_balance_nex_charge_limit 0.5
  set g_balance_nex_charge_rot_rate 0
- set g_balance_nex_charge_rot_pause 0 // Dont rot down untill this long after release of charge button
+ set g_balance_nex_charge_rot_pause 0 // Dont rot down until this long after release of charge button
  set g_balance_nex_charge_shot_multiplier 0.5
  set g_balance_nex_charge_velocity_rate 0.2
  set g_balance_nex_charge_minspeed 400
  set g_balance_nex_charge_maxspeed 1000
+ set g_balance_nex_switchdelay_drop 0.15
+ set g_balance_nex_switchdelay_raise 0.15
+ set g_balance_nex_reload_ammo 0 //default: 25
+ set g_balance_nex_reload_time 2
  // }}}
  // {{{ minstanex
  set g_balance_minstanex_refire 1
  set g_balance_minstanex_animtime 0.3
  set g_balance_minstanex_ammo 10
+ set g_balance_minstanex_laser_ammo 0
+ set g_balance_minstanex_laser_animtime 0.3
+ set g_balance_minstanex_laser_refire 0.7
+ set g_balance_minstanex_switchdelay_drop 0.15
+ set g_balance_minstanex_switchdelay_raise 0.15
+ set g_balance_minstanex_reload_ammo 0 //default: 50
+ set g_balance_minstanex_reload_time 2
  // }}}
  // {{{ hagar
  set g_balance_hagar_primary_damage 37
  set g_balance_hagar_primary_edgedamage 15
  set g_balance_hagar_primary_force 100
+ set g_balance_hagar_primary_health 0
+ set g_balance_hagar_primary_damageforcescale 0
  set g_balance_hagar_primary_radius 65
  set g_balance_hagar_primary_spread 0.010
  set g_balance_hagar_primary_speed 3000
@@@ -544,9 -560,21 +590,21 @@@ set g_balance_hagar_primary_lifetime 3
  set g_balance_hagar_primary_refire 0.15
  set g_balance_hagar_primary_ammo 1
  set g_balance_hagar_secondary 1
+ set g_balance_hagar_secondary_load 0
+ set g_balance_hagar_secondary_load_speed 0.6
+ set g_balance_hagar_secondary_load_spread 0.075
+ set g_balance_hagar_secondary_load_spread_bias 0.5
+ set g_balance_hagar_secondary_load_max 4
+ set g_balance_hagar_secondary_load_hold 0
+ set g_balance_hagar_secondary_load_releasedeath 1
+ set g_balance_hagar_secondary_load_abort 1
+ set g_balance_hagar_secondary_load_linkexplode 0
+ set g_balance_hagar_secondary_load_animtime 0.2
  set g_balance_hagar_secondary_damage 37
  set g_balance_hagar_secondary_edgedamage 15
  set g_balance_hagar_secondary_force 100
+ set g_balance_hagar_secondary_health 0
+ set g_balance_hagar_secondary_damageforcescale 0
  set g_balance_hagar_secondary_radius 65
  set g_balance_hagar_secondary_spread 0.015
  set g_balance_hagar_secondary_speed 1400
@@@ -554,6 -582,10 +612,10 @@@ set g_balance_hagar_secondary_lifetime_
  set g_balance_hagar_secondary_lifetime_rand 0
  set g_balance_hagar_secondary_refire 0.15
  set g_balance_hagar_secondary_ammo 1
+ set g_balance_hagar_switchdelay_drop 0.15
+ set g_balance_hagar_switchdelay_raise 0.15
+ set g_balance_hagar_reload_ammo 0 //default: 25
+ set g_balance_hagar_reload_time 2
  // }}}
  // {{{ rocketlauncher
  set g_balance_rocketlauncher_damage 105
@@@ -579,12 -611,23 +641,23 @@@ set g_balance_rocketlauncher_remote_dam
  set g_balance_rocketlauncher_remote_edgedamage 40
  set g_balance_rocketlauncher_remote_radius 150
  set g_balance_rocketlauncher_remote_force 600
+ set g_balance_rocketlauncher_switchdelay_drop 0.15
+ set g_balance_rocketlauncher_switchdelay_raise 0.15
+ set g_balance_rocketlauncher_reload_ammo 0 //default: 25
+ set g_balance_rocketlauncher_reload_time 2
  // }}}
  // {{{ porto
  set g_balance_porto_primary_refire 1.5
  set g_balance_porto_primary_animtime 0.3
  set g_balance_porto_primary_speed 2000
  set g_balance_porto_primary_lifetime 30
+ set g_balance_porto_secondary 0
+ set g_balance_porto_secondary_refire 1.5
+ set g_balance_porto_secondary_animtime 0.3
+ set g_balance_porto_secondary_speed 2000
+ set g_balance_porto_secondary_lifetime 30
+ set g_balance_porto_switchdelay_drop 0.15
+ set g_balance_porto_switchdelay_raise 0.15
  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
  // }}}
@@@ -607,73 -650,10 +680,10 @@@ set g_balance_hook_secondary_refire 3 /
  set g_balance_hook_secondary_animtime 0.3 // good shoot anim
  set g_balance_hook_secondary_power 3 // effect behaves like a square function
  set g_balance_hook_secondary_duration 1.5 // effect runs for three seconds
- // }}}
- // {{{ hlac
- set g_balance_hlac_primary_spread_min 0.01
- set g_balance_hlac_primary_spread_max 0.25
- set g_balance_hlac_primary_spread_add 0.0045
- set g_balance_hlac_primary_spread_crouchmod 0.25
- set g_balance_hlac_primary_damage 23
- set g_balance_hlac_primary_edgedamage 10
- set g_balance_hlac_primary_force 100
- set g_balance_hlac_primary_radius 70
- set g_balance_hlac_primary_speed 9000
- set g_balance_hlac_primary_lifetime 5
- set g_balance_hlac_primary_refire 0.1
- set g_balance_hlac_primary_animtime 0.4
- set g_balance_hlac_primary_ammo 1
- set g_balance_hlac_secondary 1
- set g_balance_hlac_secondary_spread 0.15
- set g_balance_hlac_secondary_spread_crouchmod 0.5
- set g_balance_hlac_secondary_damage 23
- set g_balance_hlac_secondary_edgedamage 10
- set g_balance_hlac_secondary_force 100
- set g_balance_hlac_secondary_radius 70
- set g_balance_hlac_secondary_speed 9000
- set g_balance_hlac_secondary_lifetime 5
- set g_balance_hlac_secondary_refire 1
- set g_balance_hlac_secondary_animtime 0.3
- set g_balance_hlac_secondary_ammo 10
- set g_balance_hlac_secondary_shots 6
- // }}}
- // {{{ sniperrifle
- set g_balance_sniperrifle_magazinecapacity 8
- set g_balance_sniperrifle_reloadtime 2 // matches reload anim
- set g_balance_sniperrifle_auto_reload_on_switch 0
- set g_balance_sniperrifle_bursttime 0
- set g_balance_sniperrifle_primary_tracer 0
- set g_balance_sniperrifle_primary_damage 60
- set g_balance_sniperrifle_primary_headshotaddeddamage 100
- set g_balance_sniperrifle_primary_spread 0
- set g_balance_sniperrifle_primary_force 2
- set g_balance_sniperrifle_primary_speed 35000
- set g_balance_sniperrifle_primary_lifetime 5
- set g_balance_sniperrifle_primary_refire 0.8
- set g_balance_sniperrifle_primary_animtime 0.3
- set g_balance_sniperrifle_primary_ammo 10
- set g_balance_sniperrifle_primary_bulletconstant 130 // 56.3qu
- set g_balance_sniperrifle_primary_burstcost 0
- set g_balance_sniperrifle_primary_bullethail 0 // empty magazine on shot
- set g_balance_sniperrifle_secondary 1
- set g_balance_sniperrifle_secondary_reload 0
- set g_balance_sniperrifle_secondary_tracer 0
- set g_balance_sniperrifle_secondary_damage 35
- set g_balance_sniperrifle_secondary_headshotaddeddamage 15 // 50 damage only on head
- set g_balance_sniperrifle_secondary_spread 0.008
- set g_balance_sniperrifle_secondary_force 1
- set g_balance_sniperrifle_secondary_speed 20000
- set g_balance_sniperrifle_secondary_lifetime 5
- set g_balance_sniperrifle_secondary_refire 0.15
- set g_balance_sniperrifle_secondary_animtime 0.1
- set g_balance_sniperrifle_secondary_ammo 10
- set g_balance_sniperrifle_secondary_bulletconstant 130 // 18.3qu
- set g_balance_sniperrifle_secondary_burstcost 0
- set g_balance_sniperrifle_secondary_bullethail 0 // empty magazine on shot
+ set g_balance_hook_secondary_health 0
+ set g_balance_hook_secondary_damageforcescale 0
+ set g_balance_hook_switchdelay_drop 0.15
+ set g_balance_hook_switchdelay_raise 0.15
  // }}}
  // {{{ tuba
  set g_balance_tuba_refire 0.05
@@@ -685,9 -665,11 +695,11 @@@ set g_balance_tuba_damage 
  set g_balance_tuba_edgedamage 0
  set g_balance_tuba_radius 200
  set g_balance_tuba_force 40
+ set g_balance_tuba_pitchstep 6
+ set g_balance_tuba_switchdelay_drop 0.15
+ set g_balance_tuba_switchdelay_raise 0.15
  // }}}
  // {{{ fireball
- set g_balance_fireball_primary_ammo 40
  set g_balance_fireball_primary_animtime 0.15
  set g_balance_fireball_primary_bfgdamage 100
  set g_balance_fireball_primary_bfgforce 0
@@@ -707,7 -689,6 +719,6 @@@ set g_balance_fireball_primary_refire 
  set g_balance_fireball_primary_refire2 0
  set g_balance_fireball_primary_speed 650
  set g_balance_fireball_primary_spread 0
- set g_balance_fireball_secondary_ammo 5
  set g_balance_fireball_secondary_animtime 0.3
  set g_balance_fireball_secondary_damage 40
  set g_balance_fireball_secondary_damageforcescale 4
@@@ -723,54 -704,6 +734,6 @@@ set g_balance_fireball_secondary_speed 
  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.15
+ set g_balance_fireball_switchdelay_raise 0.15
  // }}}
- // {{{ seeker
- set g_balance_seeker_flac_ammo 0.5
- 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 3000
- set g_balance_seeker_missile_ammo 2
- set g_balance_seeker_missile_animtime 0.3
- set g_balance_seeker_missile_count 4
- set g_balance_seeker_missile_damage 40
- set g_balance_seeker_missile_damageforcescale 4
- set g_balance_seeker_missile_decel 6000
- set g_balance_seeker_missile_delay 0.25
- set g_balance_seeker_missile_edgedamage 10
- set g_balance_seeker_missile_force 250
- 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_up 300
- set g_balance_seeker_missile_speed_z 0
- set g_balance_seeker_missile_speed_max 1250
- set g_balance_seeker_missile_spread 0
- set g_balance_seeker_missile_turnrate 0.65
- set g_balance_seeker_tag_ammo 1
- set g_balance_seeker_tag_animtime 0.3
- 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.7
- set g_balance_seeker_tag_speed 9000
- set g_balance_seeker_tag_spread 0
- // End new seeker
diff --combined balanceFruitieX.cfg
index 0000000000000000000000000000000000000000,ce125421f91a64877c6e975cba3bbdfce025dbe8..5fa32c593189744c41c3c4e742856ae86a2575b8
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,709 +1,739 @@@
+ g_mod_balance FruitieX
+ // {{{ starting gear
+ set g_start_weapon_laser -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+ set g_start_weapon_shotgun -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+ set g_start_weapon_uzi -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+ set g_start_weapon_grenadelauncher -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+ set g_start_weapon_electro -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+ set g_start_weapon_crylink -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+ set g_start_weapon_nex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+ set g_start_weapon_hagar -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+ set g_start_weapon_rocketlauncher -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+ set g_start_weapon_minstanex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+ set g_start_weapon_porto -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+ set g_start_weapon_hook -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+ set g_start_weapon_tuba -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+ set g_start_weapon_fireball -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+ set g_balance_health_start 125
+ set g_balance_armor_start 0
+ set g_start_ammo_shells 20
+ set g_start_ammo_nails 0
+ set g_start_ammo_rockets 0
+ set g_start_ammo_cells 0
+ set g_start_ammo_fuel 0
+ set g_warmup_start_health 200 "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 50 "starting values when being in warmup-stage"
+ set g_warmup_start_ammo_nails 150 "starting values when being in warmup-stage"
+ set g_warmup_start_ammo_rockets 50 "starting values when being in warmup-stage"
+ set g_warmup_start_ammo_cells 50 "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 100
+ set g_lms_start_ammo_shells 30
+ set g_lms_start_ammo_nails 200
+ set g_lms_start_ammo_rockets 150
+ set g_lms_start_ammo_cells 150
+ 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 15
+ set g_balance_nix_ammo_nails 45
+ set g_balance_nix_ammo_rockets 15
+ set g_balance_nix_ammo_cells 15
+ set g_balance_nix_ammo_fuel 0
+ set g_balance_nix_ammoincr_shells 2
+ 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_fuel 2
+ // }}}
+ // {{{ pickup items
+ set g_pickup_ammo_anyway 1
+ set g_pickup_weapons_anyway 1
+ set g_pickup_shells 20
+ set g_pickup_shells_weapon 10
+ set g_pickup_shells_max 45
+ set g_pickup_nails 120
+ set g_pickup_nails_weapon 60
+ set g_pickup_nails_max 300
+ set g_pickup_rockets 25
+ set g_pickup_rockets_weapon 15
+ set g_pickup_rockets_max 150
+ set g_pickup_cells 30
+ set g_pickup_cells_weapon 20
+ set g_pickup_cells_max 150
+ set g_pickup_fuel 25
+ set g_pickup_fuel_weapon 15
+ set g_pickup_fuel_jetpack 50
+ set g_pickup_fuel_max 100
+ set g_pickup_armorsmall 5
+ set g_pickup_armorsmall_max 150
+ set g_pickup_armorsmall_anyway 1
+ set g_pickup_armormedium 25
+ set g_pickup_armormedium_max 50
+ set g_pickup_armormedium_anyway 0
+ set g_pickup_armorbig 50
+ set g_pickup_armorbig_max 75; // LOG: to allow a little more armor from medium armor
+ set g_pickup_armorbig_anyway 0
+ set g_pickup_armorlarge 100
+ set g_pickup_armorlarge_max 150
+ set g_pickup_armorlarge_anyway 1
+ set g_pickup_healthsmall 5
+ set g_pickup_healthsmall_max 250
+ set g_pickup_healthsmall_anyway 1
+ set g_pickup_healthmedium 25
+ set g_pickup_healthmedium_max 100
+ set g_pickup_healthmedium_anyway 0
+ set g_pickup_healthlarge 50
+ set g_pickup_healthlarge_max 150
+ set g_pickup_healthlarge_anyway 0
+ set g_pickup_healthmega 100
+ set g_pickup_healthmega_max 250
+ 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 25
+ set g_pickup_respawntimejitter_short 0
+ set g_pickup_respawntimejitter_medium 0
+ set g_pickup_respawntimejitter_long 0
+ set g_pickup_respawntimejitter_powerup 10
+ 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.05
+ set g_balance_health_regenlinear 0
+ set g_balance_pause_health_regen 5
+ set g_balance_pause_health_regen_spawn 0
+ set g_balance_health_rot 0
+ set g_balance_health_rotlinear 1
+ set g_balance_pause_health_rot 1
+ set g_balance_pause_health_rot_spawn 0
+ set g_balance_health_regenstable 100
+ set g_balance_health_rotstable 100
+ set g_balance_health_limit 999
+ set g_balance_armor_regen 0
+ set g_balance_armor_regenlinear 0
+ set g_balance_armor_rot 0
+ set g_balance_armor_rotlinear 1
+ set g_balance_pause_armor_rot 1
+ set g_balance_pause_armor_rot_spawn 0
+ set g_balance_armor_regenstable 100
+ set g_balance_armor_rotstable 100
+ set g_balance_armor_limit 999
+ 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 999
+ // }}}
+ // {{{ 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.7
+ set g_throughfloor_force 0.8
+ 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 0
+ set g_projectiles_newton_style 2
+ // 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.7
+ set g_projectiles_newton_style_2_maxfactor 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 150
+ set g_balance_falldamage_minspeed 800
+ set g_balance_falldamage_factor 0.20
+ set g_balance_falldamage_maxdamage 15
+ 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_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.6
+ set g_balance_powerup_invincible_time 30
+ set g_balance_powerup_strength_damage 3
+ set g_balance_powerup_strength_force 4
+ 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 1500 "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_attenuation 2 "jetpack sound attenuation"
+ 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 130
+ set g_balance_grapplehook_damagedbycontents 0
+ // }}}
+ // {{{ weapon properties
+ // {{{ laser
+ set g_balance_laser_primary_damage 20 // dps 33, hope that's not too high
+ set g_balance_laser_primary_edgedamage 20
+ set g_balance_laser_primary_force 150 // this looks insanely low, but actually isn't with zscale and velocitybias
+ set g_balance_laser_primary_radius 60
+ set g_balance_laser_primary_speed 5000
+ set g_balance_laser_primary_spread 0
+ set g_balance_laser_primary_refire 0.6
+ set g_balance_laser_primary_animtime 0.4
+ set g_balance_laser_primary_lifetime 5
+ set g_balance_laser_primary_shotangle 0
+ set g_balance_laser_primary_delay 0
+ set g_balance_laser_primary_gauntlet 0
+ set g_balance_laser_primary_force_zscale 2 // 300 upforce
+ set g_balance_laser_primary_force_velocitybias 0.3
+ set g_balance_laser_primary_force_other_scale 2.5 // force 375 when pushing others around
+ set g_balance_laser_secondary 0 // when 1, a secondary laser mode exists
+ set g_balance_laser_secondary_damage 200 // dps
+ set g_balance_laser_secondary_edgedamage 0
+ set g_balance_laser_secondary_force 1300
+ set g_balance_laser_secondary_radius 60
+ set g_balance_laser_secondary_speed 0
+ set g_balance_laser_secondary_spread 0
+ set g_balance_laser_secondary_refire 0.066
+ set g_balance_laser_secondary_animtime 0.066
+ set g_balance_laser_secondary_lifetime 0
+ set g_balance_laser_secondary_shotangle 0
+ set g_balance_laser_secondary_delay 0
+ set g_balance_laser_secondary_gauntlet 1
+ set g_balance_laser_secondary_force_zscale 1.25
+ set g_balance_laser_secondary_force_velocitybias 0
+ set g_balance_laser_secondary_force_other_scale 0
+ set g_balance_laser_switchdelay_drop 0.15
+ set g_balance_laser_switchdelay_raise 0.15
+ set g_balance_laser_reload_ammo 0 //default: 6
+ set g_balance_laser_reload_time 2
+ // }}}
+ // {{{ shotgun
+ set g_balance_shotgun_primary_bullets 18
+ set g_balance_shotgun_primary_damage 3.5 // LOG: changed from 4 to 3.5, total damage 63
+ set g_balance_shotgun_primary_force 20
+ set g_balance_shotgun_primary_spread 0.16 // LOG: changed from 0.18 -> 0.16 to compensate a little for lower damage
+ set g_balance_shotgun_primary_refire 1
+ set g_balance_shotgun_primary_animtime 0.3
+ set g_balance_shotgun_primary_ammo 1
+ set g_balance_shotgun_primary_speed 12000
+ set g_balance_shotgun_primary_bulletconstant 75 // 3.8qu
+ set g_balance_shotgun_secondary 1
+ set g_balance_shotgun_secondary_melee_delay 0.25 // 0.35 was too slow
+ 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_melee_no_doubleslap 1
+ set g_balance_shotgun_secondary_melee_nonplayerdamage 0
+ set g_balance_shotgun_secondary_melee_multihit 1
+ set g_balance_shotgun_secondary_damage 110
+ set g_balance_shotgun_secondary_force 150
+ set g_balance_shotgun_secondary_refire 1.1
+ set g_balance_shotgun_secondary_animtime 1
+ set g_balance_shotgun_switchdelay_drop 0.15
+ set g_balance_shotgun_switchdelay_raise 0.15
+ set g_balance_shotgun_reload_ammo 0 //default: 5
+ set g_balance_shotgun_reload_time 2
+ // }}}
+ // {{{ uzi
+ set g_balance_uzi_mode 1                              // Activates varible spread for sustained & burst mode secondary
+ set g_balance_uzi_spread_min 0.02
+ set g_balance_uzi_spread_max 0.3 // LOG: 0.6 -> 0.3
+ set g_balance_uzi_spread_add 0.008
+ set g_balance_uzi_burst 3                             // # of bullets in a burst (if set to 2 or more)
+ set g_balance_uzi_burst_animtime 0.45
+ set g_balance_uzi_burst_refire 0.05           // refire between burst bullets
+ set g_balance_uzi_burst_refire2 0.45  // refire after burst
+ set g_balance_uzi_burst_spread 0.07
+ set g_balance_uzi_burst_damage 25
+ set g_balance_uzi_burst_force 50
+ set g_balance_uzi_burst_ammo 3
+ set g_balance_uzi_first 1
+ set g_balance_uzi_first_damage 15 / f/ LOG: 22 -> 15
+ set g_balance_uzi_first_force 50
+ set g_balance_uzi_first_spread 0.03
+ set g_balance_uzi_first_refire 0.2
+ set g_balance_uzi_first_ammo 2
+ set g_balance_uzi_sustained_damage 12   // 120 dps
+ set g_balance_uzi_sustained_force 12
+ set g_balance_uzi_sustained_spread 0.06
+ set g_balance_uzi_sustained_refire 0.1
+ set g_balance_uzi_sustained_ammo 1
+ set g_balance_uzi_speed 18000
+ set g_balance_uzi_bulletconstant 115 // 13.1qu
+ set g_balance_uzi_switchdelay_drop 0.15
+ set g_balance_uzi_switchdelay_raise 0.15
+ set g_balance_uzi_reload_ammo 0 //default: 30
+ set g_balance_uzi_reload_time 2
+ // }}}
+ // {{{ mortar
+ set g_balance_grenadelauncher_primary_type 0
+ set g_balance_grenadelauncher_primary_damage 44
+ set g_balance_grenadelauncher_primary_edgedamage 32
+ set g_balance_grenadelauncher_primary_force 300
+ set g_balance_grenadelauncher_primary_radius 115
+ set g_balance_grenadelauncher_primary_speed 1500
+ set g_balance_grenadelauncher_primary_speed_up 225
+ set g_balance_grenadelauncher_primary_speed_z 0
+ set g_balance_grenadelauncher_primary_spread 0
+ set g_balance_grenadelauncher_primary_lifetime 5
+ set g_balance_grenadelauncher_primary_lifetime2 0.65
+ set g_balance_grenadelauncher_primary_refire 0.8
+ set g_balance_grenadelauncher_primary_animtime 0.3
+ set g_balance_grenadelauncher_primary_ammo 2
+ set g_balance_grenadelauncher_primary_health 80
+ set g_balance_grenadelauncher_primary_damageforcescale 0
+ set g_balance_grenadelauncher_primary_remote_minbouncecnt 0
+ set g_balance_grenadelauncher_secondary_type 1
+ set g_balance_grenadelauncher_secondary_damage 62
+ set g_balance_grenadelauncher_secondary_edgedamage 32
+ set g_balance_grenadelauncher_secondary_force 300
+ set g_balance_grenadelauncher_secondary_radius 150
+ set g_balance_grenadelauncher_secondary_speed 1000
+ set g_balance_grenadelauncher_secondary_speed_up 250
+ set g_balance_grenadelauncher_secondary_speed_z 0
+ set g_balance_grenadelauncher_secondary_spread 0
+ set g_balance_grenadelauncher_secondary_lifetime 3
+ set g_balance_grenadelauncher_secondary_lifetime_bounce 0
+ set g_balance_grenadelauncher_secondary_lifetime_stick 0.65
+ set g_balance_grenadelauncher_secondary_refire 0.8
+ set g_balance_grenadelauncher_secondary_animtime 0.3
+ set g_balance_grenadelauncher_secondary_ammo 2
+ set g_balance_grenadelauncher_secondary_health 40
+ set g_balance_grenadelauncher_secondary_damageforcescale 0
+ set g_balance_grenadelauncher_secondary_remote_detonateprimary 0
+ set g_balance_grenadelauncher_bouncefactor 0.5
+ set g_balance_grenadelauncher_bouncestop 0.12
+ set g_balance_grenadelauncher_switchdelay_drop 0.15
+ set g_balance_grenadelauncher_switchdelay_raise 0.15
+ set g_balance_grenadelauncher_reload_ammo 0 //default: 12
+ set g_balance_grenadelauncher_reload_time 2
+ // }}}
+ // {{{ electro
+ set g_balance_electro_lightning 1
+ set g_balance_electro_primary_damage 100
+ set g_balance_electro_primary_edgedamage 0
+ set g_balance_electro_primary_force 425
+ set g_balance_electro_primary_force_up 125
+ set g_balance_electro_primary_radius 850
+ set g_balance_electro_primary_comboradius 150
+ set g_balance_electro_primary_speed 0
+ set g_balance_electro_primary_spread 0
+ set g_balance_electro_primary_lifetime 0
+ set g_balance_electro_primary_refire 0.4
+ set g_balance_electro_primary_animtime 0.2
+ set g_balance_electro_primary_ammo 5
+ set g_balance_electro_primary_range 800
+ set g_balance_electro_primary_falloff_mindist 0
+ set g_balance_electro_primary_falloff_maxdist 0
+ set g_balance_electro_primary_falloff_halflifedist 0
+ set g_balance_electro_secondary_damage 25
+ set g_balance_electro_secondary_edgedamage 0
+ set g_balance_electro_secondary_force 100
+ set g_balance_electro_secondary_radius 100
+ set g_balance_electro_secondary_speed 700
+ set g_balance_electro_secondary_speed_up 200
+ set g_balance_electro_secondary_speed_z 0
+ set g_balance_electro_secondary_spread 0.08
+ set g_balance_electro_secondary_lifetime 3.5
+ set g_balance_electro_secondary_refire 0.2
+ set g_balance_electro_secondary_refire2 2
+ set g_balance_electro_secondary_animtime 0.2
+ set g_balance_electro_secondary_ammo 2
+ set g_balance_electro_secondary_health 10
+ set g_balance_electro_secondary_damageforcescale 4
+ set g_balance_electro_secondary_damagedbycontents 0
+ set g_balance_electro_secondary_count 3
+ set g_balance_electro_secondary_bouncefactor 0.5
+ set g_balance_electro_secondary_bouncestop 0.075
+ set g_balance_electro_combo_damage 50
+ set g_balance_electro_combo_edgedamage 0
+ set g_balance_electro_combo_force 80
+ set g_balance_electro_combo_radius 250
+ set g_balance_electro_combo_comboradius 0
+ set g_balance_electro_combo_speed 400
+ set g_balance_electro_combo_safeammocheck 1
+ set g_balance_electro_switchdelay_drop 0.15
+ set g_balance_electro_switchdelay_raise 0.15
+ set g_balance_electro_reload_ammo 0 //default: 20
+ set g_balance_electro_reload_time 2
+ // }}}
++// {{{ lightning
++set g_balance_lightning_primary_ammo 5
++set g_balance_lightning_primary_animtime 0.2
++set g_balance_lightning_primary_damage 100
++set g_balance_lightning_primary_edgedamage 0
++set g_balance_lightning_primary_falloff_mindist 0
++set g_balance_lightning_primary_falloff_maxdist 0
++set g_balance_lightning_primary_falloff_halflifedist 0
++set g_balance_lightning_primary_force 425
++set g_balance_lightning_primary_lifetime 0
++set g_balance_lightning_primary_radius 850
++set g_balance_lightning_primary_range 800
++set g_balance_lightning_primary_refire 0.4
++set g_balance_lightning_primary_speed 0
++set g_balance_lightning_primary_spread 0
++set g_balance_lightning_secondary_ammo 5
++set g_balance_lightning_secondary_animtime 0.5
++set g_balance_lightning_secondary_damage 100
++set g_balance_lightning_secondary_damageforcescale 4
++set g_balance_lightning_secondary_edgedamage 80
++set g_balance_lightning_secondary_flyingdamage 1
++set g_balance_lightning_secondary_flyingforce -80
++set g_balance_lightning_secondary_flyingradius 200
++set g_balance_lightning_secondary_force -200
++set g_balance_lightning_secondary_health 1
++set g_balance_lightning_secondary_lifetime 30
++set g_balance_lightning_secondary_radius 300
++set g_balance_lightning_secondary_refire 5
++set g_balance_lightning_secondary_speed 600
++// }}}
+ // {{{ crylink
+ set g_balance_crylink_primary_damage 7 // LOG: 10 -> 7
+ set g_balance_crylink_primary_edgedamage 4 // LOG: 6 -> 4
+ set g_balance_crylink_primary_force 35
+ set g_balance_crylink_primary_radius 80
+ set g_balance_crylink_primary_speed 1500
+ set g_balance_crylink_primary_spread 0.05
+ set g_balance_crylink_primary_shots 7
+ set g_balance_crylink_primary_bounces 2
+ set g_balance_crylink_primary_refire 0.8
+ set g_balance_crylink_primary_animtime 0.3
+ set g_balance_crylink_primary_ammo 2
+ set g_balance_crylink_primary_bouncedamagefactor 0.2
+ set g_balance_crylink_primary_joindelay 0
+ set g_balance_crylink_primary_joinspread 0.2
+ set g_balance_crylink_primary_jointime 0.1
+ set g_balance_crylink_primary_joinexplode 0
+ set g_balance_crylink_primary_joinexplode_damage 0
+ set g_balance_crylink_primary_joinexplode_edgedamage 0
+ set g_balance_crylink_primary_joinexplode_radius 0
+ set g_balance_crylink_primary_joinexplode_force 0
+ set g_balance_crylink_primary_linkexplode 1
+ set g_balance_crylink_primary_middle_lifetime 5 // range: 10000 full, fades to 20000
+ set g_balance_crylink_primary_middle_fadetime 5
+ set g_balance_crylink_primary_other_lifetime 2 // range: 800 full, fades to 1300
+ set g_balance_crylink_primary_other_fadetime 0.25
+ set g_balance_crylink_secondary 1
+ set g_balance_crylink_secondary_damage 5 // LOG: 8 -> 5
+ set g_balance_crylink_secondary_edgedamage 3
+ set g_balance_crylink_secondary_force 16 // LOG: 20 -> 16
+ set g_balance_crylink_secondary_radius 15 // LOG: 20 -> 15
+ set g_balance_crylink_secondary_speed 1250 // LOG: 1500 -> 1250
+ set g_balance_crylink_secondary_spread 0.1
+ set g_balance_crylink_secondary_spreadtype 0
+ set g_balance_crylink_secondary_shots 6
+ set g_balance_crylink_secondary_bounces 2
+ set g_balance_crylink_secondary_refire 0.9 // LOG: 0.8 -> 0.9
+ set g_balance_crylink_secondary_animtime 0.3
+ set g_balance_crylink_secondary_ammo 3 // LOG: 2 -> 3
+ set g_balance_crylink_secondary_bouncedamagefactor 0.4 // LOG: 0.2 -> 0.4
+ set g_balance_crylink_secondary_joindelay 0
+ set g_balance_crylink_secondary_joinspread 0.2
+ set g_balance_crylink_secondary_jointime 0.1
+ 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_radius 0
+ set g_balance_crylink_secondary_joinexplode_force 0
+ set g_balance_crylink_secondary_linkexplode 0
+ set g_balance_crylink_secondary_middle_lifetime 5 // range: 10000 full, fades to 10000
+ set g_balance_crylink_secondary_middle_fadetime 5
+ set g_balance_crylink_secondary_line_lifetime 2 // range: 4000 full, fades to 8000
+ set g_balance_crylink_secondary_line_fadetime 0.25
+ set g_balance_crylink_switchdelay_drop 0.15
+ set g_balance_crylink_switchdelay_raise 0.15
+ set g_balance_crylink_reload_ammo 0 //default: 10
+ set g_balance_crylink_reload_time 2
+ // }}}
+ // {{{ nex
+ set g_balance_nex_primary_damage 90
+ set g_balance_nex_primary_force 500
+ set g_balance_nex_primary_refire 1
+ set g_balance_nex_primary_animtime 0.3
+ set g_balance_nex_primary_ammo 5
+ set g_balance_nex_primary_damagefalloff_mindist 0
+ set g_balance_nex_primary_damagefalloff_maxdist 0
+ set g_balance_nex_primary_damagefalloff_halflife 0
+ set g_balance_nex_primary_damagefalloff_forcehalflife 0
+ set g_balance_nex_secondary 0 // LOG: disable secondary
+ set g_balance_nex_secondary_charge 0 // LOG: disable secondary charge
+ set g_balance_nex_secondary_charge_rate 0.4
+ set g_balance_nex_secondary_chargepool 1
+ set g_balance_nex_secondary_chargepool_regen 0.25
+ set g_balance_nex_secondary_chargepool_pause_regen 2
+ set g_balance_nex_secondary_chargepool_pause_health_regen 0.5
+ set g_balance_nex_secondary_damage 0
+ set g_balance_nex_secondary_force 0
+ set g_balance_nex_secondary_refire 0
+ set g_balance_nex_secondary_animtime 0
+ set g_balance_nex_secondary_ammo 0.4 // full charge pool is 1, so it depletes in 2.5 secs
+ set g_balance_nex_secondary_damagefalloff_mindist 0
+ set g_balance_nex_secondary_damagefalloff_maxdist 0
+ set g_balance_nex_secondary_damagefalloff_halflife 0
+ set g_balance_nex_secondary_damagefalloff_forcehalflife 0
+ set g_balance_nex_charge 1
+ set g_balance_nex_charge_mindmg 20
+ set g_balance_nex_charge_start 0.5
+ set g_balance_nex_charge_rate 0.5
+ set g_balance_nex_charge_animlimit 0.5
+ set g_balance_nex_charge_limit 1 // LOG: 0.5 -> 1 - allow to fully charge automaticaly
+ set g_balance_nex_charge_rot_rate 0 // LOG: 0.1 -> 0 - disable rot
+ set g_balance_nex_charge_rot_pause 0.5 // Dont rot down until this long after release of charge button
+ set g_balance_nex_charge_shot_multiplier 0
+ set g_balance_nex_charge_velocity_rate 0
+ set g_balance_nex_charge_minspeed 600
+ set g_balance_nex_charge_maxspeed 1000
+ set g_balance_nex_switchdelay_drop 0.15
+ set g_balance_nex_switchdelay_raise 0.15
+ set g_balance_nex_reload_ammo 0 //default: 25
+ set g_balance_nex_reload_time 2
+ // }}}
+ // {{{ minstanex
+ set g_balance_minstanex_refire 1
+ set g_balance_minstanex_animtime 0.50
+ set g_balance_minstanex_ammo 10
+ set g_balance_minstanex_laser_ammo 0
+ set g_balance_minstanex_laser_animtime 0.3
+ set g_balance_minstanex_laser_refire 0.6
+ set g_balance_minstanex_switchdelay_drop 0.15
+ set g_balance_minstanex_switchdelay_raise 0.15
+ set g_balance_minstanex_reload_ammo 0 //default: 50
+ set g_balance_minstanex_reload_time 2
+ // }}}
+ // {{{ hagar
+ set g_balance_hagar_primary_damage 14
+ set g_balance_hagar_primary_edgedamage 6
+ set g_balance_hagar_primary_force 70
+ set g_balance_hagar_primary_health 0
+ set g_balance_hagar_primary_damageforcescale 0
+ set g_balance_hagar_primary_radius 110
+ set g_balance_hagar_primary_spread 0.1
+ set g_balance_hagar_primary_speed 1800
+ set g_balance_hagar_primary_lifetime 5
+ set g_balance_hagar_primary_refire 0.12
+ set g_balance_hagar_primary_ammo 1
+ set g_balance_hagar_secondary 1
+ set g_balance_hagar_secondary_load 0
+ set g_balance_hagar_secondary_load_speed 0.6
+ set g_balance_hagar_secondary_load_spread 0.075
+ set g_balance_hagar_secondary_load_spread_bias 0.5
+ set g_balance_hagar_secondary_load_max 4
+ set g_balance_hagar_secondary_load_hold 0
+ set g_balance_hagar_secondary_load_releasedeath 1
+ set g_balance_hagar_secondary_load_abort 1
+ set g_balance_hagar_secondary_load_linkexplode 0
+ set g_balance_hagar_secondary_load_animtime 0.2
+ set g_balance_hagar_secondary_damage 14 // default for _load: 32
+ set g_balance_hagar_secondary_edgedamage 6 // default for _load: 10
+ set g_balance_hagar_secondary_force 70 // default for _load: 160
+ set g_balance_hagar_secondary_health 0
+ set g_balance_hagar_secondary_damageforcescale 0
+ set g_balance_hagar_secondary_radius 125
+ set g_balance_hagar_secondary_spread 0.15 // default for _load: 0.08
+ set g_balance_hagar_secondary_speed 1800
+ set g_balance_hagar_secondary_lifetime_min 5
+ set g_balance_hagar_secondary_lifetime_rand 0
+ set g_balance_hagar_secondary_refire 0.12 // default for _load: 0.8
+ set g_balance_hagar_secondary_ammo 1
+ set g_balance_hagar_switchdelay_drop 0.15
+ set g_balance_hagar_switchdelay_raise 0.15
+ set g_balance_hagar_reload_ammo 0 //default: 25
+ set g_balance_hagar_reload_time 2
+ // }}}
+ // {{{ rocketlauncher
+ set g_balance_rocketlauncher_damage 82
+ set g_balance_rocketlauncher_edgedamage 32
+ set g_balance_rocketlauncher_force 350
+ set g_balance_rocketlauncher_radius 130
+ set g_balance_rocketlauncher_speed 1400
+ set g_balance_rocketlauncher_speedaccel 1400
+ set g_balance_rocketlauncher_speedstart 800
+ set g_balance_rocketlauncher_lifetime 5
+ set g_balance_rocketlauncher_refire 1
+ set g_balance_rocketlauncher_animtime 0.3
+ set g_balance_rocketlauncher_ammo 3
+ set g_balance_rocketlauncher_health 0
+ set g_balance_rocketlauncher_damageforcescale 0
+ set g_balance_rocketlauncher_detonatedelay 0.05 // positive: timer till detonation is allowed, negative: "security device" that prevents ANY remote detonation if it could hurt its owner, zero: detonatable at any time
+ set g_balance_rocketlauncher_guiderate 42 // max degrees per second
+ set g_balance_rocketlauncher_guideratedelay 0.01 // immediate
+ set g_balance_rocketlauncher_guidegoal 512 // goal distance for (non-laser) guiding (higher = less control, lower = erratic)
+ set g_balance_rocketlauncher_guidedelay 0.15 // delay before guiding kicks in
+ set g_balance_rocketlauncher_guidestop 0 // stop guiding when firing again
+ set g_balance_rocketlauncher_remote_damage 60
+ set g_balance_rocketlauncher_remote_edgedamage 20
+ set g_balance_rocketlauncher_remote_radius 120
+ set g_balance_rocketlauncher_remote_force 350
+ set g_balance_rocketlauncher_switchdelay_drop 0.15
+ set g_balance_rocketlauncher_switchdelay_raise 0.15
+ set g_balance_rocketlauncher_reload_ammo 0 //default: 25
+ set g_balance_rocketlauncher_reload_time 2
+ // }}}
+ // {{{ porto
+ set g_balance_porto_primary_refire 1.5
+ set g_balance_porto_primary_animtime 0.2
+ set g_balance_porto_primary_speed 2000
+ set g_balance_porto_primary_lifetime 5
+ set g_balance_porto_secondary 0
+ set g_balance_porto_secondary_refire 1.5
+ set g_balance_porto_secondary_animtime 0.2
+ set g_balance_porto_secondary_speed 2000
+ set g_balance_porto_secondary_lifetime 5
+ set g_balance_porto_switchdelay_drop 0.15
+ set g_balance_porto_switchdelay_raise 0.15
+ 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
+ // }}}
+ // {{{ hook
+ set g_balance_hook_primary_fuel 5 // hook monkeys set 0
+ set g_balance_hook_primary_refire 0 // hook monkeys set 0
+ set g_balance_hook_primary_animtime 0.2 // good shoot anim
+ set g_balance_hook_primary_hooked_time_max 0 // infinite
+ set g_balance_hook_primary_hooked_time_free 2 // 2s being hooked are free
+ set g_balance_hook_primary_hooked_fuel 5 // fuel per second hooked
+ set g_balance_hook_secondary_damage 25 // not much
+ set g_balance_hook_secondary_edgedamage 5 // not much
+ set g_balance_hook_secondary_radius 500 // LOTS
+ set g_balance_hook_secondary_force -2000 // LOTS
+ set g_balance_hook_secondary_ammo 50 // a whole pack
+ set g_balance_hook_secondary_lifetime 5 // infinite
+ set g_balance_hook_secondary_speed 0 // not much throwing
+ set g_balance_hook_secondary_gravity 5 // fast falling
+ set g_balance_hook_secondary_refire 3 // don't drop too many bombs...
+ set g_balance_hook_secondary_animtime 0.2 // good shoot anim
+ set g_balance_hook_secondary_power 3 // effect behaves like a square function
+ set g_balance_hook_secondary_duration 1.5 // effect runs for three seconds
+ set g_balance_hook_secondary_health 0
+ set g_balance_hook_secondary_damageforcescale 0
+ set g_balance_hook_switchdelay_drop 0.15
+ set g_balance_hook_switchdelay_raise 0.15
+ // }}}
+ // {{{ tuba
+ set g_balance_tuba_refire 0.05
+ set g_balance_tuba_animtime 0.05
+ set g_balance_tuba_attenuation 0.5
+ set g_balance_tuba_volume 1
+ set g_balance_tuba_fadetime 0.25
+ set g_balance_tuba_damage 5
+ set g_balance_tuba_edgedamage 0
+ set g_balance_tuba_radius 200
+ set g_balance_tuba_force 40
+ set g_balance_tuba_pitchstep 6
+ set g_balance_tuba_switchdelay_drop 0.15
+ set g_balance_tuba_switchdelay_raise 0.15
+ // }}}
+ // {{{ fireball
+ set g_balance_fireball_primary_animtime 0.2
+ 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 4
+ set g_balance_fireball_primary_edgedamage 0
+ set g_balance_fireball_primary_force 700
+ set g_balance_fireball_primary_health 50
+ 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 5
+ set g_balance_fireball_primary_refire2 0
+ set g_balance_fireball_primary_speed 650
+ set g_balance_fireball_primary_spread 0
+ set g_balance_fireball_secondary_animtime 0.2
+ 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_force 100
+ 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 2
+ 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.15
+ set g_balance_fireball_switchdelay_raise 0.15
+ // }}}
diff --combined balanceXPM.cfg
index 0000000000000000000000000000000000000000,f8ffd03381281b57c46ffa236eb0a174956b6da0..e952b59d1ded19f61f7e96d43b1f1d9ff6ff57c9
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,709 +1,739 @@@
+ g_mod_balance XPM
+ // {{{ starting gear
+ set g_start_weapon_laser -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+ set g_start_weapon_shotgun -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+ set g_start_weapon_uzi -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+ set g_start_weapon_grenadelauncher -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+ set g_start_weapon_electro -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+ set g_start_weapon_crylink -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+ set g_start_weapon_nex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+ set g_start_weapon_hagar -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms" // UNTIL IT CAN BE REMOVED FROM CODE
+ set g_start_weapon_rocketlauncher -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+ set g_start_weapon_minstanex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+ set g_start_weapon_porto -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+ set g_start_weapon_hook -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+ set g_start_weapon_tuba -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+ set g_start_weapon_fireball -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+ 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_fuel 0
+ 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_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_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_fuel 0
+ 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_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_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_armorlarge 100
+ set g_pickup_armorlarge_max 200
+ set g_pickup_armorlarge_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_healthlarge 50
+ set g_pickup_healthlarge_max 100
+ set g_pickup_healthlarge_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 15
+ set g_pickup_respawntimejitter_short 0
+ set g_pickup_respawntimejitter_medium 0
+ set g_pickup_respawntimejitter_long 0
+ set g_pickup_respawntimejitter_powerup 30
+ 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.03
+ set g_balance_health_rotlinear 0.75
+ 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 999
+ set g_balance_armor_regen 0
+ set g_balance_armor_regenlinear 0
+ set g_balance_armor_rot 0.03
+ set g_balance_armor_rotlinear 0.75
+ 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 999
+ set g_balance_armor_blockpercent 0.6
+ 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 999
+ // }}}
+ // {{{ 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 1
+ // 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 0
+ set g_projectiles_newton_style 0
+ // possible values:
+ // 0: absolute velocity projectiles (like Quake)
+ // 1: relative velocity projectiles, "Newtonian" (like Tribes 2)
+ // 2: relative velocity projectiles, but aim is precorrected so projectiles hit the crosshair (note: strafe rockets then are SLOWER than ones shot while standing, happens in 1 too when aiming correctly which is hard)
+ set g_projectiles_newton_style_2_minfactor 0.8
+ set g_projectiles_newton_style_2_maxfactor 1.5
+ set g_projectiles_spread_style 7
+ // possible values:
+ // 0: forward + solid sphere (like Quake) - varies velocity
+ // 1: forward + flattened solid sphere
+ // 2: forward + solid circle
+ // 3: forward + normal distribution 3D - varies velocity
+ // 4: forward + normal distribution on a plane
+ // 5: forward + circle with 1-r falloff
+ // 6: forward + circle with 1-r^2 falloff
+ // 7: forward + circle with (1-r)(2-r) falloff
+ set g_balance_falldamage_deadminspeed 250
+ set g_balance_falldamage_minspeed 900
+ set g_balance_falldamage_factor 0.20
+ set g_balance_falldamage_maxdamage 40
+ set g_balance_damagepush_speedfactor 2.5
+ set g_balance_contents_damagerate 0.2 // ticrate interval for applying damage with playerdamage/projectiledamage
+ set g_balance_contents_drowndelay 10 // time under water before a player begins drowning
+ set g_balance_contents_playerdamage_drowning 20 // damage per second for while player is drowning
+ set g_balance_contents_playerdamage_lava 50 // damage per second for while player is inside lava
+ set g_balance_contents_playerdamage_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.25 // only 1/4th damage is taken
+ 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_attenuation 2 "jetpack sound attenuation"
+ 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
+ // }}}
+ // {{{ weapon properties
+ // {{{ laser
+ set g_balance_laser_primary_damage 25
+ set g_balance_laser_primary_edgedamage 12.5
+ set g_balance_laser_primary_force 300
+ set g_balance_laser_primary_radius 70
+ set g_balance_laser_primary_speed 6000
+ set g_balance_laser_primary_spread 0
+ set g_balance_laser_primary_refire 0.7
+ set g_balance_laser_primary_animtime 0.2
+ set g_balance_laser_primary_lifetime 5
+ set g_balance_laser_primary_shotangle 0
+ set g_balance_laser_primary_delay 0
+ set g_balance_laser_primary_gauntlet 0
+ set g_balance_laser_primary_force_zscale 1.2
+ set g_balance_laser_primary_force_velocitybias 0
+ set g_balance_laser_primary_force_other_scale 1
+ set g_balance_laser_secondary 0 // when 1, a secondary laser mode exists
+ set g_balance_laser_secondary_damage 25
+ set g_balance_laser_secondary_edgedamage 12.5
+ set g_balance_laser_secondary_force 400
+ set g_balance_laser_secondary_radius 70
+ set g_balance_laser_secondary_speed 12000
+ set g_balance_laser_secondary_spread 0
+ set g_balance_laser_secondary_refire 0.7
+ set g_balance_laser_secondary_animtime 0.2
+ set g_balance_laser_secondary_lifetime 5
+ set g_balance_laser_secondary_shotangle -90
+ set g_balance_laser_secondary_delay 0
+ set g_balance_laser_secondary_gauntlet 0
+ set g_balance_laser_secondary_force_zscale 1.25
+ set g_balance_laser_secondary_force_velocitybias 0
+ set g_balance_laser_secondary_force_other_scale 1
+ set g_balance_laser_switchdelay_drop 0.15
+ set g_balance_laser_switchdelay_raise 0.15
+ set g_balance_laser_reload_ammo 0 //default: 6
+ set g_balance_laser_reload_time 2
+ // }}}
+ // {{{ shotgun
+ set g_balance_shotgun_primary_bullets 14
+ set g_balance_shotgun_primary_damage 4
+ set g_balance_shotgun_primary_force 15
+ set g_balance_shotgun_primary_spread 0.12
+ set g_balance_shotgun_primary_refire 0.75
+ set g_balance_shotgun_primary_animtime 0.2
+ set g_balance_shotgun_primary_ammo 1
+ set g_balance_shotgun_primary_speed 8000
+ set g_balance_shotgun_primary_bulletconstant 75 // 3.8qu
+ set g_balance_shotgun_secondary 1
+ set g_balance_shotgun_secondary_melee_delay 0.25 // 0.35 was too slow
+ 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_melee_no_doubleslap 1
+ set g_balance_shotgun_secondary_melee_nonplayerdamage 40
+ set g_balance_shotgun_secondary_melee_multihit 1
+ set g_balance_shotgun_secondary_damage 80
+ set g_balance_shotgun_secondary_force 200
+ set g_balance_shotgun_secondary_refire 1.25
+ set g_balance_shotgun_secondary_animtime 1
+ set g_balance_shotgun_switchdelay_drop 0.2
+ set g_balance_shotgun_switchdelay_raise 0.2
+ set g_balance_shotgun_reload_ammo 0 //default: 5
+ set g_balance_shotgun_reload_time 2
+ // }}}
+ // {{{ uzi
+ set g_balance_uzi_mode 1                              // Activates varible spread for sustained & burst mode secondary
+ set g_balance_uzi_spread_min 0.02
+ set g_balance_uzi_spread_max 0.05
+ set g_balance_uzi_spread_add 0.012
+ set g_balance_uzi_burst 3                             // # of bullets in a burst (if set to 2 or more)
+ set g_balance_uzi_burst_animtime 0.3
+ set g_balance_uzi_burst_refire 0.06           // refire between burst bullets
+ set g_balance_uzi_burst_refire2 0.45  // refire after burst
+ set g_balance_uzi_burst_spread 0.02
+ set g_balance_uzi_burst_damage 25             
+ set g_balance_uzi_burst_force 20
+ set g_balance_uzi_burst_ammo 3
+ set g_balance_uzi_first 1
+ set g_balance_uzi_first_damage 14
+ set g_balance_uzi_first_force 5
+ set g_balance_uzi_first_spread 0.03
+ set g_balance_uzi_first_refire 0.125
+ set g_balance_uzi_first_ammo 1
+ set g_balance_uzi_sustained_damage 10 // 100 dps
+ set g_balance_uzi_sustained_force 5
+ set g_balance_uzi_sustained_spread 0.03
+ set g_balance_uzi_sustained_refire 0.1
+ set g_balance_uzi_sustained_ammo 1
+ set g_balance_uzi_speed 18000
+ set g_balance_uzi_bulletconstant 115 // 13.1qu
+ set g_balance_uzi_switchdelay_drop 0.2
+ set g_balance_uzi_switchdelay_raise 0.2
+ set g_balance_uzi_reload_ammo 60 //default: 30
+ set g_balance_uzi_reload_time 2
+ // }}}
+ // {{{ mortar
+ set g_balance_grenadelauncher_primary_type 0
+ set g_balance_grenadelauncher_primary_damage 50
+ set g_balance_grenadelauncher_primary_edgedamage 25
+ set g_balance_grenadelauncher_primary_force 250
+ set g_balance_grenadelauncher_primary_radius 120
+ set g_balance_grenadelauncher_primary_speed 1900
+ set g_balance_grenadelauncher_primary_speed_up 225
+ set g_balance_grenadelauncher_primary_speed_z 0
+ set g_balance_grenadelauncher_primary_spread 0
+ set g_balance_grenadelauncher_primary_lifetime 5
+ set g_balance_grenadelauncher_primary_lifetime2 1
+ set g_balance_grenadelauncher_primary_refire 0.8
+ set g_balance_grenadelauncher_primary_animtime 0.3
+ set g_balance_grenadelauncher_primary_ammo 2
+ set g_balance_grenadelauncher_primary_health 15
+ set g_balance_grenadelauncher_primary_damageforcescale 0
+ set g_balance_grenadelauncher_primary_remote_minbouncecnt 0
+ set g_balance_grenadelauncher_secondary_type 1
+ set g_balance_grenadelauncher_secondary_damage 60
+ set g_balance_grenadelauncher_secondary_edgedamage 30
+ set g_balance_grenadelauncher_secondary_force 250
+ set g_balance_grenadelauncher_secondary_radius 120
+ set g_balance_grenadelauncher_secondary_speed 1400
+ set g_balance_grenadelauncher_secondary_speed_up 150
+ set g_balance_grenadelauncher_secondary_speed_z 0
+ set g_balance_grenadelauncher_secondary_spread 0
+ set g_balance_grenadelauncher_secondary_lifetime 5
+ set g_balance_grenadelauncher_secondary_lifetime_bounce 0.5
+ set g_balance_grenadelauncher_secondary_lifetime_stick 0
+ set g_balance_grenadelauncher_secondary_refire 0.7
+ set g_balance_grenadelauncher_secondary_animtime 0.3
+ set g_balance_grenadelauncher_secondary_ammo 2
+ set g_balance_grenadelauncher_secondary_health 30
+ set g_balance_grenadelauncher_secondary_damageforcescale 4
+ set g_balance_grenadelauncher_secondary_remote_detonateprimary 0
+ set g_balance_grenadelauncher_bouncefactor 0.5
+ set g_balance_grenadelauncher_bouncestop 0.075
+ set g_balance_grenadelauncher_switchdelay_drop 0.2
+ set g_balance_grenadelauncher_switchdelay_raise 0.2
+ set g_balance_grenadelauncher_reload_ammo 0 //default: 12
+ set g_balance_grenadelauncher_reload_time 2
+ // }}}
+ // {{{ electro
+ set g_balance_electro_lightning 0
+ 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_force_up 0
+ set g_balance_electro_primary_radius 100
+ set g_balance_electro_primary_comboradius 200
+ set g_balance_electro_primary_speed 2500
+ set g_balance_electro_primary_spread 0
+ set g_balance_electro_primary_lifetime 5
+ set g_balance_electro_primary_refire 0.6
+ set g_balance_electro_primary_animtime 0.3
+ set g_balance_electro_primary_ammo 4
+ set g_balance_electro_primary_range 0
+ set g_balance_electro_primary_falloff_mindist 255 // 0.3 * radius
+ set g_balance_electro_primary_falloff_maxdist 850
+ set g_balance_electro_primary_falloff_halflifedist 425
+ set g_balance_electro_secondary_damage 40
+ set g_balance_electro_secondary_edgedamage 20
+ set g_balance_electro_secondary_force 50
+ set g_balance_electro_secondary_radius 150
+ 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.04
+ set g_balance_electro_secondary_lifetime 4
+ set g_balance_electro_secondary_refire 0.2
+ set g_balance_electro_secondary_refire2 1.6
+ set g_balance_electro_secondary_animtime 0.2
+ set g_balance_electro_secondary_ammo 2
+ set g_balance_electro_secondary_health 5
+ set g_balance_electro_secondary_damageforcescale 4
+ set g_balance_electro_secondary_damagedbycontents 1
+ set g_balance_electro_secondary_count 3
+ set g_balance_electro_secondary_bouncefactor 0.3
+ set g_balance_electro_secondary_bouncestop 0.05
+ 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_comboradius 300
+ set g_balance_electro_combo_speed 2000
+ set g_balance_electro_combo_safeammocheck 1
+ set g_balance_electro_switchdelay_drop 0.2
+ set g_balance_electro_switchdelay_raise 0.2
+ set g_balance_electro_reload_ammo 0 //default: 20
+ set g_balance_electro_reload_time 2
+ // }}}
++// {{{ lightning
++set g_balance_lightning_primary_ammo 5
++set g_balance_lightning_primary_animtime 0.2
++set g_balance_lightning_primary_damage 100
++set g_balance_lightning_primary_edgedamage 0
++set g_balance_lightning_primary_falloff_mindist 0
++set g_balance_lightning_primary_falloff_maxdist 0
++set g_balance_lightning_primary_falloff_halflifedist 0
++set g_balance_lightning_primary_force 425
++set g_balance_lightning_primary_lifetime 0
++set g_balance_lightning_primary_radius 850
++set g_balance_lightning_primary_range 800
++set g_balance_lightning_primary_refire 0.4
++set g_balance_lightning_primary_speed 0
++set g_balance_lightning_primary_spread 0
++set g_balance_lightning_secondary_ammo 5
++set g_balance_lightning_secondary_animtime 0.5
++set g_balance_lightning_secondary_damage 100
++set g_balance_lightning_secondary_damageforcescale 4
++set g_balance_lightning_secondary_edgedamage 80
++set g_balance_lightning_secondary_flyingdamage 1
++set g_balance_lightning_secondary_flyingforce -80
++set g_balance_lightning_secondary_flyingradius 200
++set g_balance_lightning_secondary_force -200
++set g_balance_lightning_secondary_health 1
++set g_balance_lightning_secondary_lifetime 30
++set g_balance_lightning_secondary_radius 300
++set g_balance_lightning_secondary_refire 5
++set g_balance_lightning_secondary_speed 600
++// }}}
+ // {{{ crylink 
+ set g_balance_crylink_primary_damage 12
+ set g_balance_crylink_primary_edgedamage 6
+ set g_balance_crylink_primary_force -50
+ set g_balance_crylink_primary_radius 80
+ set g_balance_crylink_primary_speed 2000
+ set g_balance_crylink_primary_spread 0.08
+ set g_balance_crylink_primary_shots 6
+ set g_balance_crylink_primary_bounces 1
+ set g_balance_crylink_primary_refire 0.7
+ set g_balance_crylink_primary_animtime 0.3
+ set g_balance_crylink_primary_ammo 3
+ set g_balance_crylink_primary_bouncedamagefactor 0.5
+ set g_balance_crylink_primary_joindelay 0.1
+ set g_balance_crylink_primary_joinspread 0.2
+ set g_balance_crylink_primary_jointime 0
+ 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_radius 0
+ set g_balance_crylink_primary_joinexplode_force 0
+ set g_balance_crylink_primary_linkexplode 1
+ set g_balance_crylink_primary_middle_lifetime 5 // range: 35000 full, fades to 70000
+ set g_balance_crylink_primary_middle_fadetime 5
+ set g_balance_crylink_primary_other_lifetime 5 
+ set g_balance_crylink_primary_other_fadetime 5
+ set g_balance_crylink_secondary 1
+ set g_balance_crylink_secondary_damage 10
+ set g_balance_crylink_secondary_edgedamage 5
+ set g_balance_crylink_secondary_force -250
+ set g_balance_crylink_secondary_radius 100
+ set g_balance_crylink_secondary_speed 3000
+ set g_balance_crylink_secondary_spread 0.01
+ set g_balance_crylink_secondary_spreadtype 1
+ set g_balance_crylink_secondary_shots 5
+ set g_balance_crylink_secondary_bounces 0
+ set g_balance_crylink_secondary_refire 0.7
+ set g_balance_crylink_secondary_animtime 0.2
+ set g_balance_crylink_secondary_ammo 2
+ set g_balance_crylink_secondary_bouncedamagefactor 0.5
+ set g_balance_crylink_secondary_joindelay 0
+ set g_balance_crylink_secondary_joinspread 0
+ set g_balance_crylink_secondary_jointime 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_radius 0
+ set g_balance_crylink_secondary_joinexplode_force 0
+ set g_balance_crylink_secondary_linkexplode 1
+ set g_balance_crylink_secondary_middle_lifetime 5 // range: 35000 full, fades to 70000
+ set g_balance_crylink_secondary_middle_fadetime 5
+ set g_balance_crylink_secondary_line_lifetime 5 
+ set g_balance_crylink_secondary_line_fadetime 5
+ set g_balance_crylink_switchdelay_drop 0.2
+ set g_balance_crylink_switchdelay_raise 0.2
+ set g_balance_crylink_reload_ammo 0 //default: 10
+ set g_balance_crylink_reload_time 2
+ // }}}
+ // {{{ nex
+ set g_balance_nex_primary_damage 80
+ set g_balance_nex_primary_force 400
+ set g_balance_nex_primary_refire 1.5
+ set g_balance_nex_primary_animtime 0.6
+ set g_balance_nex_primary_ammo 6
+ set g_balance_nex_primary_damagefalloff_mindist 0 // 1000    For tZork ;3
+ set g_balance_nex_primary_damagefalloff_maxdist 0 // 3000
+ set g_balance_nex_primary_damagefalloff_halflife 0 // 1500
+ set g_balance_nex_primary_damagefalloff_forcehalflife 0 // 1500
+ set g_balance_nex_secondary 0
+ set g_balance_nex_secondary_charge 0
+ set g_balance_nex_secondary_charge_rate 0.1
+ set g_balance_nex_secondary_chargepool 0
+ set g_balance_nex_secondary_chargepool_regen 0.15
+ set g_balance_nex_secondary_chargepool_pause_regen 1
+ set g_balance_nex_secondary_chargepool_pause_health_regen 1
+ set g_balance_nex_secondary_damage 0
+ set g_balance_nex_secondary_force 0
+ set g_balance_nex_secondary_refire 0
+ set g_balance_nex_secondary_animtime 0
+ set g_balance_nex_secondary_ammo 2
+ set g_balance_nex_secondary_damagefalloff_mindist 0
+ set g_balance_nex_secondary_damagefalloff_maxdist 0
+ set g_balance_nex_secondary_damagefalloff_halflife 0
+ set g_balance_nex_secondary_damagefalloff_forcehalflife 0
+ set g_balance_nex_charge 1
+ set g_balance_nex_charge_mindmg 40
+ set g_balance_nex_charge_start 0.5
+ set g_balance_nex_charge_rate 0.4
+ set g_balance_nex_charge_animlimit 0.5
+ set g_balance_nex_charge_limit 1
+ set g_balance_nex_charge_rot_rate 0
+ set g_balance_nex_charge_rot_pause 0 // Dont rot down until this long after release of charge button
+ set g_balance_nex_charge_shot_multiplier 0
+ set g_balance_nex_charge_velocity_rate 0
+ set g_balance_nex_charge_minspeed 400
+ set g_balance_nex_charge_maxspeed 800
+ set g_balance_nex_switchdelay_drop 0.3
+ set g_balance_nex_switchdelay_raise 0.3
+ set g_balance_nex_reload_ammo 0 //default: 25
+ set g_balance_nex_reload_time 2
+ // }}}
+ // {{{ minstanex
+ set g_balance_minstanex_refire 1
+ set g_balance_minstanex_animtime 0.3
+ set g_balance_minstanex_ammo 10
+ set g_balance_minstanex_laser_ammo 0
+ set g_balance_minstanex_laser_animtime 0.3
+ set g_balance_minstanex_laser_refire 0.7
+ set g_balance_minstanex_switchdelay_drop 0.2
+ set g_balance_minstanex_switchdelay_raise 0.2
+ set g_balance_minstanex_reload_ammo 0 //default: 50
+ set g_balance_minstanex_reload_time 2
+ // }}}
+ // {{{ hagar
+ set g_balance_hagar_primary_damage 25
+ 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_damageforcescale 0
+ set g_balance_hagar_primary_radius 65
+ set g_balance_hagar_primary_spread 0.03
+ set g_balance_hagar_primary_speed 2500
+ set g_balance_hagar_primary_lifetime 5
+ set g_balance_hagar_primary_refire 0.16667 // 6 rockets per second
+ set g_balance_hagar_primary_ammo 1
+ set g_balance_hagar_secondary 1
+ set g_balance_hagar_secondary_load 1
+ 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_load_max 4
+ set g_balance_hagar_secondary_load_hold 4
+ set g_balance_hagar_secondary_load_releasedeath 0
+ set g_balance_hagar_secondary_load_abort 0
+ set g_balance_hagar_secondary_load_linkexplode 0
+ set g_balance_hagar_secondary_load_animtime 0.2
+ set g_balance_hagar_secondary_damage 40
+ set g_balance_hagar_secondary_edgedamage 20
+ set g_balance_hagar_secondary_force 75
+ set g_balance_hagar_secondary_health 15
+ set g_balance_hagar_secondary_damageforcescale 0
+ set g_balance_hagar_secondary_radius 80
+ set g_balance_hagar_secondary_spread 0.05
+ set g_balance_hagar_secondary_speed 2000
+ set g_balance_hagar_secondary_lifetime_min 10
+ set g_balance_hagar_secondary_lifetime_rand 0
+ set g_balance_hagar_secondary_refire 0.5
+ set g_balance_hagar_secondary_ammo 1
+ set g_balance_hagar_switchdelay_drop 0.2
+ set g_balance_hagar_switchdelay_raise 0.2
+ set g_balance_hagar_reload_ammo 0 //default: 25
+ set g_balance_hagar_reload_time 2
+ // }}}
+ // {{{ rocketlauncher
+ set g_balance_rocketlauncher_damage 80
+ set g_balance_rocketlauncher_edgedamage 40
+ set g_balance_rocketlauncher_force 450
+ set g_balance_rocketlauncher_radius 110
+ set g_balance_rocketlauncher_speed 1300
+ set g_balance_rocketlauncher_speedaccel 1300
+ set g_balance_rocketlauncher_speedstart 1000
+ set g_balance_rocketlauncher_lifetime 10
+ set g_balance_rocketlauncher_refire 1.1
+ set g_balance_rocketlauncher_animtime 0.4
+ set g_balance_rocketlauncher_ammo 4
+ set g_balance_rocketlauncher_health 30 // 30 // 5 hitpoints above maximum laser value -- this way lasers can't blow it up, but grenadelauncher still can most the time.
+ set g_balance_rocketlauncher_damageforcescale 1 // low damage force scale so that it can still be affected by other hits, but not so much that it does a 90 degree turn
+ set g_balance_rocketlauncher_detonatedelay 0.02 // positive: timer till detonation is allowed, negative: "security device" that prevents ANY remote detonation if it could hurt its owner, zero: detonatable at any time
+ set g_balance_rocketlauncher_guiderate 90 // max degrees per second
+ set g_balance_rocketlauncher_guideratedelay 0.01 // immediate
+ set g_balance_rocketlauncher_guidegoal 512 // goal distance for (non-laser) guiding (higher = less control, lower = erratic)
+ set g_balance_rocketlauncher_guidedelay 0.2 // delay before guiding kicks in
+ set g_balance_rocketlauncher_guidestop 0 // stop guiding when firing again
+ set g_balance_rocketlauncher_remote_damage 70
+ set g_balance_rocketlauncher_remote_edgedamage 35
+ set g_balance_rocketlauncher_remote_radius 110
+ set g_balance_rocketlauncher_remote_force 400
+ set g_balance_rocketlauncher_switchdelay_drop 0.2
+ set g_balance_rocketlauncher_switchdelay_raise 0.2
+ set g_balance_rocketlauncher_reload_ammo 0 //default: 25
+ set g_balance_rocketlauncher_reload_time 2
+ // }}}
+ // {{{ porto
+ set g_balance_porto_primary_refire 1.5
+ set g_balance_porto_primary_animtime 0.3
+ set g_balance_porto_primary_speed 1000
+ set g_balance_porto_primary_lifetime 5
+ set g_balance_porto_secondary 1
+ set g_balance_porto_secondary_refire 1.5
+ set g_balance_porto_secondary_animtime 0.3
+ set g_balance_porto_secondary_speed 1000
+ set g_balance_porto_secondary_lifetime 5
+ set g_balance_porto_switchdelay_drop 0.2
+ set g_balance_porto_switchdelay_raise 0.2
+ 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
+ // }}}
+ // {{{ hook
+ set g_balance_hook_primary_fuel 5 // hook monkeys set 0
+ set g_balance_hook_primary_refire 0 // hook monkeys set 0
+ set g_balance_hook_primary_animtime 0.3 // good shoot anim
+ set g_balance_hook_primary_hooked_time_max 0 // infinite
+ set g_balance_hook_primary_hooked_time_free 2 // 2s being hooked are free
+ set g_balance_hook_primary_hooked_fuel 5 // fuel per second hooked
+ set g_balance_hook_secondary_damage 25 // not much
+ set g_balance_hook_secondary_edgedamage 5 // not much
+ set g_balance_hook_secondary_radius 500 // LOTS
+ set g_balance_hook_secondary_force -2000 // LOTS
+ set g_balance_hook_secondary_ammo 30 // a whole pack
+ set g_balance_hook_secondary_lifetime 5 // infinite
+ set g_balance_hook_secondary_speed 0 // not much throwing
+ set g_balance_hook_secondary_gravity 5 // fast falling
+ set g_balance_hook_secondary_refire 3 // don't drop too many bombs...
+ set g_balance_hook_secondary_animtime 0.3 // good shoot anim
+ set g_balance_hook_secondary_power 3 // effect behaves like a square function
+ set g_balance_hook_secondary_duration 1.5 // effect runs for three seconds
+ set g_balance_hook_secondary_health 15
+ set g_balance_hook_secondary_damageforcescale 0
+ set g_balance_hook_switchdelay_drop 0.2
+ set g_balance_hook_switchdelay_raise 0.2
+ // }}}
+ // {{{ tuba
+ set g_balance_tuba_refire 0.05
+ set g_balance_tuba_animtime 0.05
+ set g_balance_tuba_attenuation 0.5
+ set g_balance_tuba_volume 1
+ set g_balance_tuba_fadetime 0.25
+ set g_balance_tuba_damage 5
+ set g_balance_tuba_edgedamage 0
+ set g_balance_tuba_radius 200
+ set g_balance_tuba_force 40
+ set g_balance_tuba_pitchstep 6
+ set g_balance_tuba_switchdelay_drop 0.2
+ set g_balance_tuba_switchdelay_raise 0.2
+ // }}}
+ // {{{ fireball // this is a superweapon -- lets make it behave as one. 
+ set g_balance_fireball_primary_animtime 0.2
+ 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_force 100
+ 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
+ // }}}
diff --combined balanceXonotic.cfg
index 60526282a74a19bfaf3ae5e467a34cfd29c198fd,ca9d32c1dddcce2c588bbdf4fe2ad369d13f4182..60a746c17304b9a11794aadb7d0c966bc38958b0
@@@ -1,51 -1,49 +1,49 @@@
+ g_mod_balance Xonotic
  // {{{ starting gear
- set g_start_weapon_laser -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
- set g_start_weapon_shotgun -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
- set g_start_weapon_uzi -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
- set g_start_weapon_grenadelauncher -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
- set g_start_weapon_minelayer -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
- set g_start_weapon_electro -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
- set g_start_weapon_crylink -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
- set g_start_weapon_nex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
- set g_start_weapon_hagar -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
- set g_start_weapon_rocketlauncher -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
- set g_start_weapon_minstanex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
- set g_start_weapon_porto -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
- set g_start_weapon_hook -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
- set g_start_weapon_hlac -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
- set g_start_weapon_sniperrifle -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
- set g_start_weapon_tuba -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
- set g_start_weapon_fireball -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
- set g_start_weapon_seeker -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
- set g_balance_health_start 125
+ set g_start_weapon_laser -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
+ set g_start_weapon_shotgun -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
+ set g_start_weapon_uzi -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
+ set g_start_weapon_grenadelauncher -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
+ set g_start_weapon_electro -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
+ set g_start_weapon_crylink -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
+ set g_start_weapon_nex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
+ set g_start_weapon_hagar -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default" // UNTIL IT CAN BE REMOVED FROM CODE
+ set g_start_weapon_rocketlauncher -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
+ set g_start_weapon_minstanex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
+ set g_start_weapon_porto -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
+ set g_start_weapon_hook -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
+ set g_start_weapon_tuba -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
+ set g_start_weapon_fireball -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
+ set g_balance_health_start 100
  set g_balance_armor_start 0
- set g_start_ammo_shells 20
+ 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_fuel 0
- set g_warmup_start_health 200 "starting values when being in warmup-stage"
+ 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 50 "starting values when being in warmup-stage"
- set g_warmup_start_ammo_nails 150 "starting values when being in warmup-stage"
- set g_warmup_start_ammo_rockets 50 "starting values when being in warmup-stage"
- set g_warmup_start_ammo_cells 50 "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_fuel 0 "starting values when being in warmup-stage"
  set g_lms_start_health 200
- set g_lms_start_armor 100
- set g_lms_start_ammo_shells 30
- set g_lms_start_ammo_nails 200
- set g_lms_start_ammo_rockets 150
- set g_lms_start_ammo_cells 150
+ 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_fuel 0
  set g_balance_nix_roundtime 25
  set g_balance_nix_incrtime 1.6
- set g_balance_nix_ammo_shells 15
- set g_balance_nix_ammo_nails 45
- set g_balance_nix_ammo_rockets 15
- set g_balance_nix_ammo_cells 15
+ 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_fuel 0
- set g_balance_nix_ammoincr_shells 2
+ 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
@@@ -55,82 -53,84 +53,84 @@@ set g_balance_nix_ammoincr_fuel 
  // {{{ pickup items
  set g_pickup_ammo_anyway 1
  set g_pickup_weapons_anyway 1
- set g_pickup_shells 20
- set g_pickup_shells_weapon 10
- set g_pickup_shells_max 45
- set g_pickup_nails 120
- set g_pickup_nails_weapon 60
- set g_pickup_nails_max 300
- set g_pickup_rockets 25
- set g_pickup_rockets_weapon 15
- set g_pickup_rockets_max 150
+ 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 20
- set g_pickup_cells_max 150
- set g_pickup_fuel 25
- set g_pickup_fuel_weapon 15
- set g_pickup_fuel_jetpack 50
+ set g_pickup_cells_weapon 30
+ set g_pickup_cells_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 150
+ set g_pickup_armorsmall_max 200
  set g_pickup_armorsmall_anyway 1
  set g_pickup_armormedium 25
- set g_pickup_armormedium_max 50
- set g_pickup_armormedium_anyway 0
+ set g_pickup_armormedium_max 200
+ set g_pickup_armormedium_anyway 1
  set g_pickup_armorbig 50
- set g_pickup_armorbig_max 75; // LOG: to allow a little more armor from medium armor
- set g_pickup_armorbig_anyway 0
+ set g_pickup_armorbig_max 200
+ set g_pickup_armorbig_anyway 1
  set g_pickup_armorlarge 100
- set g_pickup_armorlarge_max 150
+ set g_pickup_armorlarge_max 200
  set g_pickup_armorlarge_anyway 1
  set g_pickup_healthsmall 5
- set g_pickup_healthsmall_max 250
+ set g_pickup_healthsmall_max 200
  set g_pickup_healthsmall_anyway 1
  set g_pickup_healthmedium 25
- set g_pickup_healthmedium_max 100
- set g_pickup_healthmedium_anyway 0
+ set g_pickup_healthmedium_max 200
+ set g_pickup_healthmedium_anyway 1
  set g_pickup_healthlarge 50
- set g_pickup_healthlarge_max 150
- set g_pickup_healthlarge_anyway 0
+ set g_pickup_healthlarge_max 200
+ set g_pickup_healthlarge_anyway 1
  set g_pickup_healthmega 100
- set g_pickup_healthmega_max 250
+ 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_ammo 25
+ set g_pickup_respawntime_superweapon 120
+ set g_pickup_respawntime_ammo 10
  set g_pickup_respawntimejitter_short 0
  set g_pickup_respawntimejitter_medium 0
  set g_pickup_respawntimejitter_long 0
- set g_pickup_respawntimejitter_powerup 10
+ set g_pickup_respawntimejitter_powerup 30
  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.05
- set g_balance_health_regenlinear 0
+ 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
- set g_balance_health_rotlinear 1
+ set g_balance_health_rot 0.04
+ set g_balance_health_rotlinear 0.75
  set g_balance_pause_health_rot 1
- set g_balance_pause_health_rot_spawn 0
+ 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 999
  set g_balance_armor_regen 0
  set g_balance_armor_regenlinear 0
- set g_balance_armor_rot 0
- set g_balance_armor_rotlinear 1
+ set g_balance_armor_rot 0.04
+ set g_balance_armor_rotlinear 0.75
  set g_balance_pause_armor_rot 1
- set g_balance_pause_armor_rot_spawn 0
+ 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 999
- set g_balance_armor_blockpercent 0.7
+ set g_balance_armor_blockpercent 0.6
  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
@@@ -145,7 -145,6 +145,6 @@@ set g_balance_fuel_limit 99
  
  // {{{ misc
  set g_balance_selfdamagepercent 0.65
- set g_balance_weaponswitchdelay 0.15
  set g_weaponspeedfactor 1 "weapon projectile speed multiplier"
  set g_weaponratefactor 1 "weapon fire rate multiplier"
  set g_weapondamagefactor 1 "weapon damage multiplier"
@@@ -153,17 -152,23 +152,23 @@@ set g_weaponforcefactor 1 "weapon forc
  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.7
- set g_throughfloor_force 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 0
  set g_projectiles_newton_style 2
  // 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)
- // 3: absolute velocity + player velocity component in shot direction (note: does NOT yield the right relative velocity, but may be good enough, but it is somewhat prone to sniper rockets)
- // 4: just add the player velocity length to the absolute velocity (tZork's sniper rockets)
- set g_projectiles_newton_style_2_minfactor 0.7
- set g_projectiles_newton_style_2_maxfactor 5
+ 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
  // 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 150
- set g_balance_falldamage_minspeed 800
+ set g_balance_falldamage_deadminspeed 250
+ set g_balance_falldamage_minspeed 900
  set g_balance_falldamage_factor 0.20
- set g_balance_falldamage_maxdamage 15
+ set g_balance_falldamage_maxdamage 40
+ set g_balance_damagepush_speedfactor 2.5
+ set g_balance_contents_damagerate 0.2 // ticrate interval for applying damage with playerdamage/projectiledamage
+ set g_balance_contents_drowndelay 10 // time under water before a player begins drowning
+ set g_balance_contents_playerdamage_drowning 20 // damage per second for while player is drowning
+ set g_balance_contents_playerdamage_lava 50 // damage per second for while player is inside lava
+ set g_balance_contents_playerdamage_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.6
+ set g_balance_powerup_invincible_takedamage 0.25 // only 1/4th damage is taken
  set g_balance_powerup_invincible_time 30
  set g_balance_powerup_strength_damage 3
- set g_balance_powerup_strength_force 4
+ 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 1500 "max speed of the jetpack in xy direction"
+ 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_attenuation 2 "jetpack sound attenuation"
@@@ -207,391 -221,420 +221,450 @@@ set g_balance_grapplehook_force_rubber_
  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 130
+ set g_balance_grapplehook_health 50
+ set g_balance_grapplehook_damagedbycontents 1
  // }}}
  
  // {{{ weapon properties
  // {{{ laser
- set g_balance_laser_primary_damage 20 // dps 33, hope that's not too high
- set g_balance_laser_primary_edgedamage 20
- set g_balance_laser_primary_force 150 // this looks insanely low, but actually isn't with zscale and velocitybias
- set g_balance_laser_primary_radius 60
- set g_balance_laser_primary_speed 5000
+ set g_balance_laser_primary_damage 25
+ set g_balance_laser_primary_edgedamage 12.5
+ set g_balance_laser_primary_force 300
+ set g_balance_laser_primary_radius 70
+ set g_balance_laser_primary_speed 6000
  set g_balance_laser_primary_spread 0
- set g_balance_laser_primary_refire 0.6
- set g_balance_laser_primary_animtime 0.4
+ set g_balance_laser_primary_refire 0.7
+ set g_balance_laser_primary_animtime 0.2
  set g_balance_laser_primary_lifetime 5
  set g_balance_laser_primary_shotangle 0
  set g_balance_laser_primary_delay 0
  set g_balance_laser_primary_gauntlet 0
- set g_balance_laser_primary_force_zscale 2 // 300 upforce
- set g_balance_laser_primary_force_velocitybias 0.3
- set g_balance_laser_primary_force_other_scale 2.5 // force 375 when pushing others around
+ set g_balance_laser_primary_force_zscale 1.2
+ set g_balance_laser_primary_force_velocitybias 0
+ set g_balance_laser_primary_force_other_scale 1
  set g_balance_laser_secondary 0 // when 1, a secondary laser mode exists
- set g_balance_laser_secondary_damage 200 // dps
- set g_balance_laser_secondary_edgedamage 0
- set g_balance_laser_secondary_force 1300
- set g_balance_laser_secondary_radius 60
- set g_balance_laser_secondary_speed 0
+ set g_balance_laser_secondary_damage 25
+ set g_balance_laser_secondary_edgedamage 12.5
+ set g_balance_laser_secondary_force 400
+ set g_balance_laser_secondary_radius 70
+ set g_balance_laser_secondary_speed 12000
  set g_balance_laser_secondary_spread 0
- set g_balance_laser_secondary_refire 0.066
- set g_balance_laser_secondary_animtime 0.066
- set g_balance_laser_secondary_lifetime 0
- set g_balance_laser_secondary_shotangle 0
+ set g_balance_laser_secondary_refire 0.7
+ set g_balance_laser_secondary_animtime 0.2
+ set g_balance_laser_secondary_lifetime 5
+ set g_balance_laser_secondary_shotangle -90
  set g_balance_laser_secondary_delay 0
- set g_balance_laser_secondary_gauntlet 1
+ set g_balance_laser_secondary_gauntlet 0
  set g_balance_laser_secondary_force_zscale 1.25
  set g_balance_laser_secondary_force_velocitybias 0
- set g_balance_laser_secondary_force_other_scale 0
+ set g_balance_laser_secondary_force_other_scale 1
+ set g_balance_laser_switchdelay_drop 0.15
+ set g_balance_laser_switchdelay_raise 0.15
+ set g_balance_laser_reload_ammo 0 //default: 6
+ set g_balance_laser_reload_time 2
  // }}}
  // {{{ shotgun
- set g_balance_shotgun_primary_bullets 18
- set g_balance_shotgun_primary_damage 3.5 // LOG: changed from 4 to 3.5, total damage 63
- set g_balance_shotgun_primary_force 20
- set g_balance_shotgun_primary_spread 0.16 // LOG: changed from 0.18 -> 0.16 to compensate a little for lower damage
- set g_balance_shotgun_primary_refire 1
- set g_balance_shotgun_primary_animtime 0.3
+ set g_balance_shotgun_primary_bullets 14
+ set g_balance_shotgun_primary_damage 4
+ set g_balance_shotgun_primary_force 15
+ set g_balance_shotgun_primary_spread 0.12
+ set g_balance_shotgun_primary_refire 0.75
+ set g_balance_shotgun_primary_animtime 0.2
  set g_balance_shotgun_primary_ammo 1
- set g_balance_shotgun_primary_speed 12000
+ set g_balance_shotgun_primary_speed 8000
  set g_balance_shotgun_primary_bulletconstant 75 // 3.8qu
  set g_balance_shotgun_secondary 1
- set g_balance_shotgun_secondary_melee_delay 0.35 // match the anim
- set g_balance_shotgun_secondary_melee_range 85
- set g_balance_shotgun_secondary_melee_swing 50
- set g_balance_shotgun_secondary_melee_time 0.1
- set g_balance_shotgun_secondary_damage 110
- set g_balance_shotgun_secondary_force 150
- set g_balance_shotgun_secondary_refire 1.1
+ set g_balance_shotgun_secondary_melee_delay 0.25 // 0.35 was too slow
+ 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_melee_no_doubleslap 1
+ set g_balance_shotgun_secondary_melee_nonplayerdamage 40
+ set g_balance_shotgun_secondary_melee_multihit 1
+ set g_balance_shotgun_secondary_damage 80
+ set g_balance_shotgun_secondary_force 200
+ set g_balance_shotgun_secondary_refire 1.25
  set g_balance_shotgun_secondary_animtime 1
+ set g_balance_shotgun_switchdelay_drop 0.2
+ set g_balance_shotgun_switchdelay_raise 0.2
+ set g_balance_shotgun_reload_ammo 0 //default: 5
+ set g_balance_shotgun_reload_time 2
  // }}}
  // {{{ uzi
  set g_balance_uzi_mode 1                              // Activates varible spread for sustained & burst mode secondary
  set g_balance_uzi_spread_min 0.02
- set g_balance_uzi_spread_max 0.3 // LOG: 0.6 -> 0.3
- set g_balance_uzi_spread_add 0.008
+ set g_balance_uzi_spread_max 0.05
+ set g_balance_uzi_spread_add 0.012
  
  set g_balance_uzi_burst 3                             // # of bullets in a burst (if set to 2 or more)
- set g_balance_uzi_burst_animtime 0.45
- set g_balance_uzi_burst_refire 0.05           // refire between burst bullets
- set g_balance_uzi_burst_refire2 0.45  // refire after burst
- set g_balance_uzi_burst_spread 0.07
- set g_balance_uzi_burst_damage 25
- set g_balance_uzi_burst_force 50
+ set g_balance_uzi_burst_animtime 0.3
+ set g_balance_uzi_burst_refire 0.06           // refire between burst bullets
+ set g_balance_uzi_burst_refire2 0.45  // refire after burst
+ set g_balance_uzi_burst_spread 0.02
+ set g_balance_uzi_burst_damage 25             
+ set g_balance_uzi_burst_force 20
  set g_balance_uzi_burst_ammo 3
  
  set g_balance_uzi_first 1
- set g_balance_uzi_first_damage 15 / f/ LOG: 22 -> 15
- set g_balance_uzi_first_force 50
+ set g_balance_uzi_first_damage 14
+ set g_balance_uzi_first_force 5
  set g_balance_uzi_first_spread 0.03
- set g_balance_uzi_first_refire 0.2
- set g_balance_uzi_first_ammo 2
+ set g_balance_uzi_first_refire 0.125
+ set g_balance_uzi_first_ammo 1
  
- set g_balance_uzi_sustained_damage 12   // 120 dps
- set g_balance_uzi_sustained_force 12
- set g_balance_uzi_sustained_spread 0.06
+ set g_balance_uzi_sustained_damage 10 // 100 dps
+ set g_balance_uzi_sustained_force 5
+ set g_balance_uzi_sustained_spread 0.03
  set g_balance_uzi_sustained_refire 0.1
  set g_balance_uzi_sustained_ammo 1
  
  set g_balance_uzi_speed 18000
  set g_balance_uzi_bulletconstant 115 // 13.1qu
+ set g_balance_uzi_switchdelay_drop 0.2
+ set g_balance_uzi_switchdelay_raise 0.2
+ set g_balance_uzi_reload_ammo 60 //default: 30
+ set g_balance_uzi_reload_time 2
  // }}}
  // {{{ mortar
  set g_balance_grenadelauncher_primary_type 0
- set g_balance_grenadelauncher_primary_damage 44
- set g_balance_grenadelauncher_primary_edgedamage 32
- set g_balance_grenadelauncher_primary_force 300
- set g_balance_grenadelauncher_primary_radius 115
- set g_balance_grenadelauncher_primary_speed 1500
+ set g_balance_grenadelauncher_primary_damage 50
+ set g_balance_grenadelauncher_primary_edgedamage 25
+ set g_balance_grenadelauncher_primary_force 250
+ set g_balance_grenadelauncher_primary_radius 120
+ set g_balance_grenadelauncher_primary_speed 1900
  set g_balance_grenadelauncher_primary_speed_up 225
  set g_balance_grenadelauncher_primary_speed_z 0
  set g_balance_grenadelauncher_primary_spread 0
  set g_balance_grenadelauncher_primary_lifetime 5
- set g_balance_grenadelauncher_primary_lifetime2 0.65
+ set g_balance_grenadelauncher_primary_lifetime2 1
  set g_balance_grenadelauncher_primary_refire 0.8
  set g_balance_grenadelauncher_primary_animtime 0.3
  set g_balance_grenadelauncher_primary_ammo 2
- set g_balance_grenadelauncher_primary_health 80
+ set g_balance_grenadelauncher_primary_health 15
  set g_balance_grenadelauncher_primary_damageforcescale 0
  set g_balance_grenadelauncher_primary_remote_minbouncecnt 0
  
  set g_balance_grenadelauncher_secondary_type 1
- set g_balance_grenadelauncher_secondary_damage 62
- set g_balance_grenadelauncher_secondary_edgedamage 32
- set g_balance_grenadelauncher_secondary_force 300
- set g_balance_grenadelauncher_secondary_radius 150
- set g_balance_grenadelauncher_secondary_speed 1000
- set g_balance_grenadelauncher_secondary_speed_up 250
+ set g_balance_grenadelauncher_secondary_damage 60
+ set g_balance_grenadelauncher_secondary_edgedamage 30
+ set g_balance_grenadelauncher_secondary_force 250
+ set g_balance_grenadelauncher_secondary_radius 120
+ set g_balance_grenadelauncher_secondary_speed 1400
+ set g_balance_grenadelauncher_secondary_speed_up 150
  set g_balance_grenadelauncher_secondary_speed_z 0
  set g_balance_grenadelauncher_secondary_spread 0
- set g_balance_grenadelauncher_secondary_lifetime 3
- set g_balance_grenadelauncher_secondary_lifetime2 0.65
- set g_balance_grenadelauncher_secondary_refire 0.8
+ set g_balance_grenadelauncher_secondary_lifetime 5
+ set g_balance_grenadelauncher_secondary_lifetime_bounce 0.5
+ set g_balance_grenadelauncher_secondary_lifetime_stick 0
+ set g_balance_grenadelauncher_secondary_refire 0.7
  set g_balance_grenadelauncher_secondary_animtime 0.3
  set g_balance_grenadelauncher_secondary_ammo 2
- set g_balance_grenadelauncher_secondary_health 40
- set g_balance_grenadelauncher_secondary_damageforcescale 0
+ set g_balance_grenadelauncher_secondary_health 30
+ set g_balance_grenadelauncher_secondary_damageforcescale 4
  set g_balance_grenadelauncher_secondary_remote_detonateprimary 0
  
  set g_balance_grenadelauncher_bouncefactor 0.5
- set g_balance_grenadelauncher_bouncestop 0.12
- // }}}
- // {{{ minelayer
- set g_balance_minelayer_damage 42
- set g_balance_minelayer_edgedamage 30
- set g_balance_minelayer_force 250
- set g_balance_minelayer_radius 175
- set g_balance_minelayer_proximityradius 150
- set g_balance_minelayer_speed 750
- set g_balance_minelayer_lifetime 60
- set g_balance_minelayer_lifetime_countdown 0
- set g_balance_minelayer_refire 1.5
- set g_balance_minelayer_animtime 0.3
- set g_balance_minelayer_ammo 5
- set g_balance_minelayer_health 15
- set g_balance_minelayer_limit 3 // 0 disables the limit // LOG: 4 -> 3
- set g_balance_minelayer_protection 1 // don't explode if the mine would hurt the owner or a team mate
- set g_balance_minelayer_damageforcescale 0
- set g_balance_minelayer_detonatedelay -1 // positive: timer till detonation is allowed, negative: "security device" that prevents ANY remote detonation if it could hurt its owner, zero: detonatable at any time
- set g_balance_minelayer_time 0.5
- set g_balance_minelayer_remote_damage 45
- set g_balance_minelayer_remote_edgedamage 40
- set g_balance_minelayer_remote_radius 200
- set g_balance_minelayer_remote_force 300
+ set g_balance_grenadelauncher_bouncestop 0.075
+ set g_balance_grenadelauncher_switchdelay_drop 0.2
+ set g_balance_grenadelauncher_switchdelay_raise 0.2
+ set g_balance_grenadelauncher_reload_ammo 0 //default: 12
+ set g_balance_grenadelauncher_reload_time 2
  // }}}
  // {{{ electro
- set g_balance_electro_lightning 1
- set g_balance_electro_primary_damage 100
- set g_balance_electro_primary_edgedamage 0
- set g_balance_electro_primary_force 425
- set g_balance_electro_primary_force_up 125
- set g_balance_electro_primary_radius 850
- set g_balance_electro_primary_comboradius 150
- set g_balance_electro_primary_speed 0
+ set g_balance_electro_lightning 0
+ 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_force_up 0
+ set g_balance_electro_primary_radius 100
+ set g_balance_electro_primary_comboradius 200
+ set g_balance_electro_primary_speed 2500
  set g_balance_electro_primary_spread 0
- set g_balance_electro_primary_lifetime 0
- set g_balance_electro_primary_refire 0.4
- set g_balance_electro_primary_animtime 0.2
- set g_balance_electro_primary_ammo 5
- set g_balance_electro_primary_range 800
- set g_balance_electro_primary_falloff_mindist 0
- set g_balance_electro_primary_falloff_maxdist 0
- set g_balance_electro_primary_falloff_halflifedist 0
- set g_balance_electro_secondary_damage 25
- set g_balance_electro_secondary_edgedamage 0
- set g_balance_electro_secondary_force 100
- set g_balance_electro_secondary_radius 100
- set g_balance_electro_secondary_speed 700
+ set g_balance_electro_primary_lifetime 5
+ set g_balance_electro_primary_refire 0.6
+ set g_balance_electro_primary_animtime 0.3
+ set g_balance_electro_primary_ammo 4
+ set g_balance_electro_primary_range 0
+ set g_balance_electro_primary_falloff_mindist 255 // 0.3 * radius
+ set g_balance_electro_primary_falloff_maxdist 850
+ set g_balance_electro_primary_falloff_halflifedist 425
+ set g_balance_electro_secondary_damage 40
+ set g_balance_electro_secondary_edgedamage 20
+ set g_balance_electro_secondary_force 50
+ set g_balance_electro_secondary_radius 150
+ 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.08
- set g_balance_electro_secondary_lifetime 3.5
+ set g_balance_electro_secondary_spread 0.04
+ set g_balance_electro_secondary_lifetime 4
  set g_balance_electro_secondary_refire 0.2
- set g_balance_electro_secondary_refire2 2
+ set g_balance_electro_secondary_refire2 1.6
  set g_balance_electro_secondary_animtime 0.2
  set g_balance_electro_secondary_ammo 2
- set g_balance_electro_secondary_health 10
+ set g_balance_electro_secondary_health 5
  set g_balance_electro_secondary_damageforcescale 4
+ set g_balance_electro_secondary_damagedbycontents 1
  set g_balance_electro_secondary_count 3
- set g_balance_electro_secondary_bouncefactor 0.5
- set g_balance_electro_secondary_bouncestop 0.075
+ set g_balance_electro_secondary_bouncefactor 0.3
+ set g_balance_electro_secondary_bouncestop 0.05
  set g_balance_electro_combo_damage 50
- set g_balance_electro_combo_edgedamage 0
- set g_balance_electro_combo_force 80
- set g_balance_electro_combo_radius 250
- set g_balance_electro_combo_comboradius 0
- set g_balance_electro_combo_speed 400
+ 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_comboradius 300
+ set g_balance_electro_combo_speed 2000
+ set g_balance_electro_combo_safeammocheck 1
+ set g_balance_electro_switchdelay_drop 0.2
+ set g_balance_electro_switchdelay_raise 0.2
+ set g_balance_electro_reload_ammo 0 //default: 20
+ set g_balance_electro_reload_time 2
  // }}}
- // {{{ crylink
- set g_balance_crylink_primary_damage 7 // LOG: 10 -> 7
- set g_balance_crylink_primary_edgedamage 4 // LOG: 6 -> 4
- set g_balance_crylink_primary_force 35
 +// {{{ lightning
 +set g_balance_lightning_primary_ammo 5
 +set g_balance_lightning_primary_animtime 0.2
 +set g_balance_lightning_primary_damage 100
 +set g_balance_lightning_primary_edgedamage 0
 +set g_balance_lightning_primary_falloff_mindist 0
 +set g_balance_lightning_primary_falloff_maxdist 0
 +set g_balance_lightning_primary_falloff_halflifedist 0
 +set g_balance_lightning_primary_force 425
 +set g_balance_lightning_primary_lifetime 0
 +set g_balance_lightning_primary_radius 850
 +set g_balance_lightning_primary_range 800
 +set g_balance_lightning_primary_refire 0.4
 +set g_balance_lightning_primary_speed 0
 +set g_balance_lightning_primary_spread 0
 +set g_balance_lightning_secondary_ammo 5
 +set g_balance_lightning_secondary_animtime 0.5
 +set g_balance_lightning_secondary_damage 100
 +set g_balance_lightning_secondary_damageforcescale 4
 +set g_balance_lightning_secondary_edgedamage 80
 +set g_balance_lightning_secondary_flyingdamage 1
 +set g_balance_lightning_secondary_flyingforce -80
 +set g_balance_lightning_secondary_flyingradius 200
 +set g_balance_lightning_secondary_force -200
 +set g_balance_lightning_secondary_health 1
 +set g_balance_lightning_secondary_lifetime 30
 +set g_balance_lightning_secondary_radius 300
 +set g_balance_lightning_secondary_refire 5
 +set g_balance_lightning_secondary_speed 600
 +// }}}
+ // {{{ crylink 
+ set g_balance_crylink_primary_damage 12
+ set g_balance_crylink_primary_edgedamage 6
+ set g_balance_crylink_primary_force -50
  set g_balance_crylink_primary_radius 80
- set g_balance_crylink_primary_speed 1500
- set g_balance_crylink_primary_spread 0.05
- set g_balance_crylink_primary_shots 7
- set g_balance_crylink_primary_bounces 2
- set g_balance_crylink_primary_refire 0.8
+ set g_balance_crylink_primary_speed 2000
+ set g_balance_crylink_primary_spread 0.08
+ set g_balance_crylink_primary_shots 6
+ set g_balance_crylink_primary_bounces 1
+ set g_balance_crylink_primary_refire 0.7
  set g_balance_crylink_primary_animtime 0.3
- set g_balance_crylink_primary_ammo 2
- set g_balance_crylink_primary_bouncedamagefactor 0.2
- set g_balance_crylink_primary_joindelay 0
+ set g_balance_crylink_primary_ammo 3
+ set g_balance_crylink_primary_bouncedamagefactor 0.5
+ set g_balance_crylink_primary_joindelay 0.1
  set g_balance_crylink_primary_joinspread 0.2
- set g_balance_crylink_primary_jointime 0.1
- set g_balance_crylink_primary_joinexplode 0
+ set g_balance_crylink_primary_jointime 0
+ 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_radius 0
  set g_balance_crylink_primary_joinexplode_force 0
  set g_balance_crylink_primary_linkexplode 1
  
- set g_balance_crylink_primary_middle_lifetime 5 // range: 10000 full, fades to 20000
+ set g_balance_crylink_primary_middle_lifetime 5 // range: 35000 full, fades to 70000
  set g_balance_crylink_primary_middle_fadetime 5
- set g_balance_crylink_primary_other_lifetime 2 // range: 800 full, fades to 1300
- set g_balance_crylink_primary_other_fadetime 0.25
+ set g_balance_crylink_primary_other_lifetime 
+ set g_balance_crylink_primary_other_fadetime 5
  
  set g_balance_crylink_secondary 1
- set g_balance_crylink_secondary_damage 5 // LOG: 8 -> 5
- set g_balance_crylink_secondary_edgedamage 3
- set g_balance_crylink_secondary_force 16 // LOG: 20 -> 16
- set g_balance_crylink_secondary_radius 15 // LOG: 20 -> 15
- set g_balance_crylink_secondary_speed 1250 // LOG: 1500 -> 1250
- set g_balance_crylink_secondary_spread 0.1
- set g_balance_crylink_secondary_shots 6
- set g_balance_crylink_secondary_bounces 2
- set g_balance_crylink_secondary_refire 0.9 // LOG: 0.8 -> 0.9
- set g_balance_crylink_secondary_animtime 0.3
- set g_balance_crylink_secondary_ammo 3 // LOG: 2 -> 3
- set g_balance_crylink_secondary_bouncedamagefactor 0.4 // LOG: 0.2 -> 0.4
+ set g_balance_crylink_secondary_damage 10
+ set g_balance_crylink_secondary_edgedamage 5
+ set g_balance_crylink_secondary_force -250
+ set g_balance_crylink_secondary_radius 100
+ set g_balance_crylink_secondary_speed 3000
+ set g_balance_crylink_secondary_spread 0.01
+ set g_balance_crylink_secondary_spreadtype 1
+ set g_balance_crylink_secondary_shots 5
+ set g_balance_crylink_secondary_bounces 0
+ set g_balance_crylink_secondary_refire 0.7
+ set g_balance_crylink_secondary_animtime 0.2
+ set g_balance_crylink_secondary_ammo 2
+ set g_balance_crylink_secondary_bouncedamagefactor 0.5
  set g_balance_crylink_secondary_joindelay 0
- set g_balance_crylink_secondary_joinspread 0.2
- set g_balance_crylink_secondary_jointime 0.1
+ set g_balance_crylink_secondary_joinspread 0
+ set g_balance_crylink_secondary_jointime 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_radius 0
  set g_balance_crylink_secondary_joinexplode_force 0
- set g_balance_crylink_secondary_linkexplode 0
+ set g_balance_crylink_secondary_linkexplode 1
  
- set g_balance_crylink_secondary_middle_lifetime 5 // range: 10000 full, fades to 10000
+ set g_balance_crylink_secondary_middle_lifetime 5 // range: 35000 full, fades to 70000
  set g_balance_crylink_secondary_middle_fadetime 5
- set g_balance_crylink_secondary_line_lifetime 2 // range: 4000 full, fades to 8000
- set g_balance_crylink_secondary_line_fadetime 0.25
+ set g_balance_crylink_secondary_line_lifetime 5 
+ set g_balance_crylink_secondary_line_fadetime 5
+ set g_balance_crylink_switchdelay_drop 0.2
+ set g_balance_crylink_switchdelay_raise 0.2
+ set g_balance_crylink_reload_ammo 0 //default: 10
+ set g_balance_crylink_reload_time 2
  // }}}
  // {{{ nex
- set g_balance_nex_primary_damage 90
- set g_balance_nex_primary_force 500
- set g_balance_nex_primary_refire 1
- set g_balance_nex_primary_animtime 0.3
- set g_balance_nex_primary_ammo 5
- set g_balance_nex_primary_damagefalloff_mindist 0
- set g_balance_nex_primary_damagefalloff_maxdist 0
- set g_balance_nex_primary_damagefalloff_halflife 0
- set g_balance_nex_primary_damagefalloff_forcehalflife 0
+ set g_balance_nex_primary_damage 80
+ set g_balance_nex_primary_force 400
+ set g_balance_nex_primary_refire 1.5
+ set g_balance_nex_primary_animtime 0.6
+ set g_balance_nex_primary_ammo 6
+ set g_balance_nex_primary_damagefalloff_mindist 0 // 1000    For tZork ;3
+ set g_balance_nex_primary_damagefalloff_maxdist 0 // 3000
+ set g_balance_nex_primary_damagefalloff_halflife 0 // 1500
+ set g_balance_nex_primary_damagefalloff_forcehalflife 0 // 1500
  
- set g_balance_nex_secondary 0 // LOG: disable secondary
- set g_balance_nex_secondary_charge 0 // LOG: disable secondary charge
- set g_balance_nex_secondary_charge_rate 0.4
- set g_balance_nex_secondary_chargepool 1
- set g_balance_nex_secondary_chargepool_regen 0.25
- set g_balance_nex_secondary_chargepool_pause_regen 2
- set g_balance_nex_secondary_chargepool_pause_health_regen 0.5
+ set g_balance_nex_secondary 0
+ set g_balance_nex_secondary_charge 0
+ set g_balance_nex_secondary_charge_rate 0.1
+ set g_balance_nex_secondary_chargepool 0
+ set g_balance_nex_secondary_chargepool_regen 0.15
+ set g_balance_nex_secondary_chargepool_pause_regen 1
+ set g_balance_nex_secondary_chargepool_pause_health_regen 1
  set g_balance_nex_secondary_damage 0
  set g_balance_nex_secondary_force 0
  set g_balance_nex_secondary_refire 0
  set g_balance_nex_secondary_animtime 0
- set g_balance_nex_secondary_ammo 0.4 // full charge pool is 1, so it depletes in 2.5 secs
+ set g_balance_nex_secondary_ammo 2
  set g_balance_nex_secondary_damagefalloff_mindist 0
  set g_balance_nex_secondary_damagefalloff_maxdist 0
  set g_balance_nex_secondary_damagefalloff_halflife 0
  set g_balance_nex_secondary_damagefalloff_forcehalflife 0
  
  set g_balance_nex_charge 1
- set g_balance_nex_charge_mindmg 20
+ set g_balance_nex_charge_mindmg 40
  set g_balance_nex_charge_start 0.5
- set g_balance_nex_charge_rate 0.5
+ set g_balance_nex_charge_rate 0.4
  set g_balance_nex_charge_animlimit 0.5
- set g_balance_nex_charge_limit 1 // LOG: 0.5 -> 1 - allow to fully charge automaticaly
- set g_balance_nex_charge_rot_rate 0 // LOG: 0.1 -> 0 - disable rot
- set g_balance_nex_charge_rot_pause 0.5 // Dont rot down until this long after release of charge button
+ set g_balance_nex_charge_limit 1
+ set g_balance_nex_charge_rot_rate 0
+ set g_balance_nex_charge_rot_pause 0 // Dont rot down until this long after release of charge button
  set g_balance_nex_charge_shot_multiplier 0
  set g_balance_nex_charge_velocity_rate 0
- set g_balance_nex_charge_minspeed 600
- set g_balance_nex_charge_maxspeed 1000
+ set g_balance_nex_charge_minspeed 400
+ set g_balance_nex_charge_maxspeed 800
+ set g_balance_nex_switchdelay_drop 0.3
+ set g_balance_nex_switchdelay_raise 0.3
+ set g_balance_nex_reload_ammo 0 //default: 25
+ set g_balance_nex_reload_time 2
  // }}}
  // {{{ minstanex
  set g_balance_minstanex_refire 1
- set g_balance_minstanex_animtime 0.50
+ set g_balance_minstanex_animtime 0.3
  set g_balance_minstanex_ammo 10
+ set g_balance_minstanex_laser_ammo 0
+ set g_balance_minstanex_laser_animtime 0.3
+ set g_balance_minstanex_laser_refire 0.7
+ set g_balance_minstanex_switchdelay_drop 0.2
+ set g_balance_minstanex_switchdelay_raise 0.2
+ set g_balance_minstanex_reload_ammo 0 //default: 50
+ set g_balance_minstanex_reload_time 2
  // }}}
  // {{{ hagar
- set g_balance_hagar_primary_damage 14
- set g_balance_hagar_primary_edgedamage 6
- set g_balance_hagar_primary_force 70
- set g_balance_hagar_primary_radius 110
- set g_balance_hagar_primary_spread 0.1
- set g_balance_hagar_primary_speed 1800
+ set g_balance_hagar_primary_damage 25
+ 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_damageforcescale 0
+ set g_balance_hagar_primary_radius 65
+ set g_balance_hagar_primary_spread 0.03
+ set g_balance_hagar_primary_speed 2500
  set g_balance_hagar_primary_lifetime 5
- set g_balance_hagar_primary_refire 0.12
+ set g_balance_hagar_primary_refire 0.16667 // 6 rockets per second
  set g_balance_hagar_primary_ammo 1
  set g_balance_hagar_secondary 1
- set g_balance_hagar_secondary_damage 14
- set g_balance_hagar_secondary_edgedamage 6
- set g_balance_hagar_secondary_force 70
- set g_balance_hagar_secondary_radius 125
- set g_balance_hagar_secondary_spread 0.15
- set g_balance_hagar_secondary_speed 1800
- set g_balance_hagar_secondary_lifetime_min 5
+ set g_balance_hagar_secondary_load 1
+ 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_load_max 4
+ set g_balance_hagar_secondary_load_hold 4
+ set g_balance_hagar_secondary_load_releasedeath 0
+ set g_balance_hagar_secondary_load_abort 0
+ set g_balance_hagar_secondary_load_linkexplode 0
+ set g_balance_hagar_secondary_load_animtime 0.2
+ set g_balance_hagar_secondary_damage 40
+ set g_balance_hagar_secondary_edgedamage 20
+ set g_balance_hagar_secondary_force 75
+ set g_balance_hagar_secondary_health 15
+ set g_balance_hagar_secondary_damageforcescale 0
+ set g_balance_hagar_secondary_radius 80
+ set g_balance_hagar_secondary_spread 0.05
+ set g_balance_hagar_secondary_speed 2500
+ set g_balance_hagar_secondary_lifetime_min 10
  set g_balance_hagar_secondary_lifetime_rand 0
- set g_balance_hagar_secondary_refire 0.12
+ set g_balance_hagar_secondary_refire 0.5
  set g_balance_hagar_secondary_ammo 1
+ set g_balance_hagar_switchdelay_drop 0.2
+ set g_balance_hagar_switchdelay_raise 0.2
+ set g_balance_hagar_reload_ammo 0 //default: 25
+ set g_balance_hagar_reload_time 2
  // }}}
  // {{{ rocketlauncher
- set g_balance_rocketlauncher_damage 82
- set g_balance_rocketlauncher_edgedamage 32
- set g_balance_rocketlauncher_force 350
- set g_balance_rocketlauncher_radius 130
- set g_balance_rocketlauncher_speed 1400
- set g_balance_rocketlauncher_speedaccel 1400
- set g_balance_rocketlauncher_speedstart 800
- set g_balance_rocketlauncher_lifetime 5
- set g_balance_rocketlauncher_refire 1
- set g_balance_rocketlauncher_animtime 0.3
- set g_balance_rocketlauncher_ammo 3
- set g_balance_rocketlauncher_health 0
- set g_balance_rocketlauncher_damageforcescale 0
- set g_balance_rocketlauncher_detonatedelay 0.05 // positive: timer till detonation is allowed, negative: "security device" that prevents ANY remote detonation if it could hurt its owner, zero: detonatable at any time
- set g_balance_rocketlauncher_guiderate 42 // max degrees per second
+ set g_balance_rocketlauncher_damage 80
+ set g_balance_rocketlauncher_edgedamage 40
+ set g_balance_rocketlauncher_force 450
+ set g_balance_rocketlauncher_radius 110
+ set g_balance_rocketlauncher_speed 1300
+ set g_balance_rocketlauncher_speedaccel 1300
+ set g_balance_rocketlauncher_speedstart 1000
+ set g_balance_rocketlauncher_lifetime 10
+ set g_balance_rocketlauncher_refire 1.1
+ set g_balance_rocketlauncher_animtime 0.4
+ set g_balance_rocketlauncher_ammo 4
+ set g_balance_rocketlauncher_health 30 // 30 // 5 hitpoints above maximum laser value -- this way lasers can't blow it up, but grenadelauncher still can most the time.
+ set g_balance_rocketlauncher_damageforcescale 1 // low damage force scale so that it can still be affected by other hits, but not so much that it does a 90 degree turn
+ set g_balance_rocketlauncher_detonatedelay 0.02 // positive: timer till detonation is allowed, negative: "security device" that prevents ANY remote detonation if it could hurt its owner, zero: detonatable at any time
+ set g_balance_rocketlauncher_guiderate 90 // max degrees per second
  set g_balance_rocketlauncher_guideratedelay 0.01 // immediate
  set g_balance_rocketlauncher_guidegoal 512 // goal distance for (non-laser) guiding (higher = less control, lower = erratic)
- set g_balance_rocketlauncher_guidedelay 0.15 // delay before guiding kicks in
+ set g_balance_rocketlauncher_guidedelay 0.2 // delay before guiding kicks in
  set g_balance_rocketlauncher_guidestop 0 // stop guiding when firing again
- set g_balance_rocketlauncher_remote_damage 60
- set g_balance_rocketlauncher_remote_edgedamage 20
- set g_balance_rocketlauncher_remote_radius 120
- set g_balance_rocketlauncher_remote_force 350
+ set g_balance_rocketlauncher_remote_damage 70
+ set g_balance_rocketlauncher_remote_edgedamage 35
+ set g_balance_rocketlauncher_remote_radius 110
+ set g_balance_rocketlauncher_remote_force 400
+ set g_balance_rocketlauncher_switchdelay_drop 0.2
+ set g_balance_rocketlauncher_switchdelay_raise 0.2
+ set g_balance_rocketlauncher_reload_ammo 0 //default: 25
+ set g_balance_rocketlauncher_reload_time 2
  // }}}
  // {{{ porto
  set g_balance_porto_primary_refire 1.5
- set g_balance_porto_primary_animtime 0.2
- set g_balance_porto_primary_speed 2000
+ set g_balance_porto_primary_animtime 0.3
+ set g_balance_porto_primary_speed 1000
  set g_balance_porto_primary_lifetime 5
+ set g_balance_porto_secondary 1
+ set g_balance_porto_secondary_refire 1.5
+ set g_balance_porto_secondary_animtime 0.3
+ set g_balance_porto_secondary_speed 1000
+ set g_balance_porto_secondary_lifetime 5
+ set g_balance_porto_switchdelay_drop 0.2
+ set g_balance_porto_switchdelay_raise 0.2
  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
  // }}}
  // {{{ hook
  set g_balance_hook_primary_fuel 5 // hook monkeys set 0
  set g_balance_hook_primary_refire 0 // hook monkeys set 0
- set g_balance_hook_primary_animtime 0.2 // good shoot anim
+ set g_balance_hook_primary_animtime 0.3 // good shoot anim
  set g_balance_hook_primary_hooked_time_max 0 // infinite
  set g_balance_hook_primary_hooked_time_free 2 // 2s being hooked are free
  set g_balance_hook_primary_hooked_fuel 5 // fuel per second hooked
@@@ -599,81 -642,18 +672,18 @@@ set g_balance_hook_secondary_damage 25 
  set g_balance_hook_secondary_edgedamage 5 // not much
  set g_balance_hook_secondary_radius 500 // LOTS
  set g_balance_hook_secondary_force -2000 // LOTS
- set g_balance_hook_secondary_ammo 50 // a whole pack
+ set g_balance_hook_secondary_ammo 30 // a whole pack
  set g_balance_hook_secondary_lifetime 5 // infinite
  set g_balance_hook_secondary_speed 0 // not much throwing
  set g_balance_hook_secondary_gravity 5 // fast falling
  set g_balance_hook_secondary_refire 3 // don't drop too many bombs...
- set g_balance_hook_secondary_animtime 0.2 // good shoot anim
+ set g_balance_hook_secondary_animtime 0.3 // good shoot anim
  set g_balance_hook_secondary_power 3 // effect behaves like a square function
  set g_balance_hook_secondary_duration 1.5 // effect runs for three seconds
- // }}}
- // {{{ hlac
- set g_balance_hlac_primary_spread_min 0.01
- set g_balance_hlac_primary_spread_max 0.075
- set g_balance_hlac_primary_spread_add 0.001
- set g_balance_hlac_primary_spread_crouchmod 0.25
- set g_balance_hlac_primary_damage 15
- set g_balance_hlac_primary_edgedamage 10
- set g_balance_hlac_primary_force 70
- set g_balance_hlac_primary_radius 40
- set g_balance_hlac_primary_speed 9000
- set g_balance_hlac_primary_lifetime 5
- set g_balance_hlac_primary_refire 0.1
- set g_balance_hlac_primary_animtime 0.2
- set g_balance_hlac_primary_ammo 1
- set g_balance_hlac_secondary 1
- set g_balance_hlac_secondary_spread 0.15
- set g_balance_hlac_secondary_spread_crouchmod 0.5
- set g_balance_hlac_secondary_damage 20
- set g_balance_hlac_secondary_edgedamage 13
- set g_balance_hlac_secondary_force 100
- set g_balance_hlac_secondary_radius 45
- set g_balance_hlac_secondary_speed 9000
- set g_balance_hlac_secondary_lifetime 5
- set g_balance_hlac_secondary_refire 0.8
- set g_balance_hlac_secondary_animtime 0.4
- set g_balance_hlac_secondary_ammo 4
- set g_balance_hlac_secondary_shots 6
- // }}}
- // {{{ sniperrifle
- set g_balance_sniperrifle_magazinecapacity 8 // make it pretty much useless in close combat
- set g_balance_sniperrifle_reloadtime 2 // matches reload anim
- set g_balance_sniperrifle_auto_reload_on_switch 0
- set g_balance_sniperrifle_bursttime 0
- set g_balance_sniperrifle_primary_tracer 1
- set g_balance_sniperrifle_primary_damage 60
- set g_balance_sniperrifle_primary_headshotaddeddamage 60
- set g_balance_sniperrifle_primary_spread 0
- set g_balance_sniperrifle_primary_force 2
- set g_balance_sniperrifle_primary_speed 40000
- set g_balance_sniperrifle_primary_lifetime 5
- set g_balance_sniperrifle_primary_refire 1.5
- set g_balance_sniperrifle_primary_animtime 1.4
- set g_balance_sniperrifle_primary_ammo 10
- set g_balance_sniperrifle_primary_bulletconstant 110 // 62.2qu
- set g_balance_sniperrifle_primary_burstcost 0
- set g_balance_sniperrifle_primary_bullethail 0 // empty magazine on shot
- set g_balance_sniperrifle_secondary 1
- set g_balance_sniperrifle_secondary_reload 1
- set g_balance_sniperrifle_secondary_tracer 0
- set g_balance_sniperrifle_secondary_damage 42
- set g_balance_sniperrifle_secondary_headshotaddeddamage 42
- set g_balance_sniperrifle_secondary_spread 0
- set g_balance_sniperrifle_secondary_force 2
- set g_balance_sniperrifle_secondary_speed 20000
- set g_balance_sniperrifle_secondary_lifetime 5
- set g_balance_sniperrifle_secondary_refire 1.5
- set g_balance_sniperrifle_secondary_animtime 1.4
- set g_balance_sniperrifle_secondary_ammo 10
- set g_balance_sniperrifle_secondary_bulletconstant 110 // 15.5qu
- set g_balance_sniperrifle_secondary_burstcost 0
- set g_balance_sniperrifle_secondary_bullethail 0 // empty magazine on shot
+ set g_balance_hook_secondary_health 15
+ set g_balance_hook_secondary_damageforcescale 0
+ set g_balance_hook_switchdelay_drop 0.2
+ set g_balance_hook_switchdelay_raise 0.2
  // }}}
  // {{{ tuba
  set g_balance_tuba_refire 0.05
@@@ -685,30 -665,31 +695,31 @@@ set g_balance_tuba_damage 
  set g_balance_tuba_edgedamage 0
  set g_balance_tuba_radius 200
  set g_balance_tuba_force 40
+ set g_balance_tuba_pitchstep 6
+ set g_balance_tuba_switchdelay_drop 0.2
+ set g_balance_tuba_switchdelay_raise 0.2
  // }}}
- // {{{ fireball
- set g_balance_fireball_primary_ammo 40
+ // {{{ fireball // this is a superweapon -- lets make it behave as one. 
  set g_balance_fireball_primary_animtime 0.2
  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 4
- set g_balance_fireball_primary_edgedamage 0
- set g_balance_fireball_primary_force 700
- set g_balance_fireball_primary_health 50
+ 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 5
+ set g_balance_fireball_primary_refire 2
  set g_balance_fireball_primary_refire2 0
- set g_balance_fireball_primary_speed 650
+ set g_balance_fireball_primary_speed 1200
  set g_balance_fireball_primary_spread 0
- set g_balance_fireball_secondary_ammo 5
- set g_balance_fireball_secondary_animtime 0.2
+ 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
@@@ -718,59 -699,11 +729,11 @@@ set g_balance_fireball_secondary_laserd
  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 2
+ 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
  // }}}
- // {{{ seeker
- set g_balance_seeker_flac_ammo 0.5
- 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 // LOG: 8 -> 3
- set g_balance_seeker_missile_damage 30 // LOG: 15 -> 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 // LOG: 100 -> 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_up 300
- set g_balance_seeker_missile_speed_z 0
- set g_balance_seeker_missile_speed_max 1300 // LOG: 1400 -> 1300
- set g_balance_seeker_missile_spread 0
- set g_balance_seeker_missile_turnrate 0.65
- 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 // LOG: 0.7 -> 0.75
- set g_balance_seeker_tag_speed 5000
- set g_balance_seeker_tag_spread 0
- // End new seeker
diff --combined qcsrc/client/Defs.qc
index 98c61ff88b52fee8e69cc6f78df2b0da9f2ce866,b89a177f043a465c99c5fc7812a8b0d1eb83f3c3..8f1317827461092f7c1ae28975f798c462151803
@@@ -1,6 -1,3 +1,3 @@@
- #pragma flag off fastarrays // make dp behave with new fteqcc versions. remove when dp bug with fteqcc fastarrays is fixed
  //NOTE: THIS IS AN INTERFACE FILE. DO NOT EDIT.
  //MODIFYING THIS FILE CAN RESULT IN CRC ERRORS.
  //YOU HAVE BEEN WARNED.
@@@ -28,7 -25,7 +25,7 @@@ entity                world
  float         time;
  float         frametime;
  
- float                 player_localentnum;     //the entnum
+ float                 player_localentnum;     //the entnum of the VIEW entity
  float                 player_localnum;        //the playernum
  float         maxclients;     //a constant filled in by the engine. gah, portability eh?
  
@@@ -177,9 -174,6 +174,6 @@@ float              dmg_take
  float vid_conwidth, vid_conheight;
  float binddb;
  
- //    Announcer
- string announce_snd;
  // QUALIFYING
  float race_checkpoint;
  float race_time;
@@@ -225,16 -219,11 +219,12 @@@ float spectatee_status
  // short mapname
  string shortmapname;
  
- //remaining maptime announcer sounds, true when sound was already played
- float announcer_1min;
- float announcer_5min;
  // database for misc stuff
  float tempdb;
  float ClientProgsDB;
  vector hook_shotorigin[4];
  vector electro_shotorigin[4];
 +vector lightning_shotorigin[4];
  vector gauntlet_shotorigin[4];
  
  #ifdef BLURTEST
@@@ -246,6 -235,9 +236,9 @@@ float servertime, serverprevtime, serve
  float ticrate;
  
  .float damageforcescale;
+ #define MIN_DAMAGEEXTRARADIUS 2
+ #define MAX_DAMAGEEXTRARADIUS 16
+ .float damageextraradius;
  .void(float thisdmg, float hittype, vector org, vector thisforce) event_damage;
  
  // only for Porto
@@@ -256,16 -248,15 +249,15 @@@ vector angles_held
  .float silent;
  
  float w_deathtype, w_issilent, w_random;
- string w_deathtypestring;
  vector w_org, w_backoff;
  
- float sniperrifle_scope;
+ float rifle_scope;
  float nex_scope;
  
- float cr_maxbullets;
  float minelayer_maxmines;
  
+ float hagar_maxrockets;
  float bgmtime;
  
  string weaponorder_byimpulse;
@@@ -276,3 -267,9 +268,9 @@@ float nex_charge_movingavg
  float serverflags;
  
  float uid2name_dialog;
+ .float csqcmodel_isdead; // used by shownames and miscfunctions (float getplayerisdead(float) {}) to know when a player is dead
+ #define player_currententnum (spectatee_status > 0 ? spectatee_status : player_localnum + 1)
+ float g_balance_porto_secondary;
diff --combined qcsrc/client/Main.qc
index 6611c34e278866c1753ecba4c193a6181cfcc760,7178cdba1abbf9c4a62aac03d833c1191fddfb03..d7130197e6e979e58843300f06a29f0b3ed79231
@@@ -2,52 -2,91 +2,91 @@@
  // BEGIN REQUIRED CSQC FUNCTIONS
  //include "main.qh"
  
- #define DP_CSQC_ENTITY_REMOVE_IS_B0RKED
- void cvar_clientsettemp(string cv, string val)
+ entity clearentity_ent;
+ void clearentity(entity e)
  {
-       entity e;
-       for(e = world; (e = find(e, classname, "saved_cvar_value")); )
-               if(e.netname == cv)
-                       goto saved;
-       e = spawn();
-       e.classname = "saved_cvar_value";
-       e.netname = strzone(cv);
-       e.message = strzone(cvar_string(cv));
- :saved
-       cvar_set(cv, val);
- }
- void cvar_clientsettemp_restore()
- {
-       entity e;
-       for(e = world; (e = find(e, classname, "saved_cvar_value")); )
-                       cvar_set(e.netname, e.message);
+       if not(clearentity_ent)
+       {
+               clearentity_ent = spawn();
+               clearentity_ent.classname = "clearentity";
+       }
+       float n = e.entnum;
+       copyentity(clearentity_ent, e);
+       e.entnum = n;
  }
  
- void() menu_show_error =
+ #define DP_CSQC_ENTITY_REMOVE_IS_B0RKED
+ void menu_show_error()
  {
        drawstring('0 200 0', _("ERROR - MENU IS VISIBLE BUT NO MENU WAS DEFINED!"), '8 8 0', '1 0 0', 1, 0);
- };
+ }
  
  // CSQC_Init : Called every time the CSQC code is initialized (essentially at map load)
  // Useful for precaching things
  
- void() menu_sub_null =
+ void menu_sub_null()
  {
- };
+ }
  
  #ifdef USE_FTE
  float __engine_check;
  #endif
  
+ void precache_playermodel(string m)
+ {
+       string f;
+       if(substring(m, -9,5) == "_lod1")
+               return;
+       if(substring(m, -9,5) == "_lod2")
+               return;
+       precache_model(m);
+       f = strcat(substring(m, 0, -5), "_lod1", substring(m, -4, -1));
+       if(fexists(f))
+               precache_model(f);
+       f = strcat(substring(m, 0, -5), "_lod2", substring(m, -4, -1));
+       if(fexists(f))
+               precache_model(f);
+       /*
+       float globhandle, i, n;
+       globhandle = search_begin(strcat(m, "_*.sounds"), TRUE, FALSE);
+       if (globhandle < 0)
+               return;
+       n = search_getsize(globhandle);
+       for (i = 0; i < n; ++i)
+       {
+               //print(search_getfilename(globhandle, i), "\n");
+               f = search_getfilename(globhandle, i);
+               PrecachePlayerSounds(f);
+       }
+       search_end(globhandle);
+       */
+ }
+ void precache_all_playermodels(string pattern)
+ {
+       float globhandle, i, n;
+       string f;
+       globhandle = search_begin(pattern, TRUE, FALSE);
+       if (globhandle < 0)
+               return;
+       n = search_getsize(globhandle);
+       for (i = 0; i < n; ++i)
+       {
+               //print(search_getfilename(globhandle, i), "\n");
+               f = search_getfilename(globhandle, i);
+               precache_playermodel(f);
+       }
+       search_end(globhandle);
+ }
  string forcefog;
- string cl_announcer_prev;
  void WaypointSprite_Load();
+ void ConsoleCommand_macro_init();
  void CSQC_Init(void)
  {
        prvm_language = cvar_string("prvm_language");
-       
  #ifdef USE_FTE
  #pragma target ID
        __engine_check = checkextension("DP_SV_WRITEPICTURE");
        check_unacceptable_compiler_bugs();
  
  #ifdef WATERMARK
-       print(sprintf(_("^4CSQC Build information: %s\n"), WATERMARK()));
+       print(sprintf(_("^4CSQC Build information: ^1%s\n"), WATERMARK));
  #endif
  
        float i;
  
+ #ifdef COMPAT_XON050_ENGINE
+       // old engine lacks implementation of player_localnum
+       player_localnum = player_localentnum - 1;
+ #endif
        binddb = db_create();
        tempdb = db_create();
        ClientProgsDB = db_load("client.db");
        compressShortVector_init();
  
-       drawfont = FONT_USER+1;
+       draw_endBoldFont();
        menu_visible = FALSE;
        menu_show = menu_show_error;
-       menu_action = menu_sub_null;
+       menu_action = func_null;
  
        for(i = 0; i < 255; ++i)
-               if(getplayerkey(i, "viewentity") == "")
+               if(getplayerkeyvalue(i, "viewentity") == "")
                        break;
        maxclients = i;
  
-       //ctf_temp_1 = "";
-       // localcmd("alias order \"cmd order $*\""); enable if ctf-command thingy is used
-       //registercmd("ctf_menu");
-       registercmd("ons_map");
-       registercmd("hud_configure");
-       registercmd("hud_save");
-       //registercmd("menu_action");
-       registercmd("+button3");
-       registercmd("-button3");
-       registercmd("+button4");
-       registercmd("-button4");
-       registercmd("+showscores");registercmd("-showscores");
-       registercmd("+showaccuracy");registercmd("-showaccuracy");
- #ifndef CAMERATEST
-       if(isdemo())
-       {
- #endif
-               registercmd("+forward");registercmd("-forward");
-               registercmd("+back");registercmd("-back");
-               registercmd("+moveup");registercmd("-moveup");
-               registercmd("+movedown");registercmd("-movedown");
-               registercmd("+moveright");registercmd("-moveright");
-               registercmd("+moveleft");registercmd("-moveleft");
-               registercmd("+roll_right");registercmd("-roll_right");
-               registercmd("+roll_left");registercmd("-roll_left");
- #ifndef CAMERATEST
-       }
- #endif
+       //registercommand("hud_configure");
+       //registercommand("hud_save");
+       //registercommand("menu_action");
+       
+       ConsoleCommand_macro_init();
        registercvar("hud_usecsqc", "1");
-       registercvar("scoreboard_columns", "default", CVAR_SAVE);
+       registercvar("scoreboard_columns", "default");
  
        gametype = 0;
  
        teams = Sort_Spawn();
        players = Sort_Spawn();
  
-       GetTeam(COLOR_SPECTATOR, true); // add specs first
+       GetTeam(NUM_SPECTATOR, true); // add specs first
  
-       RegisterWeapons();
+       // needs to be done so early because of the constants they create
+       CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
+       CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
+       CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
+       CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
+       CALL_ACCUMULATED_FUNCTION(RegisterHUD_Panels);
  
        WaypointSprite_Load();
  
        // precaches
+       precache_model("null");
        precache_sound("misc/hit.wav");
        precache_sound("misc/typehit.wav");
+       if (autocvar_cl_precacheplayermodels)
+       {
+               precache_all_playermodels("models/player/*.zym");
+               precache_all_playermodels("models/player/*.dpm");
+               precache_all_playermodels("models/player/*.md3");
+               precache_all_playermodels("models/player/*.psk");
+               precache_all_playermodels("models/player/*.iqm");
+       }
        Projectile_Precache();
        Hook_Precache();
        GibSplash_Precache();
        Casings_Precache();
        DamageInfo_Precache();
-       if(autocvar_cl_announcer != cl_announcer_prev) {
-               Announcer_Precache();
-               if(cl_announcer_prev)
-                       strunzone(cl_announcer_prev);
-               cl_announcer_prev = strzone(autocvar_cl_announcer);
-       }
+       Vehicles_Precache();
+       turrets_precache();
        Tuba_Precache();
+       CSQCPlayer_Precache();
+       
+       if(autocvar_cl_reticle)
+       {
+               if(autocvar_cl_reticle_item_normal) { precache_pic("gfx/reticle_normal"); }
+               if(autocvar_cl_reticle_item_nex) { precache_pic("gfx/reticle_nex"); }
+       }
+       
        get_mi_min_max_texcoords(1); // try the CLEVER way first
        minimapname = strcat("gfx/", mi_shortname, "_radar.tga");
        shortmapname = mi_shortname;
        minimapname = strzone(minimapname);
  
        WarpZone_Init();
+       hud_skin_path = strzone(strcat("gfx/hud/", autocvar_hud_skin));
        hud_configure_prev = -1;
+       draw_currentSkin = strzone(strcat("gfx/menu/", cvar_string("menu_skin")));
  }
  
  // CSQC_Shutdown : Called every time the CSQC code is shutdown (changing maps, quitting, etc)
- void CSQC_Shutdown(void)
+ void Shutdown(void)
  {
  #ifdef USE_FTE
  #pragma TARGET id
                db_save(ClientProgsDB, "client.db");
        db_close(ClientProgsDB);
  
-       cvar_clientsettemp_restore();
        if(camera_active)
                cvar_set("chase_active",ftos(chase_active_backup));
  
+       // unset the event chasecam's chase_active
+       if(autocvar_chase_active < 0)
+               cvar_set("chase_active", "0");
        if not(isdemo())
        {
                if not(calledhooks & HOOK_START)
@@@ -218,16 -262,16 +262,16 @@@ float SetTeam(entity o, float Team
                switch(Team)
                {
                        case -1:
-                       case COLOR_TEAM1:
-                       case COLOR_TEAM2:
-                       case COLOR_TEAM3:
-                       case COLOR_TEAM4:
+                       case NUM_TEAM_1:
+                       case NUM_TEAM_2:
+                       case NUM_TEAM_3:
+                       case NUM_TEAM_4:
                                break;
                        default:
-                               if(GetTeam(Team, false) == NULL)
+                               if(GetTeam(Team, false) == world)
                                {
                                        print(sprintf(_("trying to switch to unsupported team %d\n"), Team));
-                                       Team = COLOR_SPECTATOR;
+                                       Team = NUM_SPECTATOR;
                                }
                                break;
                }
                        case 0:
                                break;
                        default:
-                               if(GetTeam(Team, false) == NULL)
+                               if(GetTeam(Team, false) == world)
                                {
                                        print(sprintf(_("trying to switch to unsupported team %d\n"), Team));
-                                       Team = COLOR_SPECTATOR;
+                                       Team = NUM_SPECTATOR;
                                }
                                break;
                }
@@@ -337,319 -381,18 +381,18 @@@ void PostInit(void
        postinit = true;
  }
  
- // CSQC_ConsoleCommand : Used to parse commands in the console that have been registered with the "registercmd" function
- // Return value should be 1 if CSQC handled the command, otherwise return 0 to have the engine handle it.
  float button_zoom;
- void Cmd_HUD_SetFields(float);
- void Cmd_HUD_Help(float);
- float CSQC_ConsoleCommand(string strMessage)
- {
-       float argc;
-       // Tokenize String
-       //argc = tokenize(strMessage);
-       argc = tokenize_console(strMessage);
-       // Acquire Command
-       local string strCmd;
-       strCmd = argv(0);
-       if(strCmd == "hud_configure") { // config hud
-               cvar_set("_hud_configure", ftos(!autocvar__hud_configure));
-               return true;
-       } else if(strCmd == "hud_save") { // save hud config
-               if(argv(1) == "" || argv(2)) {
-                       print(_("Usage:\n"));
-                       print(_("hud_save configname   (saves to hud_skinname_configname.cfg)\n"));
-               }
-               else
-                       HUD_Panel_ExportCfg(argv(1));
-               return true;
-       } else if(strCmd == "+button4") { // zoom
-               // return false, because the message shall be sent to the server anyway (for demos/speccing)
-               if(ignore_plus_zoom)
-               {
-                       --ignore_plus_zoom;
-                       return false;
-               }
-               button_zoom = 1;
-               return true;
-       } else if(strCmd == "-button4") { // zoom
-               if(ignore_minus_zoom)
-               {
-                       --ignore_minus_zoom;
-                       return false;
-               }
-               button_zoom = 0;
-               return true;
-       } else if(strCmd == "+button3") { // secondary
-               button_attack2 = 1;
-               return false;
-       } else if(strCmd == "-button3") { // secondary
-               button_attack2 = 0;
-               return false;
-       } else if(strCmd == "+showscores") {
-               scoreboard_showscores = true;
-               return true;
-       } else if(strCmd == "-showscores") {
-               scoreboard_showscores = false;
-               return true;
-       } else if(strCmd == "+showaccuracy") {
-               scoreboard_showaccuracy = true;
-               return true;
-       } else if(strCmd == "-showaccuracy") {
-               scoreboard_showaccuracy = false;
-               return true;
-       }
-       if(camera_active)
-       if(strCmd == "+forward" || strCmd == "-back") {
-               ++camera_direction_x;
-               return true;
-       } else if(strCmd == "-forward" || strCmd == "+back") {
-               --camera_direction_x;
-               return true;
-       } else if(strCmd == "+moveright" || strCmd == "-moveleft") {
-               --camera_direction_y;
-               return true;
-       } else if(strCmd == "-moveright" || strCmd == "+moveleft") {
-               ++camera_direction_y;
-               return true;
-       } else if(strCmd == "+moveup" || strCmd == "-movedown") {
-               ++camera_direction_z;
-               return true;
-       } else if(strCmd == "-moveup" || strCmd == "+movedown") {
-               --camera_direction_z;
-               return true;
-       } else if(strCmd == "+roll_right" || strCmd == "-roll_left") {
-               ++camera_roll;
-               return true;
-       } else if(strCmd == "+roll_left" || strCmd == "-roll_right") {
-               --camera_roll;
-               return true;
-       }
-       return false;
- }
- .vector view_ofs;
- entity debug_shotorg;
- void ShotOrg_Draw()
- {
-       self.origin = view_origin + view_forward * self.view_ofs_x + view_right * self.view_ofs_y + view_up * self.view_ofs_z;
-       self.angles = view_angles;
-       self.angles_x = -self.angles_x;
-       if not(self.cnt)
-               self.drawmask = MASK_NORMAL;
-       else
-               self.drawmask = 0;
- }
- void ShotOrg_Draw2D()
- {
-       vector coord2d_topleft, coord2d_topright, coord2d;
-       string s;
-       vector fs;
-       s = vtos(self.view_ofs);
-       s = substring(s, 1, strlen(s) - 2);
-       if(tokenize_console(s) == 3)
-               s = strcat(argv(0), " ", argv(1), " ", argv(2));
-       coord2d_topleft = project_3d_to_2d(self.origin + view_up * 4 - view_right * 4);
-       coord2d_topright = project_3d_to_2d(self.origin + view_up * 4 + view_right * 4);
-       fs = '1 1 0' * ((coord2d_topright_x - coord2d_topleft_x) / stringwidth(s, FALSE, '8 8 0'));
-       coord2d = coord2d_topleft;
-       if(fs_x < 8)
-       {
-               coord2d_x += (coord2d_topright_x - coord2d_topleft_x) * (1 - 8 / fs_x) * 0.5;
-               fs = '8 8 0';
-       }
-       coord2d_y -= fs_y;
-       coord2d_z = 0;
-       drawstring(coord2d, s, fs, '1 1 1', 1, 0);
- }
- void ShotOrg_Spawn()
- {
-       debug_shotorg = spawn();
-       debug_shotorg.draw = ShotOrg_Draw;
-       debug_shotorg.draw2d = ShotOrg_Draw2D;
-       debug_shotorg.renderflags = RF_VIEWMODEL;
-       debug_shotorg.effects = EF_FULLBRIGHT;
-       precache_model("models/shotorg_adjuster.md3");
-       setmodel(debug_shotorg, "models/shotorg_adjuster.md3");
-       debug_shotorg.scale = 2;
-       debug_shotorg.view_ofs = '25 8 -8';
- }
- void DrawDebugModel()
- {
-       if(time - floor(time) > 0.5)
-       {
-               PolyDrawModel(self);
-               self.drawmask = 0;
-       }
-       else
-       {
-               self.renderflags = 0;
-               self.drawmask = MASK_NORMAL;
-       }
- }
- void GameCommand(string msg)
- {
-       string s;
-       float argc;
-       entity e;
-       argc = tokenize_console(msg);
-       if(argv(0) == "help" || argc == 0)
-       {
-               print(_("Usage: cl_cmd COMMAND..., where possible commands are:\n"));
-               print(_("  settemp cvar value\n"));
-               print(_("  scoreboard_columns_set ...\n"));
-               print(_("  scoreboard_columns_help\n"));
-               GameCommand_Generic("help");
-               return;
-       }
-       if(GameCommand_Generic(msg))
-               return;
-       string cmd;
-       cmd = argv(0);
-       if(cmd == "mv_download") {
-               Cmd_MapVote_MapDownload(argc);
-       }
-       else if(cmd == "settemp") {
-               cvar_clientsettemp(argv(1), argv(2));
-       }
-       else if(cmd == "scoreboard_columns_set") {
-               Cmd_HUD_SetFields(argc);
-       }
-       else if(cmd == "scoreboard_columns_help") {
-               Cmd_HUD_Help(argc);
-       }
- #ifdef BLURTEST
-       else if(cmd == "blurtest") {
-               blurtest_time0 = time;
-               blurtest_time1 = time + stof(argv(1));
-               blurtest_radius = stof(argv(2));
-               blurtest_power = stof(argv(3));
-       }
- #endif
-       else if(cmd == "shotorg_move") {
-               if(!debug_shotorg)
-                       ShotOrg_Spawn();
-               else
-                       debug_shotorg.view_ofs = debug_shotorg.view_ofs + stov(argv(1));
-               localcmd("sv_cmd debug_shotorg \"", vtos(debug_shotorg.view_ofs), "\"\n");
-       }
-       else if(cmd == "shotorg_movez") {
-               if(!debug_shotorg)
-                       ShotOrg_Spawn();
-               else
-                       debug_shotorg.view_ofs = debug_shotorg.view_ofs + stof(argv(1)) * (debug_shotorg.view_ofs * (1 / debug_shotorg.view_ofs_x)); // closer/farther, same xy pos
-               localcmd("sv_cmd debug_shotorg \"", vtos(debug_shotorg.view_ofs), "\"\n");
-       }
-       else if(cmd == "shotorg_set") {
-               if(!debug_shotorg)
-                       ShotOrg_Spawn();
-               else
-                       debug_shotorg.view_ofs = stov(argv(1));
-               localcmd("sv_cmd debug_shotorg \"", vtos(debug_shotorg.view_ofs), "\"\n");
-       }
-       else if(cmd == "shotorg_setz") {
-               if(!debug_shotorg)
-                       ShotOrg_Spawn();
-               else
-                       debug_shotorg.view_ofs = debug_shotorg.view_ofs * (stof(argv(1)) / debug_shotorg.view_ofs_x); // closer/farther, same xy pos
-               localcmd("sv_cmd debug_shotorg \"", vtos(debug_shotorg.view_ofs), "\"\n");
-       }
-       else if(cmd == "shotorg_toggle_hide") {
-               if(debug_shotorg)
-               {
-                       debug_shotorg.cnt = !debug_shotorg.cnt;
-               }
-       }
-       else if(cmd == "shotorg_end") {
-               if(debug_shotorg)
-               {
-                       print(vtos(debug_shotorg.view_ofs), "\n");
-                       remove(debug_shotorg);
-                       debug_shotorg = world;
-               }
-               localcmd("sv_cmd debug_shotorg\n");
-       }
-       else if(cmd == "sendcvar") {
-               // W_FixWeaponOrder will trash argv, so save what we need.
-               string thiscvar;
-               thiscvar = strzone(argv(1));
-               s = cvar_string(thiscvar);
-               if(thiscvar == "cl_weaponpriority")
-                       s = W_FixWeaponOrder(W_NumberWeaponOrder(s), 1);
-               else if(substring(thiscvar, 0, 17) == "cl_weaponpriority" && strlen(thiscvar) == 18)
-                       s = W_FixWeaponOrder(W_NumberWeaponOrder(s), 0);
-               localcmd("cmd sentcvar ", thiscvar, " \"", s, "\"\n");
-               strunzone(thiscvar);
-       }
-       else if(cmd == "spawn") {
-               s = argv(1);
-               e = spawn();
-               precache_model(s);
-               setmodel(e, s);
-               setorigin(e, view_origin);
-               e.angles = view_angles;
-               e.draw = DrawDebugModel;
-               e.classname = "debugmodel";
-       }
-     else if(cmd == "vyes")
-     {
-         if(uid2name_dialog)
-         {
-             vote_active = 0; // force the panel to disappear right as we have selected the value (to prevent it from fading out in the normal vote panel pos)
-             vote_prev = 0;
-             cvar_set("cl_allow_uid2name", "1");
-             vote_change = -9999;
-         }
-         else
-         {
-             localcmd("cmd vote yes\n");
-         }
-     }
-     else if(cmd == "vno")
-     {
-         if(uid2name_dialog)
-         {
-             vote_active = 0;
-             vote_prev = 0;
-             cvar_set("cl_allow_uid2name", "0");
-             vote_change = -9999;
-         }
-         else
-         {
-             localcmd("cmd vote no\n");
-         }
-     }
-       else
-       {
-               print("Invalid command. For a list of supported commands, try cl_cmd help.\n");
-       }
-       return;
- }
  
  // CSQC_InputEvent : Used to perform actions based on any key pressed, key released and mouse on the client.
  // Return value should be 1 if CSQC handled the input, otherwise return 0 to have the input passed to the engine.
  // All keys are in ascii.
- // bInputType = 0 is key pressed, 1 is key released, 2 is mouse input.
+ // bInputType = 0 is key pressed, 1 is key released, 2 and 3 are mouse input.
  // In the case of keyboard input, nPrimary is the ascii code, and nSecondary is 0.
  // In the case of mouse input, nPrimary is xdelta, nSecondary is ydelta.
+ // In the case of mouse input after a setcursormode(1) call, nPrimary is xpos, nSecondary is ypos.
  float CSQC_InputEvent(float bInputType, float nPrimary, float nSecondary)
  {
-       local float bSkipKey;
+       float bSkipKey;
        bSkipKey = false;
  
        if (HUD_Panel_InputEvent(bInputType, nPrimary, nSecondary))
        if (MapVote_InputEvent(bInputType, nPrimary, nSecondary))
                return true;
  
-       if(menu_visible)
+       if(menu_visible && menu_action)
                if(menu_action(bInputType, nPrimary, nSecondary))
                        return TRUE;
  
  
  // --------------------------------------------------------------------------
  // BEGIN OPTIONAL CSQC FUNCTIONS
+ void Ent_RemoveEntCS()
+ {
+       entcs_receiver[self.sv_entnum] = world;
+ }
  void Ent_ReadEntCS()
  {
+       float sf;
        InterpolateOrigin_Undo();
  
        self.classname = "entcs_receiver";
-       self.sv_entnum = ReadByte() - 1;
-       self.origin_x = ReadShort();
-       self.origin_y = ReadShort();
-       self.origin_z = ReadShort();
-       self.angles_y = ReadByte() * 360.0 / 256;
-       self.origin_z = self.angles_x = self.angles_z = 0;
+       sf = ReadByte();
+       if(sf & 1)
+               self.sv_entnum = ReadByte();
+       if(sf & 2)
+       {
+               self.origin_x = ReadShort();
+               self.origin_y = ReadShort();
+               self.origin_z = ReadShort();
+               setorigin(self, self.origin);
+       }
+       if(sf & 4)
+       {
+               self.angles_y = ReadByte() * 360.0 / 256;
+               self.angles_x = self.angles_z = 0;
+       }
+       if(sf & 8)
+               self.healthvalue = ReadByte() * 10;
+       if(sf & 16)
+               self.armorvalue = ReadByte() * 10;
+       entcs_receiver[self.sv_entnum] = self;
+       self.entremove = Ent_RemoveEntCS;
+       self.iflags |= IFLAG_ORIGIN;
  
        InterpolateOrigin_Note();
  }
@@@ -714,7 -480,8 +480,8 @@@ void Ent_ReadPlayerScore(
  #ifdef DP_CSQC_ENTITY_REMOVE_IS_B0RKED
        if(!isNew && n != self.sv_entnum)
        {
-               print(_("A CSQC entity changed its owner!\n"));
+               //print("A CSQC entity changed its owner!\n");
+               print(sprintf("A CSQC entity changed its owner! (edict: %d, classname: %s)\n", num_for_edict(self), self.classname));
                isNew = true;
                Ent_Remove();
                self.enttype = ENT_CLIENT_SCORES;
@@@ -786,10 -553,6 +553,6 @@@ void Ent_ReadTeamScore(
        HUD_UpdateTeamPos(o);
  }
  
- void Net_Reset()
- {
- }
  void Ent_ClientData()
  {
        float f;
        if(f & 2)
        {
                newspectatee_status = ReadByte();
-               if(newspectatee_status == player_localentnum)
+               if(newspectatee_status == player_localnum + 1)
                        newspectatee_status = -1; // observing
        }
        else
  
        if(newspectatee_status != spectatee_status)
        {
-               float i;
                // clear race stuff
                race_laptime = 0;
                race_checkpointtime = 0;
        }
+       if (autocvar_hud_panel_healtharmor_progressbar_gfx)
+       {
+               if ( (spectatee_status == -1 && newspectatee_status > 0) //before observing, now spectating
+                 || (spectatee_status > 0 && newspectatee_status > 0 && spectatee_status != newspectatee_status) //changed spectated player
+               )
+                       prev_p_health = -1;
+               else if(spectatee_status && !newspectatee_status) //before observing/spectating, now playing
+                       prev_health = -1;
+       }
        spectatee_status = newspectatee_status;
+       // non-COMPAT_XON050_ENGINE: we could get rid of spectatee_status, and derive it from player_localentnum and player_localnum
  }
  
  void Ent_Nagger()
  {
        float nags, i, j, b, f;
  
-       nags = ReadByte();
+       nags = ReadByte(); // NAGS NAGS NAGS NAGS NAGS NAGS NADZ NAGS NAGS NAGS
+       if(!(nags & 4))
+       {
+               if(vote_called_vote)
+                       strunzone(vote_called_vote);
+               vote_called_vote = string_null;
+               vote_active = 0;
+       }
+       else
+       {
+               vote_active = 1;
+       }
+       if(nags & 64)
+       {
+               vote_yescount = ReadByte();
+               vote_nocount = ReadByte();
+               vote_needed = ReadByte();
+               vote_highlighted = ReadChar();
+       }
  
        if(nags & 128)
        {
@@@ -884,8 -676,8 +676,8 @@@ void Ent_ReadAccuracy(void
                        weapon_accuracy[w] = -1;
                return;
        }
-       
-       for(w = 0, f = 1; w <= WEP_LAST - WEP_FIRST; ++w, f *= 2)
+       for(w = 0, f = 1; w <= WEP_LAST - WEP_FIRST; ++w)
        {
                if(sf & f)
                {
                        else
                                weapon_accuracy[w] = (b - 1.0) / 100.0;
                }
+               if(f == 0x800000)
+                       f = 1;
+               else
+                       f *= 2;
+       }
+ }
+ void Spawn_Draw(void)
+ {
+       pointparticles(self.cnt, self.origin + '0 0 28', '0 0 2', bound(0, frametime, 0.1));
+ }
+ void Ent_ReadSpawnPoint(float is_new) // entity for spawnpoint
+ {
+       float teamnum = (ReadByte() - 1);
+       vector spn_origin;
+       spn_origin_x = ReadShort();
+       spn_origin_y = ReadShort();
+       spn_origin_z = ReadShort();
+       
+       if(is_new)
+       {
+               self.origin = spn_origin;
+               setsize(self, PL_MIN, PL_MAX);
+               droptofloor();
+               /*if(autocvar_cl_spawn_point_model) // needs a model first
+               {
+                       self.mdl = "models/spawnpoint.md3";
+                       self.colormod = Team_ColorRGB(teamnum);
+                       precache_model(self.mdl);
+                       setmodel(self, self.mdl);
+                       self.drawmask = MASK_NORMAL;
+                       //self.movetype = MOVETYPE_NOCLIP;
+                       //self.draw = Spawn_Draw;
+               }*/
+               if(autocvar_cl_spawn_point_particles)
+               {
+                       if((serverflags & SERVERFLAG_TEAMPLAY))
+                       {
+                               switch(teamnum)
+                               {
+                                       case NUM_TEAM_1: self.cnt = particleeffectnum("spawn_point_red"); break;
+                                       case NUM_TEAM_2: self.cnt = particleeffectnum("spawn_point_blue"); break;
+                                       case NUM_TEAM_3: self.cnt = particleeffectnum("spawn_point_yellow"); break;
+                                       case NUM_TEAM_4: self.cnt = particleeffectnum("spawn_point_pink"); break;
+                                       default: self.cnt = particleeffectnum("spawn_point_neutral"); break;
+                               }
+                       }
+                       else { self.cnt = particleeffectnum("spawn_point_neutral"); }
+                       
+                       self.draw = Spawn_Draw;
+               }
+       }
+       //print(sprintf("Ent_ReadSpawnPoint(is_new = %d); origin = %s, team = %d, effect = %d\n", is_new, vtos(self.origin), teamnum, self.cnt));
+ }
+ void Ent_ReadSpawnEvent(float is_new)
+ {
+       // If entnum is 0, ONLY do the local spawn actions
+       // this way the server can disable the sending of
+       // spawn origin or such to clients if wanted.
+       float entnum = ReadByte();
+       
+       if(entnum)
+       {
+               self.origin_x = ReadShort();
+               self.origin_y = ReadShort();
+               self.origin_z = ReadShort();
+               if(is_new)
+               {
+                       float teamnum = GetPlayerColor(entnum - 1);
+                       if(autocvar_cl_spawn_event_particles)
+                       {
+                               switch(teamnum)
+                               {
+                                       case NUM_TEAM_1: pointparticles(particleeffectnum("spawn_event_red"), self.origin, '0 0 0', 1); break;
+                                       case NUM_TEAM_2: pointparticles(particleeffectnum("spawn_event_blue"), self.origin, '0 0 0', 1); break;
+                                       case NUM_TEAM_3: pointparticles(particleeffectnum("spawn_event_yellow"), self.origin, '0 0 0', 1); break;
+                                       case NUM_TEAM_4: pointparticles(particleeffectnum("spawn_event_pink"), self.origin, '0 0 0', 1); break;
+                                       default: pointparticles(particleeffectnum("spawn_event_neutral"), self.origin, '0 0 0', 1); break;
+                               }
+                       }
+                       if(autocvar_cl_spawn_event_sound)
+                       {
+                               sound(self, CH_TRIGGER, "misc/spawn.wav", VOL_BASE, ATTN_NORM);
+                       }
+               }
        }
+       
+       // local spawn actions
+       if(is_new && (!entnum || (entnum == player_localentnum)))
+       {
+               zoomin_effect = 1;
+               current_viewzoom = (1 / bound(1, autocvar_cl_spawnzoom_factor, 16));
+               if(autocvar_cl_unpress_zoom_on_spawn)
+               {
+                       localcmd("-zoom\n");
+                       button_zoom = FALSE;
+               }
+       }
+       
+       //print(sprintf("Ent_ReadSpawnEvent(is_new = %d); origin = %s, entnum = %d, localentnum = %d\n", is_new, vtos(self.origin), entnum, player_localentnum));
  }
  
  // CSQC_Ent_Update : Called every frame that the server has indicated an update to the SSQC / CSQC entity has occured.
  void Ent_RadarLink();
  void Ent_Init();
  void Ent_ScoresInfo();
- void(float bIsNewEntity) CSQC_Ent_Update =
+ void CSQC_Ent_Update(float bIsNewEntity)
  {
        float t;
        float savetime;
        t = ReadByte();
  
+       if(autocvar_developer_csqcentities)
+               print(sprintf("CSQC_Ent_Update(%d) with self=%i self.entnum=%d self.enttype=%d t=%d\n", bIsNewEntity, self, self.entnum, self.enttype, t));
        // set up the "time" global for received entities to be correct for interpolation purposes
        savetime = time;
        if(servertime)
  
  #ifdef DP_CSQC_ENTITY_REMOVE_IS_B0RKED
        if(self.enttype)
-               if(t != self.enttype)
+       {
+               if(t != self.enttype || bIsNewEntity)
                {
-                       print(_("A CSQC entity changed its type!\n"));
+                       //print("A CSQC entity changed its type!\n");
+                       print(sprintf("A CSQC entity changed its type! (edict: %d, server: %d, type: %d -> %d)\n", num_for_edict(self), self.entnum, self.enttype, t));
                        Ent_Remove();
+                       clearentity(self);
                        bIsNewEntity = 1;
                }
+       }
+       else
+       {
+               if(!bIsNewEntity)
+               {
+                       print(sprintf("A CSQC entity appeared out of nowhere! (edict: %d, server: %d, type: %d)\n", num_for_edict(self), self.entnum, t));
+                       bIsNewEntity = 1;
+               }
+       }
  #endif
        self.enttype = t;
        switch(t)
                case ENT_CLIENT_TUBANOTE: Ent_TubaNote(bIsNewEntity); break;
                case ENT_CLIENT_WARPZONE: WarpZone_Read(bIsNewEntity); break;
                case ENT_CLIENT_WARPZONE_CAMERA: WarpZone_Camera_Read(bIsNewEntity); break;
+               case ENT_CLIENT_WARPZONE_TELEPORTED: WarpZone_Teleported_Read(bIsNewEntity); break;
                case ENT_CLIENT_TRIGGER_MUSIC: Ent_ReadTriggerMusic(); break;
                case ENT_CLIENT_HOOK: Ent_ReadHook(bIsNewEntity, ENT_CLIENT_HOOK); break;
 -              case ENT_CLIENT_LGBEAM: Ent_ReadHook(bIsNewEntity, ENT_CLIENT_LGBEAM); break;
 +              case ENT_CLIENT_ELECTRO_BEAM: Ent_ReadHook(bIsNewEntity, ENT_CLIENT_ELECTRO_BEAM); break;
 +              case ENT_CLIENT_LIGHTNING_BEAM: Ent_ReadHook(bIsNewEntity, ENT_CLIENT_LIGHTNING_BEAM); break;
                case ENT_CLIENT_GAUNTLET: Ent_ReadHook(bIsNewEntity, ENT_CLIENT_GAUNTLET); break;
                case ENT_CLIENT_ACCURACY: Ent_ReadAccuracy(); break;
+               case ENT_CLIENT_AUXILIARYXHAIR: Net_AuXair2(bIsNewEntity); break;
+               case ENT_CLIENT_TURRET: ent_turret(); break; 
+               case ENT_CLIENT_MODEL: CSQCModel_Read(bIsNewEntity); break;
+               case ENT_CLIENT_ITEM: ItemRead(bIsNewEntity); break;  
+               case ENT_CLIENT_BUMBLE_RAYGUN: bumble_raygun_read(bIsNewEntity); break;
+               case ENT_CLIENT_SPAWNPOINT: Ent_ReadSpawnPoint(bIsNewEntity); break;
+               case ENT_CLIENT_SPAWNEVENT: Ent_ReadSpawnEvent(bIsNewEntity); break;
+               case ENT_CLIENT_NOTIFICATION: Read_Notification(bIsNewEntity); break;
                default:
-                       error(strcat(_("unknown entity type in CSQC_Ent_Update: %d\n"), self.enttype));
+                       //error(strcat(_("unknown entity type in CSQC_Ent_Update: %d\n"), self.enttype));
+                       error(sprintf(_("Unknown entity type in CSQC_Ent_Update (enttype: %d, edict: %d, classname: %s)\n"), self.enttype, num_for_edict(self), self.classname));
                        break;
        }
  
        time = savetime;
- };
+ }
  // Destructor, but does NOT deallocate the entity by calling remove(). Also
  // used when an entity changes its type. For an entity that someone interacts
  // with others, make sure it can no longer do so.
@@@ -980,6 -903,18 +904,18 @@@ void Ent_Remove(
        if(self.entremove)
                self.entremove();
  
+       if(self.skeletonindex)
+       {
+               skel_delete(self.skeletonindex);
+               self.skeletonindex = 0;
+       }
+       if(self.snd_looping > 0)
+       {
+               sound(self, self.snd_looping, "misc/null.wav", VOL_BASE, autocvar_g_jetpack_attenuation);
+               self.snd_looping = 0;
+       }
        self.enttype = 0;
        self.classname = "";
        self.draw = menu_sub_null;
  // CSQC_Ent_Remove : Called when the server requests a SSQC / CSQC entity to be removed.  Essentially call remove(self) as well.
  void CSQC_Ent_Remove()
  {
+       if(autocvar_developer_csqcentities)
+               print(sprintf("CSQC_Ent_Remove() with self=%i self.entnum=%d self.enttype=%d\n", self, self.entnum, self.enttype));
+       if(wasfreed(self))
+       {
+               print("WARNING: CSQC_Ent_Remove called for already removed entity. Packet loss?\n");
+               return;
+       }
        if(self.enttype)
                Ent_Remove();
        remove(self);
  
  void Gamemode_Init()
  {
-       if(gametype == GAME_ONSLAUGHT) {
-               print(strcat("Using ", minimapname, " as minimap.\n"));
-               precache_pic("gfx/ons-cp-neutral.tga");
-               precache_pic("gfx/ons-cp-red.tga");
-               precache_pic("gfx/ons-cp-blue.tga");
-               precache_pic("gfx/ons-frame.tga");
-               precache_pic("gfx/ons-frame-team.tga");
-       }
        if not(isdemo())
        {
-               localcmd("\n_cl_hook_gamestart ", GametypeNameFromType(gametype), "\n");
+               if(!(calledhooks & HOOK_START))
+                       localcmd("\n_cl_hook_gamestart ", MapInfo_Type_ToString(gametype), "\n");
                calledhooks |= HOOK_START;
        }
  }
  // CSQC_Parse_StuffCmd : Provides the stuffcmd string in the first parameter that the server provided.  To execute standard behavior, simply execute localcmd with the string.
  void CSQC_Parse_StuffCmd(string strMessage)
  {
+       if(autocvar_developer_csqcentities)
+               print(sprintf("CSQC_Parse_StuffCmd(\"%s\")\n", strMessage));
        localcmd(strMessage);
  }
  // CSQC_Parse_Print : Provides the print string in the first parameter that the server provided.  To execute standard behavior, simply execute print with the string.
  void CSQC_Parse_Print(string strMessage)
  {
+       if(autocvar_developer_csqcentities)
+               print(sprintf("CSQC_Parse_Print(\"%s\")\n", strMessage));
        print(ColorTranslateRGB(strMessage));
  }
  
- // CSQC_Parse_CenterPrint : Provides the centerprint string in the first parameter that the server provided.
+ // CSQC_Parse_CenterPrint : Provides the centerprint_hud string in the first parameter that the server provided.
  void CSQC_Parse_CenterPrint(string strMessage)
  {
-       centerprint(strMessage);
+       if(autocvar_developer_csqcentities)
+               print(sprintf("CSQC_Parse_CenterPrint(\"%s\")\n", strMessage));
+       centerprint_hud(strMessage);
  }
  
  string notranslate_fogcmd1 = "\nfog ";
@@@ -1043,7 -987,7 +988,7 @@@ void Ent_ScoresInfo(
  {
        float i;
        self.classname = "ent_client_scores_info";
-       gametype = ReadByte();
+       gametype = ReadInt24_t();
        for(i = 0; i < MAX_SCORE; ++i)
        {
                scores_label[i] = strzone(ReadString());
@@@ -1072,10 -1016,6 +1017,10 @@@ void Ent_Init(
        electro_shotorigin[1] = decompressShotOrigin(ReadInt24_t());
        electro_shotorigin[2] = decompressShotOrigin(ReadInt24_t());
        electro_shotorigin[3] = decompressShotOrigin(ReadInt24_t());
 +      lightning_shotorigin[0] = decompressShotOrigin(ReadInt24_t());
 +      lightning_shotorigin[1] = decompressShotOrigin(ReadInt24_t());
 +      lightning_shotorigin[2] = decompressShotOrigin(ReadInt24_t());
 +      lightning_shotorigin[3] = decompressShotOrigin(ReadInt24_t());
        gauntlet_shotorigin[0] = decompressShotOrigin(ReadInt24_t());
        gauntlet_shotorigin[1] = decompressShotOrigin(ReadInt24_t());
        gauntlet_shotorigin[2] = decompressShotOrigin(ReadInt24_t());
  
        armorblockpercent = ReadByte() / 255.0;
  
-       g_weaponswitchdelay = ReadByte() / 255.0;
        g_balance_grenadelauncher_bouncefactor = ReadCoord();
        g_balance_grenadelauncher_bouncestop = ReadCoord();
        g_balance_electro_secondary_bouncefactor = ReadCoord();
        g_balance_electro_secondary_bouncestop = ReadCoord();
  
        nex_scope = !ReadByte();
-       sniperrifle_scope = !ReadByte();
+       rifle_scope = !ReadByte();
  
        serverflags = ReadByte();
  
-       cr_maxbullets = ReadByte();
-       
        minelayer_maxmines = ReadByte();
  
+       hagar_maxrockets = ReadByte();
        g_trueaim_minrange = ReadCoord();
+       g_balance_porto_secondary = ReadByte();
  
        if(!postinit)
                PostInit();
@@@ -1254,7 -1193,7 +1198,7 @@@ void Net_ReadRace(
                                strunzone(grecordholder[pos-1]);
                        grecordholder[pos-1] = strzone(ReadString());
                        grecordtime[pos-1] = ReadInt24_t();
-                       if(grecordholder[pos-1] == GetPlayerName(player_localentnum -1))
+                       if(grecordholder[pos-1] == GetPlayerName(player_localnum))
                                race_myrank = pos;
                        break;
                case RACE_NET_SERVER_STATUS:
        }
  }
  
- void Net_ReadSpawn()
- {
-       zoomin_effect = 1;
-       current_viewzoom = 0.6;
- }
  void Net_TeamNagger()
  {
        teamnagger = 1;
@@@ -1290,37 -1223,8 +1228,8 @@@ void Net_ReadPingPLReport(
        playerslots[e].ping_movementloss = ml / 255.0;
  }
  
- void Net_VoteDialog(float highlight) {
-       if(highlight) {
-               vote_highlighted = ReadByte();
-               return;
-       }
-       vote_yescount = ReadByte();
-       vote_nocount = ReadByte();
-       vote_needed = ReadByte();
-       vote_active = 1;
- }
- void Net_VoteDialogReset() {
-       vote_active = 0;
- }
- void Net_Notify() {
-       float type;
-       type = ReadByte();
-       if(type == CSQC_KILLNOTIFY)
-       {
-               HUD_KillNotify(ReadString(), ReadString(), ReadString(), ReadShort(), ReadByte());
-       }
-       else if(type == CSQC_CENTERPRINT)
-       {
-               HUD_Centerprint(ReadString(), ReadString(), ReadShort(), ReadByte());
-       }
- }
- void Net_WeaponComplain() {
+ void Net_WeaponComplain()
+ {
        complain_weapon = ReadByte();
  
        if(complain_weapon_name)
  
        complain_weapon_time = time;
        weapontime = time; // ping the weapon panel
+       switch(complain_weapon_type)
+       {
+               case 0: Local_Notification(MSG_MULTI, ITEM_WEAPON_NOAMMO, complain_weapon); break;
+               case 1: Local_Notification(MSG_MULTI, ITEM_WEAPON_DONTHAVE, complain_weapon); break;
+               default: Local_Notification(MSG_MULTI, ITEM_WEAPON_UNAVAILABLE, complain_weapon); break;
+       }
  }
  
  // CSQC_Parse_TempEntity : Handles all temporary entity network data in the CSQC layer.
  // Return value should be 1 if CSQC handled the temporary entity, otherwise return 0 to have the engine process the event.
  float CSQC_Parse_TempEntity()
  {
-       local float bHandled;
+       float bHandled;
                bHandled  = true;
        // Acquire TE ID
-       local float nTEID;
+       float nTEID;
                nTEID = ReadByte();
  
+       if(autocvar_developer_csqcentities)
+               print(sprintf("CSQC_Parse_TempEntity() with nTEID=%d\n", nTEID));
                // NOTE: Could just do return instead of break...
        switch(nTEID)
        {
                        Net_ReadRace();
                        bHandled = true;
                        break;
-               case TE_CSQC_SPAWN:
-                       Net_ReadSpawn();
-                       bHandled = true;
-                       break;
                case TE_CSQC_ZCURVEPARTICLES:
                        Net_ReadZCurveParticles();
                        bHandled = true;
                        Net_TeamNagger();
                        bHandled = true;
                        break;
-               case TE_CSQC_VOTE:
-                       Net_VoteDialog(ReadByte());
-                       bHandled = true;
-                       break;
-               case TE_CSQC_VOTERESET:
-                       Net_VoteDialogReset();
-                       bHandled = true;
-                       break;
                case TE_CSQC_LIGHTNINGARC:
                        Net_ReadLightningarc();
                        bHandled = true;
                        Net_ReadPingPLReport();
                        bHandled = true;
                        break;
-               case TE_CSQC_ANNOUNCE:
-                       announce_snd = strzone(ReadString());
+               case TE_CSQC_WEAPONCOMPLAIN:
+                       Net_WeaponComplain();
                        bHandled = true;
                        break;
-               case TE_CSQC_NOTIFY:
-                       Net_Notify();
+               case TE_CSQC_VEHICLESETUP:
+                       Net_VehicleSetup();
                        bHandled = true;
                        break;
-               case TE_CSQC_WEAPONCOMPLAIN:
-                       Net_WeaponComplain();
+               case TE_CSQC_SVNOTICE:
+                       cl_notice_read();
                        bHandled = true;
                        break;
                default:
  string getcommandkey(string text, string command)
  {
        string keys;
-       float n, j, k, l;
+       float n, j, k, l = 0;
  
-       if (!hud_showbinds)
+       if (!autocvar_hud_showbinds)
                return text;
  
        keys = db_get(binddb, command);
-       if (!keys)
+       if (keys == "")
        {
-               n = tokenize(findkeysforcommand(command)); // uses '...' strings
+               n = tokenize(findkeysforcommand(command, 0)); // uses '...' strings
                for(j = 0; j < n; ++j)
                {
                        k = stof(argv(j));
                                        keys = strcat(keys, ", ", keynumtostring(k));
  
                                ++l;
-                               if (hud_showbinds_limit > 0 && hud_showbinds_limit >= l) break;
+                               if (autocvar_hud_showbinds_limit > 0 && autocvar_hud_showbinds_limit <= l)
+                                       break;
                        }
  
                }
+               if (keys == "")
+                       keys = "NO_KEY";
                db_put(binddb, command, keys);
        }
  
-       if ("" == keys) {
-               if (hud_showbinds > 1)
+       if (keys == "NO_KEY") {
+               if (autocvar_hud_showbinds > 1)
                        return sprintf(_("%s (not bound)"), text);
                else
                        return text;
        }
-       else if (hud_showbinds > 1)
+       else if (autocvar_hud_showbinds > 1)
                return sprintf(_("%s (%s)"), text, keys);
        else
                return keys;
diff --combined qcsrc/client/hook.qc
index dc0780e047608f54b718cdb40a9fe96179c73ac4,11070bae5cfe4c10500e36db2b5b3c7bb6607ffb..a228d22b82df8175f7d431425a923547c32fec69
@@@ -4,7 -4,7 +4,7 @@@
  .float HookSilent;
  .float HookRange;
  
- void Draw_CylindricLine(vector from, vector to, float thickness, string texture, float aspect, float shift, vector rgb, float alpha, float drawflag, vector vieworg)
+ void Draw_CylindricLine(vector from, vector to, float thickness, string texture, float aspect, float shift, vector rgb, float theAlpha, float drawflag, vector vieworg)
  {
        // I want to draw a quad...
        // from and to are MIDPOINTS.
        D = to - thickdir * (thickness / 2);
  
        R_BeginPolygon(texture, drawflag);
-       R_PolygonVertex(A, '0 0 0' + shift * '1 0 0', rgb, alpha);
-       R_PolygonVertex(B, '0 1 0' + shift * '1 0 0', rgb, alpha);
-       R_PolygonVertex(C, '0 1 0' + (shift + length_tex) * '1 0 0', rgb, alpha);
-       R_PolygonVertex(D, '0 0 0' + (shift + length_tex) * '1 0 0', rgb, alpha);
+       R_PolygonVertex(A, '0 0 0' + shift * '1 0 0', rgb, theAlpha);
+       R_PolygonVertex(B, '0 1 0' + shift * '1 0 0', rgb, theAlpha);
+       R_PolygonVertex(C, '0 1 0' + (shift + length_tex) * '1 0 0', rgb, theAlpha);
+       R_PolygonVertex(D, '0 0 0' + (shift + length_tex) * '1 0 0', rgb, theAlpha);
        R_EndPolygon();
  }
  
@@@ -59,7 -59,7 +59,7 @@@ void Draw_GrapplingHook(
        if(self.teleport_time)
        if(time > self.teleport_time)
        {
-               sound (self, CHAN_PROJECTILE, "misc/null.wav", VOL_BASE, ATTN_NORM); // safeguard
+               sound (self, CH_SHOTS_SINGLE, "misc/null.wav", VOL_BASE, ATTN_NORM); // safeguard
                self.teleport_time = 0;
        }
  
                case ENT_CLIENT_HOOK:
                        vs = hook_shotorigin[s];
                        break;
 -              case ENT_CLIENT_LGBEAM:
 +              case ENT_CLIENT_ELECTRO_BEAM:
                        vs = electro_shotorigin[s];
                        break;
 +              case ENT_CLIENT_LIGHTNING_BEAM:
 +                      vs = lightning_shotorigin[s];
 +                      break;
                case ENT_CLIENT_GAUNTLET:
                        vs = gauntlet_shotorigin[s];
                        break;
@@@ -95,8 -92,7 +95,8 @@@
                                a = view_origin + view_forward * vs_x + view_right * -vs_y + view_up * vs_z;
                                b = self.origin;
                                break;
 -                      case ENT_CLIENT_LGBEAM:
 +                      case ENT_CLIENT_ELECTRO_BEAM:
 +                      case ENT_CLIENT_LIGHTNING_BEAM:
                        case ENT_CLIENT_GAUNTLET:
                                if(self.HookRange)
                                        b = view_origin + view_forward * self.HookRange;
                                a = self.velocity;
                                b = self.origin;
                                break;
 -                      case ENT_CLIENT_LGBEAM:
 +                      case ENT_CLIENT_ELECTRO_BEAM:
 +                      case ENT_CLIENT_LIGHTNING_BEAM:
                        case ENT_CLIENT_GAUNTLET:
                                a = self.origin;
                                b = self.velocity;
                case ENT_CLIENT_HOOK:
                        intensity = 1;
                        offset = 0;
-                       if(t == COLOR_TEAM1)
+                       if(t == NUM_TEAM_1)
                        {
                                tex = "particles/hook_red";
                                rgb = '1 .3 .3';
                        }
-                       else if(t == COLOR_TEAM2)
+                       else if(t == NUM_TEAM_2)
                        {
                                tex = "particles/hook_blue";
                                rgb = '.3 .3 1';
                        }
-                       else if(t == COLOR_TEAM3)
+                       else if(t == NUM_TEAM_3)
                        {
                                tex = "particles/hook_yellow";
                                rgb = '1 1 .3';
                        }
-                       else if(t == COLOR_TEAM4)
+                       else if(t == NUM_TEAM_4)
                        {
                                tex = "particles/hook_pink";
                                rgb = '1 .3 1';
                                rgb = '.3 1 .3';
                        }
                        break;
 -              case ENT_CLIENT_LGBEAM:
 +              case ENT_CLIENT_ELECTRO_BEAM:
 +                      intensity = bound(0.2, 1 + Noise_Pink(self, frametime) * 1 + Noise_Burst(self, frametime, 0.03) * 0.3, 2);
 +                      offset = Noise_Brown(self, frametime) * 10;
 +                      tex = "particles/lgbeam";
 +                      rgb = '1 1 1';
 +                      break;
 +              case ENT_CLIENT_LIGHTNING_BEAM: // todo
                        intensity = bound(0.2, 1 + Noise_Pink(self, frametime) * 1 + Noise_Burst(self, frametime, 0.03) * 0.3, 2);
                        offset = Noise_Brown(self, frametime) * 10;
                        tex = "particles/lgbeam";
                                self.drawmask = 0;
                        }
                        break;
 -              case ENT_CLIENT_LGBEAM:
 +              case ENT_CLIENT_ELECTRO_BEAM:
 +              case ENT_CLIENT_LIGHTNING_BEAM:
                case ENT_CLIENT_GAUNTLET:
                        setorigin(self, a); // beam origin!
                        break;
                default:
                case ENT_CLIENT_HOOK:
                        break;
 -              case ENT_CLIENT_LGBEAM:
 -                      pointparticles(particleeffectnum("electro_lightning"), trace_endpos, normalize(atrans - trace_endpos), frametime * intensity);
 +              case ENT_CLIENT_ELECTRO_BEAM:
 +                      pointparticles(particleeffectnum("electro_lightning"), trace_endpos, normalize(atrans - trace_endpos), frametime * intensity); // todo: new effect
 +                      break;
 +              case ENT_CLIENT_LIGHTNING_BEAM:
 +                      pointparticles(particleeffectnum("electro_lightning"), trace_endpos, normalize(atrans - trace_endpos), frametime * intensity); // todo: new effect
                        break;
                case ENT_CLIENT_GAUNTLET:
                        pointparticles(particleeffectnum("gauntlet_lightning"), b, normalize(a - b), frametime * intensity);
  
  void Remove_GrapplingHook()
  {
-       sound (self, CHAN_PROJECTILE, "misc/null.wav", VOL_BASE, ATTN_NORM);
+       sound (self, CH_SHOTS_SINGLE, "misc/null.wav", VOL_BASE, ATTN_NORM);
  }
  
  void Ent_ReadHook(float bIsNew, float type)
        sf = ReadByte();
  
        self.HookSilent = (sf & 0x80);
-       self.iflags = IFLAG_VELOCITY;
+       self.iflags = IFLAG_VELOCITY | IFLAG_ORIGIN;
  
        InterpolateOrigin_Undo();
  
                        case ENT_CLIENT_GAUNTLET:
                                self.HookRange = 0;
                                break;
 -                      case ENT_CLIENT_LGBEAM:
 +                      case ENT_CLIENT_ELECTRO_BEAM:
 +                      case ENT_CLIENT_LIGHTNING_BEAM:
                                self.HookRange = ReadCoord();
                                break;
                }
                                setmodel(self, "models/hook.md3");
                                self.drawmask = MASK_NORMAL;
                                break;
 -                      case ENT_CLIENT_LGBEAM:
 +                      case ENT_CLIENT_ELECTRO_BEAM:
-                               sound (self, CHAN_PROJECTILE, "weapons/lgbeam_fly.wav", VOL_BASE, ATTN_NORM);
++                              sound (self, CH_SHOTS_SINGLE, "weapons/lgbeam_fly.wav", VOL_BASE, ATTN_NORM);
 +                              break;
 +                      case ENT_CLIENT_LIGHTNING_BEAM:
-                               sound (self, CHAN_PROJECTILE, "weapons/lgbeam_fly.wav", VOL_BASE, ATTN_NORM);
+                               sound (self, CH_SHOTS_SINGLE, "weapons/lgbeam_fly.wav", VOL_BASE, ATTN_NORM);
                                break;
                        case ENT_CLIENT_GAUNTLET:
-                               sound (self, CHAN_PROJECTILE, "weapons/gauntletbeam_fly.wav", VOL_BASE, ATTN_NORM);
+                               sound (self, CH_SHOTS_SINGLE, "weapons/gauntletbeam_fly.wav", VOL_BASE, ATTN_NORM);
                                break;
                }
        }
index c10961a39f9dba862bc05d1a271761740d28568d,b399f3857c3454e3c16572d0aed19a7aea627801..6e3e8027dc33f86d01f17f1c049538fa7cd3e3c6
  // Revision 22: hook shot origin
  #define CSQC_REVISION 22
  
- // probably put these in common/
- // so server/ and client/ can be synced better
- const float GAME_DEATHMATCH           = 1;
- const float GAME_TEAM_DEATHMATCH      = 2;
- const float GAME_DOMINATION           = 3;
- const float GAME_CTF                  = 4;
- const float GAME_RUNEMATCH            = 5;
- const float GAME_LMS                  = 6;
- const float GAME_ARENA                = 7;
- const float GAME_KEYHUNT              = 8;
- const float GAME_ASSAULT              = 9;
- const float GAME_ONSLAUGHT    = 10;
- const float GAME_RACE = 11;
- const float GAME_NEXBALL = 12;
- const float GAME_CTS = 13;
- const float GAME_CA           = 14;
- const float GAME_FREEZETAG            = 15;
- const float GAME_KEEPAWAY             = 16;
  const float AS_STRING         = 1;
  const float AS_INT            = 2;
  const float AS_FLOAT_TRUNCATED        = 2;
@@@ -49,21 -30,18 +30,18 @@@ const float AS_FLOAT               = 8
  
  const float TE_CSQC_PICTURE = 100;
  const float TE_CSQC_RACE = 101;
- const float TE_CSQC_SPAWN = 102;
- const float TE_CSQC_ZCURVEPARTICLES = 103;
- const float TE_CSQC_NEXGUNBEAMPARTICLE = 104;
- const float TE_CSQC_LIGHTNINGARC = 105;
- const float TE_CSQC_TEAMNAGGER = 106;
- const float TE_CSQC_PINGPLREPORT = 107;
- const float TE_CSQC_VOTE = 108;
- const float TE_CSQC_VOTERESET = 109;
- const float TE_CSQC_ANNOUNCE = 110;
- const float TE_CSQC_TARGET_MUSIC = 111;
- const float TE_CSQC_NOTIFY = 112;
- const float TE_CSQC_WEAPONCOMPLAIN = 113;
- const float TE_CSQC_NEX_SCOPE = 116;
- const float TE_CSQC_CR_MAXBULLETS = 117;
- const float TE_CSQC_MINELAYER_MAXMINES = 118;
+ const float TE_CSQC_ZCURVEPARTICLES = 102;
+ const float TE_CSQC_NEXGUNBEAMPARTICLE = 103;
+ const float TE_CSQC_LIGHTNINGARC = 104;
+ const float TE_CSQC_TEAMNAGGER = 105;
+ const float TE_CSQC_PINGPLREPORT = 106;
+ const float TE_CSQC_TARGET_MUSIC = 107;
+ const float TE_CSQC_WEAPONCOMPLAIN = 108;
+ const float TE_CSQC_NEX_SCOPE = 109;
+ const float TE_CSQC_MINELAYER_MAXMINES = 110;
+ const float TE_CSQC_HAGAR_MAXROCKETS = 111;
+ const float TE_CSQC_VEHICLESETUP = 112;
+ const float TE_CSQC_SVNOTICE = 113;
  
  const float RACE_NET_CHECKPOINT_HIT_QUALIFYING = 0; // byte checkpoint, short time, short recordtime, string recordholder
  const float RACE_NET_CHECKPOINT_CLEAR = 1;
@@@ -80,9 -58,6 +58,6 @@@ const float RACE_NET_SERVER_RANKINGS = 
  const float RACE_NET_SERVER_STATUS = 12;
  const float RANKINGS_CNT = 15;
  
- const float CSQC_KILLNOTIFY = 0;
- const float CSQC_CENTERPRINT = 1;
  const float ENT_CLIENT = 0;
  const float ENT_CLIENT_DEAD = 1;
  const float ENT_CLIENT_ENTCS = 2;
@@@ -111,16 -86,26 +86,27 @@@ const float ENT_CLIENT_WARPZONE = 24
  const float ENT_CLIENT_WARPZONE_CAMERA = 25;
  const float ENT_CLIENT_TRIGGER_MUSIC = 26;
  const float ENT_CLIENT_HOOK = 27;
 -const float ENT_CLIENT_LGBEAM = 28;
 -const float ENT_CLIENT_GAUNTLET = 29;
 -const float ENT_CLIENT_ACCURACY = 30;
 -const float ENT_CLIENT_SHOWNAMES = 31;
 -const float ENT_CLIENT_WARPZONE_TELEPORTED = 32;
 -const float ENT_CLIENT_MODEL = 33;
 -const float ENT_CLIENT_ITEM = 34;
 -const float ENT_CLIENT_BUMBLE_RAYGUN = 35;
 -const float ENT_CLIENT_SPAWNPOINT = 36;
 -const float ENT_CLIENT_SPAWNEVENT = 37;
 -const float ENT_CLIENT_NOTIFICATION = 38;
 +const float ENT_CLIENT_ELECTRO_BEAM = 28;
 +const float ENT_CLIENT_LIGHTNING_BEAM = 29;
 +const float ENT_CLIENT_GAUNTLET = 30;
 +const float ENT_CLIENT_ACCURACY = 31;
++const float ENT_CLIENT_SHOWNAMES = 32;
++const float ENT_CLIENT_WARPZONE_TELEPORTED = 33;
++const float ENT_CLIENT_MODEL = 34;
++const float ENT_CLIENT_ITEM = 35;
++const float ENT_CLIENT_BUMBLE_RAYGUN = 36;
++const float ENT_CLIENT_SPAWNPOINT = 37;
++const float ENT_CLIENT_SPAWNEVENT = 38;
++const float ENT_CLIENT_NOTIFICATION = 39;
  
  const float ENT_CLIENT_TURRET = 40;
+ const float ENT_CLIENT_AUXILIARYXHAIR = 50;
+ const float ENT_CLIENT_VEHICLE = 60;
  
  const float SPRITERULE_DEFAULT = 0;
  const float SPRITERULE_TEAMPLAY = 1;
  
+ const float RADARICON_NONE = 0;
  const float RADARICON_FLAG = 1;
  const float RADARICON_FLAGCARRIER = 1;
  const float RADARICON_HERE = 1; // TODO make these 3 and 4, and make images for them
@@@ -132,151 -117,7 +118,7 @@@ const float RADARICON_GENERATOR = 1
  const float RADARICON_OBJECTIVE = 1;
  const float RADARICON_DOMPOINT = 1;
  const float RADARICON_POWERUP = 1;
- ///////////////////////////
- // key constants
- //
- // these are the key numbers that should be passed to Key_Event
- //
- const float K_TAB                     =       9;
- const float K_ENTER           =       13;
- const float K_ESCAPE          =       27;
- const float K_SPACE           =       32;
- // normal keys should be passed as lowercased ascii
- const float K_BACKSPACE       =       127;
- const float K_UPARROW         =       128;
- const float K_DOWNARROW       =       129;
- const float K_LEFTARROW       =       130;
- const float K_RIGHTARROW      =       131;
- const float K_ALT             =       132;
- const float K_CTRL    =       133;
- const float K_SHIFT   =       134;
- const float K_F1              =       135;
- const float K_F2              =       136;
- const float K_F3              =       137;
- const float K_F4              =       138;
- const float K_F5              =       139;
- const float K_F6              =       140;
- const float K_F7              =       141;
- const float K_F8              =       142;
- const float K_F9              =       143;
- const float K_F10             =       144;
- const float K_F11             =       145;
- const float K_F12             =       146;
- const float K_INS             =       147;
- const float K_DEL             =       148;
- const float K_PGDN    =       149;
- const float K_PGUP    =       150;
- const float K_HOME    =       151;
- const float K_END             =       152;
- const float K_NUMLOCK         =       154;
- const float K_CAPSLOCK                =       155;
- const float K_SCROLLOCK               =       156;
- const float K_KP_0                    =       157;
- const float K_KP_INS          =       K_KP_0;
- const float K_KP_1                    =       158;
- const float K_KP_END          =       K_KP_1;
- const float K_KP_2                    =       159;
- const float K_KP_DOWNARROW    =       K_KP_2;
- const float K_KP_3                    =       160;
- const float K_KP_PGDN         =       K_KP_3;
- const float K_KP_4                    =       161;
- const float K_KP_LEFTARROW    =       K_KP_4;
- const float K_KP_5                    =       162;
- const float K_KP_6                    =       163;
- const float K_KP_RIGHTARROW   =       K_KP_6;
- const float K_KP_7                    =       164;
- const float K_KP_HOME         =       K_KP_7;
- const float K_KP_8                    =       165;
- const float K_KP_UPARROW      =       K_KP_8;
- const float K_KP_9                    =       166;
- const float K_KP_PGUP         =       K_KP_9;
- const float K_KP_PERIOD               =       167;
- const float K_KP_DEL          =       K_KP_PERIOD;
- const float K_KP_DIVIDE               =       168;
- const float K_KP_SLASH                =       K_KP_DIVIDE;
- const float K_KP_MULTIPLY     =       169;
- const float K_KP_MINUS                =       170;
- const float K_KP_PLUS         =       171;
- const float K_KP_ENTER                =       172;
- const float K_KP_EQUALS               =       173;
- const float K_PAUSE           =       255;
- //
- // joystick buttons
- //
- const float K_JOY1            =       768;
- const float K_JOY2            =       769;
- const float K_JOY3            =       770;
- const float K_JOY4            =       771;
- //
- // aux keys are for multi-buttoned joysticks to generate so they can use
- // the normal binding process
- //
- const float K_AUX1            =       772;
- const float K_AUX2            =       773;
- const float K_AUX3            =       774;
- const float K_AUX4            =       775;
- const float K_AUX5            =       776;
- const float K_AUX6            =       777;
- const float K_AUX7            =       778;
- const float K_AUX8            =       779;
- const float K_AUX9            =       780;
- const float K_AUX10           =       781;
- const float K_AUX11           =       782;
- const float K_AUX12           =       783;
- const float K_AUX13           =       784;
- const float K_AUX14           =       785;
- const float K_AUX15           =       786;
- const float K_AUX16           =       787;
- const float K_AUX17           =       788;
- const float K_AUX18           =       789;
- const float K_AUX19           =       790;
- const float K_AUX20           =       791;
- const float K_AUX21           =       792;
- const float K_AUX22           =       793;
- const float K_AUX23           =       794;
- const float K_AUX24           =       795;
- const float K_AUX25           =       796;
- const float K_AUX26           =       797;
- const float K_AUX27           =       798;
- const float K_AUX28           =       799;
- const float K_AUX29           =       800;
- const float K_AUX30           =       801;
- const float K_AUX31           =       802;
- const float K_AUX32           =       803;
- //
- // mouse buttons generate virtual keys
- //
- const float K_MOUSE1          =       512;
- const float K_MOUSE2          =       513;
- const float K_MOUSE3          =       514;
- const float K_MWHEELUP        =       515;
- const float K_MWHEELDOWN      =       516;
- const float K_MOUSE4          =       517;
- const float K_MOUSE5          =       518;
- const float K_MOUSE6          =       519;
- const float K_MOUSE7          =       520;
- const float K_MOUSE8          =       521;
- const float K_MOUSE9          =       522;
- const float K_MOUSE10         =       523;
- const float K_MOUSE11         =       524;
- const float K_MOUSE12         =       525;
- const float K_MOUSE13         =       526;
- const float K_MOUSE14         =       527;
- const float K_MOUSE15         =       528;
- const float K_MOUSE16         =       529;
+ const float RADARICON_TAGGED = 1;
  
  ///////////////////////////
  // keys pressed
@@@ -286,6 -127,8 +128,8 @@@ const float KEY_LEFT               =       4
  const float KEY_RIGHT         =       8;
  const float KEY_JUMP          =       16;
  const float KEY_CROUCH                =       32;
+ const float KEY_ATCK          =       64;
+ const float KEY_ATCK2         =       128;
  
  ///////////////////////////
  // cvar constants
@@@ -310,32 -153,18 +154,18 @@@ const float STAT_FUEL = 44
  const float STAT_NB_METERSTART = 45;
  const float STAT_SHOTORG = 46; // compressShotOrigin
  const float STAT_LEADLIMIT = 47;
- const float STAT_BULLETS_LOADED = 48;
- const float STAT_NEX_CHARGE = 49;
- const float STAT_LAST_PICKUP = 50;
- const float STAT_HUD = 51;
- const float STAT_NEX_CHARGEPOOL = 52;
- const float STAT_HIT_TIME = 53;
- const float STAT_TYPEHIT_TIME = 54;
- const float STAT_LAYED_MINES = 55;
- // see DP source, quakedef.h
- const float STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW = 222;
- const float STAT_MOVEVARS_AIRSTRAFEACCEL_QW = 223;
- const float STAT_MOVEVARS_MAXSPEED = 244;
- const float STAT_MOVEVARS_AIRACCEL_QW = 254;
- const float CTF_STATE_ATTACK = 1;
- const float CTF_STATE_DEFEND = 2;
- const float CTF_STATE_COMMANDER = 3;
- const float HUD_NORMAL = 0;
- const float HUD_SPIDERBOT = 10;
- const float HUD_WAKIZASHI = 11;
- const float HUD_RAPTOR    = 12;
- const vector eX = '1 0 0';
- const vector eY = '0 1 0';
- const vector eZ = '0 0 1';
+ const float STAT_WEAPON_CLIPLOAD = 48;
+ const float STAT_WEAPON_CLIPSIZE = 49;
+ const float STAT_NEX_CHARGE = 50;
+ const float STAT_LAST_PICKUP = 51;
+ const float STAT_HUD = 52;
+ const float STAT_NEX_CHARGEPOOL = 53;
+ const float STAT_HIT_TIME = 54;
+ const float STAT_TYPEHIT_TIME = 55;
+ const float STAT_LAYED_MINES = 56;
+ const float STAT_HAGAR_LOAD = 57;
+ const float STAT_SWITCHINGWEAPON = 58;
+ const float STAT_SUPERWEAPONS_FINISHED = 59;
  
  const float STAT_VEHICLESTAT_HEALTH  = 60;
  const float STAT_VEHICLESTAT_SHIELD  = 61;
@@@ -345,6 -174,12 +175,12 @@@ const float STAT_VEHICLESTAT_RELOAD1 = 
  const float STAT_VEHICLESTAT_AMMO2   = 65;
  const float STAT_VEHICLESTAT_RELOAD2 = 66;
  
+ const float STAT_SECRETS_TOTAL = 70;
+ const float STAT_SECRETS_FOUND = 71;
+ const float STAT_RESPAWN_TIME = 72;
+ const float STAT_ROUNDSTARTTIME = 73;
  // mod stats (1xx)
  const float STAT_REDALIVE = 100;
  const float STAT_BLUEALIVE = 101;
@@@ -355,11 -190,38 +191,38 @@@ const float STAT_PINKALIVE = 103
  const float STAT_FROZEN = 104;
  const float STAT_REVIVE_PROGRESS = 105;
  
+ // domination
+ const float STAT_DOM_TOTAL_PPS = 100;
+ const float STAT_DOM_PPS_RED = 101;
+ const float STAT_DOM_PPS_BLUE = 102;
+ const float STAT_DOM_PPS_PINK = 103;
+ const float STAT_DOM_PPS_YELLOW = 104;
  //const float STAT_SPIDERBOT_AIM     53 // compressShotOrigin
  //const float STAT_SPIDERBOT_TARGET  54 // compressShotOrigin
  
+ // see DP source, quakedef.h
+ const float STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW = 222;
+ const float STAT_MOVEVARS_AIRSTRAFEACCEL_QW = 223;
+ const float STAT_MOVEVARS_MAXSPEED = 244;
+ const float STAT_MOVEVARS_AIRACCEL_QW = 254;
  
+ const float CTF_STATE_ATTACK = 1;
+ const float CTF_STATE_DEFEND = 2;
+ const float CTF_STATE_COMMANDER = 3;
  
+ const float HUD_NORMAL = 0;
+ const float HUD_VEHICLE_FIRST   = 10;
+ const float HUD_SPIDERBOT       = 10;
+ const float HUD_WAKIZASHI       = 11;
+ const float HUD_RAPTOR          = 12;
+ const float HUD_BUMBLEBEE       = 13;
+ const float HUD_BUMBLEBEE_GUN   = 14;
+ const float HUD_VEHICLE_LAST    = 14;
+ const vector eX = '1 0 0';
+ const vector eY = '0 1 0';
+ const vector eZ = '0 0 1';
  
  // moved that here so the client knows the max.
  // # of maps, I'll use arrays for them :P
  #define SP_SCORE 3
  // game mode specific indices are not in common/, but in server/scores_rules.qc!
  
- // this assignment must match menu/xonotic/dialog_settings_misc.c!
- float CHAN_AUTO                               = 0;
-       // on world: announcers, ...                     INFO
-       // on players: item pickup                       ITEMS
-       // on entities: UNUSED
-       // on csqc: announcers                           INFO
- float CHAN_WEAPON                             = 1; // Weapon fire
-       // on world: UNUSED
-       // on players: weapon firing                     WEAPONS
-       // on entities: turret firing                    WEAPONS
-       // on csqc: UNUSED
- float CHAN_VOICE                              = 2; // Voice/Radio
-       // on world: UNUSED
-       // on players: voice                             VOICE
-       // on entities: ambient                          AMBIENT
-       // on csqc: background music                     BGM
- float CHAN_TRIGGER                    = 3; // Triggers/Items
-       // on world: UNUSED
-       // on players: item pickup                       ITEMS
-       // on entities: platforms moving etc.            ITEMS
-       // on csqc: platforms moving etc.                ITEMS
- float CHAN_PROJECTILE                 = 4; // Projectiles
-       // on world: UNUSED
-       // on players: projectiles hitting player        SHOTS
-       // on entities: projectiles                      SHOTS
-       // on csqc: projectile sounds                    SHOTS
- float CHAN_WEAPON2                    = 5; // Nex fire (separated as it is a very long sound)
-       // on world: UNUSED
-       // on players: weapon firing                     WEAPONS
-       // on entities: turret firing                    WEAPONS
-       // on csqc: UNUSED
- float CHAN_PAIN                               = 6; // Pain
-       // on world: UNUSED
-       // on players: pain                              PAIN
-       // on entities: projectiles flying               SHOTS
-       // on csqc: player pain                          PAIN
- float CHAN_PLAYER                             = 7; // Player body
-       // on world: UNUSED
-       // on players: player sounds                     PLAYER
-       // on entities: player sounds                    PLAYER
-       // on csqc: UNUSED
+ #ifdef COMPAT_XON010_CHANNELS
+ float CH_INFO = 0; // only on world and csqc
+ float CH_TRIGGER = 0; // only on players; compat: FALSELY CONTROLLED BY "Info"
+ float CH_WEAPON_A = 1; // only on players and entities
+ float CH_WEAPON_SINGLE = 5; // only on players and entities
+ float CH_VOICE = 2; // only on players
+ float CH_BGM_SINGLE = 2; // only on csqc; compat: FALSELY CONTROLLED BY "Voice"
+ float CH_AMBIENT = 2; // only on csqc; compat: FALSELY CONTROLLED BY "Voice"
+ float CH_TRIGGER_SINGLE = 3; // only on players, entities, csqc
+ float CH_SHOTS = 4; // only on players, entities, csqc
+ float CH_SHOTS_SINGLE = 4; // only on players, entities, csqc
+ float CH_WEAPON_B = 5; // only on players and entities
+ float CH_PAIN = 6; // only on players and csqc
+ float CH_PAIN_SINGLE = 6; // only on players and csqc
+ float CH_PLAYER = 7; // only on players and entities
+ float CH_TUBA = 5; // only on csqc
+ #else
+ float CH_INFO = 0;
+ float CH_TRIGGER = -3;
+ float CH_WEAPON_A = -1;
+ float CH_WEAPON_SINGLE = 1;
+ float CH_VOICE = -2;
+ float CH_BGM_SINGLE = 8;
+ float CH_AMBIENT = -9;
+ float CH_TRIGGER_SINGLE = 3;
+ float CH_SHOTS = -4;
+ float CH_SHOTS_SINGLE = 4;
+ float CH_WEAPON_B = -1;
+ float CH_PAIN = -6;
+ float CH_PAIN_SINGLE = 6;
+ float CH_PLAYER = -7;
+ float CH_TUBA = 5;
+ #endif
  
  float ATTN_NONE                               = 0;
  float ATTN_MIN                                = 0.015625;
  float ATTN_NORM                               = 0.5;
+ float ATTN_LARGE                              = 1;
  float ATTN_IDLE                               = 2;
  float ATTN_STATIC                             = 3;
  float ATTN_MAX                                = 3.984375;
@@@ -490,6 -345,16 +346,16 @@@ float PROJECTILE_FIREBALL = 21
  float PROJECTILE_FIREMINE = 22;
  float PROJECTILE_BULLET_GLOWING_TRACER = 23;
  
+ float PROJECTILE_RAPTORCANNON   = 24;
+ float PROJECTILE_RAPTORBOMB     = 25;
+ float PROJECTILE_RAPTORBOMBLET  = 26;
+ float PROJECTILE_SPIDERROCKET   = 27;
+ float PROJECTILE_WAKIROCKET     = 28;
+ float PROJECTILE_WAKICANNON     = 29;
+ float PROJECTILE_BUMBLE_GUN     = 30;
+ float PROJECTILE_BUMBLE_BEAM    = 31;
  float SPECIES_HUMAN        =  0;
  float SPECIES_ROBOT_SOLID  =  1;
  float SPECIES_ALIEN        =  2;
@@@ -498,71 -363,12 +364,12 @@@ float SPECIES_ROBOT_RUSTY  =  4
  float SPECIES_ROBOT_SHINY  =  5;
  float SPECIES_RESERVED     = 15;
  
- // Deathtypes (weapon deathtypes are the IT_* constants below)
- // NOTE: when adding death types, please add an explanation to Docs/spamlog.txt too.
- float DEATH_SPECIAL_START = 10000;
- float DEATH_FALL = 10000;
- float DEATH_TELEFRAG = 10001;
- float DEATH_DROWN = 10002;
- float DEATH_HURTTRIGGER = 10003;
- float DEATH_LAVA = 10004;
- float DEATH_SLIME = 10005;
- float DEATH_KILL = 10006;
- float DEATH_NOAMMO = 10007;
- float DEATH_SWAMP = 10008;
- float DEATH_TEAMCHANGE = 10009;
- float DEATH_AUTOTEAMCHANGE = 10010;
- float DEATH_CAMP = 10011;
- float DEATH_SHOOTING_STAR = 10012;
- float DEATH_ROT = 10013;
- float DEATH_MIRRORDAMAGE = 10014;
- float DEATH_TOUCHEXPLODE = 10015;
- float DEATH_CHEAT = 10016;
- float DEATH_FIRE = 10017;
- float DEATH_TURRET = 10020;
- float DEATH_QUIET = 10021;
- float DEATH_HEADSHOT = 10022;
- float DEATH_SBMINIGUN = 10030;
- float DEATH_SBROCKET  = 10031;
- float DEATH_SBCRUSH   = 10032;
- float DEATH_SBBLOWUP  = 10033;
- float DEATH_WAKIGUN    = 10040;
- float DEATH_WAKIROCKET = 10041;
- float DEATH_WAKIBLOWUP = 10042;
- float DEATH_GENERIC = 10050;
- float DEATH_WEAPON = 10100;
- float DEATH_CUSTOM = 10300;
- float DEATH_WEAPONMASK = 0xFF;
- float DEATH_HITTYPEMASK = 0x1F00; // which is WAY below 10000 used for normal deaths
- float HITTYPE_SECONDARY = 0x100;
- float HITTYPE_SPLASH = 0x200;
- float HITTYPE_BOUNCE = 0x400;
- float HITTYPE_HEADSHOT = 0x800;
- float HITTYPE_RESERVED = 0x1000; // unused yet
- // macros to access these
- #define DEATH_ISSPECIAL(t)            ((t) >= DEATH_SPECIAL_START)
- #define DEATH_WEAPONOFWEAPONDEATH(t)  ((t) & DEATH_WEAPONMASK)
- #define DEATH_ISWEAPON(t,w)           (!DEATH_ISSPECIAL(t) && DEATH_WEAPONOFWEAPONDEATH(t) == (w))
- #define DEATH_WEAPONOF(t)             (DEATH_ISSPECIAL(t) ? 0 : DEATH_WEAPONOFWEAPONDEATH(t))
- #define WEP_VALID(w)                  ((w) >= WEP_FIRST && (w) <= WEP_LAST)
  #define FRAGS_PLAYER 0
  #define FRAGS_SPECTATOR -666
  #define FRAGS_LMS_LOSER -616
  #define FRAGS_PLAYER_NONSOLID -616
  // we can use this frags value for both
  
- //misc. stuff
- #define NEWLINES "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  // water levels
  float WATERLEVEL_NONE = 0;
  float WATERLEVEL_WETFEET = 1;
@@@ -571,49 -377,6 +378,6 @@@ float WATERLEVEL_SUBMERGED = 3
  
  float MAX_SHOT_DISTANCE = 32768;
  
- // CSQC centerprint/notify message types
- float MSG_SUICIDE = 0;
- float MSG_KILL = 1;
- float MSG_SPREE = 2;
- float MSG_KILL_ACTION = 3;
- float MSG_KILL_ACTION_SPREE = 4;
- float MSG_INFO = 5;
- float MSG_KA = 6;
- float MSG_RACE = 10;
- float KILL_TEAM_RED = 10301;
- float KILL_TEAM_BLUE = 10302;
- float KILL_TEAM_SPREE = 10303;
- float KILL_FIRST_BLOOD = 10304;
- float KILL_FIRST_VICTIM = 10305;
- float KILL_TYPEFRAG = 10306;
- float KILL_TYPEFRAGGED = 10307;
- float KILL_FRAG = 10308;
- float KILL_FRAGGED = 10309;
- float KILL_SPREE = 10310;
- float KILL_END_SPREE = 10311;
- float KILL_SPREE_3 = 10312;
- float KILL_SPREE_5 = 10313;
- float KILL_SPREE_10 = 10314;
- float KILL_SPREE_15 = 10315;
- float KILL_SPREE_20 = 10316;
- float KILL_SPREE_25 = 10317;
- float KILL_SPREE_30 = 10318;
- float INFO_GOTFLAG = 10319;
- float INFO_PICKUPFLAG = 10320;
- float INFO_LOSTFLAG = 10321;
- float INFO_RETURNFLAG = 10322;
- float INFO_CAPTUREFLAG = 10323;
- float KA_PICKUPBALL = 10350;
- float KA_DROPBALL = 10351;
- float RACE_SERVER_RECORD = 10400;
- float RACE_NEW_TIME = 10401;
- float RACE_NEW_RANK = 10402;
- float RACE_FAIL = 10403;
  // weapon requests
  float WR_SETUP                = 1; // (SVQC) setup weapon data
  float WR_THINK                = 2; // (SVQC) logic to run every frame
@@@ -621,47 -384,58 +385,58 @@@ float WR_CHECKAMMO1     = 3; // (SVQC) chec
  float WR_CHECKAMMO2   = 4; // (SVQC) checks ammo for weapon
  float WR_AIM          = 5; // (SVQC) runs bot aiming code for this weapon
  float WR_PRECACHE     = 6; // (CSQC and SVQC) precaches models/sounds used by this weapon
- float WR_SUICIDEMESSAGE = 7; // (CSQC) sets w_deathtypestring or leaves it alone (and may inspect w_deathtype for details)
- float WR_KILLMESSAGE    = 8; // (CSQC) sets w_deathtypestring or leaves it alone
+ float WR_SUICIDEMESSAGE = 7; // (SVQC) notification number for suicide message (may inspect w_deathtype for details)
+ float WR_KILLMESSAGE    = 8; // (SVQC) notification number for kill message (may inspect w_deathtype for details)
  float WR_RELOAD         = 9; // (SVQC) does not need to do anything
  float WR_RESETPLAYER    = 10; // (SVQC) does not need to do anything
  float WR_IMPACTEFFECT = 11; // (CSQC) impact effect
- float HUD_PANEL_WEAPONS               = 0;
- float HUD_PANEL_AMMO          = 1;
- float HUD_PANEL_POWERUPS      = 2;
- float HUD_PANEL_HEALTHARMOR   = 3;
- float HUD_PANEL_NOTIFY                = 4;
- float HUD_PANEL_TIMER         = 5;
- float HUD_PANEL_RADAR         = 6;
- float HUD_PANEL_SCORE         = 7;
- float HUD_PANEL_RACETIMER     = 8;
- float HUD_PANEL_VOTE          = 9;
- float HUD_PANEL_MODICONS      = 10;
- float HUD_PANEL_PRESSEDKEYS   = 11;
- float HUD_PANEL_CHAT          = 12;
- float HUD_PANEL_ENGINEINFO    = 13;
- float HUD_PANEL_INFOMESSAGES  = 14;
- float HUD_PANEL_NUM           = 15; // always last panel id + 1, please increment when adding a new panel
- string HUD_PANELNAME_WEAPONS          = "weapons";
- string HUD_PANELNAME_AMMO             = "ammo";
- string HUD_PANELNAME_POWERUPS         = "powerups";
- string HUD_PANELNAME_HEALTHARMOR      = "healtharmor";
- string HUD_PANELNAME_NOTIFY           = "notify";
- string HUD_PANELNAME_TIMER            = "timer";
- string HUD_PANELNAME_RADAR            = "radar";
- string HUD_PANELNAME_SCORE            = "score";
- string HUD_PANELNAME_RACETIMER                = "racetimer";
- string HUD_PANELNAME_VOTE             = "vote";
- string HUD_PANELNAME_MODICONS         = "modicons";
- string HUD_PANELNAME_PRESSEDKEYS      = "pressedkeys";
- string HUD_PANELNAME_CHAT             = "chat";
- string HUD_PANELNAME_ENGINEINFO               = "engineinfo";
- string HUD_PANELNAME_INFOMESSAGES     = "infomessages";
- float HUD_MENU_ENABLE         = 0;
+ float WR_SWITCHABLE   = 12; // (CSQC) impact effect
+ float WR_PLAYERDEATH    = 13; // (SVQC) does not need to do anything
+ float WR_GONETHINK    = 14; // (SVQC) logic to run every frame, also if no longer having the weapon as long as the switch away has not been performed
  
  #define SERVERFLAG_ALLOW_FULLBRIGHT 1
  #define SERVERFLAG_TEAMPLAY 2
+ #define SERVERFLAG_PLAYERSTATS 4
+ // FIXME/EXPLAINME: why?
+ noref var vector autocvar_sv_player_maxs = '16 16 45';
+ noref var vector autocvar_sv_player_mins = '-16 -16 -24';
+ noref var vector autocvar_sv_player_viewoffset = '0 0 20';
+ noref var vector autocvar_sv_player_crouch_maxs = '16 16 25';
+ noref var vector autocvar_sv_player_crouch_mins = '-16 -16 -24';
+ noref var vector autocvar_sv_player_crouch_viewoffset = '0 0 20';
+ noref var vector autocvar_sv_player_headsize = '24 24 12';
+ #define PL_VIEW_OFS autocvar_sv_player_viewoffset
+ #define PL_MIN autocvar_sv_player_mins
+ #define PL_MAX autocvar_sv_player_maxs
+ #define PL_CROUCH_VIEW_OFS autocvar_sv_player_crouch_viewoffset
+ #define PL_CROUCH_MIN autocvar_sv_player_crouch_mins
+ #define PL_CROUCH_MAX autocvar_sv_player_crouch_maxs
+ #define PL_HEAD autocvar_sv_player_headsize
+ // helpers
+ #define PL_VIEW_OFS_z autocvar_sv_player_viewoffset_z
+ #define PL_MIN_z autocvar_sv_player_mins_z
+ #define PL_MAX_z autocvar_sv_player_maxs_z
+ #define PL_CROUCH_VIEW_OFS_z autocvar_sv_player_crouch_viewoffset_z
+ #define PL_CROUCH_MIN_z autocvar_sv_player_mins_z
+ #define PL_HEAD_x autocvar_sv_player_headsize_x
+ #define PL_HEAD_y autocvar_sv_player_headsize_y
+ #define PL_HEAD_z autocvar_sv_player_headsize_z
+ // spawnpoint prios
+ #define SPAWN_PRIO_NEAR_TEAMMATE_FOUND    200
+ #define SPAWN_PRIO_NEAR_TEAMMATE_SAMETEAM 100
+ #define SPAWN_PRIO_RACE_PREVIOUS_SPAWN     50
+ #define SPAWN_PRIO_GOOD_DISTANCE           10
+ // URI handles
+ #define URI_GET_DISCARD              0
+ #define URI_GET_IPBAN                1
+ #define URI_GET_IPBAN_END           16
+ #define URI_GET_CURL                17
+ #define URI_GET_CURL_END            32
+ #define URI_GET_UPDATENOTIFICATION  33
+ #define URI_GET_URLLIB             128
+ #define URI_GET_URLLIB_END         191
index de34de4da8a3ffa61c4a0878e61cf5ae9f401e3b,dead5a9d4b360d924a0642f4b21fe0161e734ccd..bc6a80fafae97f9d094a8af7289838b68b1e27ff
@@@ -1,3 -1,6 +1,6 @@@
+ float autocvar__notarget;
+ float autocvar__independent_players;
+ float autocvar__campaign_testrun;
  float autocvar__campaign_index;
  string autocvar__campaign_name;
  float autocvar__sv_init;
@@@ -54,9 -57,12 +57,12 @@@ float autocvar_bot_sound_monopoly
  #define autocvar_bot_suffix cvar_string("bot_suffix")
  float autocvar_bot_usemodelnames;
  float autocvar_bot_vs_human;
+ float autocvar_bot_debug;
+ float autocvar_bot_debug_tracewalk;
+ float autocvar_bot_debug_goalstack;
+ float autocvar_bot_wander_enable;
  float autocvar_captureleadlimit_override;
  #define autocvar_capturelimit_override cvar("capturelimit_override")
- float autocvar_deathmatch_force_teamplay;
  #define autocvar_developer cvar("developer")
  float autocvar_developer_fteqccbugs;
  float autocvar_ekg;
@@@ -69,10 -75,9 +75,9 @@@ float autocvar_g_antilag_nudge
  float autocvar_g_arena_maxspawned;
  float autocvar_g_arena_point_leadlimit;
  float autocvar_g_arena_point_limit;
- float autocvar_g_arena_powerups;
  float autocvar_g_arena_roundbased;
+ float autocvar_g_arena_round_timelimit;
  float autocvar_g_arena_warmup;
- float autocvar_g_assault;
  float autocvar_g_balance_armor_blockpercent;
  float autocvar_g_balance_armor_limit;
  float autocvar_g_balance_armor_regen;
@@@ -82,39 -87,44 +87,44 @@@ float autocvar_g_balance_armor_rot
  float autocvar_g_balance_armor_rotlinear;
  float autocvar_g_balance_armor_rotstable;
  float autocvar_g_balance_armor_start;
- float autocvar_g_balance_sniperrifle_auto_reload_on_switch;
- float autocvar_g_balance_sniperrifle_bursttime;
- float autocvar_g_balance_sniperrifle_magazinecapacity;
- float autocvar_g_balance_sniperrifle_primary_ammo;
- float autocvar_g_balance_sniperrifle_primary_animtime;
- float autocvar_g_balance_sniperrifle_primary_bulletconstant;
- float autocvar_g_balance_sniperrifle_primary_bullethail;
- float autocvar_g_balance_sniperrifle_primary_burstcost;
- float autocvar_g_balance_sniperrifle_primary_damage;
- float autocvar_g_balance_sniperrifle_primary_force;
- float autocvar_g_balance_sniperrifle_primary_headshotaddeddamage;
- float autocvar_g_balance_sniperrifle_primary_lifetime;
- float autocvar_g_balance_sniperrifle_primary_refire;
- float autocvar_g_balance_sniperrifle_primary_speed;
- float autocvar_g_balance_sniperrifle_primary_spread;
- float autocvar_g_balance_sniperrifle_primary_tracer;
- float autocvar_g_balance_sniperrifle_reloadtime;
- float autocvar_g_balance_sniperrifle_secondary;
- float autocvar_g_balance_sniperrifle_secondary_ammo;
- float autocvar_g_balance_sniperrifle_secondary_animtime;
- float autocvar_g_balance_sniperrifle_secondary_bulletconstant;
- float autocvar_g_balance_sniperrifle_secondary_bullethail;
- float autocvar_g_balance_sniperrifle_secondary_burstcost;
- float autocvar_g_balance_sniperrifle_secondary_damage;
- float autocvar_g_balance_sniperrifle_secondary_force;
- float autocvar_g_balance_sniperrifle_secondary_headshotaddeddamage;
- float autocvar_g_balance_sniperrifle_secondary_lifetime;
- float autocvar_g_balance_sniperrifle_secondary_reload;
- float autocvar_g_balance_sniperrifle_secondary_refire;
- float autocvar_g_balance_sniperrifle_secondary_speed;
- float autocvar_g_balance_sniperrifle_secondary_spread;
- float autocvar_g_balance_sniperrifle_secondary_tracer;
+ float autocvar_g_balance_rifle_bursttime;
+ float autocvar_g_balance_rifle_primary_ammo;
+ float autocvar_g_balance_rifle_primary_animtime;
+ float autocvar_g_balance_rifle_primary_bulletconstant;
+ float autocvar_g_balance_rifle_primary_bullethail;
+ float autocvar_g_balance_rifle_primary_burstcost;
+ float autocvar_g_balance_rifle_primary_damage;
+ float autocvar_g_balance_rifle_primary_force;
+ float autocvar_g_balance_rifle_primary_lifetime;
+ float autocvar_g_balance_rifle_primary_refire;
+ float autocvar_g_balance_rifle_primary_shots;
+ float autocvar_g_balance_rifle_primary_speed;
+ float autocvar_g_balance_rifle_primary_spread;
+ float autocvar_g_balance_rifle_primary_tracer;
+ float autocvar_g_balance_rifle_secondary;
+ float autocvar_g_balance_rifle_secondary_ammo;
+ float autocvar_g_balance_rifle_secondary_animtime;
+ float autocvar_g_balance_rifle_secondary_bulletconstant;
+ float autocvar_g_balance_rifle_secondary_bullethail;
+ float autocvar_g_balance_rifle_secondary_burstcost;
+ float autocvar_g_balance_rifle_secondary_damage;
+ float autocvar_g_balance_rifle_secondary_force;
+ float autocvar_g_balance_rifle_secondary_lifetime;
+ float autocvar_g_balance_rifle_secondary_reload;
+ float autocvar_g_balance_rifle_secondary_refire;
+ float autocvar_g_balance_rifle_secondary_shots;
+ float autocvar_g_balance_rifle_secondary_speed;
+ float autocvar_g_balance_rifle_secondary_spread;
+ float autocvar_g_balance_rifle_secondary_tracer;
+ float autocvar_g_balance_rifle_reload_ammo;
+ float autocvar_g_balance_rifle_reload_time;
  float autocvar_g_balance_cloaked_alpha;
+ float autocvar_g_balance_contents_damagerate;
+ float autocvar_g_balance_contents_drowndelay;
+ float autocvar_g_balance_contents_playerdamage_drowning;
+ float autocvar_g_balance_contents_playerdamage_lava;
+ float autocvar_g_balance_contents_playerdamage_slime;
+ float autocvar_g_balance_contents_projectiledamage;
  float autocvar_g_balance_crylink_primary_ammo;
  float autocvar_g_balance_crylink_primary_animtime;
  float autocvar_g_balance_crylink_primary_bouncedamagefactor;
@@@ -166,24 -176,17 +176,17 @@@ float autocvar_g_balance_crylink_second
  float autocvar_g_balance_crylink_secondary_shots;
  float autocvar_g_balance_crylink_secondary_speed;
  float autocvar_g_balance_crylink_secondary_spread;
- float autocvar_g_balance_ctf_damageforcescale;
- float autocvar_g_balance_ctf_delay_collect;
- float autocvar_g_balance_curse_empathy_minhealth;
- float autocvar_g_balance_curse_empathy_takedamage;
- float autocvar_g_balance_curse_slow_atkrate;
- float autocvar_g_balance_curse_slow_highspeed;
- float autocvar_g_balance_curse_venom_hpmod;
- float autocvar_g_balance_curse_venom_limitmod;
- float autocvar_g_balance_curse_venom_rotrate;
- float autocvar_g_balance_curse_vulner_takedamage;
- float autocvar_g_balance_curse_weak_damage;
- float autocvar_g_balance_curse_weak_force;
+ float autocvar_g_balance_crylink_secondary_spreadtype;
+ float autocvar_g_balance_crylink_reload_ammo;
+ float autocvar_g_balance_crylink_reload_time;
+ float autocvar_g_balance_damagepush_speedfactor;
  float autocvar_g_balance_electro_combo_comboradius;
  float autocvar_g_balance_electro_combo_damage;
  float autocvar_g_balance_electro_combo_edgedamage;
  float autocvar_g_balance_electro_combo_force;
  float autocvar_g_balance_electro_combo_radius;
  float autocvar_g_balance_electro_combo_speed;
+ float autocvar_g_balance_electro_combo_safeammocheck;
  float autocvar_g_balance_electro_lightning;
  float autocvar_g_balance_electro_primary_ammo;
  float autocvar_g_balance_electro_primary_animtime;
@@@ -207,6 -210,7 +210,7 @@@ float autocvar_g_balance_electro_second
  float autocvar_g_balance_electro_secondary_count;
  float autocvar_g_balance_electro_secondary_damage;
  float autocvar_g_balance_electro_secondary_damageforcescale;
+ float autocvar_g_balance_electro_secondary_damagedbycontents;
  float autocvar_g_balance_electro_secondary_edgedamage;
  float autocvar_g_balance_electro_secondary_force;
  float autocvar_g_balance_electro_secondary_health;
@@@ -215,11 -219,12 +219,12 @@@ float autocvar_g_balance_electro_second
  float autocvar_g_balance_electro_secondary_refire;
  float autocvar_g_balance_electro_secondary_refire2;
  float autocvar_g_balance_electro_secondary_speed;
+ float autocvar_g_balance_electro_reload_ammo;
+ float autocvar_g_balance_electro_reload_time;
  float autocvar_g_balance_falldamage_deadminspeed;
  float autocvar_g_balance_falldamage_factor;
  float autocvar_g_balance_falldamage_maxdamage;
  float autocvar_g_balance_falldamage_minspeed;
- float autocvar_g_balance_fireball_primary_ammo;
  float autocvar_g_balance_fireball_primary_animtime;
  float autocvar_g_balance_fireball_primary_bfgdamage;
  float autocvar_g_balance_fireball_primary_bfgforce;
@@@ -238,7 -243,6 +243,6 @@@ float autocvar_g_balance_fireball_prima
  float autocvar_g_balance_fireball_primary_refire;
  float autocvar_g_balance_fireball_primary_refire2;
  float autocvar_g_balance_fireball_primary_speed;
- float autocvar_g_balance_fireball_secondary_ammo;
  float autocvar_g_balance_fireball_secondary_animtime;
  float autocvar_g_balance_fireball_secondary_damage;
  float autocvar_g_balance_fireball_secondary_damageforcescale;
@@@ -268,6 -272,7 +272,7 @@@ float autocvar_g_balance_grapplehook_le
  float autocvar_g_balance_grapplehook_speed_fly;
  float autocvar_g_balance_grapplehook_speed_pull;
  float autocvar_g_balance_grapplehook_stretch;
+ float autocvar_g_balance_grapplehook_damagedbycontents;
  float autocvar_g_balance_grenadelauncher_bouncefactor;
  float autocvar_g_balance_grenadelauncher_bouncestop;
  float autocvar_g_balance_grenadelauncher_primary_ammo;
@@@ -278,7 -283,7 +283,7 @@@ float autocvar_g_balance_grenadelaunche
  float autocvar_g_balance_grenadelauncher_primary_force;
  float autocvar_g_balance_grenadelauncher_primary_health;
  float autocvar_g_balance_grenadelauncher_primary_lifetime;
- float autocvar_g_balance_grenadelauncher_primary_lifetime2;
+ float autocvar_g_balance_grenadelauncher_primary_lifetime_stick;
  float autocvar_g_balance_grenadelauncher_primary_radius;
  float autocvar_g_balance_grenadelauncher_primary_refire;
  float autocvar_g_balance_grenadelauncher_primary_remote_minbouncecnt;
@@@ -293,29 -298,50 +298,50 @@@ float autocvar_g_balance_grenadelaunche
  float autocvar_g_balance_grenadelauncher_secondary_force;
  float autocvar_g_balance_grenadelauncher_secondary_health;
  float autocvar_g_balance_grenadelauncher_secondary_lifetime;
- float autocvar_g_balance_grenadelauncher_secondary_lifetime2;
+ float autocvar_g_balance_grenadelauncher_secondary_lifetime_bounce;
+ float autocvar_g_balance_grenadelauncher_secondary_lifetime_stick;
  float autocvar_g_balance_grenadelauncher_secondary_radius;
  float autocvar_g_balance_grenadelauncher_secondary_refire;
  float autocvar_g_balance_grenadelauncher_secondary_speed;
  float autocvar_g_balance_grenadelauncher_secondary_speed_up;
  float autocvar_g_balance_grenadelauncher_secondary_type;
+ float autocvar_g_balance_grenadelauncher_reload_ammo;
+ float autocvar_g_balance_grenadelauncher_reload_time;
  float autocvar_g_balance_hagar_primary_ammo;
  float autocvar_g_balance_hagar_primary_damage;
  float autocvar_g_balance_hagar_primary_edgedamage;
  float autocvar_g_balance_hagar_primary_force;
+ float autocvar_g_balance_hagar_primary_health;
+ float autocvar_g_balance_hagar_primary_damageforcescale;
  float autocvar_g_balance_hagar_primary_lifetime;
  float autocvar_g_balance_hagar_primary_radius;
  float autocvar_g_balance_hagar_primary_refire;
  float autocvar_g_balance_hagar_primary_speed;
  float autocvar_g_balance_hagar_secondary;
+ float autocvar_g_balance_hagar_secondary_load;
+ float autocvar_g_balance_hagar_secondary_load_speed;
+ float autocvar_g_balance_hagar_secondary_load_spread;
+ float autocvar_g_balance_hagar_secondary_load_spread_bias;
+ float autocvar_g_balance_hagar_secondary_load_max;
+ float autocvar_g_balance_hagar_secondary_load_hold;
+ float autocvar_g_balance_hagar_secondary_load_releasedeath;
+ float autocvar_g_balance_hagar_secondary_load_abort;
+ float autocvar_g_balance_hagar_secondary_load_linkexplode;
+ float autocvar_g_balance_hagar_secondary_load_animtime;
  float autocvar_g_balance_hagar_secondary_ammo;
  float autocvar_g_balance_hagar_secondary_damage;
  float autocvar_g_balance_hagar_secondary_edgedamage;
  float autocvar_g_balance_hagar_secondary_force;
+ float autocvar_g_balance_hagar_secondary_health;
+ float autocvar_g_balance_hagar_secondary_damageforcescale;
  float autocvar_g_balance_hagar_secondary_lifetime_min;
  float autocvar_g_balance_hagar_secondary_lifetime_rand;
  float autocvar_g_balance_hagar_secondary_radius;
  float autocvar_g_balance_hagar_secondary_refire;
+ float autocvar_g_balance_hagar_secondary_speed;
+ float autocvar_g_balance_hagar_secondary_spread;
+ float autocvar_g_balance_hagar_reload_ammo;
+ float autocvar_g_balance_hagar_reload_time;
  float autocvar_g_balance_health_limit;
  float autocvar_g_balance_health_regen;
  float autocvar_g_balance_health_regenlinear;
@@@ -350,6 -376,8 +376,8 @@@ float autocvar_g_balance_hlac_secondary
  float autocvar_g_balance_hlac_secondary_speed;
  float autocvar_g_balance_hlac_secondary_spread;
  float autocvar_g_balance_hlac_secondary_spread_crouchmod;
+ float autocvar_g_balance_hlac_reload_ammo;
+ float autocvar_g_balance_hlac_reload_time;
  float autocvar_g_balance_hook_primary_animtime;
  float autocvar_g_balance_hook_primary_fuel;
  float autocvar_g_balance_hook_primary_hooked_fuel;
@@@ -368,9 -396,10 +396,10 @@@ float autocvar_g_balance_hook_secondary
  float autocvar_g_balance_hook_secondary_radius;
  float autocvar_g_balance_hook_secondary_refire;
  float autocvar_g_balance_hook_secondary_speed;
+ float autocvar_g_balance_hook_secondary_health;
+ float autocvar_g_balance_hook_secondary_damageforcescale;
  float autocvar_g_balance_keyhunt_damageforcescale;
  float autocvar_g_balance_keyhunt_delay_collect;
- float autocvar_g_balance_keyhunt_delay_drop;
  float autocvar_g_balance_keyhunt_delay_return;
  float autocvar_g_balance_keyhunt_delay_round;
  float autocvar_g_balance_keyhunt_delay_tracking;
@@@ -410,33 -439,8 +439,35 @@@ float autocvar_g_balance_laser_secondar
  float autocvar_g_balance_laser_secondary_lifetime;
  float autocvar_g_balance_laser_secondary_radius;
  float autocvar_g_balance_laser_secondary_speed;
+ float autocvar_g_balance_laser_reload_ammo;
+ float autocvar_g_balance_laser_reload_time;
 +float autocvar_g_balance_lightning_primary_ammo;
 +float autocvar_g_balance_lightning_primary_animtime;
 +float autocvar_g_balance_lightning_primary_damage;
 +float autocvar_g_balance_lightning_primary_edgedamage;
 +float autocvar_g_balance_lightning_primary_falloff_halflifedist;
 +float autocvar_g_balance_lightning_primary_falloff_maxdist;
 +float autocvar_g_balance_lightning_primary_falloff_mindist;
 +float autocvar_g_balance_lightning_primary_force;
 +float autocvar_g_balance_lightning_primary_lifetime;
 +float autocvar_g_balance_lightning_primary_radius;
 +float autocvar_g_balance_lightning_primary_range;
 +float autocvar_g_balance_lightning_primary_refire;
 +float autocvar_g_balance_lightning_primary_speed;
 +float autocvar_g_balance_lightning_secondary_ammo;
 +float autocvar_g_balance_lightning_secondary_animtime;
 +float autocvar_g_balance_lightning_secondary_damage;
 +float autocvar_g_balance_lightning_secondary_damageforcescale;
 +float autocvar_g_balance_lightning_secondary_edgedamage;
 +float autocvar_g_balance_lightning_secondary_flyingdamage;
 +float autocvar_g_balance_lightning_secondary_flyingforce;
 +float autocvar_g_balance_lightning_secondary_flyingradius;
 +float autocvar_g_balance_lightning_secondary_force;
 +float autocvar_g_balance_lightning_secondary_health;
 +float autocvar_g_balance_lightning_secondary_lifetime;
 +float autocvar_g_balance_lightning_secondary_radius;
 +float autocvar_g_balance_lightning_secondary_refire;
 +float autocvar_g_balance_lightning_secondary_speed;
  float autocvar_g_balance_minelayer_ammo;
  float autocvar_g_balance_minelayer_animtime;
  float autocvar_g_balance_minelayer_damage;
@@@ -458,9 -462,16 +489,16 @@@ float autocvar_g_balance_minelayer_remo
  float autocvar_g_balance_minelayer_remote_radius;
  float autocvar_g_balance_minelayer_speed;
  float autocvar_g_balance_minelayer_time;
+ float autocvar_g_balance_minelayer_reload_ammo;
+ float autocvar_g_balance_minelayer_reload_time;
  float autocvar_g_balance_minstanex_ammo;
+ float autocvar_g_balance_minstanex_laser_ammo;
+ float autocvar_g_balance_minstanex_laser_animtime;
+ float autocvar_g_balance_minstanex_laser_refire;
  float autocvar_g_balance_minstanex_animtime;
  float autocvar_g_balance_minstanex_refire;
+ float autocvar_g_balance_minstanex_reload_ammo;
+ float autocvar_g_balance_minstanex_reload_time;
  float autocvar_g_balance_nex_charge;
  float autocvar_g_balance_nex_charge_animlimit;
  float autocvar_g_balance_nex_charge_limit;
@@@ -498,6 -509,8 +536,8 @@@ float autocvar_g_balance_nex_secondary_
  float autocvar_g_balance_nex_secondary_damagefalloff_mindist;
  float autocvar_g_balance_nex_secondary_force;
  float autocvar_g_balance_nex_secondary_refire;
+ float autocvar_g_balance_nex_reload_ammo;
+ float autocvar_g_balance_nex_reload_time;
  float autocvar_g_balance_nexball_primary_animtime;
  float autocvar_g_balance_nexball_primary_refire;
  float autocvar_g_balance_nexball_primary_speed;
@@@ -533,6 -546,11 +573,11 @@@ float autocvar_g_balance_porto_primary_
  float autocvar_g_balance_porto_primary_lifetime;
  float autocvar_g_balance_porto_primary_refire;
  float autocvar_g_balance_porto_primary_speed;
+ float autocvar_g_balance_porto_secondary;
+ float autocvar_g_balance_porto_secondary_animtime;
+ float autocvar_g_balance_porto_secondary_lifetime;
+ float autocvar_g_balance_porto_secondary_refire;
+ float autocvar_g_balance_porto_secondary_speed;
  float autocvar_g_balance_powerup_invincible_takedamage;
  float autocvar_g_balance_powerup_invincible_time;
  float autocvar_g_balance_powerup_strength_damage;
@@@ -540,7 -558,7 +585,7 @@@ float autocvar_g_balance_powerup_streng
  float autocvar_g_balance_powerup_strength_selfdamage;
  float autocvar_g_balance_powerup_strength_selfforce;
  float autocvar_g_balance_powerup_strength_time;
- float autocvar_g_balance_powerup_timer;
+ float autocvar_g_balance_superweapons_time;
  float autocvar_g_balance_rocketlauncher_ammo;
  float autocvar_g_balance_rocketlauncher_animtime;
  float autocvar_g_balance_rocketlauncher_damage;
@@@ -564,26 -582,9 +609,9 @@@ float autocvar_g_balance_rocketlauncher
  float autocvar_g_balance_rocketlauncher_speed;
  float autocvar_g_balance_rocketlauncher_speedaccel;
  float autocvar_g_balance_rocketlauncher_speedstart;
- float autocvar_g_balance_rune_defense_combo_takedamage;
- float autocvar_g_balance_rune_defense_takedamage;
- float autocvar_g_balance_rune_regen_combo_hpmod;
- float autocvar_g_balance_rune_regen_combo_limitmod;
- float autocvar_g_balance_rune_regen_combo_regenrate;
- float autocvar_g_balance_rune_regen_combo_rotrate;
- float autocvar_g_balance_rune_regen_hpmod;
- float autocvar_g_balance_rune_regen_limitmod;
- float autocvar_g_balance_rune_regen_regenrate;
- float autocvar_g_balance_rune_speed_atkrate;
- float autocvar_g_balance_rune_speed_combo_atkrate;
- float autocvar_g_balance_rune_speed_combo_highspeed;
- float autocvar_g_balance_rune_speed_highspeed;
- float autocvar_g_balance_rune_strength_combo_damage;
- float autocvar_g_balance_rune_strength_combo_force;
- float autocvar_g_balance_rune_strength_damage;
- float autocvar_g_balance_rune_strength_force;
- float autocvar_g_balance_rune_vampire_absorb;
- float autocvar_g_balance_rune_vampire_combo_absorb;
- float autocvar_g_balance_rune_vampire_maxhealth;
+ float autocvar_g_balance_rocketlauncher_reload_ammo;
+ float autocvar_g_balance_rocketlauncher_reload_time;
+ float autocvar_g_balance_seeker_type;
  float autocvar_g_balance_seeker_flac_ammo;
  float autocvar_g_balance_seeker_flac_animtime;
  float autocvar_g_balance_seeker_flac_damage;
@@@ -595,6 -596,7 +623,7 @@@ float autocvar_g_balance_seeker_flac_ra
  float autocvar_g_balance_seeker_flac_refire;
  float autocvar_g_balance_seeker_missile_accel;
  float autocvar_g_balance_seeker_missile_ammo;
+ float autocvar_g_balance_seeker_missile_animtime;
  float autocvar_g_balance_seeker_missile_count;
  float autocvar_g_balance_seeker_missile_damage;
  float autocvar_g_balance_seeker_missile_damageforcescale;
@@@ -608,6 -610,7 +637,7 @@@ float autocvar_g_balance_seeker_missile
  float autocvar_g_balance_seeker_missile_proxy_delay;
  float autocvar_g_balance_seeker_missile_proxy_maxrange;
  float autocvar_g_balance_seeker_missile_radius;
+ float autocvar_g_balance_seeker_missile_refire;
  float autocvar_g_balance_seeker_missile_smart;
  float autocvar_g_balance_seeker_missile_smart_mindist;
  float autocvar_g_balance_seeker_missile_smart_trace_max;
@@@ -621,6 -624,9 +651,9 @@@ float autocvar_g_balance_seeker_tag_hea
  float autocvar_g_balance_seeker_tag_lifetime;
  float autocvar_g_balance_seeker_tag_refire;
  float autocvar_g_balance_seeker_tag_speed;
+ float autocvar_g_balance_seeker_tag_tracker_lifetime;
+ float autocvar_g_balance_seeker_reload_ammo;
+ float autocvar_g_balance_seeker_reload_time;
  float autocvar_g_balance_selfdamagepercent;
  float autocvar_g_balance_shotgun_primary_ammo;
  float autocvar_g_balance_shotgun_primary_animtime;
@@@ -637,12 -643,19 +670,19 @@@ float autocvar_g_balance_shotgun_second
  float autocvar_g_balance_shotgun_secondary_force;
  float autocvar_g_balance_shotgun_secondary_melee_delay;
  float autocvar_g_balance_shotgun_secondary_melee_range;
- float autocvar_g_balance_shotgun_secondary_melee_swing;
+ float autocvar_g_balance_shotgun_secondary_melee_swing_side;
+ float autocvar_g_balance_shotgun_secondary_melee_swing_up;
  float autocvar_g_balance_shotgun_secondary_melee_time;
+ float autocvar_g_balance_shotgun_secondary_melee_traces;
+ float autocvar_g_balance_shotgun_secondary_melee_no_doubleslap;
+ float autocvar_g_balance_shotgun_secondary_melee_nonplayerdamage;
+ float autocvar_g_balance_shotgun_secondary_melee_multihit;
  float autocvar_g_balance_shotgun_secondary_refire;
+ float autocvar_g_balance_shotgun_reload_ammo;
+ float autocvar_g_balance_shotgun_reload_time;
  float autocvar_g_balance_teams;
- float autocvar_g_balance_teams_force;
  float autocvar_g_balance_teams_prevent_imbalance;
+ float autocvar_g_balance_teams_scorefactor;
  float autocvar_g_balance_tuba_animtime;
  float autocvar_g_balance_tuba_attenuation;
  float autocvar_g_balance_tuba_damage;
@@@ -673,7 -686,8 +713,8 @@@ float autocvar_g_balance_uzi_sustained_
  float autocvar_g_balance_uzi_sustained_force;
  float autocvar_g_balance_uzi_sustained_refire;
  float autocvar_g_balance_uzi_sustained_spread;
- float autocvar_g_balance_weaponswitchdelay;
+ float autocvar_g_balance_uzi_reload_ammo;
+ float autocvar_g_balance_uzi_reload_time;
  float autocvar_g_ballistics_density_corpse;
  float autocvar_g_ballistics_density_player;
  float autocvar_g_ballistics_materialconstant;
@@@ -694,9 -708,12 +735,12 @@@ float autocvar_g_ca_damage2score_multip
  float autocvar_g_ca_point_leadlimit;
  float autocvar_g_ca_point_limit;
  float autocvar_g_ca_round_timelimit;
+ float autocvar_g_ca_spectate_enemies;
+ float autocvar_g_ca_teams;
+ float autocvar_g_ca_teams_override;
  float autocvar_g_ca_warmup;
  float autocvar_g_campaign;
- float autocvar_g_campaign_forceteam;
+ #define autocvar_g_campaign_forceteam cvar("g_campaign_forceteam")
  float autocvar_g_campaign_skill;
  float autocvar_g_casings;
  float autocvar_g_changeteam_banned;
@@@ -712,29 -729,77 +756,77 @@@ float autocvar_g_chat_flood_spl_team
  float autocvar_g_chat_flood_spl_tell;
  float autocvar_g_chat_nospectators;
  float autocvar_g_chat_teamcolors;
- float autocvar_g_ctf_allow_drop;
- float autocvar_g_ctf_captimerecord_always;
- float autocvar_g_ctf_capture_leadlimit;
- float autocvar_g_ctf_capture_limit;
+ float autocvar_g_chat_tellprivacy;
+ float autocvar_g_ctf_allow_vehicle_carry;
+ float autocvar_g_ctf_allow_vehicle_touch;
+ float autocvar_g_ctf_throw;
+ float autocvar_g_ctf_throw_angle_max;
+ float autocvar_g_ctf_throw_angle_min;
+ float autocvar_g_ctf_throw_punish_count;
+ float autocvar_g_ctf_throw_punish_delay;
+ float autocvar_g_ctf_throw_punish_time;
+ float autocvar_g_ctf_throw_strengthmultiplier;
+ float autocvar_g_ctf_throw_velocity_forward;
+ float autocvar_g_ctf_throw_velocity_up;
+ float autocvar_g_ctf_drop_velocity_up;
+ float autocvar_g_ctf_drop_velocity_side;
+ float autocvar_g_ctf_portalteleport;
+ float autocvar_g_ctf_pass;
+ float autocvar_g_ctf_pass_arc;
+ float autocvar_g_ctf_pass_arc_max;
+ float autocvar_g_ctf_pass_directional_max;
+ float autocvar_g_ctf_pass_directional_min;
+ float autocvar_g_ctf_pass_radius;
+ float autocvar_g_ctf_pass_wait;
+ float autocvar_g_ctf_pass_request;
+ float autocvar_g_ctf_pass_turnrate;
+ float autocvar_g_ctf_pass_timelimit;
+ float autocvar_g_ctf_pass_velocity;
  float autocvar_g_ctf_dynamiclights;
  string autocvar_g_ctf_flag_blue_model;
  float autocvar_g_ctf_flag_blue_skin;
- float autocvar_g_ctf_flag_capture_effects;
+ float autocvar_g_ctf_flag_collect_delay;
+ float autocvar_g_ctf_flag_damageforcescale;
+ float autocvar_g_ctf_flag_dropped_waypoint;
+ float autocvar_g_ctf_flag_dropped_floatinwater;
  float autocvar_g_ctf_flag_glowtrails;
- float autocvar_g_ctf_flag_pickup_effects;
+ float autocvar_g_ctf_flag_health;
  string autocvar_g_ctf_flag_red_model;
  float autocvar_g_ctf_flag_red_skin;
- float autocvar_g_ctf_flag_returntime;
- float autocvar_g_ctf_flagcarrier_selfdamage;
- float autocvar_g_ctf_flagcarrier_selfforce;
+ float autocvar_g_ctf_flag_return_time;
+ float autocvar_g_ctf_flag_return_when_unreachable;
+ float autocvar_g_ctf_flag_return_damage;
+ float autocvar_g_ctf_flag_return_dropped;
+ float autocvar_g_ctf_flagcarrier_auto_helpme_damage;
+ float autocvar_g_ctf_flagcarrier_auto_helpme_time;
+ float autocvar_g_ctf_flagcarrier_selfdamagefactor;
+ float autocvar_g_ctf_flagcarrier_selfforcefactor;
+ float autocvar_g_ctf_flagcarrier_damagefactor;
+ float autocvar_g_ctf_flagcarrier_forcefactor;
+ //float autocvar_g_ctf_flagcarrier_waypointforenemy_spotting;
  float autocvar_g_ctf_fullbrightflags;
  float autocvar_g_ctf_ignore_frags;
+ float autocvar_g_ctf_score_capture;
+ float autocvar_g_ctf_score_capture_assist;
+ float autocvar_g_ctf_score_kill;
+ float autocvar_g_ctf_score_penalty_drop;
+ //float autocvar_g_ctf_score_penalty_suicidedrop;
+ float autocvar_g_ctf_score_penalty_returned;
+ float autocvar_g_ctf_score_pickup_base;
+ float autocvar_g_ctf_score_pickup_dropped_early;
+ float autocvar_g_ctf_score_pickup_dropped_late;
+ float autocvar_g_ctf_score_return;
  float autocvar_g_ctf_shield_force;
  float autocvar_g_ctf_shield_max_ratio;
  float autocvar_g_ctf_shield_min_negscore;
+ float autocvar_g_ctf_stalemate;
+ float autocvar_g_ctf_stalemate_endcondition;
+ float autocvar_g_ctf_stalemate_time;
+ float autocvar_g_ctf_reverse;
+ float autocvar_g_ctf_dropped_capture_delay;
+ float autocvar_g_ctf_dropped_capture_radius;
  float autocvar_g_cts_finish_kill_delay;
  float autocvar_g_cts_selfdamage;
- float autocvar_g_deathglow;
  float autocvar_g_debug_bot_commands;
  float autocvar_g_domination_default_teams;
  float autocvar_g_domination_disable_frags;
@@@ -751,11 -816,15 +843,15 @@@ string autocvar_g_forced_team_pink
  string autocvar_g_forced_team_red;
  string autocvar_g_forced_team_yellow;
  float autocvar_g_freezetag_frozen_force;
+ float autocvar_g_freezetag_frozen_maxtime;
  float autocvar_g_freezetag_point_leadlimit;
  float autocvar_g_freezetag_point_limit;
  float autocvar_g_freezetag_revive_extra_size;
  float autocvar_g_freezetag_revive_speed;
  float autocvar_g_freezetag_revive_clearspeed;
+ float autocvar_g_freezetag_round_timelimit;
+ float autocvar_g_freezetag_teams;
+ float autocvar_g_freezetag_teams_override;
  float autocvar_g_freezetag_warmup;
  #define autocvar_g_friendlyfire cvar("g_friendlyfire")
  #define autocvar_g_friendlyfire_virtual cvar("g_friendlyfire_virtual")
  float autocvar_g_full_getstatus_responses;
  float autocvar_g_fullbrightitems;
  float autocvar_g_fullbrightplayers;
- string autocvar_g_ghost_items_color;
  #define autocvar_g_grappling_hook cvar("g_grappling_hook")
  float autocvar_g_grappling_hook_tarzan;
  float autocvar_g_hitplots;
@@@ -771,7 -839,6 +866,6 @@@ string autocvar_g_hitplots_individuals
  float autocvar_g_jetpack_acceleration_side;
  float autocvar_g_jetpack_acceleration_up;
  float autocvar_g_jetpack_antigravity;
- float autocvar_g_jetpack_attenuation;
  float autocvar_g_jetpack_fuel;
  float autocvar_g_jetpack_maxspeed_side;
  float autocvar_g_jetpack_maxspeed_up;
@@@ -800,8 -867,8 +894,8 @@@ float autocvar_g_keyhunt_teams
  float autocvar_g_keyhunt_teams_override;
  float autocvar_g_lms_campcheck_damage;
  float autocvar_g_lms_campcheck_distance;
+ float autocvar_g_lms_extra_lives;
  float autocvar_g_lms_campcheck_interval;
- string autocvar_g_lms_campcheck_message;
  float autocvar_g_lms_join_anytime;
  float autocvar_g_lms_last_join;
  #define autocvar_g_lms_lives_override cvar("g_lms_lives_override")
@@@ -831,26 -898,10 +925,10 @@@ float autocvar_g_midair_shieldtime
  float autocvar_g_minstagib_ammo_drop;
  float autocvar_g_minstagib_extralives;
  float autocvar_g_minstagib_speed_highspeed;
+ float autocvar_g_minstagib_invis_alpha;
  #define autocvar_g_mirrordamage cvar("g_mirrordamage")
  #define autocvar_g_mirrordamage_virtual cvar("g_mirrordamage_virtual")
- float autocvar_g_monster_zombie_attack_run_damage;
- float autocvar_g_monster_zombie_attack_run_delay;
- float autocvar_g_monster_zombie_attack_run_force;
- float autocvar_g_monster_zombie_attack_run_hitrange;
- float autocvar_g_monster_zombie_attack_run_range;
- float autocvar_g_monster_zombie_attack_stand_damage;
- float autocvar_g_monster_zombie_attack_stand_delay;
- float autocvar_g_monster_zombie_attack_stand_force;
- float autocvar_g_monster_zombie_attack_stand_range;
- float autocvar_g_monster_zombie_health;
- float autocvar_g_monster_zombie_idle_timer_max;
- float autocvar_g_monster_zombie_idle_timer_min;
- float autocvar_g_monster_zombie_movespeed;
- float autocvar_g_monster_zombie_respawntime;
- float autocvar_g_monster_zombie_stopspeed;
- float autocvar_g_monster_zombie_targetrange;
- float autocvar_g_monster_zombie_turnspeed;
- float autocvar_g_monsters;
  var float autocvar_g_movement_highspeed = 1;
  float autocvar_g_multijump;
  float autocvar_g_multijump_add;
@@@ -872,10 -923,10 +950,10 @@@ float autocvar_g_nexball_goalleadlimit
  float autocvar_g_nexball_radar_showallplayers;
  float autocvar_g_nexball_sound_bounce;
  float autocvar_g_nexball_trail_color;
- float autocvar_g_nick_flood_penalty;
//float autocvar_g_nick_flood_penalty;
  float autocvar_g_nick_flood_penalty_red;
  float autocvar_g_nick_flood_penalty_yellow;
- float autocvar_g_nick_flood_timeout;
//float autocvar_g_nick_flood_timeout;
  float autocvar_g_nix_with_healtharmor;
  float autocvar_g_nix_with_laser;
  float autocvar_g_nix_with_powerups;
@@@ -897,10 -948,9 +975,9 @@@ float autocvar_g_player_alpha
  float autocvar_g_player_brightness;
  float autocvar_g_playerclip_collisions;
  string autocvar_g_playerstats_uri;
- float autocvar_g_playerstats_debug;
- float autocvar_g_powerup_shield;
- float autocvar_g_powerup_strength;
- float autocvar_g_powerup_superhealth;
+ float autocvar_g_powerups;
+ float autocvar_g_projectiles_damage;
+ float autocvar_g_projectiles_keep_owner;
  float autocvar_g_projectiles_newton_style;
  float autocvar_g_projectiles_newton_style_2_maxfactor;
  float autocvar_g_projectiles_newton_style_2_minfactor;
@@@ -914,32 -964,17 +991,17 @@@ float autocvar_g_respawn_ghosts
  float autocvar_g_respawn_ghosts_maxtime;
  float autocvar_g_respawn_ghosts_speed;
  float autocvar_g_respawn_waves;
- float autocvar_g_runematch_allow_same;
- float autocvar_g_runematch_drop_runes_max;
- float autocvar_g_runematch_fixedspawns;
- float autocvar_g_runematch_frags_killed_runeholder;
- float autocvar_g_runematch_frags_killedby_runeholder;
- float autocvar_g_runematch_frags_norune;
- float autocvar_g_runematch_point_leadlimit;
- #define autocvar_g_runematch_point_limit cvar("g_runematch_point_limit")
- float autocvar_g_runematch_pointamt;
- float autocvar_g_runematch_pointrate;
- float autocvar_g_runematch_respawntime;
- float autocvar_g_runematch_rune_alpha;
- float autocvar_g_runematch_rune_color_strength;
- float autocvar_g_runematch_rune_effects;
- float autocvar_g_runematch_shuffletime;
  float autocvar_g_running_guns;
  float autocvar_g_shootfromcenter;
  float autocvar_g_shootfromclient;
  float autocvar_g_shootfromeye;
  string autocvar_g_shootfromfixedorigin;
  float autocvar_g_showweaponspawns;
+ float autocvar_g_spawn_alloweffects;
  float autocvar_g_spawn_furthest;
+ float autocvar_g_spawn_useallspawns;
  float autocvar_g_spawnpoints_auto_move_out_of_solid;
  #define autocvar_g_spawnshieldtime cvar("g_spawnshieldtime")
- float autocvar_g_spawnsound;
- float autocvar_g_start_delay;
  #define autocvar_g_start_weapon_laser cvar("g_start_weapon_laser")
  float autocvar_g_tdm_team_spawns;
  float autocvar_g_tdm_teams;
@@@ -950,8 -985,15 +1012,15 @@@ float autocvar_g_telefrags
  float autocvar_g_telefrags_avoid;
  float autocvar_g_telefrags_teamplay;
  float autocvar_g_teleport_maxspeed;
+ float autocvar_g_throughfloor_debug;
  float autocvar_g_throughfloor_damage;
  float autocvar_g_throughfloor_force;
+ float autocvar_g_throughfloor_damage_max_stddev;
+ float autocvar_g_throughfloor_force_max_stddev;
+ float autocvar_g_throughfloor_min_steps_player;
+ float autocvar_g_throughfloor_max_steps_player;
+ float autocvar_g_throughfloor_min_steps_other;
+ float autocvar_g_throughfloor_max_steps_other;
  float autocvar_g_triggerimpulse_accel_multiplier;
  float autocvar_g_triggerimpulse_accel_power;
  float autocvar_g_triggerimpulse_directional_multiplier;
@@@ -992,74 -1034,15 +1061,15 @@@ float autocvar_g_turrets_unit_walker_st
  float autocvar_g_turrets_unit_walker_std_rocket_turnrate;
  float autocvar_g_turrets_unit_walker_std_rockets_range;
  float autocvar_g_turrets_unit_walker_std_rockets_range_min;
+ float autocvar_g_turrets_unit_walker_turn;
+ float autocvar_g_turrets_unit_walker_turn_walk;
+ float autocvar_g_turrets_unit_walker_turn_run;
+ float autocvar_g_turrets_unit_walker_turn_strafe;
+ float autocvar_g_turrets_unit_walker_turn_swim;
  float autocvar_g_use_ammunition;
- float autocvar_g_vehicle_racer_afterburn_cost;
- float autocvar_g_vehicle_racer_anglestabilizer;
- float autocvar_g_vehicle_racer_downforce;
- float autocvar_g_vehicle_racer_energy;
- float autocvar_g_vehicle_racer_energy_usepause;
- float autocvar_g_vehicle_racer_health;
- float autocvar_g_vehicle_racer_laser_cost;
- float autocvar_g_vehicle_racer_laser_damage;
- float autocvar_g_vehicle_racer_laser_radius;
- float autocvar_g_vehicle_racer_laser_refire;
- float autocvar_g_vehicle_racer_laser_speed;
- float autocvar_g_vehicle_racer_pitchspeed;
- float autocvar_g_vehicle_racer_power_air;
- float autocvar_g_vehicle_racer_power_min;
- float autocvar_g_vehicle_racer_power_solid;
- float autocvar_g_vehicle_racer_reload;
- float autocvar_g_vehicle_racer_respawntime;
- float autocvar_g_vehicle_racer_rocket_accel;
- float autocvar_g_vehicle_racer_rocket_damage;
- float autocvar_g_vehicle_racer_rocket_radius;
- float autocvar_g_vehicle_racer_rocket_refire;
- float autocvar_g_vehicle_racer_rocket_speed;
- float autocvar_g_vehicle_racer_rocket_turnrate;
- float autocvar_g_vehicle_racer_shield;
- float autocvar_g_vehicle_racer_speed_afterburn;
- float autocvar_g_vehicle_racer_speed_forward;
- float autocvar_g_vehicle_racer_speed_strafe;
- float autocvar_g_vehicle_racer_springlength;
- float autocvar_g_vehicle_racer_turnroll;
- float autocvar_g_vehicle_racer_turnspeed;
- float autocvar_g_vehicle_raptor_reload;
- float autocvar_g_vehicle_spiderbot_crush_dmg;
- float autocvar_g_vehicle_spiderbot_crush_force;
- float autocvar_g_vehicle_spiderbot_head_pitchlimit_down;
- float autocvar_g_vehicle_spiderbot_head_pitchlimit_up;
- float autocvar_g_vehicle_spiderbot_head_pitchspeed;
- float autocvar_g_vehicle_spiderbot_head_turnlimit;
- float autocvar_g_vehicle_spiderbot_head_turnspeed;
- float autocvar_g_vehicle_spiderbot_health;
- float autocvar_g_vehicle_spiderbot_minigun_cooldown;
- float autocvar_g_vehicle_spiderbot_minigun_damage;
- float autocvar_g_vehicle_spiderbot_minigun_heat;
- float autocvar_g_vehicle_spiderbot_minigun_refire;
- float autocvar_g_vehicle_spiderbot_minigun_spread;
- float autocvar_g_vehicle_spiderbot_movement_inertia;
- float autocvar_g_vehicle_spiderbot_respawntime;
- float autocvar_g_vehicle_spiderbot_rocket_damage;
- float autocvar_g_vehicle_spiderbot_rocket_edgedamage;
- float autocvar_g_vehicle_spiderbot_rocket_force;
- float autocvar_g_vehicle_spiderbot_rocket_health;
- float autocvar_g_vehicle_spiderbot_rocket_lifetime;
- float autocvar_g_vehicle_spiderbot_rocket_noise;
- float autocvar_g_vehicle_spiderbot_rocket_radius;
- float autocvar_g_vehicle_spiderbot_rocket_refire;
- float autocvar_g_vehicle_spiderbot_rocket_reload;
- float autocvar_g_vehicle_spiderbot_rocket_speed;
- float autocvar_g_vehicle_spiderbot_rocket_turnrate;
- float autocvar_g_vehicle_spiderbot_shield;
- float autocvar_g_vehicle_spiderbot_speed_stop;
- float autocvar_g_vehicle_spiderbot_speed_strafe;
- float autocvar_g_vehicle_spiderbot_speed_walk;
- float autocvar_g_vehicle_spiderbot_turnspeed;
  float autocvar_g_waypointeditor;
+ float autocvar_g_waypointeditor_auto;
  float autocvar_g_waypoints_for_items;
- float autocvar_g_waypointsprite_deadlifetime;
- float autocvar_g_waypointsprite_deployed_lifetime;
- float autocvar_g_waypointsprite_limitedrange;
  float autocvar_g_weapon_charge_colormod_blue_full;
  float autocvar_g_weapon_charge_colormod_blue_half;
  float autocvar_g_weapon_charge_colormod_green_full;
@@@ -1071,7 -1054,6 +1081,6 @@@ float autocvar_g_weapon_charge_colormod
  float autocvar_g_weapon_throwable;
  #define autocvar_g_weaponarena cvar_string("g_weaponarena")
  string autocvar_g_xonoticversion;
- float autocvar_gamecfg;
  float autocvar_gameversion;
  float autocvar_gameversion_min;
  float autocvar_gameversion_max;
@@@ -1085,21 -1067,23 +1094,23 @@@ float autocvar_minplayers
  string autocvar_nextmap;
  float autocvar_prvm_backtraceforwarnings;
  string autocvar_quit_and_redirect;
+ float autocvar_quit_and_redirect_timer;
  float autocvar_quit_when_empty;
  float autocvar_r_showbboxes;
  float autocvar_rescan_pending;
  float autocvar_samelevel;
+ string autocvar_sessionid;
  #define autocvar_skill cvar("skill")
  float autocvar_skill_auto;
  #define autocvar_slowmo cvar("slowmo")
  float autocvar_snd_soundradius;
  float autocvar_spawn_debug;
- float autocvar_spawn_debugview;
  float autocvar_speedmeter;
  float autocvar_sv_accelerate;
  var float autocvar_sv_accuracy_data_share = 1;
  string autocvar_sv_adminnick;
  float autocvar_sv_airaccel_qw;
+ float autocvar_sv_airaccel_qw_stretchfactor;
  float autocvar_sv_airaccel_sideways_friction;
  float autocvar_sv_airaccelerate;
  float autocvar_sv_aircontrol;
@@@ -1109,9 -1093,10 +1120,10 @@@ float autocvar_sv_airspeedlimit_nonqw
  float autocvar_sv_airstopaccelerate;
  float autocvar_sv_airstrafeaccel_qw;
  float autocvar_sv_airstrafeaccelerate;
- float autocvar_sv_allow_shownames;
  float autocvar_sv_autoscreenshot;
  float autocvar_sv_cheats;
+ float autocvar_sv_clientcommand_antispam_time;
+ float autocvar_sv_clientcommand_antispam_count;
  float autocvar_sv_curl_serverpackages_auto;
  float autocvar_sv_db_saveasdump;
  float autocvar_sv_defaultcharacter;
@@@ -1138,13 -1123,10 +1150,10 @@@ float autocvar_sv_eventlog_files_counte
  string autocvar_sv_eventlog_files_nameprefix;
  string autocvar_sv_eventlog_files_namesuffix;
  float autocvar_sv_eventlog_files_timestamps;
- float autocvar_sv_fragmessage_information_handicap;
- float autocvar_sv_fragmessage_information_ping;
- float autocvar_sv_fragmessage_information_stats;
- float autocvar_sv_fragmessage_information_typefrag;
  float autocvar_sv_friction;
  float autocvar_sv_friction_on_land;
  float autocvar_sv_gameplayfix_q2airaccelerate;
+ float autocvar_sv_gentle;
  #define autocvar_sv_gravity cvar("sv_gravity")
  string autocvar_sv_intermission_cdtrack;
  string autocvar_sv_jumpspeedcap_max;
@@@ -1160,23 -1142,16 +1169,16 @@@ float autocvar_sv_maxairspeed
  float autocvar_sv_maxairstrafespeed;
  float autocvar_sv_maxspeed;
  string autocvar_sv_motd;
- string autocvar_sv_player_crouch_maxs;
- string autocvar_sv_player_crouch_mins;
- string autocvar_sv_player_crouch_viewoffset;
- string autocvar_sv_player_headsize;
- string autocvar_sv_player_maxs;
- string autocvar_sv_player_mins;
- string autocvar_sv_player_viewoffset;
  float autocvar_sv_precacheplayermodels;
  float autocvar_sv_precacheweapons;
  float autocvar_sv_q3acompat_machineshotgunswap;
- float autocvar_sv_qcweaponanimation;
  float autocvar_sv_ready_restart;
  float autocvar_sv_ready_restart_after_countdown;
  float autocvar_sv_ready_restart_repeatable;
  float autocvar_sv_servermodelsonly;
  float autocvar_sv_spectate;
  float autocvar_sv_spectator_speed_multiplier;
+ float autocvar_sv_status_privacy;
  float autocvar_sv_stepheight;
  float autocvar_sv_stopspeed;
  float autocvar_sv_strengthsound_antispam_refire_threshold;
@@@ -1190,24 -1165,33 +1192,33 @@@ float autocvar_sv_timeout_resumetime
  float autocvar_sv_vote_call;
  float autocvar_sv_vote_change;
  string autocvar_sv_vote_commands;
+ float autocvar_sv_vote_limit;
  float autocvar_sv_vote_majority_factor;
+ float autocvar_sv_vote_majority_factor_of_voted;
  float autocvar_sv_vote_master;
+ float autocvar_sv_vote_master_callable;
  string autocvar_sv_vote_master_commands;
  string autocvar_sv_vote_master_password;
+ float autocvar_sv_vote_master_playerlimit;
+ float autocvar_sv_vote_no_stops_vote;
  float autocvar_sv_vote_nospectators;
- string autocvar_sv_vote_only_commands;
//string autocvar_sv_vote_only_commands;
  float autocvar_sv_vote_override_mostrecent;
- float autocvar_sv_vote_simple_majority_factor;
  float autocvar_sv_vote_singlecount;
  float autocvar_sv_vote_stop;
  float autocvar_sv_vote_timeout;
  float autocvar_sv_vote_wait;
+ float autocvar_sv_vote_gamestart;
  float autocvar_sv_warsowbunny_accel;
  float autocvar_sv_warsowbunny_airforwardaccel;
  float autocvar_sv_warsowbunny_backtosideratio;
  float autocvar_sv_warsowbunny_topspeed;
  float autocvar_sv_warsowbunny_turnaccel;
+ float autocvar_sv_waypointsprite_deadlifetime;
+ float autocvar_sv_waypointsprite_deployed_lifetime;
+ float autocvar_sv_waypointsprite_limitedrange;
  string autocvar_sv_weaponstats_file;
+ float autocvar_sv_gibhealth;
  float autocvar_sys_ticrate;
  float autocvar_teamplay_lockonrestart;
  float autocvar_teamplay_mode;
@@@ -1225,3 -1209,28 +1236,28 @@@ float autocvar_waypoint_benchmark
  float autocvar_welcome_message_time;
  float autocvar_sv_gameplayfix_gravityunaffectedbyticrate;
  float autocvar_g_trueaim_minrange;
+ float autocvar_g_debug_defaultsounds;
+ float autocvar_g_grab_range;
+ float autocvar_g_sandbox_info;
+ float autocvar_g_sandbox_readonly;
+ string autocvar_g_sandbox_storage_name;
+ float autocvar_g_sandbox_storage_autosave;
+ float autocvar_g_sandbox_storage_autoload;
+ float autocvar_g_sandbox_editor_flood;
+ float autocvar_g_sandbox_editor_maxobjects;
+ float autocvar_g_sandbox_editor_free;
+ float autocvar_g_sandbox_editor_distance_spawn;
+ float autocvar_g_sandbox_editor_distance_edit;
+ float autocvar_g_sandbox_object_scale_min;
+ float autocvar_g_sandbox_object_scale_max;
+ float autocvar_g_sandbox_object_material_velocity_min;
+ float autocvar_g_sandbox_object_material_velocity_factor;
+ float autocvar_g_max_info_autoscreenshot;
+ float autocvar_physics_ode;
+ float autocvar_g_physical_items;
+ float autocvar_g_physical_items_damageforcescale;
+ float autocvar_g_physical_items_reset;
+ float autocvar_g_touchexplode_radius;
+ float autocvar_g_touchexplode_damage;
+ float autocvar_g_touchexplode_edgedamage;
+ float autocvar_g_touchexplode_force;
index 12b70cef60eb3cab09c5383c6af4d437d8fc2c28,036bb45fb6dc48f029212faead961db052d00d12..2908958405e291da418a95a4e739906509171169
@@@ -6,22 -6,6 +6,6 @@@ void send_CSQC_teamnagger() 
        WriteByte(MSG_BROADCAST, TE_CSQC_TEAMNAGGER);
  }
  
- void Announce(string snd) {
-       WriteByte(MSG_ALL, SVC_TEMPENTITY);
-       WriteByte(MSG_ALL, TE_CSQC_ANNOUNCE);
-       WriteString(MSG_ALL, snd);
- }
- void AnnounceTo(entity e, string snd) {
-       if (clienttype(e) == CLIENTTYPE_REAL)
-       {
-               msg_entity = e;
-               WriteByte(MSG_ONE, SVC_TEMPENTITY);
-               WriteByte(MSG_ONE, TE_CSQC_ANNOUNCE);
-               WriteString(MSG_ONE, snd);
-       }
- }
  float ClientData_Send(entity to, float sf)
  {
        if(to != self.owner)
@@@ -33,7 -17,7 +17,7 @@@
        entity e;
  
        e = to;
-       if(to.classname == "spectator")
+       if(IS_SPEC(to))
                e = to.enemy;
  
        sf = 0;
@@@ -84,311 -68,14 +68,14 @@@ void ClientData_Touch(entity e
        FOR_EACH_REALCLIENT(e2)
        {
                if(e2 != e)
-                       if(e2.classname == "spectator")
+                       if(IS_SPEC(e2))
                                if(e2.enemy == e)
                                        e2.clientdata.SendFlags = 1;
        }
  }
  
- .vector spawnpoint_score;
  .string netname_previous;
  
- void spawnfunc_info_player_survivor (void)
- {
-       spawnfunc_info_player_deathmatch();
- }
- void spawnfunc_info_player_start (void)
- {
-       spawnfunc_info_player_deathmatch();
- }
- void spawnfunc_info_player_deathmatch (void)
- {
-       self.classname = "info_player_deathmatch";
-       relocate_spawnpoint();
- }
- void spawnpoint_use()
- {
-       if(teams_matter)
-       if(have_team_spawns > 0)
-       {
-               self.team = activator.team;
-               some_spawn_has_been_used = 1;
-       }
- };
- // Returns:
- //   _x: prio (-1 if unusable)
- //   _y: weight
- vector Spawn_Score(entity spot, entity playerlist, float teamcheck, float anypoint)
- {
-       float shortest, thisdist;
-       float prio;
-       entity player;
-       prio = 0;
-       // filter out spots for the wrong team
-       if(teamcheck)
-       if(spot.team != teamcheck)
-               return '-1 0 0';
-       if(race_spawns)
-               if(spot.target == "")
-                       return '-1 0 0';
-       if(clienttype(self) == CLIENTTYPE_REAL)
-       {
-               if(spot.restriction == 1)
-                       return '-1 0 0';
-       }
-       else
-       {
-               if(spot.restriction == 2)
-                       return '-1 0 0';
-       }
-       // filter out spots for assault
-       if(spot.target != "") {
-               local entity ent;
-               float good, found;
-               ent = find(world, targetname, spot.target);
-               while(ent) {
-                       if(ent.classname == "target_objective")
-                       {
-                               found = 1;
-                               if(ent.health < 0 || ent.health >= ASSAULT_VALUE_INACTIVE)
-                                       return '-1 0 0';
-                               good = 1;
-                       }
-                       else if(ent.classname == "trigger_race_checkpoint")
-                       {
-                               found = 1;
-                               if(!anypoint) // spectators may spawn everywhere
-                               {
-                                       if(g_race_qualifying)
-                                       {
-                                               // spawn at first
-                                               if(ent.race_checkpoint != 0)
-                                                       return '-1 0 0';
-                                               if(spot.race_place != race_lowest_place_spawn)
-                                                       return '-1 0 0';
-                                       }
-                                       else
-                                       {
-                                               if(ent.race_checkpoint != self.race_respawn_checkpoint)
-                                                       return '-1 0 0';
-                                               // try reusing the previous spawn
-                                               if(ent == self.race_respawn_spotref || spot == self.race_respawn_spotref)
-                                                       prio += 1;
-                                               if(ent.race_checkpoint == 0)
-                                               {
-                                                       float pl;
-                                                       pl = self.race_place;
-                                                       if(pl > race_highest_place_spawn)
-                                                               pl = 0;
-                                                       if(pl == 0 && !self.race_started)
-                                                               pl = race_highest_place_spawn; // use last place if he has not even touched finish yet
-                                                       if(spot.race_place != pl)
-                                                               return '-1 0 0';
-                                               }
-                                       }
-                               }
-                               good = 1;
-                       }
-                       ent = find(ent, targetname, spot.target);
-               }
-               if(found && !good)
-                       return '-1 0 0';
-       }
-       player = playerlist;
-       shortest = vlen(world.maxs - world.mins);
-       for(player = playerlist; player; player = player.chain)
-               if (player != self)
-               {
-                       thisdist = vlen(player.origin - spot.origin);
-                       if (thisdist < shortest)
-                               shortest = thisdist;
-               }
-       return prio * '1 0 0' + shortest * '0 1 0';
- }
- float spawn_allbad;
- float spawn_allgood;
- entity Spawn_FilterOutBadSpots(entity firstspot, entity playerlist, float mindist, float teamcheck, float anypoint)
- {
-       local entity spot, spotlist, spotlistend;
-       spawn_allgood = TRUE;
-       spawn_allbad = TRUE;
-       spotlist = world;
-       spotlistend = world;
-       for(spot = firstspot; spot; spot = spot.chain)
-       {
-               spot.spawnpoint_score = Spawn_Score(spot, playerlist, teamcheck, anypoint);
-               if(autocvar_spawn_debugview)
-               {
-                       setmodel(spot, "models/runematch/rune.mdl");
-                       if(spot.spawnpoint_score_y < mindist)
-                       {
-                               spot.colormod = '1 0 0';
-                               spot.scale = 1;
-                       }
-                       else
-                       {
-                               spot.colormod = '0 1 0';
-                               spot.scale = spot.spawnpoint_score_y / mindist;
-                       }
-               }
-               if(spot.spawnpoint_score_x >= 0) // spawning allowed here
-               {
-                       if(spot.spawnpoint_score_y < mindist)
-                       {
-                               // too short distance
-                               spawn_allgood = FALSE;
-                       }
-                       else
-                       {
-                               // perfect
-                               spawn_allbad = FALSE;
-                               if(spotlistend)
-                                       spotlistend.chain = spot;
-                               spotlistend = spot;
-                               if(!spotlist)
-                                       spotlist = spot;
-                               /*
-                               if(teamcheck)
-                               if(spot.team != teamcheck)
-                                       error("invalid spawn added");
-                               print("added ", etos(spot), "\n");
-                               */
-                       }
-               }
-       }
-       if(spotlistend)
-               spotlistend.chain = world;
-       /*
-               entity e;
-               if(teamcheck)
-                       for(e = spotlist; e; e = e.chain)
-                       {
-                               print("seen ", etos(e), "\n");
-                               if(e.team != teamcheck)
-                                       error("invalid spawn found");
-                       }
-       */
-       return spotlist;
- }
- entity Spawn_WeightedPoint(entity firstspot, float lower, float upper, float exponent)
- {
-       // weight of a point: bound(lower, mindisttoplayer, upper)^exponent
-       // multiplied by spot.cnt (useful if you distribute many spawnpoints in a small area)
-       local entity spot;
-       RandomSelection_Init();
-       for(spot = firstspot; spot; spot = spot.chain)
-               RandomSelection_Add(spot, 0, string_null, pow(bound(lower, spot.spawnpoint_score_y, upper), exponent) * spot.cnt, (spot.spawnpoint_score_y >= lower) * 0.5 + spot.spawnpoint_score_x);
-       return RandomSelection_chosen_ent;
- }
- /*
- =============
- SelectSpawnPoint
- Finds a point to respawn
- =============
- */
- entity SelectSpawnPoint (float anypoint)
- {
-       local float teamcheck;
-       local entity firstspot_new;
-       local entity spot, firstspot, playerlist;
-       spot = find (world, classname, "testplayerstart");
-       if (spot)
-               return spot;
-       teamcheck = 0;
-       if(!anypoint && have_team_spawns > 0)
-               teamcheck = self.team;
-       // get the list of players
-       playerlist = findchain(classname, "player");
-       // get the entire list of spots
-       firstspot = findchain(classname, "info_player_deathmatch");
-       // filter out the bad ones
-       // (note this returns the original list if none survived)
-       if(anypoint)
-       {
-               spot = Spawn_WeightedPoint(firstspot, 1, 1, 1);
-       }
-       else
-       {
-               firstspot_new = Spawn_FilterOutBadSpots(firstspot, playerlist, 100, teamcheck, anypoint);
-               if(!firstspot_new)
-                       firstspot_new = Spawn_FilterOutBadSpots(firstspot, playerlist, -1, teamcheck, anypoint);
-               firstspot = firstspot_new;
-               // there is 50/50 chance of choosing a random spot or the furthest spot
-               // (this means that roughly every other spawn will be furthest, so you
-               // usually won't get fragged at spawn twice in a row)
-               if (arena_roundbased && !g_ca)
-               {
-                       firstspot_new = Spawn_FilterOutBadSpots(firstspot, playerlist, 800, teamcheck, anypoint);
-                       if(firstspot_new)
-                               firstspot = firstspot_new;
-                       spot = Spawn_WeightedPoint(firstspot, 1, 1, 1);
-               }
-               else if (random() > autocvar_g_spawn_furthest)
-                       spot = Spawn_WeightedPoint(firstspot, 1, 1, 1);
-               else
-                       spot = Spawn_WeightedPoint(firstspot, 1, 5000, 5); // chooses a far far away spawnpoint
-       }
-       if(autocvar_spawn_debugview)
-       {
-               print("spot mindistance: ", vtos(spot.spawnpoint_score), "\n");
-               entity e;
-               if(teamcheck)
-                       for(e = firstspot; e; e = e.chain)
-                               if(e.team != teamcheck)
-                                       error("invalid spawn found");
-       }
-       if (!spot)
-       {
-               if(autocvar_spawn_debug)
-                       GotoNextMap();
-               else
-               {
-                       if(some_spawn_has_been_used)
-                               return world; // team can't spawn any more, because of actions of other team
-                       else
-                               error("Cannot find a spawn point - please fix the map!");
-               }
-       }
-       return spot;
- }
  
  /*
  =============
@@@ -407,160 -94,36 +94,36 @@@ string CheckPlayerModel(string plyermod
                // to change a cvar default, we'll have a small leak here.
                FallbackPlayerModel = strzone(cvar_defstring("_cl_playermodel"));
        }
-       if(strlen(plyermodel) < 4)
-               return FallbackPlayerModel;
+       // only in right path
        if( substring(plyermodel,0,14) != "models/player/")
                return FallbackPlayerModel;
-       else if(autocvar_sv_servermodelsonly)
+       // only good file extensions
+       if(substring(plyermodel,-4,4) != ".zym")
+       if(substring(plyermodel,-4,4) != ".dpm")
+       if(substring(plyermodel,-4,4) != ".iqm")
+       if(substring(plyermodel,-4,4) != ".md3")
+       if(substring(plyermodel,-4,4) != ".psk")
+               return FallbackPlayerModel;
+       // forbid the LOD models
+       if(substring(plyermodel, -9,5) == "_lod1")
+               return FallbackPlayerModel;
+       if(substring(plyermodel, -9,5) == "_lod2")
+               return FallbackPlayerModel;
+       if(plyermodel != strtolower(plyermodel))
+               return FallbackPlayerModel;
+       // also, restrict to server models
+       if(autocvar_sv_servermodelsonly)
        {
-               if(substring(plyermodel,-4,4) != ".zym")
-               if(substring(plyermodel,-4,4) != ".dpm")
-               if(substring(plyermodel,-4,4) != ".iqm")
-               if(substring(plyermodel,-4,4) != ".md3")
-               if(substring(plyermodel,-4,4) != ".psk")
-                       return FallbackPlayerModel;
-               // forbid the LOD models
-               if(substring(plyermodel, -9,5) == "_lod1")
-                       return FallbackPlayerModel;
-               if(substring(plyermodel, -9,5) == "_lod2")
-                       return FallbackPlayerModel;
-               if(plyermodel != strtolower(plyermodel))
-                       return FallbackPlayerModel;
                if(!fexists(plyermodel))
                        return FallbackPlayerModel;
        }
        return plyermodel;
  }
  
- /*
- =============
- Client_customizeentityforclient
- LOD reduction
- =============
- */
- void Client_uncustomizeentityforclient()
+ void setplayermodel(entity e, string modelname)
  {
-       if(self.modelindex == 0) // no need to uncustomize then
-               return;
-       self.modelindex = self.modelindex_lod0;
-       self.skin = self.skinindex;
- }
- float Client_customizeentityforclient()
- {
-       entity modelsource;
-       if(self.modelindex == 0)
-               return TRUE;
-       // forcemodel stuff
- #ifdef PROFILING
-       float t0;
-       t0 = gettime(GETTIME_HIRES); // reference
- #endif
-       modelsource = self;
- #ifdef ALLOW_FORCEMODELS
-       if(other.cvar_cl_forceplayermodelsfromxonotic)
-               if not(self.modelindex_lod0_from_xonotic)
-                       modelsource = other;
-       if(other.cvar_cl_forceplayermodels && sv_clforceplayermodels)
-               modelsource = other;
- #endif
-       self.skin = modelsource.skinindex;
- #if 0
-       if(modelsource == self)
-               self.skin = modelsource.skinindex;
-       else
-               self.skin = mod(modelsource.skinindex, 3); // forbid the fbskins as forced skins
- #endif
-       // self: me
-       // other: the player viewing me
-       float distance;
-       float f;
-       if(other.cvar_cl_playerdetailreduction <= 0)
-       {
-               if(other.cvar_cl_playerdetailreduction <= -2)
-                       self.modelindex = modelsource.modelindex_lod2;
-               else if(other.cvar_cl_playerdetailreduction <= -1)
-                       self.modelindex = modelsource.modelindex_lod1;
-               else
-                       self.modelindex = modelsource.modelindex_lod0;
-       }
-       else
-       {
-               distance = vlen(self.origin - other.origin);
-               f = (distance + 100.0) * other.cvar_cl_playerdetailreduction;
-               if(f > sv_loddistance2)
-                       self.modelindex = modelsource.modelindex_lod2;
-               else if(f > sv_loddistance1)
-                       self.modelindex = modelsource.modelindex_lod1;
-               else
-                       self.modelindex = modelsource.modelindex_lod0;
-       }
- #ifdef PROFILING
-       float t1;
-       t1 = gettime(GETTIME_HIRES); // reference
-       client_cefc_accumulator += (t1 - t0);
- #endif
-       return TRUE;
- }
- void setmodel_lod(entity e, string modelname)
- {
-       string s;
-       if(sv_loddistance1)
-       {
-               // FIXME: this only supports 3-letter extensions
-               s = strcat(substring(modelname, 0, strlen(modelname)-4), "_lod1", substring(modelname, -4, 4));
-               if(fexists(s))
-               {
-                       setmodel(e, s); // players have high precision
-                       self.modelindex_lod1 = self.modelindex;
-               }
-               else
-                       self.modelindex_lod1 = -1;
-               s = strcat(substring(modelname, 0, strlen(modelname)-4), "_lod2", substring(modelname, -4, 4));
-               if(fexists(s))
-               {
-                       setmodel(e, s); // players have high precision
-                       self.modelindex_lod2 = self.modelindex;
-               }
-               else
-                       self.modelindex_lod2 = -1;
-               precache_model(modelname);
-               setmodel(e, modelname); // players have high precision
-               self.modelindex_lod0 = self.modelindex;
-               if(self.modelindex_lod1 < 0)
-                       self.modelindex_lod1 = self.modelindex;
-               if(self.modelindex_lod2 < 0)
-                       self.modelindex_lod2 = self.modelindex;
-       }
-       else
-       {
-               precache_model(modelname);
-               setmodel(e, modelname); // players have high precision
-               self.modelindex_lod0 = self.modelindex;
-                       // save it for possible player model forcing
-       }
-       s = whichpack(self.model);
-       self.modelindex_lod0_from_xonotic = ((s == "") || (substring(s, 0, 4) == "data"));
+       precache_model(modelname);
+       setmodel(e, modelname);
        player_setupanimsformodel();
        UpdatePlayerSounds();
  }
@@@ -576,7 -139,7 +139,7 @@@ void FixPlayermodel()
  void PutObserverInServer (void)
  {
        entity  spot;
+     self.hud = HUD_NORMAL;
        race_PreSpawnObserver();
  
        spot = SelectSpawnPoint (TRUE);
                error("No spawnpoints for observers?!?\n");
        RemoveGrapplingHook(self); // Wazat's Grappling Hook
  
-       if(clienttype(self) == CLIENTTYPE_REAL)
+       if(IS_REAL_CLIENT(self))
        {
                msg_entity = self;
                WriteByte(MSG_ONE, SVC_SETVIEW);
                WriteEntity(MSG_ONE, self);
        }
  
-       DropAllRunes(self);
+       if((g_race && g_race_qualifying) || g_cts)
+       {
+               if(PlayerScore_Add(self, SP_RACE_FASTEST, 0))
+                       self.frags = FRAGS_LMS_LOSER;
+               else
+                       self.frags = FRAGS_SPECTATOR;
+       }
+       else
+               self.frags = FRAGS_SPECTATOR;
        MUTATOR_CALLHOOK(MakePlayerObserver);
  
        Portal_ClearAll(self);
+       
        if(self.alivetime)
        {
-               PlayerStats_Event(self, PLAYERSTATS_ALIVETIME, time - self.alivetime);
+               if(!inWarmupStage)
+                       PlayerStats_Event(self, PLAYERSTATS_ALIVETIME, time - self.alivetime);
                self.alivetime = 0;
        }
  
-       if(self.flagcarried)
-               DropFlag(self.flagcarried, world, world);
-       if(self.ballcarried && g_nexball)
-               DropBall(self.ballcarried, self.origin + self.ballcarried.origin, self.velocity);
+       if(self.vehicle)
+               vehicles_exit(VHEF_RELESE);         
  
        WaypointSprite_PlayerDead();
  
        if not(g_ca)  // don't reset teams when moving a ca player to the spectators
                self.team = -1;  // move this as it is needed to log the player spectating in eventlog
  
-       if(self.killcount != -666) {
-               if(g_lms) {
-                       if(PlayerScore_Add(self, SP_LMS_RANK, 0) > 0)
-                               bprint ("^4", self.netname, "^4 has no more lives left\n");
-                       else
-                               bprint ("^4", self.netname, "^4 is spectating now\n"); // TODO turn this into a proper forfeit?
-               } else
-                       bprint ("^4", self.netname, "^4 is spectating now\n");
+       if(self.killcount != -666)
+       {
+               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_QUIT_SPECTATE, self.netname);
  
                if(self.just_joined == FALSE) {
                        LogTeamchange(self.playerid, -1, 4);
        accuracy_resend(self);
  
        self.spectatortime = time;
+       
        self.classname = "observer";
        self.iscreature = FALSE;
+       self.teleportable = TELEPORT_SIMPLE;
+       self.damagedbycontents = FALSE;
        self.health = -666;
        self.takedamage = DAMAGE_NO;
        self.solid = SOLID_NOT;
-       self.movetype = MOVETYPE_NOCLIP;
+       self.movetype = MOVETYPE_FLY_WORLDONLY; // user preference is controlled by playerprethink
        self.flags = FL_CLIENT | FL_NOTARGET;
        self.armorvalue = 666;
        self.effects = 0;
        self.pauseregen_finished = 0;
        self.damageforcescale = 0;
        self.death_time = 0;
-       self.dead_frame = 0;
+       self.respawn_flags = 0;
+       self.respawn_time = 0;
+       self.stat_respawn_time = 0;
        self.alpha = 0;
        self.scale = 0;
        self.fade_time = 0;
        self.pain_finished = 0;
        self.strength_finished = 0;
        self.invincible_finished = 0;
+       self.superweapons_finished = 0;
        self.pushltime = 0;
-       self.think = SUB_Null;
+       self.istypefrag = 0;
+       self.think = func_null;
        self.nextthink = 0;
        self.hook_time = 0;
-       self.runes = 0;
        self.deadflag = DEAD_NO;
        self.angles = spot.angles;
        self.angles_z = 0;
        self.fixangle = TRUE;
        self.crouch = FALSE;
  
-       self.view_ofs = PL_VIEW_OFS;
-       setorigin (self, spot.origin);
-       setsize (self, '0 0 0', '0 0 0');
+       setorigin (self, (spot.origin + PL_VIEW_OFS)); // offset it so that the spectator spawns higher off the ground, looks better this way
        self.prevorigin = self.origin;
        self.items = 0;
-       self.weapons = 0;
+       WEPSET_CLEAR_E(self);
        self.model = "";
        FixPlayermodel();
-       self.model = "";
-       self.modelindex = 0;
+       setmodel(self, "null");
+       self.drawonlytoclient = self;
+       setsize (self, PL_CROUCH_MIN, PL_CROUCH_MAX); // give the spectator some space between walls for MOVETYPE_FLY_WORLDONLY
+       self.view_ofs = '0 0 0'; // so that your view doesn't go into the ceiling with MOVETYPE_FLY_WORLDONLY, previously "PL_VIEW_OFS"
        self.weapon = 0;
+       self.weaponname = "";
+       self.switchingweapon = 0;
        self.weaponmodel = "";
        self.weaponentity = world;
        self.exteriorweaponentity = world;
        self.punchvector = '0 0 0';
        self.oldvelocity = self.velocity;
        self.fire_endtime = -1;
-       if(sv_loddistance1)
-               SetCustomizer(self, Client_customizeentityforclient, Client_uncustomizeentityforclient);
-       if(g_arena)
-       {
-               if(self.version_mismatch)
-               {
-                       Spawnqueue_Unmark(self);
-                       Spawnqueue_Remove(self);
-               }
-               else
-               {
-                       Spawnqueue_Insert(self);
-               }
-       }
-       else if(g_lms)
-       {
-               // Only if the player cannot play at all
-               if(PlayerScore_Add(self, SP_LMS_RANK, 0) == 666)
-                       self.frags = FRAGS_SPECTATOR;
-               else
-                       self.frags = FRAGS_LMS_LOSER;
-       }
-       else
-               self.frags = FRAGS_SPECTATOR;
  }
  
+ .float model_randomizer;
  void FixPlayermodel()
  {
-       local string defaultmodel;
-       local float defaultskin, chmdl, oldskin;
-       local vector m1, m2;
+       string defaultmodel;
+       float defaultskin, chmdl, oldskin, n, i;
+       vector m1, m2;
  
        defaultmodel = "";
+       defaultskin = 0;
+       chmdl = FALSE;
  
-       if(autocvar_sv_defaultcharacter == 1) {
-               defaultskin = 0;
-               if(teams_matter)
+       if(autocvar_sv_defaultcharacter == 1)
+       {
+               if(teamplay)
                {
                        string s;
-                       s = Team_ColorNameLowerCase(self.team);
+                       s = Team_ColorName_Lower(self.team);
                        if(s != "neutral")
                        {
                                defaultmodel = cvar_string(strcat("sv_defaultplayermodel_", s));
                        defaultmodel = autocvar_sv_defaultplayermodel;
                        defaultskin = autocvar_sv_defaultplayerskin;
                }
-       }
  
-       if(self.modelindex == 0 && self.deadflag == DEAD_NO)
-       {
-               if(self.model != "")
-                       bprint("\{1}^1Player ", self.netname, "^1 has a zero modelindex, trying to fix...\n");
-               self.model = ""; // force the != checks to return true
+               n = tokenize_console(defaultmodel);
+               if(n > 0)
+                       defaultmodel = argv(floor(n * self.model_randomizer));
+               i = strstrofs(defaultmodel, ":", 0);
+               if(i >= 0)
+               {
+                       defaultskin = stof(substring(defaultmodel, i+1, -1));
+                       defaultmodel = substring(defaultmodel, 0, i);
+               }
        }
  
        if(defaultmodel != "")
                {
                        m1 = self.mins;
                        m2 = self.maxs;
-                       setmodel_lod (self, defaultmodel);
+                       setplayermodel (self, defaultmodel);
                        setsize (self, m1, m2);
                        chmdl = TRUE;
                }
  
-               oldskin = self.skinindex;
-               self.skinindex = defaultskin;
+               oldskin = self.skin;
+               self.skin = defaultskin;
        } else {
                if (self.playermodel != self.model || self.playermodel == "")
                {
                        self.playermodel = CheckPlayerModel(self.playermodel); // this is never "", so no endless loop
                        m1 = self.mins;
                        m2 = self.maxs;
-                       setmodel_lod (self, self.playermodel);
+                       setplayermodel (self, self.playermodel);
                        setsize (self, m1, m2);
                        chmdl = TRUE;
                }
  
-               oldskin = self.skinindex;
-               self.skinindex = stof(self.playerskin);
+               oldskin = self.skin;
+               self.skin = stof(self.playerskin);
        }
  
-       if(chmdl || oldskin != self.skinindex)
-               self.species = player_getspecies(); // model or skin has changed
+       if(chmdl || oldskin != self.skin) // model or skin has changed
+       {
+               self.species = player_getspecies(); // update species
+               UpdatePlayerSounds(); // update skin sounds
+       }
  
-       if(!teams_matter)
+       if(!teamplay)
                if(strlen(autocvar_sv_defaultplayercolors))
                        if(self.clientcolors != stof(autocvar_sv_defaultplayercolors))
                                setcolor(self, stof(autocvar_sv_defaultplayercolors));
  }
  
- void PlayerTouchExplode(entity p1, entity p2)
- {
-       vector org;
-       org = (p1.origin + p2.origin) * 0.5;
-       org_z += (p1.mins_z + p2.mins_z) * 0.5;
-       te_explosion(org);
-       entity e;
-       e = spawn();
-       setorigin(e, org);
-       RadiusDamage(e, world, g_touchexplode_damage, g_touchexplode_edgedamage, g_touchexplode_radius, world, g_touchexplode_force, DEATH_TOUCHEXPLODE, world);
-       remove(e);
- }
  /*
  =============
  PutClientInServer
  Called when a client spawns in the server
  =============
  */
- //void() ctf_playerchanged;
  void PutClientInServer (void)
  {
-       if(clienttype(self) == CLIENTTYPE_BOT)
-       {
+       if(IS_BOT_CLIENT(self))
                self.classname = "player";
-       }
-       else if(clienttype(self) == CLIENTTYPE_REAL)
+       else if(IS_REAL_CLIENT(self))
        {
                msg_entity = self;
                WriteByte(MSG_ONE, SVC_SETVIEW);
                WriteEntity(MSG_ONE, self);
        }
  
-       // player is dead and becomes observer
-       // FIXME fix LMS scoring for new system
-       if(g_lms)
-       {
-               if(PlayerScore_Add(self, SP_LMS_RANK, 0) > 0)
-                       self.classname = "observer";
-       }
+       // reset player keys
+       self.itemkeys = 0;
  
-       if(g_arena || (g_ca && !allowed_to_spawn))
-       if(!self.spawned)
-               self.classname = "observer";
+       MUTATOR_CALLHOOK(PutClientInServer);
  
        if(gameover)
                self.classname = "observer";
  
-       if(self.classname == "player" && (!g_ca || (g_ca && allowed_to_spawn))) {
+       if(IS_PLAYER(self))
+       {
                entity spot, oldself;
                float j;
  
                spot = SelectSpawnPoint (FALSE);
                if(!spot)
                {
-                       centerprint(self, "Sorry, no spawnpoints available!\nHope your team can fix it...");
+                       Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_JOIN_NOSPAWNS);
                        return; // spawn failed
                }
  
                self.classname = "player";
                self.wasplayer = TRUE;
                self.iscreature = TRUE;
+               self.teleportable = TELEPORT_NORMAL;
+               self.damagedbycontents = TRUE;
                self.movetype = MOVETYPE_WALK;
                self.solid = SOLID_SLIDEBOX;
                self.dphitcontentsmask = DPCONTENTS_BODY | DPCONTENTS_SOLID;
                if(autocvar_g_playerclip_collisions)
                        self.dphitcontentsmask |= DPCONTENTS_PLAYERCLIP;
-               if(clienttype(self) == CLIENTTYPE_BOT && autocvar_g_botclip_collisions)
+               if(IS_BOT_CLIENT(self) && autocvar_g_botclip_collisions)
                        self.dphitcontentsmask |= DPCONTENTS_BOTCLIP;
                self.frags = FRAGS_PLAYER;
-               if(independent_players)
+               if(INDEPENDENT_PLAYERS)
                        MAKE_INDEPENDENT_PLAYER(self);
                self.flags = FL_CLIENT;
+               if(autocvar__notarget)
+                       self.flags |= FL_NOTARGET;
                self.takedamage = DAMAGE_AIM;
-               if(g_minstagib)
-                       self.effects = EF_FULLBRIGHT;
-               else
-                       self.effects = 0;
+               self.effects = 0;
+               self.effects |= EF_TELEPORT_BIT | EF_RESTARTANIM_BIT;
                self.air_finished = time + 12;
                self.dmg = 2;
                if(autocvar_g_balance_nex_charge)
                        self.ammo_fuel = warmup_start_ammo_fuel;
                        self.health = warmup_start_health;
                        self.armorvalue = warmup_start_armorvalue;
-                       self.weapons = warmup_start_weapons;
+                       WEPSET_COPY_EA(self, warmup_start_weapons);
                }
                else
                {
                        self.ammo_fuel = start_ammo_fuel;
                        self.health = start_health;
                        self.armorvalue = start_armorvalue;
-                       self.weapons = start_weapons;
+                       WEPSET_COPY_EA(self, start_weapons);
                }
  
+               if(WEPSET_CONTAINS_ANY_EA(self, WEPBIT_SUPERWEAPONS)) // exception for minstagib, as minstanex is a superweapon
+                       self.superweapons_finished = time + autocvar_g_balance_superweapons_time;
+               else
+                       self.superweapons_finished = 0;
                if(g_weaponarena_random)
                {
                        if(g_weaponarena_random_with_laser)
-                               self.weapons &~= WEPBIT_LASER;
-                       self.weapons = randombits(self.weapons, g_weaponarena_random, FALSE);
+                               WEPSET_ANDNOT_EW(self, WEP_LASER);
+                       W_RandomWeapons(self, g_weaponarena_random);
                        if(g_weaponarena_random_with_laser)
-                               self.weapons |= WEPBIT_LASER;
+                               WEPSET_OR_EW(self, WEP_LASER);
                }
  
                self.items = start_items;
-               self.jump_interval = time;
  
                self.spawnshieldtime = time + autocvar_g_spawnshieldtime;
                self.pauserotarmor_finished = time + autocvar_g_balance_pause_armor_rot_spawn;
                }
                self.damageforcescale = 2;
                self.death_time = 0;
-               self.dead_frame = 0;
-               self.alpha = 0;
+               self.respawn_flags = 0;
+               self.respawn_time = 0;
+               self.stat_respawn_time = 0;
                self.scale = 0;
                self.fade_time = 0;
                self.pain_frame = 0;
                self.invincible_finished = 0;
                self.pushltime = 0;
                // players have no think function
-               self.think = SUB_Null;
+               self.think = func_null;
                self.nextthink = 0;
                self.hook_time = 0;
                self.dmg_team = 0;
  
                self.metertime = 0;
  
-               self.runes = 0;
                self.deadflag = DEAD_NO;
  
                self.angles = spot.angles;
                self.oldvelocity = self.velocity;
                self.fire_endtime = -1;
  
-               msg_entity = self;
-               WRITESPECTATABLE_MSG_ONE({
-                       WriteByte(MSG_ONE, SVC_TEMPENTITY);
-                       WriteByte(MSG_ONE, TE_CSQC_SPAWN);
-               });
-               if(sv_loddistance1)
-                       SetCustomizer(self, Client_customizeentityforclient, Client_uncustomizeentityforclient);
+               entity spawnevent = spawn();
+               spawnevent.owner = self;
+               Net_LinkEntity(spawnevent, FALSE, 0.5, SpawnEvent_Send);
  
                self.model = "";
                FixPlayermodel();
+               self.drawonlytoclient = world;
  
                self.crouch = FALSE;
                self.view_ofs = PL_VIEW_OFS;
                self.oldorigin = self.origin;
                self.prevorigin = self.origin;
                self.lastrocket = world; // stop rocket guiding, no revenge from the grave!
-               if(g_arena)
-               {
-                       Spawnqueue_Remove(self);
-                       Spawnqueue_Mark(self);
-               }
-               else if(g_ca)
-                       self.caplayer = 1;
+               self.lastteleporttime = time; // prevent insane speeds due to changing origin
+         self.hud = HUD_NORMAL;
  
                self.event_damage = PlayerDamage;
  
                        self.killcount = 0;
                }
  
-               self.cnt = WEP_LASER;
                CL_SpawnWeaponentity();
                self.alpha = default_player_alpha;
                self.colormod = '1 1 1' * autocvar_g_player_brightness;
                self.exteriorweaponentity.alpha = default_weapon_alpha;
  
-               self.lms_nextcheck = time + autocvar_g_lms_campcheck_interval*2;
-               self.lms_traveled_distance = 0;
                self.speedrunning = FALSE;
  
                race_PostSpawn(spot);
  
-               if(autocvar_spawn_debug)
-               {
-                       sprint(self, strcat("spawnpoint origin:  ", vtos(spot.origin), "\n"));
-                       remove(spot);   // usefull for checking if there are spawnpoints, that let drop through the floor
-               }
                //stuffcmd(self, "chase_active 0");
                //stuffcmd(self, "set viewsize $tmpviewsize \n");
-               if (autocvar_g_spawnsound)
-                       sound (self, CHAN_TRIGGER, "misc/spawn.wav", VOL_BASE, ATTN_NORM);
-               if(g_assault) {
-                       if(self.team == assault_attacker_team)
-                               centerprint(self, "You are attacking!");
-                       else
-                               centerprint(self, "You are defending!");
-               }
+               
                target_voicescript_clear(self);
  
                // reset fields the weapons may use
                for (j = WEP_FIRST; j <= WEP_LAST; ++j)
+               {
                        weapon_action(j, WR_RESETPLAYER);
  
+                       // all weapons must be fully loaded when we spawn
+                       entity e;
+                       e = get_weaponinfo(j);
+                       if(e.spawnflags & WEP_FLAG_RELOADABLE) // prevent accessing undefined cvars
+                               self.(weapon_load[j]) = cvar(strcat("g_balance_", e.netname, "_reload_ammo"));
+               }
                oldself = self;
                self = spot;
                        activator = oldself;
+                               string s;
+                               s = self.target;
+                               self.target = string_null;
                                SUB_UseTargets();
+                               self.target = s;
                        activator = world;
                self = oldself;
  
+               spawn_spot = spot;
                MUTATOR_CALLHOOK(PlayerSpawn);
  
+               if(autocvar_spawn_debug)
+               {
+                       sprint(self, strcat("spawnpoint origin:  ", vtos(spot.origin), "\n"));
+                       remove(spot);   // usefull for checking if there are spawnpoints, that let drop through the floor
+               }
                self.switchweapon = w_getbestweapon(self);
-               self.cnt = self.switchweapon;
+               self.cnt = -1; // W_LastWeapon will not complain
                self.weapon = 0;
+               self.weaponname = "";
+               self.switchingweapon = 0;
  
-         self.wish_reload = 0;
+               if(!inWarmupStage)
+                       if(!self.alivetime)
+                               self.alivetime = time;
  
-               if(!self.alivetime)
-                       self.alivetime = time;
-       } else if(self.classname == "observer" || (g_ca && !allowed_to_spawn)) {
+               antilag_clear(self);
+       }
+       else if(IS_OBSERVER(self))
+       {
                PutObserverInServer ();
        }
-       //if(g_ctf)
-       //      ctf_playerchanged();
  }
  
  .float ebouncefactor, ebouncestop; // electro's values
@@@ -1092,10 -620,6 +620,10 @@@ float ClientInit_SendEntity(entity to, 
        WriteInt24_t(MSG_ENTITY, compressShotOrigin(electro_shotorigin[1]));
        WriteInt24_t(MSG_ENTITY, compressShotOrigin(electro_shotorigin[2]));
        WriteInt24_t(MSG_ENTITY, compressShotOrigin(electro_shotorigin[3]));
 +      WriteInt24_t(MSG_ENTITY, compressShotOrigin(lightning_shotorigin[0]));
 +      WriteInt24_t(MSG_ENTITY, compressShotOrigin(lightning_shotorigin[1]));
 +      WriteInt24_t(MSG_ENTITY, compressShotOrigin(lightning_shotorigin[2]));
 +      WriteInt24_t(MSG_ENTITY, compressShotOrigin(lightning_shotorigin[3]));
        WriteInt24_t(MSG_ENTITY, compressShotOrigin(gauntlet_shotorigin[0]));
        WriteInt24_t(MSG_ENTITY, compressShotOrigin(gauntlet_shotorigin[1]));
        WriteInt24_t(MSG_ENTITY, compressShotOrigin(gauntlet_shotorigin[2]));
        else
                WriteString(MSG_ENTITY, "");
        WriteByte(MSG_ENTITY, self.count * 255.0); // g_balance_armor_blockpercent
-       WriteByte(MSG_ENTITY, self.cnt * 255.0); // g_balance_weaponswitchdelay
        WriteCoord(MSG_ENTITY, self.bouncefactor); // g_balance_grenadelauncher_bouncefactor
        WriteCoord(MSG_ENTITY, self.bouncestop); // g_balance_grenadelauncher_bouncestop
        WriteCoord(MSG_ENTITY, self.ebouncefactor); // g_balance_grenadelauncher_bouncefactor
        WriteCoord(MSG_ENTITY, self.ebouncestop); // g_balance_grenadelauncher_bouncestop
        WriteByte(MSG_ENTITY, autocvar_g_balance_nex_secondary); // client has to know if it should zoom or not
-       WriteByte(MSG_ENTITY, autocvar_g_balance_sniperrifle_secondary); // client has to know if it should zoom or not
+       WriteByte(MSG_ENTITY, autocvar_g_balance_rifle_secondary); // client has to know if it should zoom or not
        WriteByte(MSG_ENTITY, serverflags); // client has to know if it should zoom or not
-       WriteByte(MSG_ENTITY, autocvar_g_balance_sniperrifle_magazinecapacity); // rifle max bullets
        WriteByte(MSG_ENTITY, autocvar_g_balance_minelayer_limit); // minelayer max mines
+       WriteByte(MSG_ENTITY, autocvar_g_balance_hagar_secondary_load_max); // hagar max loadable rockets
        WriteCoord(MSG_ENTITY, autocvar_g_trueaim_minrange);
+       WriteByte(MSG_ENTITY, autocvar_g_balance_porto_secondary);
        return TRUE;
  }
  
@@@ -1127,11 -651,6 +655,6 @@@ void ClientInit_CheckUpdate(
                self.count = autocvar_g_balance_armor_blockpercent;
                self.SendFlags |= 1;
        }
-       if(self.cnt != autocvar_g_balance_weaponswitchdelay)
-       {
-               self.cnt = autocvar_g_balance_weaponswitchdelay;
-               self.SendFlags |= 1;
-       }
        if(self.bouncefactor != autocvar_g_balance_grenadelauncher_bouncefactor)
        {
                self.bouncefactor = autocvar_g_balance_grenadelauncher_bouncefactor;
@@@ -1220,24 -739,34 +743,34 @@@ void ClientKill_Now_TeamChange(
  {
        if(self.killindicator_teamchange == -1)
        {
-               self.team = -1;
-               JoinBestTeam( self, FALSE, FALSE );
+               JoinBestTeam( self, FALSE, TRUE );
        }
        else if(self.killindicator_teamchange == -2)
        {
-               if(g_ca)
-                       self.caplayer = 0;
                if(blockSpectators)
-                       sprint(self, strcat("^7You have to become a player within the next ", ftos(autocvar_g_maxplayers_spectator_blocktime), " seconds, otherwise you will be kicked, because spectators aren't allowed at this time!\n"));
+                       Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_SPECTATE_WARNING, autocvar_g_maxplayers_spectator_blocktime);
                PutObserverInServer();
        }
        else
                SV_ChangeTeam(self.killindicator_teamchange - 1);
+       self.killindicator_teamchange = 0;
  }
  
  void ClientKill_Now()
  {
-       remove(self.killindicator);
+       if(self.vehicle)
+       {
+           vehicles_exit(VHEF_RELESE);
+           if(!self.killindicator_teamchange)
+           {
+             self.vehicle_health = -1;
+             Damage(self, self, self, 1 , DEATH_KILL, self.origin, '0 0 0');           
+           }
+       }
+       if(self.killindicator && !wasfreed(self.killindicator))
+               remove(self.killindicator);
        self.killindicator = world;
  
        if(self.killindicator_teamchange)
  }
  void KillIndicator_Think()
  {
-       if (!self.owner.modelindex)
+       if (gameover)
+       {
+               self.owner.killindicator = world;
+               remove(self);
+               return;
+       }
+       if (self.owner.alpha < 0 && !self.owner.vehicle)
        {
                self.owner.killindicator = world;
                remove(self);
        {
                if(self.cnt <= 10)
                        setmodel(self, strcat("models/sprites/", ftos(self.cnt), ".spr32"));
-               if(clienttype(self.owner) == CLIENTTYPE_REAL)
+               if(IS_REAL_CLIENT(self.owner))
                {
                        if(self.cnt <= 10)
-                               AnnounceTo(self.owner, strcat(ftos(self.cnt), ""));
-                       if(self.owner.killindicator_teamchange)
-                       {
-                               if(self.owner.killindicator_teamchange == -1)
-                                       centerprint(self.owner, strcat("Changing team in ", ftos(self.cnt), " seconds"));
-                               else if(self.owner.killindicator_teamchange == -2)
-                                       centerprint(self.owner, strcat("Spectating in ", ftos(self.cnt), " seconds"));
-                               else
-                                       centerprint(self.owner, strcat("Changing to ", ColoredTeamName(self.owner.killindicator_teamchange), " in ", ftos(self.cnt), " seconds"));
-                       }
-                       else
-                               centerprint(self.owner, strcat("^1Suicide in ", ftos(self.cnt), " seconds"));
+                               { Send_Notification(NOTIF_ONE, self.owner, MSG_ANNCE, Announcer_PickNumber(self.cnt)); }
                }
                self.nextthink = time + 1;
                self.cnt -= 1;
        }
  }
  
+ float clientkilltime;
  void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto, -2 = spec
  {
        float killtime;
+       float starttime;
        entity e;
+       if (gameover)
+               return;
        killtime = autocvar_g_balance_kill_delay;
  
        if(g_race_qualifying || g_cts)
  
      if(!self.killindicator)
        {
-               if(self.modelindex && self.deadflag == DEAD_NO)
+               if(self.deadflag == DEAD_NO)
                {
                        killtime = max(killtime, self.clientkill_nexttime - time);
                        self.clientkill_nexttime = time + killtime + autocvar_g_balance_kill_antispam;
                }
  
-               if(killtime <= 0 || !self.modelindex || self.deadflag != DEAD_NO)
+               if(killtime <= 0 || !IS_PLAYER(self) || self.deadflag != DEAD_NO)
                {
                        ClientKill_Now();
                }
                else
                {
+                       starttime = max(time, clientkilltime);
                        self.killindicator = spawn();
                        self.killindicator.owner = self;
                        self.killindicator.scale = 0.5;
                        setattachment(self.killindicator, self, "");
                        setorigin(self.killindicator, '0 0 52');
                        self.killindicator.think = KillIndicator_Think;
-                       self.killindicator.nextthink = time + (self.lip) * 0.05;
+                       self.killindicator.nextthink = starttime + (self.lip) * 0.05;
+                       clientkilltime = max(clientkilltime, self.killindicator.nextthink + 0.05);
                        self.killindicator.cnt = ceil(killtime);
                        self.killindicator.count = bound(0, ceil(killtime), 10);
                        //sprint(self, strcat("^1You'll be dead in ", ftos(self.killindicator.cnt), " seconds\n"));
                                setattachment(e.killindicator, e, "");
                                setorigin(e.killindicator, '0 0 52');
                                e.killindicator.think = KillIndicator_Think;
-                               e.killindicator.nextthink = time + (e.lip) * 0.05;
+                               e.killindicator.nextthink = starttime + (e.lip) * 0.05;
+                               clientkilltime = max(clientkilltime, e.killindicator.nextthink + 0.05);
                                e.killindicator.cnt = ceil(killtime);
                        }
                        self.lip = 0;
        if(self.killindicator)
        {
                if(targetteam == 0) // just die
+               {
                        self.killindicator.colormod = '0 0 0';
+                       if(IS_REAL_CLIENT(self))
+                       if(self.killindicator.cnt > 0)
+                               Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_TEAMCHANGE_SUICIDE, self.killindicator.cnt);
+               }
                else if(targetteam == -1) // auto
+               {
                        self.killindicator.colormod = '0 1 0';
+                       if(IS_REAL_CLIENT(self))
+                       if(self.killindicator.cnt > 0)
+                               Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_TEAMCHANGE_AUTO, self.killindicator.cnt);
+               }
                else if(targetteam == -2) // spectate
+               {
                        self.killindicator.colormod = '0.5 0.5 0.5';
+                       if(IS_REAL_CLIENT(self))
+                       if(self.killindicator.cnt > 0)
+                               Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_TEAMCHANGE_SPECTATE, self.killindicator.cnt);
+               }
                else
-                       self.killindicator.colormod = TeamColor(targetteam);
+               {
+                       self.killindicator.colormod = Team_ColorRGB(targetteam);
+                       if(IS_REAL_CLIENT(self))
+                       if(self.killindicator.cnt > 0)
+                               Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, APP_TEAM_NUM_4(targetteam, CENTER_TEAMCHANGE_), self.killindicator.cnt);
+               }
        }
  }
  
  void ClientKill (void)
  {
-       if((g_arena || g_ca) && ((champion && champion.classname == "player" && player_count > 1) || player_count == 1)) // don't allow a kill in this case either
-       {
-               // do nothing
-       }
-     else if(self.freezetag_frozen)
-     {
-         // do nothing
-     }
-       else
-               ClientKill_TeamChange(0);
+       if(gameover) return;
+       if(self.player_blocked) return;
+       if(self.freezetag_frozen) return;
+       
+       ClientKill_TeamChange(0);
  }
  
  void CTS_ClientKill (entity e) // silent version of ClientKill, used when player finishes a CTS run. Useful to prevent cheating by running back to the start line and starting out with more speed
      e.lip = 0;
  }
  
- void DoTeamChange(float destteam)
- {
-       float t, c0;
-       if(!teams_matter)
-       {
-               if(destteam >= 0)
-                       SetPlayerColors(self, destteam);
-               return;
-       }
-       if(self.classname == "player")
-       if(destteam == -1)
-       {
-               CheckAllowedTeams(self);
-               t = FindSmallestTeam(self, TRUE);
-               switch(self.team)
-               {
-                       case COLOR_TEAM1: c0 = c1; break;
-                       case COLOR_TEAM2: c0 = c2; break;
-                       case COLOR_TEAM3: c0 = c3; break;
-                       case COLOR_TEAM4: c0 = c4; break;
-                       default:          c0 = 999;
-               }
-               switch(t)
-               {
-                       case 1:
-                               if(c0 > c1)
-                                       destteam = COLOR_TEAM1;
-                               break;
-                       case 2:
-                               if(c0 > c2)
-                                       destteam = COLOR_TEAM2;
-                               break;
-                       case 3:
-                               if(c0 > c3)
-                                       destteam = COLOR_TEAM3;
-                               break;
-                       case 4:
-                               if(c0 > c4)
-                                       destteam = COLOR_TEAM4;
-                               break;
-               }
-               if(destteam == -1)
-                       return;
-       }
-       if(destteam == self.team && destteam >= 0 && !self.killindicator)
-               return;
-       ClientKill_TeamChange(destteam);
- }
  void FixClientCvars(entity e)
  {
        // send prediction settings to the client
                stuffcmd(e, "cl_cmd settemp cl_movecliptokeyboard 2\n");
        if(autocvar_g_antilag == 3) // client side hitscan
                stuffcmd(e, "cl_cmd settemp cl_prydoncursor_notrace 0\n");
-       if(sv_gentle)
+       if(autocvar_sv_gentle)
                stuffcmd(e, "cl_cmd settemp cl_gentle 1\n");
        /*
         * we no longer need to stuff this. Remove this comment block if you feel
@@@ -1498,27 -1000,26 +1004,26 @@@ ClientConnec
  Called when a client connects to the server
  =============
  */
- //void ctf_clientconnect();
- string ColoredTeamName(float t);
  void DecodeLevelParms (void);
  //void dom_player_join_team(entity pl);
+ void set_dom_state(entity e);
  void ClientConnect (void)
  {
        float t;
  
-       if(self.flags & FL_CLIENT)
+       if(IS_CLIENT(self))
        {
                print("Warning: ClientConnect, but already connected!\n");
                return;
        }
  
-       if(Ban_MaybeEnforceBan(self))
+       if(Ban_MaybeEnforceBanOnce(self))
                return;
  
        DecodeLevelParms();
  
  #ifdef WATERMARK
-       sprint(self, strcat("^4SVQC Build information: ", WATERMARK(), "\n"));
+       Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_WATERMARK, WATERMARK);
  #endif
  
        self.classname = "player_joining";
        playerdemo_init();
  
        anticheat_init();
-       
-       race_PreSpawnObserver();
  
-       //if(g_domination)
-       //      dom_player_join_team(self);
+       race_PreSpawnObserver();
  
        // identify the right forced team
        if(autocvar_g_campaign)
        {
-               if(clienttype(self) == CLIENTTYPE_REAL) // only players, not bots
+               if(IS_REAL_CLIENT(self)) // only players, not bots
                {
                        switch(autocvar_g_campaign_forceteam)
                        {
-                               case 1: self.team_forced = COLOR_TEAM1; break;
-                               case 2: self.team_forced = COLOR_TEAM2; break;
-                               case 3: self.team_forced = COLOR_TEAM3; break;
-                               case 4: self.team_forced = COLOR_TEAM4; break;
+                               case 1: self.team_forced = NUM_TEAM_1; break;
+                               case 2: self.team_forced = NUM_TEAM_2; break;
+                               case 3: self.team_forced = NUM_TEAM_3; break;
+                               case 4: self.team_forced = NUM_TEAM_4; break;
                                default: self.team_forced = 0;
                        }
                }
        }
        else if(PlayerInIDList(self, autocvar_g_forced_team_red))
-               self.team_forced = COLOR_TEAM1;
+               self.team_forced = NUM_TEAM_1;
        else if(PlayerInIDList(self, autocvar_g_forced_team_blue))
-               self.team_forced = COLOR_TEAM2;
+               self.team_forced = NUM_TEAM_2;
        else if(PlayerInIDList(self, autocvar_g_forced_team_yellow))
-               self.team_forced = COLOR_TEAM3;
+               self.team_forced = NUM_TEAM_3;
        else if(PlayerInIDList(self, autocvar_g_forced_team_pink))
-               self.team_forced = COLOR_TEAM4;
+               self.team_forced = NUM_TEAM_4;
        else if(autocvar_g_forced_team_otherwise == "red")
-               self.team_forced = COLOR_TEAM1;
+               self.team_forced = NUM_TEAM_1;
        else if(autocvar_g_forced_team_otherwise == "blue")
-               self.team_forced = COLOR_TEAM2;
+               self.team_forced = NUM_TEAM_2;
        else if(autocvar_g_forced_team_otherwise == "yellow")
-               self.team_forced = COLOR_TEAM3;
+               self.team_forced = NUM_TEAM_3;
        else if(autocvar_g_forced_team_otherwise == "pink")
-               self.team_forced = COLOR_TEAM4;
+               self.team_forced = NUM_TEAM_4;
        else if(autocvar_g_forced_team_otherwise == "spectate")
                self.team_forced = -1;
        else if(autocvar_g_forced_team_otherwise == "spectator")
        else
                self.team_forced = 0;
  
-       if(!teams_matter)
+       if(!teamplay)
                if(self.team_forced > 0)
                        self.team_forced = 0;
  
        JoinBestTeam(self, FALSE, FALSE); // if the team number is valid, keep it
  
-       if((autocvar_sv_spectate == 1 && !g_lms) || autocvar_g_campaign || self.team_forced < 0) {
+       if((autocvar_sv_spectate == 1) || autocvar_g_campaign || self.team_forced < 0) {
                self.classname = "observer";
        } else {
-               if(teams_matter)
+               if(teamplay)
                {
-                       if(autocvar_g_balance_teams || autocvar_g_balance_teams_force)
+                       if(autocvar_g_balance_teams)
                        {
                                self.classname = "player";
                                campaign_bots_may_start = 1;
  
        self.playerid = (playerid_last = playerid_last + 1);
  
+       PlayerStats_AddEvent(sprintf("kills-%d", self.playerid));
+     if(IS_BOT_CLIENT(self))
+         PlayerStats_AddPlayer(self);
        if(autocvar_sv_eventlog)
-               GameLogEcho(strcat(":join:", ftos(self.playerid), ":", ftos(num_for_edict(self)), ":", ((clienttype(self) == CLIENTTYPE_REAL) ? self.netaddress : "bot"), ":", self.netname));
+               GameLogEcho(strcat(":join:", ftos(self.playerid), ":", ftos(num_for_edict(self)), ":", ((IS_REAL_CLIENT(self)) ? self.netaddress : "bot"), ":", self.netname));
  
        LogTeamchange(self.playerid, self.team, 1);
  
  
        self.netname_previous = strzone(self.netname);
  
-       bprint("^4", self.netname, "^4 connected");
-       if(self.classname != "observer" && (g_domination || g_ctf))
-               bprint(" and joined the ", ColoredTeamName(self.team));
-       bprint("\n");
-       self.welcomemessage_time = 0;
+       if(IS_PLAYER(self) && teamplay)
+               Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(self, INFO_JOIN_CONNECT_TEAM_), self.netname);
+       else
+               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_JOIN_CONNECT, self.netname);
  
        stuffcmd(self, strcat(clientstuff, "\n"));
-       stuffcmd(self, strcat("exec maps/", mapname, ".cfg\n"));
-       stuffcmd(self, "cl_particles_reloadeffects\n");
+       stuffcmd(self, "cl_particles_reloadeffects\n"); // TODO do we still need this?
  
        FixClientCvars(self);
  
        // Wazat's grappling hook
        SetGrappleHookBindings();
  
-       // get autoswitch state from player when he toggles it
-       stuffcmd(self, "alias autoswitch \"set cl_autoswitch $1 ; cmd autoswitch $1\"\n"); // default.cfg-ed in 2.4.1
        // get version info from player
        stuffcmd(self, "cmd clientversion $gameversion\n");
  
        GetCvars(0);
  
        // notify about available teams
-       if(teams_matter)
+       if(teamplay)
        {
                CheckAllowedTeams(self);
                t = 0; if(c1 >= 0) t |= 1; if(c2 >= 0) t |= 2; if(c3 >= 0) t |= 4; if(c4 >= 0) t |= 8;
        else
                stuffcmd(self, "set _teams_available 0\n");
  
-       stuffcmd(self, strcat("set gametype ", ftos(game), "\n"));
-       if(g_arena || g_ca)
-       {
-               self.classname = "observer";
-               if(g_arena)
-                       Spawnqueue_Insert(self);
-       }
-       /*else if(g_ctf)
-       {
-               ctf_clientconnect();
-       }*/
-       if(teams_matter || radar_showennemies)
-               attach_entcs();
+       attach_entcs();
  
        bot_relinkplayerlist();
  
        self.spectatortime = time;
        if(blockSpectators)
        {
-               sprint(self, strcat("^7You have to become a player within the next ", ftos(autocvar_g_maxplayers_spectator_blocktime), " seconds, otherwise you will be kicked, because spectators aren't allowed at this time!\n"));
+               Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_SPECTATE_WARNING, autocvar_g_maxplayers_spectator_blocktime);
        }
  
        self.jointime = time;
-       self.allowedTimeouts = autocvar_sv_timeout_number;
-       if(clienttype(self) == CLIENTTYPE_REAL)
-       {
-               if(autocvar_g_bugrigs || g_weaponarena == WEPBIT_TUBA)
-                       stuffcmd(self, "cl_cmd settemp chase_active 1\n");
-       }
+       self.allowed_timeouts = autocvar_sv_timeout_number;
  
-       if(g_lms)
+       if(IS_REAL_CLIENT(self))
        {
-               if(PlayerScore_Add(self, SP_LMS_LIVES, LMS_NewPlayerLives()) <= 0)
+               if(!autocvar_g_campaign)
                {
-                       PlayerScore_Add(self, SP_LMS_RANK, 666);
-                       self.frags = FRAGS_SPECTATOR;
+                       self.motd_actived_time = -1;
+                       Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MOTD, getwelcomemessage());
                }
+               if(autocvar_g_bugrigs || WEPSET_EQ_AW(g_weaponarena_weapons, WEP_TUBA))
+                       stuffcmd(self, "cl_cmd settemp chase_active 1\n");
        }
  
        if(!sv_foginterval && world.fog != "")
                stuffcmd(self, strcat("\nfog ", world.fog, "\nr_fog_exp2 0\nr_drawfog 1\n"));
  
-       SoundEntity_Attach(self);
        if(autocvar_g_hitplots || strstrofs(strcat(" ", autocvar_g_hitplots_individuals, " "), strcat(" ", self.netaddress, " "), 0) >= 0)
        {
                self.hitplotfh = fopen(strcat("hits-", matchid, "-", self.netaddress, "-", ftos(self.playerid), ".plot"), FILE_WRITE);
                        rr = CTS_RECORD;
                else
                        rr = RACE_RECORD;
-               t = stof(db_get(ServerProgsDB, strcat(GetMapname(), rr, "time")));
  
                msg_entity = self;
                race_send_recordtime(MSG_ONE);
  
        CheatInitClient();
  
-       PlayerStats_AddPlayer(self);
- }
+       CSQCMODEL_AUTOINIT();
+       self.model_randomizer = random();
+       if(IS_REAL_CLIENT(self))
+               sv_notice_join();
  
+       MUTATOR_CALLHOOK(ClientConnect);
+ }
  /*
  =============
  ClientDisconnect
@@@ -1756,11 -1237,13 +1241,13 @@@ Called when a client disconnects from t
  =============
  */
  .entity chatbubbleentity;
- .entity teambubbleentity;
  void ReadyCount();
  void ClientDisconnect (void)
  {
-       if not(self.flags & FL_CLIENT)
+       if(self.vehicle)
+           vehicles_exit(VHEF_RELESE);
+       if not(IS_CLIENT(self))
        {
                print("Warning: ClientDisconnect without ClientConnect\n");
                return;
  
        if(autocvar_sv_eventlog)
                GameLogEcho(strcat(":part:", ftos(self.playerid)));
-       bprint ("^4",self.netname);
-       bprint ("^4 disconnected\n");
-       SoundEntity_Detach(self);
+               
+       Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_QUIT_DISCONNECT, self.netname);
  
-       DropAllRunes(self);
        MUTATOR_CALLHOOK(ClientDisconnect);
  
        Portal_ClearAll(self);
  
-       if(self.flagcarried)
-               DropFlag(self.flagcarried, world, world);
-       if(self.ballcarried && g_nexball)
-               DropBall(self.ballcarried, self.origin + self.ballcarried.origin, self.velocity);
+       RemoveGrapplingHook(self);
  
        // Here, everything has been done that requires this player to be a client.
  
        if (self.chatbubbleentity)
                remove (self.chatbubbleentity);
  
-       if (self.teambubbleentity)
-               remove (self.teambubbleentity);
        if (self.killindicator)
                remove (self.killindicator);
  
  
        bot_relinkplayerlist();
  
-       if(g_arena)
-       {
-               Spawnqueue_Unmark(self);
-               Spawnqueue_Remove(self);
-       }
        accuracy_free(self);
        ClientData_Detach();
        PlayerScore_Detach(self);
  void ChatBubbleThink()
  {
        self.nextthink = time;
-       if (!self.owner.modelindex || self.owner.chatbubbleentity != self)
+       if ((self.owner.alpha < 0) || self.owner.chatbubbleentity != self)
        {
                if(self.owner) // but why can that ever be world?
                        self.owner.chatbubbleentity = world;
                self.model = self.mdl;
        else
                self.model = "";
- };
+ }
  
  void UpdateChatBubble()
  {
-       if (!self.modelindex)
+       if (self.alpha < 0)
                return;
        // spawn a chatbubble entity if needed
        if (!self.chatbubbleentity)
  }
  
  
- void TeamBubbleThink()
- {
-       self.nextthink = time;
-       if (!self.owner.modelindex || self.owner.teambubbleentity != self)
-       {
-               if(self.owner) // but why can that ever be world?
-                       self.owner.teambubbleentity = world;
-               remove(self);
-               return;
-       }
- //    setorigin(self, self.owner.origin + '0 0 15' + self.owner.maxs_z * '0 0 1');  // bandwidth hog. setattachment does this now
-       if (self.owner.BUTTON_CHAT || self.owner.deadflag || self.owner.killindicator)
-               self.model = "";
-       else
-               self.model = self.mdl;
- };
- float TeamBubble_customizeentityforclient()
- {
-       return (self.owner != other && self.owner.team == other.team && other.killcount > -666);
- }
- void UpdateTeamBubble()
- {
-       if (!self.modelindex || !teams_matter)
-               return;
-       // spawn a teambubble entity if needed
-       if (!self.teambubbleentity && teams_matter)
-       {
-               self.teambubbleentity = spawn();
-               self.teambubbleentity.owner = self;
-               self.teambubbleentity.exteriormodeltoclient = self;
-               self.teambubbleentity.think = TeamBubbleThink;
-               self.teambubbleentity.nextthink = time;
-               setmodel(self.teambubbleentity, "models/misc/teambubble.spr"); // precision set below
- //            setorigin(self.teambubbleentity, self.origin + '0 0 15' + self.maxs_z * '0 0 1');
-               setorigin(self.teambubbleentity, '0 0 15' + self.maxs_z * '0 0 1');
-               setattachment(self.teambubbleentity, self, "");  // sticks to moving player better, also conserves bandwidth
-               self.teambubbleentity.mdl = self.teambubbleentity.model;
-               self.teambubbleentity.model = self.teambubbleentity.mdl;
-               self.teambubbleentity.customizeentityforclient = TeamBubble_customizeentityforclient;
-               self.teambubbleentity.effects = EF_LOWPRECISION;
-       }
- }
  // LordHavoc: this hack will be removed when proper _pants/_shirt layers are
  // added to the model skins
  /*void UpdateColorModHack()
  {
-       local float c;
+       float c;
        c = self.clientcolors & 15;
        // LordHavoc: only bothering to support white, green, red, yellow, blue
-            if (!teams_matter) self.colormod = '0 0 0';
+            if (!teamplay) self.colormod = '0 0 0';
        else if (c ==  0) self.colormod = '1.00 1.00 1.00';
        else if (c ==  3) self.colormod = '0.10 1.73 0.10';
        else if (c ==  4) self.colormod = '1.73 0.10 0.10';
        else if (c == 12) self.colormod = '1.22 1.22 0.10';
        else if (c == 13) self.colormod = '0.10 0.10 1.73';
        else self.colormod = '1 1 1';
- };*/
+ }*/
  
- .float oldcolormap;
  void respawn(void)
  {
-       if(self.modelindex != 0 && autocvar_g_respawn_ghosts)
+       if(self.alpha >= 0 && autocvar_g_respawn_ghosts)
        {
                self.solid = SOLID_NOT;
                self.takedamage = DAMAGE_NO;
                self.movetype = MOVETYPE_FLY;
                self.velocity = '0 0 1' * autocvar_g_respawn_ghosts_speed;
                self.avelocity = randomvec() * autocvar_g_respawn_ghosts_speed * 3 - randomvec() * autocvar_g_respawn_ghosts_speed * 3;
-               self.effects |= EF_ADDITIVE;
-               self.oldcolormap = self.colormap;
-               self.colormap = 512;
+               self.effects |= CSQCMODEL_EF_RESPAWNGHOST;
                pointparticles(particleeffectnum("respawn_ghost"), self.origin, '0 0 0', 1);
                if(autocvar_g_respawn_ghosts_maxtime)
                        SUB_SetFade (self, time + autocvar_g_respawn_ghosts_maxtime / 2 + random () * (autocvar_g_respawn_ghosts_maxtime - autocvar_g_respawn_ghosts_maxtime / 2), 1.5);
        }
  
        CopyBody(1);
        self.effects |= EF_NODRAW; // prevent another CopyBody
-       if(self.oldcolormap)
-       {
-               self.colormap = self.oldcolormap;
-               self.oldcolormap = 0;
-       }
        PutClientInServer();
  }
  
  void play_countdown(float finished, string samp)
  {
-       if(clienttype(self) == CLIENTTYPE_REAL)
+       if(IS_REAL_CLIENT(self))
                if(floor(finished - time - frametime) != floor(finished - time))
-                       if(finished - time < 6)
-                               sound (self, CHAN_AUTO, samp, VOL_BASE, ATTN_NORM);
- }
- /**
-  * When sv_timeout is used this function returs strings like
-  * "Timeout begins in 2 seconds!\n" or "Timeout ends in 23 seconds!\n".
-  * Called by centerprint functions
-  * @param addOneSecond boolean, set to 1 if the welcome-message centerprint asks for the text
-  */
- string getTimeoutText(float addOneSecond) {
-       if (!autocvar_sv_timeout || !timeoutStatus)
-               return "";
-       local string retStr;
-       if (timeoutStatus == 1) {
-               if (addOneSecond == 1) {
-                       retStr = strcat("Timeout begins in ", ftos(remainingLeadTime + 1), " seconds!\n");
-               }
-               else {
-                       retStr = strcat("Timeout begins in ", ftos(remainingLeadTime), " seconds!\n");
-               }
-               return retStr;
-       }
-       else if (timeoutStatus == 2) {
-               if (addOneSecond) {
-                       retStr = strcat("Timeout ends in ", ftos(remainingTimeoutTime + 1), " seconds!\n");
-                       //don't show messages like "Timeout ends in 0 seconds"...
-                       if ((remainingTimeoutTime + 1) > 0)
-                               return retStr;
-                       else
-                               return "";
-               }
-               else {
-                       retStr = strcat("Timeout ends in ", ftos(remainingTimeoutTime), " seconds!\n");
-                       //don't show messages like "Timeout ends in 0 seconds"...
-                       if (remainingTimeoutTime > 0)
-                               return retStr;
-                       else
-                               return "";
-               }
-       }
-       else return "";
+                       if(finished - time < 6)
+                               sound (self, CH_INFO, samp, VOL_BASE, ATTN_NORM);
  }
  
  void player_powerups (void)
  {
        // add a way to see what the items were BEFORE all of these checks for the mutator hook
        olditems = self.items;
-       
        if((self.items & IT_USING_JETPACK) && !self.deadflag)
-       {
-               SoundEntity_StartSound(self, CHAN_PLAYER, "misc/jetpack_fly.wav", VOL_BASE, autocvar_g_jetpack_attenuation);
                self.modelflags |= MF_ROCKET;
-       }
        else
-       {
-               SoundEntity_StopSound(self, CHAN_PLAYER);
                self.modelflags &~= MF_ROCKET;
-       }
  
-       self.effects &~= (EF_DIMLIGHT | EF_RED | EF_BLUE | EF_ADDITIVE | EF_FULLBRIGHT | EF_FLAME | EF_NODEPTHTEST);
+       self.effects &~= (EF_RED | EF_BLUE | EF_ADDITIVE | EF_FULLBRIGHT | EF_FLAME | EF_NODEPTHTEST);
  
-       if(!self.modelindex || self.deadflag) // don't apply the flags if the player is gibbed
+       if(self.alpha < 0 || self.deadflag) // don't apply the flags if the player is gibbed
                return;
-       
        Fire_ApplyDamage(self);
        Fire_ApplyEffect(self);
  
-       if (g_minstagib)
+       if not(g_minstagib)
        {
-               self.effects |= EF_FULLBRIGHT;
                if (self.items & IT_STRENGTH)
                {
                        play_countdown(self.strength_finished, "misc/poweroff.wav");
+                       self.effects = self.effects | (EF_BLUE | EF_ADDITIVE | EF_FULLBRIGHT);
                        if (time > self.strength_finished)
                        {
-                               self.alpha = default_player_alpha;
-                               self.exteriorweaponentity.alpha = default_weapon_alpha;
-                               self.items &~= IT_STRENGTH;
-                               sprint(self, "^3Invisibility has worn off\n");
+                               self.items = self.items - (self.items & IT_STRENGTH);
+                               //Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERDOWN_STRENGTH, self.netname);
+                               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_STRENGTH);
                        }
                }
                else
                {
                        if (time < self.strength_finished)
                        {
-                               self.alpha = g_minstagib_invis_alpha;
-                               self.exteriorweaponentity.alpha = g_minstagib_invis_alpha;
-                               self.items |= IT_STRENGTH;
-                               sprint(self, "^3You are invisible\n");
+                               self.items = self.items | IT_STRENGTH;
+                               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_STRENGTH, self.netname);
+                               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_STRENGTH);
                        }
                }
                if (self.items & IT_INVINCIBLE)
                {
                        play_countdown(self.invincible_finished, "misc/poweroff.wav");
-                       if (time > self.invincible_finished && autocvar_g_balance_powerup_timer)
+                       self.effects = self.effects | (EF_RED | EF_ADDITIVE | EF_FULLBRIGHT);
+                       if (time > self.invincible_finished)
                        {
                                self.items = self.items - (self.items & IT_INVINCIBLE);
-                               sprint(self, "^3Speed has worn off\n");
+                               //Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERDOWN_SHIELD, self.netname);
+                               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_SHIELD);
                        }
                }
                else
                        if (time < self.invincible_finished)
                        {
                                self.items = self.items | IT_INVINCIBLE;
-                               sprint(self, "^3You are on speed\n");
+                               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_SHIELD, self.netname);
+                               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_SHIELD);
                        }
                }
-       }
-       else // if we're not in minstagib, continue. I added this else to replace the "return" which was here that broke the callhook for this function -- This code is nasty.
-       {
-               if (self.items & IT_STRENGTH)
+               if (self.items & IT_SUPERWEAPON)
                {
-                       play_countdown(self.strength_finished, "misc/poweroff.wav");
-                       self.effects = self.effects | (EF_BLUE | EF_ADDITIVE | EF_FULLBRIGHT);
-                       if (time > self.strength_finished && autocvar_g_balance_powerup_timer)
+                       if (!WEPSET_CONTAINS_ANY_EA(self, WEPBIT_SUPERWEAPONS))
                        {
-                               self.items = self.items - (self.items & IT_STRENGTH);
-                               sprint(self, "^3Strength has worn off\n");
+                               self.superweapons_finished = 0;
+                               self.items = self.items - (self.items & IT_SUPERWEAPON);
+                               //Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_SUPERWEAPON_LOST, self.netname);
+                               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_SUPERWEAPON_LOST);
                        }
-               }
-               else
-               {
-                       if (time < self.strength_finished)
+                       else if (self.items & IT_UNLIMITED_SUPERWEAPONS)
                        {
-                               self.items = self.items | IT_STRENGTH;
-                               sprint(self, "^3Strength infuses your weapons with devastating power\n");
+                               // don't let them run out
+                       }
+                       else
+                       {
+                               play_countdown(self.superweapons_finished, "misc/poweroff.wav");
+                               if (time > self.superweapons_finished)
+                               {
+                                       self.items = self.items - (self.items & IT_SUPERWEAPON);
+                                       WEPSET_ANDNOT_EA(self, WEPBIT_SUPERWEAPONS);
+                                       //Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_SUPERWEAPON_BROKEN, self.netname);
+                                       Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_SUPERWEAPON_BROKEN);
+                               }
                        }
                }
-               if (self.items & IT_INVINCIBLE)
+               else if(WEPSET_CONTAINS_ANY_EA(self, WEPBIT_SUPERWEAPONS))
                {
-                       play_countdown(self.invincible_finished, "misc/poweroff.wav");
-                       self.effects = self.effects | (EF_RED | EF_ADDITIVE | EF_FULLBRIGHT);
-                       if (time > self.invincible_finished && autocvar_g_balance_powerup_timer)
+                       if (time < self.superweapons_finished || (self.items & IT_UNLIMITED_SUPERWEAPONS))
                        {
-                               self.items = self.items - (self.items & IT_INVINCIBLE);
-                               sprint(self, "^3Shield has worn off\n");
+                               self.items = self.items | IT_SUPERWEAPON;
+                               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_SUPERWEAPON_PICKUP, self.netname);
+                               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_SUPERWEAPON_PICKUP);
+                       }
+                       else
+                       {
+                               self.superweapons_finished = 0;
+                               WEPSET_ANDNOT_EA(self, WEPBIT_SUPERWEAPONS);
                        }
                }
                else
                {
-                       if (time < self.invincible_finished)
-                       {
-                               self.items = self.items | IT_INVINCIBLE;
-                               sprint(self, "^3Shield surrounds you\n");
-                       }
+                       self.superweapons_finished = 0;
                }
+       }
+       
+       if(autocvar_g_nodepthtestplayers)
+               self.effects = self.effects | EF_NODEPTHTEST;
  
-               if(autocvar_g_nodepthtestplayers)
-                       self.effects = self.effects | EF_NODEPTHTEST;
+       if(autocvar_g_fullbrightplayers)
+               self.effects = self.effects | EF_FULLBRIGHT;
  
-               if(autocvar_g_fullbrightplayers)
-                       self.effects = self.effects | EF_FULLBRIGHT;
+       // midair gamemode: damage only while in the air
+       // if in midair mode, being on ground grants temporary invulnerability
+       // (this is so that multishot weapon don't clear the ground flag on the
+       // first damage in the frame, leaving the player vulnerable to the
+       // remaining hits in the same frame)
+       if (self.flags & FL_ONGROUND)
+       if (g_midair)
+               self.spawnshieldtime = max(self.spawnshieldtime, time + autocvar_g_midair_shieldtime);
  
-               // midair gamemode: damage only while in the air
-               // if in midair mode, being on ground grants temporary invulnerability
-               // (this is so that multishot weapon don't clear the ground flag on the
-               // first damage in the frame, leaving the player vulnerable to the
-               // remaining hits in the same frame)
-               if (self.flags & FL_ONGROUND)
-               if (g_midair)
-                       self.spawnshieldtime = max(self.spawnshieldtime, time + autocvar_g_midair_shieldtime);
+       if (time >= game_starttime)
+       if (time < self.spawnshieldtime)
+               self.effects = self.effects | (EF_ADDITIVE | EF_FULLBRIGHT);
  
-               if (time >= game_starttime)
-               if (time < self.spawnshieldtime)
-                       self.effects = self.effects | (EF_ADDITIVE | EF_FULLBRIGHT);
-       }
-       
        MUTATOR_CALLHOOK(PlayerPowerups);
  }
  
@@@ -2222,32 -1593,6 +1597,6 @@@ void player_regen (void
  
        max_mod = regen_mod = rot_mod = limit_mod = 1;
  
-       if (self.runes & RUNE_REGEN)
-       {
-               if (self.runes & CURSE_VENOM) // do we have both rune/curse?
-               {
-                       regen_mod = autocvar_g_balance_rune_regen_combo_regenrate;
-                       max_mod = autocvar_g_balance_rune_regen_combo_hpmod;
-                       limit_mod = autocvar_g_balance_rune_regen_combo_limitmod;
-               }
-               else
-               {
-                       regen_mod = autocvar_g_balance_rune_regen_regenrate;
-                       max_mod = autocvar_g_balance_rune_regen_hpmod;
-                       limit_mod = autocvar_g_balance_rune_regen_limitmod;
-               }
-       }
-       else if (self.runes & CURSE_VENOM)
-       {
-               max_mod = autocvar_g_balance_curse_venom_hpmod;
-               if (self.runes & RUNE_REGEN) // do we have both rune/curse?
-                       rot_mod = autocvar_g_balance_rune_regen_combo_rotrate;
-               else
-                       rot_mod = autocvar_g_balance_curse_venom_rotrate;
-               limit_mod = autocvar_g_balance_curse_venom_limitmod;
-               //if (!self.runes & RUNE_REGEN)
-               //      rot_mod = autocvar_g_balance_curse_venom_rotrate;
-       }
        maxh = maxh * max_mod;
        //maxa = maxa * max_mod;
        //maxf = maxf * max_mod;
        limita = limita * limit_mod;
        //limitf = limitf * limit_mod;
  
-       if(g_lms && g_ca)
+       if(g_ca)
                rot_mod = 0;
  
        if (!g_minstagib && !g_ca && (!g_lms || autocvar_g_lms_regenerate))
@@@ -2328,6 -1673,15 +1677,15 @@@ void GetPressedKeys(void) 
                self.pressedkeys |= KEY_CROUCH;
        else
                self.pressedkeys &~= KEY_CROUCH;
+       if (self.BUTTON_ATCK)
+               self.pressedkeys |= KEY_ATCK;
+       else
+               self.pressedkeys &~= KEY_ATCK;
+       if (self.BUTTON_ATCK2)
+               self.pressedkeys |= KEY_ATCK2;
+       else
+               self.pressedkeys &~= KEY_ATCK2;
  }
  
  /*
@@@ -2346,6 -1700,8 +1704,8 @@@ void SpectateCopy(entity spectatee) 
        self.ammo_nails = spectatee.ammo_nails;
        self.ammo_rockets = spectatee.ammo_rockets;
        self.ammo_fuel = spectatee.ammo_fuel;
+       self.clip_load = spectatee.clip_load;
+       self.clip_size = spectatee.clip_size;
        self.effects = spectatee.effects & EFMASK_CHEAP; // eat performance
        self.health = spectatee.health;
        self.impulse = 0;
        self.strength_finished = spectatee.strength_finished;
        self.invincible_finished = spectatee.invincible_finished;
        self.pressedkeys = spectatee.pressedkeys;
-       self.weapons = spectatee.weapons;
+       WEPSET_COPY_EE(self, spectatee);
        self.switchweapon = spectatee.switchweapon;
+       self.switchingweapon = spectatee.switchingweapon;
        self.weapon = spectatee.weapon;
        self.nex_charge = spectatee.nex_charge;
        self.nex_chargepool_ammo = spectatee.nex_chargepool_ammo;
-       self.sniperrifle_bulletcounter = spectatee.sniperrifle_bulletcounter;
+       self.hagar_load = spectatee.hagar_load;
        self.minelayer_mines = spectatee.minelayer_mines;
        self.punchangle = spectatee.punchangle;
        self.view_ofs = spectatee.view_ofs;
-       self.v_angle = spectatee.v_angle;
        self.velocity = spectatee.velocity;
        self.dmg_take = spectatee.dmg_take;
        self.dmg_save = spectatee.dmg_save;
        self.dmg_inflictor = spectatee.dmg_inflictor;
+       self.v_angle = spectatee.v_angle;
        self.angles = spectatee.v_angle;
-       self.fixangle = TRUE;
+       if(!self.BUTTON_USE)
+               self.fixangle = TRUE;
        setorigin(self, spectatee.origin);
        setsize(self, spectatee.mins, spectatee.maxs);
        SetZoomState(spectatee.zoomstate);
-       anticheat_spectatecopy(spectatee);
+     
+     anticheat_spectatecopy(spectatee);
+       self.hud = spectatee.hud;
+       if(spectatee.vehicle)
+     {
+         self.fixangle = FALSE;
+         //self.velocity = spectatee.vehicle.velocity;
+         self.vehicle_health = spectatee.vehicle_health;
+         self.vehicle_shield = spectatee.vehicle_shield;
+         self.vehicle_energy = spectatee.vehicle_energy;
+         self.vehicle_ammo1 = spectatee.vehicle_ammo1;
+         self.vehicle_ammo2 = spectatee.vehicle_ammo2;
+         self.vehicle_reload1 = spectatee.vehicle_reload1;
+         self.vehicle_reload2 = spectatee.vehicle_reload2;
+         msg_entity = self;
+         
+         WriteByte (MSG_ONE, SVC_SETVIEWANGLES);
+             WriteAngle(MSG_ONE,  spectatee.v_angle_x);
+             WriteAngle(MSG_ONE,  spectatee.v_angle_y);
+             WriteAngle(MSG_ONE,  spectatee.v_angle_z);
+         //WriteByte (MSG_ONE, SVC_SETVIEW);
+         //    WriteEntity(MSG_ONE, self);            
+         //makevectors(spectatee.v_angle);
+         //setorigin(self, spectatee.origin - v_forward * 400 + v_up * 300);*/    
+     }
  }
  
  float SpectateUpdate() {
        if(!self.enemy)
-               return 0;
+           return 0;           
  
        if (self == self.enemy)
                return 0;
  
-       if(self.enemy.classname != "player")
+       if not(IS_PLAYER(self.enemy))
                return 0;
  
        SpectateCopy(self.enemy);
        return 1;
  }
  
- float SpectateNext() {
-       other = find(self.enemy, classname, "player");
  
-       if (!other)
-               other = find(other, classname, "player");
+ float SpectateSet()
+ {
+       if(self.enemy.classname != "player")
+               return FALSE;
+       /*if(self.enemy.vehicle)
+       {
  
-       if (other)
-               self.enemy = other;
+               msg_entity = self;
+               WriteByte(MSG_ONE, SVC_SETVIEW);
+               WriteEntity(MSG_ONE, self.enemy);
+               //stuffcmd(self, "set viewsize $tmpviewsize \n");
  
-       if(self.enemy.classname == "player") {
+               self.movetype = MOVETYPE_NONE;
+               accuracy_resend(self);
+       }
+       else
+       {*/
                msg_entity = self;
                WriteByte(MSG_ONE, SVC_SETVIEW);
                WriteEntity(MSG_ONE, self.enemy);
-               //stuffcmd(self, "set viewsize $tmpviewsize \n");
+               //stuffcmd(self, "set viewsize $tmpviewsize \n");
                self.movetype = MOVETYPE_NONE;
                accuracy_resend(self);
  
                if(!SpectateUpdate())
                        PutObserverInServer();
+       //}
+       return TRUE;
+ }
  
-               return 1;
-       } else {
+ float Spectate(entity pl)
+ {
+       if(g_ca && !autocvar_g_ca_spectate_enemies && self.caplayer)
+       if(pl.team != self.team)
                return 0;
+       self.enemy = pl;
+       return SpectateSet();
+ }
+ // Returns next available player to spectate if g_ca_spectate_enemies == 0
+ entity CA_SpectateNext(entity start) {
+       if (start.team == self.team) {
+               return start;
+       }
+       
+       other = start;
+       // continue from current player
+       while(other && other.team != self.team) {
+               other = find(other, classname, "player");
+       }
+       
+       if (!other) {
+               // restart from begining
+               other = find(other, classname, "player");
+               while(other && other.team != self.team) {
+                       other = find(other, classname, "player");
+               }
+       }
+       
+       return other;
+ }
+ float SpectateNext()
+ {
+       other = find(self.enemy, classname, "player");
+       if (g_ca && !autocvar_g_ca_spectate_enemies && self.caplayer) {
+               // CA and ca players when spectating enemies is forbidden
+               other = CA_SpectateNext(other);
+       } else {
+               // other modes and ca spectators or spectating enemies is allowed
+               if (!other)
+                       other = find(other, classname, "player");
+       }
+       if (other)
+               self.enemy = other;
+       return SpectateSet();
+ }
+ float SpectatePrev()
+ {
+       // NOTE: chain order is from the highest to the lower entnum (unlike find)
+       other = findchain(classname, "player");
+       if not(other) // no player
+               return FALSE;
+       entity first = other;
+       // skip players until current spectated player
+       if(self.enemy)
+       while(other && other != self.enemy)
+               other = other.chain;
+       if (g_ca && !autocvar_g_ca_spectate_enemies && self.caplayer)
+       {
+               do { other = other.chain; }
+               while(other && other.team != self.team);
+               if not(other)
+               {
+                       other = first;
+                       while(other.team != self.team)
+                               other = other.chain;
+                       if(other == self.enemy)
+                               return TRUE;
+               }
        }
+       else
+       {
+               if(other.chain)
+                       other = other.chain;
+               else
+                       other = first;
+       }
+       self.enemy = other;
+       return SpectateSet();
  }
  
  /*
@@@ -2434,50 -1912,47 +1916,47 @@@ void ShowRespawnCountdown(
                return;
        else
        {
-               number = ceil(self.death_time - time);
+               number = ceil(self.respawn_time - time);
                if(number <= 0)
                        return;
                if(number <= self.respawn_countdown)
                {
                        self.respawn_countdown = number - 1;
-                       if(ceil(self.death_time - (time + 0.5)) == number) // only say it if it is the same number even in 0.5s; to prevent overlapping sounds
-                               AnnounceTo(self, strcat(ftos(number), ""));
+                       if(ceil(self.respawn_time - (time + 0.5)) == number) // only say it if it is the same number even in 0.5s; to prevent overlapping sounds
+                               Send_Notification(NOTIF_ONE, self, MSG_ANNCE, Announcer_PickNumber(number)); 
                }
        }
  }
  
  void LeaveSpectatorMode()
  {
-       if(nJoinAllowed(1)) {
-               if(!teams_matter || autocvar_g_campaign || autocvar_g_balance_teams || (self.wasplayer && autocvar_g_changeteam_banned) || self.team_forced > 0) {
+       if(self.caplayer)
+               return;
+       if(nJoinAllowed(self))
+       {
+               if(!teamplay || autocvar_g_campaign || autocvar_g_balance_teams || (self.wasplayer && autocvar_g_changeteam_banned) || self.team_forced > 0)
+               {
                        self.classname = "player";
  
-                       if(autocvar_g_campaign || autocvar_g_balance_teams || autocvar_g_balance_teams_force)
-                               JoinBestTeam(self, FALSE, TRUE);
+                       if(autocvar_g_campaign || autocvar_g_balance_teams)
+                               { JoinBestTeam(self, FALSE, TRUE); }
  
                        if(autocvar_g_campaign)
-                               campaign_bots_may_start = 1;
+                               { campaign_bots_may_start = 1; }
  
-                       PutClientInServer();
-                       if(self.classname == "player")
-                               bprint ("^4", self.netname, "^4 is playing now\n");
+                       Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_PREVENT_JOIN);
  
-                       if(!autocvar_g_campaign)
-                               centerprint(self,""); // clear MOTD
+                       PutClientInServer();
  
-                       return;
-               } else {
-                       if (g_ca && self.caplayer) {
-                       }       // do nothing
-                       else
-                               stuffcmd(self,"menu_showteamselect\n");
-                       return;
+                       if(IS_PLAYER(self)) { Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_JOIN_PLAY, self.netname); }
                }
+               else
+                       stuffcmd(self, "menu_showteamselect\n");
        }
-       else {
-               //player may not join because of g_maxplayers is set
-               centerprint_atprio(self, CENTERPRIO_MAPVOTE, PREVENT_JOIN_TEXT);
+       else
+       {
+               // Player may not join because g_maxplayers is set
+               Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_JOIN_PREVENT);
        }
  }
  
   * it checks whether the number of currently playing players exceeds g_maxplayers.
   * @return int number of free slots for players, 0 if none
   */
- float nJoinAllowed(float includeMe) {
+ float nJoinAllowed(entity ignore) {
+       if(!ignore)
+       // this is called that way when checking if anyone may be able to join (to build qcstatus)
+       // so report 0 free slots if restricted
+       {
+               if(autocvar_g_forced_team_otherwise == "spectate")
+                       return 0;
+               if(autocvar_g_forced_team_otherwise == "spectator")
+                       return 0;
+       }
        if(self.team_forced < 0)
-               return FALSE; // forced spectators can never join
+               return 0; // forced spectators can never join
  
        // TODO simplify this
-       local entity e;
-       local float totalClients;
+       entity e;
+       float totalClients = 0;
        FOR_EACH_CLIENT(e)
-               totalClients += 1;
+               if(e != ignore)
+                       totalClients += 1;
  
        if (!autocvar_g_maxplayers)
-               return maxclients - totalClients + includeMe;
+               return maxclients - totalClients;
  
-       local float currentlyPlaying;
-       FOR_EACH_REALPLAYER(e)
-               currentlyPlaying += 1;
+       float currentlyPlaying = 0;
+       FOR_EACH_REALCLIENT(e)
+               if(IS_PLAYER(e) || e.caplayer == 1)
+                       currentlyPlaying += 1;
  
        if(currentlyPlaying < autocvar_g_maxplayers)
-               return min(maxclients - totalClients + includeMe, autocvar_g_maxplayers - currentlyPlaying);
+               return min(maxclients - totalClients, autocvar_g_maxplayers - currentlyPlaying);
  
        return 0;
  }
   * g_maxplayers_spectator_blocktime seconds
   */
  void checkSpectatorBlock() {
-       if(self.classname == "spectator" || self.classname == "observer") {
+       if(IS_SPEC(self) || IS_OBSERVER(self)) {
                if( time > (self.spectatortime + autocvar_g_maxplayers_spectator_blocktime) ) {
-                       sprint(self, "^7You were kicked from the server because you are spectator and spectators aren't allowed at the moment.\n");
+                       Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_QUIT_KICK_SPECTATING);
                        dropclient(self);
                }
        }
  }
  
+ void PrintWelcomeMessage()
+ {
+       if(self.motd_actived_time == 0)
+       {
+               if (autocvar_g_campaign) {
+                       if ((IS_PLAYER(self) && self.BUTTON_INFO) || (!IS_PLAYER(self))) {
+                               self.motd_actived_time = time;
+                               Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MOTD, campaign_message);
+                       }
+               } else {
+                       if (self.BUTTON_INFO) {
+                               self.motd_actived_time = time;
+                               Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MOTD, getwelcomemessage());
+                       }
+               }
+       }
+       else if(self.motd_actived_time > 0) // showing MOTD or campaign message
+       {
+               if (autocvar_g_campaign) {
+                       if (self.BUTTON_INFO)
+                               self.motd_actived_time = time;
+                       else if ((time - self.motd_actived_time > 2) && IS_PLAYER(self)) { // hide it some seconds after BUTTON_INFO has been released
+                               self.motd_actived_time = 0;
+                               Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_MOTD);
+                       }
+               } else {
+                       if (self.BUTTON_INFO)
+                               self.motd_actived_time = time;
+                       else if (time - self.motd_actived_time > 2) { // hide it some seconds after BUTTON_INFO has been released
+                               self.motd_actived_time = 0;
+                               Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_MOTD);
+                       }
+               }
+       }
+       else //if(self.motd_actived_time < 0) // just connected, motd is active
+       {
+               if(self.BUTTON_INFO) // BUTTON_INFO hides initial MOTD
+                       self.motd_actived_time = -2; // wait until BUTTON_INFO gets released
+               else if(self.motd_actived_time == -2 || IS_PLAYER(self) || time - self.jointime > autocvar_welcome_message_time)
+               {
+                       // instanctly hide MOTD
+                       self.motd_actived_time = 0;
+                       Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_MOTD);
+               }
+       }
+ }
  void ObserverThink()
  {
+       float prefered_movetype;
        if (self.flags & FL_JUMPRELEASED) {
                if (self.BUTTON_JUMP && !self.version_mismatch) {
-                       self.welcomemessage_time = 0;
                        self.flags &~= FL_JUMPRELEASED;
                        self.flags |= FL_SPAWNING;
                } else if(self.BUTTON_ATCK && !self.version_mismatch) {
-                       self.welcomemessage_time = 0;
                        self.flags &~= FL_JUMPRELEASED;
-                       if(SpectateNext() == 1) {
+                       if(SpectateNext()) {
                                self.classname = "spectator";
                        }
+               } else {
+                       prefered_movetype = ((!self.BUTTON_USE ? self.cvar_cl_clippedspectating : !self.cvar_cl_clippedspectating) ? MOVETYPE_FLY_WORLDONLY : MOVETYPE_NOCLIP);
+                       if (self.movetype != prefered_movetype)
+                               self.movetype = prefered_movetype;
                }
        } else {
                if (!(self.BUTTON_ATCK || self.BUTTON_JUMP)) {
                        }
                }
        }
-       PrintWelcomeMessage(self);
  }
  
  void SpectatorThink()
  {
        if (self.flags & FL_JUMPRELEASED) {
                if (self.BUTTON_JUMP && !self.version_mismatch) {
-                       self.welcomemessage_time = 0;
                        self.flags &~= FL_JUMPRELEASED;
                        self.flags |= FL_SPAWNING;
-               } else if(self.BUTTON_ATCK) {
-                       self.welcomemessage_time = 0;
+               } else if(self.BUTTON_ATCK || self.impulse == 10 || self.impulse == 15 || self.impulse == 18 || self.impulse >= 200 && self.impulse <= 209) {
+                       self.flags &~= FL_JUMPRELEASED;
+                       if(SpectateNext()) {
+                               self.classname = "spectator";
+                       } else {
+                               self.classname = "observer";
+                               PutClientInServer();
+                       }
+                       self.impulse = 0;
+               } else if(self.impulse == 12 || self.impulse == 16  || self.impulse == 19 || self.impulse >= 220 && self.impulse <= 229) {
                        self.flags &~= FL_JUMPRELEASED;
-                       if(SpectateNext() == 1) {
+                       if(SpectatePrev()) {
                                self.classname = "spectator";
                        } else {
                                self.classname = "observer";
                                PutClientInServer();
                        }
+                       self.impulse = 0;
                } else if (self.BUTTON_ATCK2) {
-                       self.welcomemessage_time = 0;
                        self.flags &~= FL_JUMPRELEASED;
                        self.classname = "observer";
                        PutClientInServer();
                                return;
                        }
                }
+               if(!SpectateUpdate())
+                       PutObserverInServer();
        }
  
-       PrintWelcomeMessage(self);
        self.flags |= FL_CLIENT | FL_NOTARGET;
  }
  
- .float touchexplode_time;
+ void PlayerUseKey()
+ {
+       if not(IS_PLAYER(self))
+               return;
+       if(self.vehicle)
+       {
+         vehicles_exit(VHEF_NORMAL);
+         return;
+       }
+       
+       // a use key was pressed; call handlers
+       MUTATOR_CALLHOOK(PlayerUseKey);
+ }
  
  /*
  =============
@@@ -2602,12 -2158,15 +2162,15 @@@ PlayerPreThin
  Called every frame for each client before the physics are run
  =============
  */
void() ctf_setstatus;
.float usekeypressed;
  void() nexball_setstatus;
  .float items_added;
  void PlayerPreThink (void)
  {
+       WarpZone_PlayerPhysics_FixVAngle();
        self.stat_game_starttime = game_starttime;
+       self.stat_round_starttime = round_starttime;
        self.stat_allow_oldnexbeam = autocvar_g_allow_oldnexbeam;
        self.stat_leadlimit = autocvar_leadlimit;
  
                if(self.cvar_g_xonoticversion)
                        if(time > self.version_nagtime)
                        {
-                               if(strstr(self.cvar_g_xonoticversion, "git", 0) < 0)
+                               // don't notify git users
+                               if(strstr(self.cvar_g_xonoticversion, "git", 0) < 0 && strstr(self.cvar_g_xonoticversion, "autobuild", 0) < 0)
                                {
-                                       if(strstr(autocvar_g_xonoticversion, "git", 0) >= 0)
+                                       if(strstr(autocvar_g_xonoticversion, "git", 0) >= 0 || strstr(autocvar_g_xonoticversion, "autobuild", 0) >= 0)
                                        {
+                                               // notify release users if connecting to git
                                                dprint("^1NOTE^7 to ", self.netname, "^7 - the server is running ^3Xonotic ", autocvar_g_xonoticversion, " (beta)^7, you have ^3Xonotic ", self.cvar_g_xonoticversion, "^1\n");
-                                               sprint(self, strcat("\{1}^1NOTE: ^7the server is running ^3Xonotic ", autocvar_g_xonoticversion, " (beta)^7, you have ^3Xonotic ", self.cvar_g_xonoticversion, "^1\n"));
+                                               Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_VERSION_BETA, autocvar_g_xonoticversion, self.cvar_g_xonoticversion);
                                        }
                                        else
                                        {
                                                r = vercmp(self.cvar_g_xonoticversion, autocvar_g_xonoticversion);
                                                if(r < 0)
                                                {
-                                                       dprint("^1NOTE^7 to ", self.netname, "^7 - ^3Xonotic ", autocvar_g_xonoticversion, "^7 is out, and you still have ^3Xonotic ", self.cvar_g_xonoticversion, "^1 - get the update from ^4http://www.xonotic.com/^1!\n");
-                                                       sprint(self, strcat("\{1}^1NOTE: ^3Xonotic ", autocvar_g_xonoticversion, "^7 is out, and you still have ^3Xonotic ", self.cvar_g_xonoticversion, "^1 - get the update from ^4http://www.xonotic.com/^1!\n"));
+                                                       // give users new version
+                                                       dprint("^1NOTE^7 to ", self.netname, "^7 - ^3Xonotic ", autocvar_g_xonoticversion, "^7 is out, and you still have ^3Xonotic ", self.cvar_g_xonoticversion, "^1 - get the update from ^4http://www.xonotic.org/^1!\n");
+                                                       Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_VERSION_OUTDATED, autocvar_g_xonoticversion, self.cvar_g_xonoticversion);
                                                }
                                                else if(r > 0)
                                                {
-                                                       dprint("^1NOTE^7 to ", self.netname, "^7 - the server is running ^3Xonotic ", autocvar_g_xonoticversion, "^7, you have ^3Xonotic ", self.cvar_g_xonoticversion, "^1\n");
-                                                       sprint(self, strcat("\{1}^1NOTE: ^7the server is running ^3Xonotic ", autocvar_g_xonoticversion, "^7, you have ^3Xonotic ", self.cvar_g_xonoticversion, "^1\n"));
+                                                       // notify users about old server version
+                                                       print("^1NOTE^7 to ", self.netname, "^7 - the server is running ^3Xonotic ", autocvar_g_xonoticversion, "^7, you have ^3Xonotic ", self.cvar_g_xonoticversion, "^1\n");
+                                                       Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_VERSION_OLD, autocvar_g_xonoticversion, self.cvar_g_xonoticversion);
                                                }
                                        }
                                }
        // GOD MODE info
        if(!(self.flags & FL_GODMODE)) if(self.max_armorvalue)
        {
-               sprint(self, strcat("godmode saved you ", ftos(self.max_armorvalue), " units of damage, cheater!\n"));
+               Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_GODMODE_OFF, self.max_armorvalue);
                self.max_armorvalue = 0;
        }
  
  
        MUTATOR_CALLHOOK(PlayerPreThink);
  
-       if(self.classname == "player") {
- //            if(self.netname == "Wazat")
- //                    bprint(self.classname, "\n");
+       if(!self.cvar_cl_newusekeysupported) // FIXME remove this - it was a stupid idea to begin with, we can JUST use the button
+       {
+               if(self.BUTTON_USE && !self.usekeypressed)
+                       PlayerUseKey();
+               self.usekeypressed = self.BUTTON_USE;
+       }
  
-               CheckRules_Player();
+       if(IS_REAL_CLIENT(self))
+               PrintWelcomeMessage();
+       if(IS_PLAYER(self))
+       {
  
-               PrintWelcomeMessage(self);
+               CheckRules_Player();
  
                if (intermission_running)
                {
                        return;                                 // the think tics
                }
  
-               if(self.teleport_time)
-               if(time > self.teleport_time)
-               {
-                       self.teleport_time = 0;
-                       self.effects = self.effects - (self.effects & EF_NODRAW);
-               }
-               if(frametime > 0) // don't do this in cl_movement frames, just in server ticks
-                       UpdateSelectedPlayer();
                //don't allow the player to turn around while game is paused!
-               if(timeoutStatus == 2) {
+               if(timeout_status == TIMEOUT_ACTIVE) {
+                       // FIXME turn this into CSQC stuff
                        self.v_angle = self.lastV_angle;
                        self.angles = self.lastV_angle;
                        self.fixangle = TRUE;
  
                if(frametime)
                {
-                       if(self.health <= 0 && autocvar_g_deathglow)
+                       if(self.weapon == WEP_NEX && autocvar_g_balance_nex_charge)
                        {
-                               if(self.glowmod_x > 0)
-                                       self.glowmod_x -= autocvar_g_deathglow * frametime;
-                               else
-                                       self.glowmod_x = -1;
-                               if(self.glowmod_y > 0)
-                                       self.glowmod_y -= autocvar_g_deathglow * frametime;
-                               else
-                                       self.glowmod_y = -1;
-                               if(self.glowmod_z > 0)
-                                       self.glowmod_z -= autocvar_g_deathglow * frametime;
-                               else
-                                       self.glowmod_z = -1;
+                               self.weaponentity_glowmod_x = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_red_half * min(1, self.nex_charge / autocvar_g_balance_nex_charge_animlimit);
+                               self.weaponentity_glowmod_y = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_green_half * min(1, self.nex_charge / autocvar_g_balance_nex_charge_animlimit);
+                               self.weaponentity_glowmod_z = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_blue_half * min(1, self.nex_charge / autocvar_g_balance_nex_charge_animlimit);
+                               if(self.nex_charge > autocvar_g_balance_nex_charge_animlimit)
+                               {
+                                       self.weaponentity_glowmod_x = self.weaponentity_glowmod_x + autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_red_full * (self.nex_charge - autocvar_g_balance_nex_charge_animlimit) / (1 - autocvar_g_balance_nex_charge_animlimit);
+                                       self.weaponentity_glowmod_y = self.weaponentity_glowmod_y + autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_green_full * (self.nex_charge - autocvar_g_balance_nex_charge_animlimit) / (1 - autocvar_g_balance_nex_charge_animlimit);
+                                       self.weaponentity_glowmod_z = self.weaponentity_glowmod_z + autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_blue_full * (self.nex_charge - autocvar_g_balance_nex_charge_animlimit) / (1 - autocvar_g_balance_nex_charge_animlimit);
+                               }
                        }
                        else
-                               self.glowmod = colormapPaletteColor(self.clientcolors & 0x0F, TRUE) * 2;
+                               self.weaponentity_glowmod = colormapPaletteColor(self.clientcolors & 0x0F, TRUE) * 2;
                        player_powerups();
                }
  
                if (self.deadflag != DEAD_NO)
                {
-                       float button_pressed, force_respawn;
                        if(self.personal && g_race_qualifying)
                        {
-                               if(time > self.death_time)
+                               if(time > self.respawn_time)
                                {
-                                       self.death_time = time + 1; // only retry once a second
+                                       self.respawn_time = time + 1; // only retry once a second
+                                       self.stat_respawn_time = self.respawn_time;
                                        respawn();
                                        self.impulse = 141;
                                }
                        }
                        else
                        {
+                               float button_pressed;
                                if(frametime)
                                        player_anim();
                                button_pressed = (self.BUTTON_ATCK || self.BUTTON_JUMP || self.BUTTON_ATCK2 || self.BUTTON_HOOK || self.BUTTON_USE);
-                               force_respawn = (g_lms || g_ca || g_cts || autocvar_g_forced_respawn);
+                               
                                if (self.deadflag == DEAD_DYING)
                                {
-                                       if(force_respawn)
+                                       if(self.respawn_flags & RESPAWN_FORCE)
                                                self.deadflag = DEAD_RESPAWNING;
                                        else if(!button_pressed)
                                                self.deadflag = DEAD_DEAD;
                                }
                                else if (self.deadflag == DEAD_RESPAWNING)
                                {
-                                       if(time > self.death_time)
+                                       if(time > self.respawn_time)
                                        {
-                                               self.death_time = time + 1; // only retry once a second
+                                               self.respawn_time = time + 1; // only retry once a second
                                                respawn();
                                        }
                                }
                                ShowRespawnCountdown();
-                       }
-                       return;
-               }
  
-               if(g_touchexplode)
-               if(time > self.touchexplode_time)
-               if(self.classname == "player")
-               if(self.deadflag == DEAD_NO)
-               if not(IS_INDEPENDENT_PLAYER(self))
-               FOR_EACH_PLAYER(other) if(self != other)
-               {
-                       if(time > other.touchexplode_time)
-                       if(other.deadflag == DEAD_NO)
-                       if not(IS_INDEPENDENT_PLAYER(other))
-                       if(boxesoverlap(self.absmin, self.absmax, other.absmin, other.absmax))
-                       {
-                               PlayerTouchExplode(self, other);
-                               self.touchexplode_time = other.touchexplode_time = time + 0.2;
+                               if(self.respawn_flags & RESPAWN_SILENT)
+                                       self.stat_respawn_time = 0;
+                               else
+                                       self.stat_respawn_time = self.respawn_time;
                        }
-               }
-               if(g_lms && !self.deadflag && autocvar_g_lms_campcheck_interval)
-               {
-                       vector dist;
  
-                       // calculate player movement (in 2 dimensions only, so jumping on one spot doesn't count as movement)
-                       dist = self.prevorigin - self.origin;
-                       dist_z = 0;
-                       self.lms_traveled_distance += fabs(vlen(dist));
+                       // if respawning, invert stat_respawn_time to indicate this, the client translates it
+                       if(self.deadflag == DEAD_RESPAWNING && self.stat_respawn_time > 0)
+                               self.stat_respawn_time *= -1;
  
-                       if((autocvar_g_campaign && !campaign_bots_may_start) || (time < game_starttime))
-                       {
-                               self.lms_nextcheck = time + autocvar_g_lms_campcheck_interval*2;
-                               self.lms_traveled_distance = 0;
-                       }
-                       if(time > self.lms_nextcheck)
-                       {
-                               //sprint(self, "distance: ", ftos(self.lms_traveled_distance), "\n");
-                               if(self.lms_traveled_distance < autocvar_g_lms_campcheck_distance)
-                               {
-                                       centerprint(self, autocvar_g_lms_campcheck_message);
-                                       // FIXME KadaverJack: gibbing player here causes playermodel to bounce around, instead of eye.md3
-                                       // I wasn't able to find out WHY that happens, so I put a workaround in place that shall prevent players from being gibbed :(
-                                       Damage(self, self, self, bound(0, autocvar_g_lms_campcheck_damage, self.health + self.armorvalue * autocvar_g_balance_armor_blockpercent + 5), DEATH_CAMP, self.origin, '0 0 0');
-                               }
-                               self.lms_nextcheck = time + autocvar_g_lms_campcheck_interval;
-                               self.lms_traveled_distance = 0;
-                       }
+                       return;
                }
  
                self.prevorigin = self.origin;
  
-               if ((self.BUTTON_CROUCH && !self.hook.state) || self.health <= g_bloodloss)
+               float do_crouch = self.BUTTON_CROUCH;
+               if(self.hook.state)
+                       do_crouch = 0;
+               if(self.health <= g_bloodloss)
+                       do_crouch = 1;
+               if(self.vehicle)
+                       do_crouch = 0;
+               if(self.freezetag_frozen)
+                       do_crouch = 0;
+               if(self.weapon == WEP_SHOTGUN && self.weaponentity.wframe == WFRAME_FIRE2 && time < self.weapon_nextthink)
+                       do_crouch = 0;
+               if (do_crouch)
                {
                        if (!self.crouch)
                        {
                                self.crouch = TRUE;
                                self.view_ofs = PL_CROUCH_VIEW_OFS;
                                setsize (self, PL_CROUCH_MIN, PL_CROUCH_MAX);
-                               setanim(self, self.anim_duck, FALSE, TRUE, TRUE);
+                               // setanim(self, self.anim_duck, FALSE, TRUE, TRUE); // this anim is BROKEN anyway
                        }
                }
                else
                if(frametime)
                        player_anim();
  
-               if (g_minstagib)
-                       minstagib_ammocheck();
-               if(g_ctf)
-                       ctf_setstatus();
                if(g_nexball)
                        nexball_setstatus();
+               
+               // secret status
+               secrets_setstatus();
+               
                self.dmg_team = max(0, self.dmg_team - autocvar_g_teamdamage_resetspeed * frametime);
  
                //self.angles_y=self.v_angle_y + 90;   // temp
                if (intermission_running)
                        IntermissionThink ();   // otherwise a button could be missed between
                return;
-       } else if(self.classname == "observer") {
+       } else if(IS_OBSERVER(self)) {
                ObserverThink();
-       } else if(self.classname == "spectator") {
+       } else if(IS_SPEC(self)) {
                SpectatorThink();
        }
  
        if(!zoomstate_set)
-               SetZoomState(self.BUTTON_ZOOM || (self.BUTTON_ATCK2 && self.weapon == WEP_NEX) || (self.BUTTON_ATCK2 && self.weapon == WEP_SNIPERRIFLE && autocvar_g_balance_sniperrifle_secondary == 0));
+               SetZoomState(self.BUTTON_ZOOM || self.BUTTON_ZOOMSCRIPT || (self.BUTTON_ATCK2 && self.weapon == WEP_NEX) || (self.BUTTON_ATCK2 && self.weapon == WEP_RIFLE && autocvar_g_balance_rifle_secondary == 0));
  
        float oldspectatee_status;
        oldspectatee_status = self.spectatee_status;
-       if(self.classname == "spectator")
+       if(IS_SPEC(self))
                self.spectatee_status = num_for_edict(self.enemy);
-       else if(self.classname == "observer")
+       else if(IS_OBSERVER(self))
                self.spectatee_status = num_for_edict(self);
        else
                self.spectatee_status = 0;
                oldself = self; self = self.teamkill_soundsource;
                oldpusher = self.pusher; self.pusher = oldself;
  
-               PlayerSound(playersound_teamshoot, CHAN_VOICE, VOICETYPE_LASTATTACKER_ONLY);
+               PlayerSound(playersound_teamshoot, CH_VOICE, VOICETYPE_LASTATTACKER_ONLY);
  
                self.pusher = oldpusher;
                self = oldself;
        if(time > self.taunt_soundtime)
        {
                self.taunt_soundtime = 0;
-               PlayerSound(playersound_taunt, CHAN_VOICE, VOICETYPE_AUTOTAUNT);
+               PlayerSound(playersound_taunt, CH_VOICE, VOICETYPE_AUTOTAUNT);
        }
  
        target_voicescript_next(self);
+       // if a player goes unarmed after holding a loaded weapon, empty his clip size and remove the crosshair ammo ring
+       if(!self.weapon)
+               self.clip_load = self.clip_size = 0;
  }
  
  float isInvisibleString(string s)
@@@ -2989,18 -2527,6 +2531,6 @@@ Called every frame for each client afte
  =============
  */
  .float idlekick_lasttimeleft;
- .entity showheadshotbbox;
- void showheadshotbbox_think()
- {
-       if(self.owner.showheadshotbbox != self)
-       {
-               remove(self);
-               return;
-       }
-       self.nextthink = time;
-       setorigin(self, self.owner.origin);
-       setsize(self, GetHeadshotMins(self.owner), GetHeadshotMaxs(self.owner));
- }
  void PlayerPostThink (void)
  {
        // Savage: Check for nameless players
                stuffcmd(self, strcat("name ", self.netname, substring(ftos(random()), 2, -1), "\n"));
        }
  
-       if(sv_maxidle && frametime)
+       if(sv_maxidle > 0 && frametime) // WORKAROUND: only use dropclient in server frames (frametime set). Never use it in cl_movement frames (frametime zero).
+       if(IS_PLAYER(self) || sv_maxidle_spectatorsareidle)
        {
-               // WORKAROUND: only use dropclient in server frames (frametime set). Never use it in cl_movement frames (frametime zero).
-               float timeleft;
-               timeleft = ceil(sv_maxidle - (time - self.parm_idlesince));
-               if(timeleft <= 0)
-               {
-                       bprint("^3", self.netname, "^3 was kicked for idling.\n");
-                       AnnounceTo(self, "terminated");
-                       dropclient(self);
-                       return;
-               }
-               else if(timeleft <= 10)
+               if (time - self.parm_idlesince < 1) // instead of (time == self.parm_idlesince) to support sv_maxidle <= 10
                {
-                       if(timeleft != self.idlekick_lasttimeleft)
+                       if(self.idlekick_lasttimeleft)
                        {
-                               centerprint_atprio(self, CENTERPRIO_IDLEKICK, strcat("^3Stop idling!\n^3Disconnecting in ", ftos(timeleft), "..."));
-                               AnnounceTo(self, strcat(ftos(timeleft), ""));
+                               self.idlekick_lasttimeleft = 0;
+                               Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_IDLING);
                        }
                }
                else
                {
-                       centerprint_expire(self, CENTERPRIO_IDLEKICK);
+                       float timeleft;
+                       timeleft = ceil(sv_maxidle - (time - self.parm_idlesince));
+                       if(timeleft == min(10, sv_maxidle - 1)) // - 1 to support sv_maxidle <= 10
+                       {
+                               if(!self.idlekick_lasttimeleft)
+                                       Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_DISCONNECT_IDLING, timeleft);
+                       }
+                       if(timeleft <= 0)
+                       {
+                               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_QUIT_KICK_IDLING, self.netname);
+                               dropclient(self);
+                               return;
+                       }
+                       else if(timeleft <= 10)
+                       {
+                               if(timeleft != self.idlekick_lasttimeleft)
+                                       Send_Notification(NOTIF_ONE, self, MSG_ANNCE, Announcer_PickNumber(timeleft));
+                               self.idlekick_lasttimeleft = timeleft;
+                       }
                }
-               self.idlekick_lasttimeleft = timeleft;
        }
  
  #ifdef TETRIS
        if(self.impulse == 100)
                ImpulseCommands();
-       if (TetrisPostFrame())
-               return;
+       if (!TetrisPostFrame())
+       {
  #endif
  
        CheatFrame();
  
-       if(self.classname == "player") {
+       //CheckPlayerJump();
+       if(IS_PLAYER(self)) {
                CheckRules_Player();
                UpdateChatBubble();
-               UpdateTeamBubble();
                if (self.impulse)
                        ImpulseCommands();
                if (intermission_running)
                        return;         // intermission or finale
                GetPressedKeys();
-       } else if (self.classname == "observer") {
-               //do nothing
-       } else if (self.classname == "spectator") {
-               //do nothing
        }
+       
+ #ifdef TETRIS
+       }
+ #endif
  
        /*
        float i;
        }
        */
  
-       Arena_Warmup();
        //pointparticles(particleeffectnum("machinegun_impact"), self.origin + self.view_ofs + '0 0 7', '0 0 0', 1);
  
        if(self.waypointsprite_attachedforcarrier)
                WaypointSprite_UpdateHealth(self.waypointsprite_attachedforcarrier, '1 0 0' * healtharmor_maxdamage(self.health, self.armorvalue, autocvar_g_balance_armor_blockpercent));
-       
-       if(self.classname == "player" && self.deadflag == DEAD_NO && autocvar_r_showbboxes)
-       {
-               if(!self.showheadshotbbox)
-               {
-                       self.showheadshotbbox = spawn();
-                       self.showheadshotbbox.classname = "headshotbbox";
-                       self.showheadshotbbox.owner = self;
-                       self.showheadshotbbox.think = showheadshotbbox_think;
-                       self.showheadshotbbox.nextthink = time;
-                       self = self.showheadshotbbox;
-                       self.think();
-                       self = self.owner;
-               }
-       }
-       else
-       {
-               if(self.showheadshotbbox)
-                       remove(self.showheadshotbbox);
-       }
  
        playerdemo_write();
  
        if((g_cts || g_race) && self.cvar_cl_allow_uidtracking == 1 && self.cvar_cl_allow_uid2name == 1)
        {
-               if(!self.stored_netname)
+               if not(self.stored_netname)
                        self.stored_netname = strzone(uid2name(self.crypto_idfp));
                if(self.stored_netname != self.netname)
                {
-                       db_put(ServerProgsDB, strcat("uid2name", self.crypto_idfp), self.netname);
+                       db_put(ServerProgsDB, strcat("/uid2name/", self.crypto_idfp), self.netname);
                        strunzone(self.stored_netname);
                        self.stored_netname = strzone(self.netname);
                }
        if(g_race)
                dprint(sprintf("%f %.6f\n", time, race_GetFractionalLapCount(self)));
        */
+       CSQCMODEL_AUTOUPDATE();
  }
diff --combined qcsrc/server/g_world.qc
index 67319b92524372f63697ab484b84fa98909d71cd,3043a30003a590f713fc6561074605fbf31d236f..9e7fa78a565c89c437f9811c34950f78392585b3
@@@ -1,3 -1,7 +1,7 @@@
+ #define LATENCY_THINKRATE 10
+ .float latency_sum;
+ .float latency_cnt;
+ .float latency_time;
  entity pingplreport;
  void PingPLReport_Think()
  {
@@@ -10,7 -14,7 +14,7 @@@
        self.nextthink = time + delta;
  
        e = edict_num(self.cnt + 1);
-       if(clienttype(e) == CLIENTTYPE_REAL)
+       if(IS_REAL_CLIENT(e))
        {
                WriteByte(MSG_BROADCAST, SVC_TEMPENTITY);
                WriteByte(MSG_BROADCAST, TE_CSQC_PINGPLREPORT);
                WriteShort(MSG_BROADCAST, max(1, e.ping));
                WriteByte(MSG_BROADCAST, ceil(e.ping_packetloss * 255));
                WriteByte(MSG_BROADCAST, ceil(e.ping_movementloss * 255));
+               // record latency times for clients throughout the match so we can report it to playerstats
+               if(time > (e.latency_time + LATENCY_THINKRATE))
+               {
+                       e.latency_sum += e.ping;
+                       e.latency_cnt += 1;
+                       e.latency_time = time;
+                       //print("sum: ", ftos(e.latency_sum), ", cnt: ", ftos(e.latency_cnt), ", avg: ", ftos(e.latency_sum / e.latency_cnt), ".\n");
+               }
        }
        else
        {
@@@ -44,9 -57,9 +57,9 @@@ float world_initialized
  
  string GetMapname();
  string GetGametype();
- void GotoNextMap();
- void ShuffleMaplist()
- float() DoNextMapOverride;
+ void GotoNextMap(float reinit);
+ void ShuffleMaplist();
+ float(float reinit) DoNextMapOverride;
  
  void SetDefaultAlpha()
  {
@@@ -95,86 -108,6 +108,6 @@@ void fteqcc_testbugs(
        world.cnt = 0;
  }
  
- /**
-  * Takes care of pausing and unpausing the game.
-  * Centerprints the information about an upcoming or active timeout to all active
-  * players. Also plays reminder sounds.
-  */
- void timeoutHandler_Think() {
-       local string timeStr;
-       local entity plr;
-       if (timeoutStatus == 1) {
-               if (remainingLeadTime > 0) {
-                       //centerprint the information to every player
-                       timeStr = getTimeoutText(0);
-                       FOR_EACH_REALCLIENT(plr) {
-                               if(plr.classname == "player") {
-                                       centerprint_atprio(plr, CENTERPRIO_SPAM, timeStr);
-                               }
-                       }
-                       remainingLeadTime -= 1;
-                       //think again in 1 second:
-                       self.nextthink = time + 1;
-               }
-               else {
-                       //now pause the game:
-                       timeoutStatus = 2;
-                       //reset all the flood variables
-                       FOR_EACH_CLIENT(plr) {
-                               plr.nickspamcount = plr.nickspamtime = plr.floodcontrol_chat = plr.floodcontrol_chatteam = plr.floodcontrol_chattell = plr.floodcontrol_voice = plr.floodcontrol_voiceteam = 0;
-                       }
-                       cvar_set("slowmo", ftos(TIMEOUT_SLOWMO_VALUE));
-                       //copy .v_angle to .lastV_angle for every player in order to fix their view during pause (see PlayerPreThink)
-                       FOR_EACH_REALPLAYER(plr) {
-                               plr.lastV_angle = plr.v_angle;
-                       }
-                       self.nextthink = time;
-               }
-       }
-       else if (timeoutStatus == 2) {
-               if (remainingTimeoutTime > 0) {
-                       timeStr = getTimeoutText(0);
-                       FOR_EACH_REALCLIENT(plr) {
-                               if(plr.classname == "player") {
-                                       centerprint_atprio(plr, CENTERPRIO_SPAM, timeStr);
-                               }
-                       }
-                       if(remainingTimeoutTime == autocvar_sv_timeout_resumetime) { //play a warning sound when only <sv_timeout_resumetime> seconds are left
-                               Announce("prepareforbattle");
-                       }
-                       remainingTimeoutTime -= 1;
-                       self.nextthink = time + TIMEOUT_SLOWMO_VALUE;
-               }
-               else {
-                       //unpause the game again
-                       remainingTimeoutTime = timeoutStatus = 0;
-                       cvar_set("slowmo", ftos(orig_slowmo));
-                       //and unlock the fixed view again once there is no timeout active anymore
-                       FOR_EACH_REALPLAYER(plr) {
-                               plr.fixangle = FALSE;
-                       }
-                       //get rid of the countdown message
-                       FOR_EACH_REALCLIENT(plr) {
-                               if(plr.classname == "player") {
-                                       centerprint_atprio(plr, CENTERPRIO_SPAM, "");
-                               }
-                       }
-                       remove(self);
-                       return;
-               }
-       }
-       else if (timeoutStatus == 0) { //if a player called the resumegame command (which set timeoutStatus to 0 already)
-               FOR_EACH_REALCLIENT(plr) {
-                       if(plr.classname == "player") {
-                               centerprint_atprio(plr, CENTERPRIO_SPAM, "");
-                       }
-               }
-               remove(self);
-               return;
-       }
- }
  void GotoFirstMap()
  {
        float n;
                MapInfo_Enumerate();
                MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
  
-               if(!DoNextMapOverride())
-                       GotoNextMap();
+               if(!DoNextMapOverride(1))
+                       GotoNextMap(1);
  
                return;
        }
@@@ -256,6 -189,7 +189,7 @@@ void cvar_changes_init(
                BADPREFIX("con_");
                BADPREFIX("scoreboard_");
                BADPREFIX("g_campaign");
+               BADPREFIX("g_waypointsprite_");
                BADPREFIX("gl_");
                BADPREFIX("joy");
                BADPREFIX("hud_");
  
                // private
                BADCVAR("developer");
-               BADCVAR("g_banned_list");
                BADCVAR("log_dest_udp");
                BADCVAR("log_file");
                BADCVAR("net_address");
                BADCVAR("port");
                BADCVAR("savedgamecfg");
                BADCVAR("serverconfig");
+               BADCVAR("sv_autoscreenshot");
                BADCVAR("sv_heartbeatperiod");
                BADCVAR("sv_vote_master_password");
                BADCVAR("sys_colortranslation");
                BADCVAR("sys_specialcharactertranslation");
+               BADCVAR("timeformat");
                BADCVAR("timestamps");
                BADPREFIX("developer_");
                BADPREFIX("g_ban_");
+               BADPREFIX("g_banned_list");
                BADPREFIX("g_chat_flood_");
+               BADPREFIX("g_ghost_items");
+               BADPREFIX("g_playerstats_");
+               BADPREFIX("g_respawn_ghosts");
                BADPREFIX("g_voice_flood_");
                BADPREFIX("rcon_");
-               BADPREFIX("settemp_");
-               BADPREFIX("sv_allowdownloads_");
+               BADPREFIX("sv_allowdownloads");
                BADPREFIX("sv_autodemo");
                BADPREFIX("sv_curl_");
                BADPREFIX("sv_eventlog");
                BADPREFIX("sv_logscores_");
                BADPREFIX("sv_master");
                BADPREFIX("sv_weaponstats_");
+               BADPREFIX("sv_waypointsprite_");
+               BADCVAR("rescan_pending");
  
                // these can contain player IDs, so better hide
-               BADCVAR("g_forced_team_red");
-               BADCVAR("g_forced_team_blue");
-               BADCVAR("g_forced_team_yellow");
-               BADCVAR("g_forced_team_pink");
+               BADPREFIX("g_forced_team_");
  
                // mapinfo
                BADCVAR("fraglimit");
                BADCVAR("g_arena");
                BADCVAR("g_assault");
                BADCVAR("g_ca");
+               BADCVAR("g_ca_teams");
                BADCVAR("g_ctf");
                BADCVAR("g_cts");
                BADCVAR("g_dm");
                BADCVAR("g_domination");
                BADCVAR("g_domination_default_teams");
                BADCVAR("g_freezetag");
+               BADCVAR("g_freezetag_teams");
                BADCVAR("g_keepaway");
                BADCVAR("g_keyhunt");
                BADCVAR("g_keyhunt_teams");
-               BADCVAR("g_keyhunt_teams");
                BADCVAR("g_lms");
                BADCVAR("g_nexball");
                BADCVAR("g_onslaught");
                BADCVAR("g_race");
                BADCVAR("g_race_qualifying_timelimit");
-               BADCVAR("g_runematch");
                BADCVAR("g_tdm");
                BADCVAR("g_tdm_teams");
                BADCVAR("leadlimit");
                BADCVAR("g_balance_kill_delay");
                BADCVAR("g_ca_point_leadlimit");
                BADCVAR("g_ctf_captimerecord_always");
-               BADCVAR("g_ctf_capture_leadlimit");
-               BADCVAR("g_ctf_flag_capture_effects");
                BADCVAR("g_ctf_flag_glowtrails");
-               BADCVAR("g_ctf_flag_pickup_effects");
+               BADCVAR("g_ctf_flag_pickup_verbosename");
                BADCVAR("g_domination_point_leadlimit");
                BADCVAR("g_forced_respawn");
                BADCVAR("g_keyhunt_point_leadlimit");
+               BADPREFIX("g_mod_");
                BADCVAR("g_nexball_goalleadlimit");
-               BADCVAR("g_runematch_point_leadlimit");
                BADCVAR("leadlimit_and_fraglimit");
                BADCVAR("leadlimit_override");
                BADCVAR("pausable");
+               BADCVAR("sv_allow_fullbright");
                BADCVAR("sv_checkforpacketsduringsleep");
+               BADCVAR("sv_fraginfo");
                BADCVAR("sv_timeout");
+               BADPREFIX("sv_timeout_");
                BADCVAR("welcome_message_time");
                BADPREFIX("crypto_");
                BADPREFIX("g_chat_");
                BADPREFIX("net_");
                BADPREFIX("prvm_");
                BADPREFIX("skill_");
-               BADPREFIX("sv_fragmessage_");
+               BADPREFIX("sv_cullentities_");
+               BADPREFIX("sv_fraginfo_");
                BADPREFIX("sv_maxidle_");
                BADPREFIX("sv_vote_");
                BADPREFIX("timelimit_");
+               BADCVAR("gameversion");
+               BADPREFIX("gameversion_");
+               BADCVAR("sv_namechangetimer");
  
                // allowed changes to server admins (please sync this to server.cfg)
                // vi commands:
                //   :%s,//\([^ ]*\).*,BADCVAR("\1");,
                //   :%!sort
                // yes, this does contain some redundant stuff, don't really care
+               BADCVAR("bot_config_file");
                BADCVAR("bot_number");
                BADCVAR("bot_prefix");
                BADCVAR("bot_suffix");
                BADCVAR("gametype");
                BADCVAR("g_antilag");
                BADCVAR("g_balance_teams");
-               BADCVAR("g_balance_teams_force");
+               BADCVAR("g_balance_teams_prevent_imbalance");
+               BADCVAR("g_balance_teams_scorefactor");
                BADCVAR("g_ban_sync_trusted_servers");
                BADCVAR("g_ban_sync_uri");
-               BADCVAR("g_ctf_capture_limit");
+               BADCVAR("g_ca_teams_override");
                BADCVAR("g_ctf_ignore_frags");
-               BADCVAR("g_ctf_win_mode");
                BADCVAR("g_domination_point_limit");
+               BADCVAR("g_freezetag_teams_override");
+               BADCVAR("g_friendlyfire");
                BADCVAR("g_fullbrightitems");
                BADCVAR("g_fullbrightplayers");
                BADCVAR("g_keyhunt_point_limit");
                BADCVAR("g_maplist_votable_abstain");
                BADCVAR("g_maplist_votable_nodetail");
                BADCVAR("g_maplist_votable_suggestions");
-               BADCVAR("g_minstagib");
+               BADCVAR("g_maxplayers");
+               BADCVAR("g_mirrordamage");
                BADCVAR("g_nexball_goallimit");
-               BADCVAR("g_runematch_point_limit");
+               BADCVAR("g_powerups");
                BADCVAR("g_start_delay");
+               BADCVAR("g_warmup");
                BADCVAR("g_weapon_stay"); BADPRESUFFIX("g_", "_weapon_stay");
                BADCVAR("hostname");
                BADCVAR("log_file");
                BADCVAR("maxplayers");
-               BADCVAR("g_maxplayers");
                BADCVAR("minplayers");
                BADCVAR("net_address");
                BADCVAR("port");
                BADCVAR("skill");
                BADCVAR("sv_adminnick");
                BADCVAR("sv_autoscreenshot");
+               BADCVAR("sv_autotaunt");
                BADCVAR("sv_curl_defaulturl");
                BADCVAR("sv_defaultcharacter");
                BADCVAR("sv_defaultplayercolors");
                BADCVAR("sv_public");
                BADCVAR("sv_ready_restart");
                BADCVAR("sv_status_privacy");
+               BADCVAR("sv_taunt");
                BADCVAR("sv_vote_call");
                BADCVAR("sv_vote_commands");
                BADCVAR("sv_vote_majority_factor");
                BADCVAR("sv_vote_master_commands");
                BADCVAR("sv_vote_master_password");
                BADCVAR("sv_vote_simple_majority_factor");
+               BADCVAR("sys_ticrate");
+               BADCVAR("teamplay_mode");
                BADCVAR("timelimit_override");
-               BADCVAR("g_warmup");
+               BADCVAR("g_spawnshieldtime");
                BADPREFIX("g_warmup_");
-               BADCVAR("teamplay_mode");
+               BADPREFIX("sv_ready_restart_");
  
-               if(autocvar_g_minstagib)
-               {
-                       BADCVAR("g_grappling_hook");
-                       BADCVAR("g_jetpack");
-               }
+               // mutators that announce themselves properly to the server browser
+               BADCVAR("g_minstagib");
+               BADCVAR("g_new_toys");
+               BADCVAR("g_nix");
+               BADCVAR("g_grappling_hook");
+               BADCVAR("g_jetpack");
+               
  #undef BADPREFIX
  #undef BADCVAR
  
@@@ -592,13 -544,18 +544,18 @@@ void spawnfunc___init_dedicated_server(
  
        self.classname = "worldspawn"; // safeguard against various stuff ;)
  
+       // needs to be done so early because of the constants they create
+       CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
+       CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
+       CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
+       CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
        MapInfo_Enumerate();
        MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
  }
  
  void Map_MarkAsRecent(string m);
  float world_already_spawned;
- void RegisterWeapons();
  void Nagger_Init();
  void ClientInit_Spawn();
  void WeaponStats_Init();
@@@ -624,9 -581,7 +581,7 @@@ void spawnfunc_worldspawn (void
  
        compressShortVector_init();
  
-       allowed_to_spawn = TRUE;
-       local entity head;
+       entity head;
        head = nextent(world);
        maxclients = 0;
        while(head)
                head = nextent(head);
        }
  
-       // needs to be done so early as they would still spawn
-       RegisterWeapons();
+       server_is_dedicated = (stof(cvar_defstring("is_dedicated")) ? TRUE : FALSE);
+       // needs to be done so early because of the constants they create
+       CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
+       CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
+       CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
+       CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
  
-       ServerProgsDB = db_load("server.db");
+       ServerProgsDB = db_load(strcat("server.db", autocvar_sessionid));
  
        TemporaryDB = db_create();
  
  
        Map_MarkAsRecent(mapname);
  
+       PlayerStats_Init(); // we need this to be initiated before InitGameplayMode
        precache_model ("null"); // we need this one before InitGameplayMode
        InitGameplayMode();
        readlevelcvars();
        GrappleHookInit();
 +      LightningInit();
        ElectroInit();
        LaserInit();
  
                if(self.spawnflags & SPAWNFLAG_NO_WAYPOINTS_FOR_ITEMS)
                        bot_waypoints_for_items = 0;
  
-       // for setting by mapinfo
-       q3acompat_machineshotgunswap = autocvar_sv_q3acompat_machineshotgunswap;
-       cvar_set("sv_q3acompat_machineshotgunswap", "0");
        precache();
  
        WaypointSprite_Init();
  
-       //if (g_domination)
-       //      dom_init();
        GameLogInit(); // prepare everything
+       // NOTE for matchid:
+       // changing the logic generating it is okay. But:
+       // it HAS to stay <= 64 chars
+       // character set: ASCII 33-126 without the following characters: : ; ' " \ $
        if(autocvar_sv_eventlog)
        {
-               s = strcat(ftos(autocvar_sv_eventlog_files_counter), ".");
-               s = strcat(s, ftos(random()));
+               s = sprintf("%d.%s.%06d", ftos(autocvar_sv_eventlog_files_counter), strftime(FALSE, "%s"), floor(random() * 1000000));
                matchid = strzone(s);
  
                GameLogEcho(strcat(":gamestart:", GetGametype(), "_", GetMapname(), ":", s));
                        s = strcat(s, ":no_use_ammunition");
  
                // initialiation stuff, not good in the mutator system
-               if(!autocvar_g_pickup_items)
+               if(autocvar_g_pickup_items == 0)
                        s = strcat(s, ":no_pickup_items");
+               if(autocvar_g_pickup_items > 0)
+                       s = strcat(s, ":pickup_items");
  
                // initialiation stuff, not good in the mutator system
                if(autocvar_g_weaponarena != "0")
                        s = strcat(s, ":midair");
  
                // TODO to mutator system
-               if(autocvar_g_minstagib)
-                       s = strcat(s, ":minstagib");
+               if(autocvar_g_powerups == 0)
+                       s = strcat(s, ":no_powerups");
+               if(autocvar_g_powerups > 0)
+                       s = strcat(s, ":powerups");
  
                GameLogEcho(s);
                GameLogEcho(":gameinfo:end");
                                        continue;
                                if(argv(0) == "cd")
                                {
-                                       print("Found ^1DEPRECATED^7 cd loop command in .cfg file; put this line in mapinfo instead:\n");
+                                       print("Found ^1UNSUPPORTED^7 cd loop command in .cfg file; put this line in mapinfo instead:\n");
                                        print("  cdtrack ", argv(2), "\n");
                                }
                                else if(argv(0) == "fog")
                                {
-                                       print("Found ^1DEPRECATED^7 fog command in .cfg file; put this line in worldspawn in the .map/.bsp/.ent file instead:\n");
+                                       print("Found ^1UNSUPPORTED^7 fog command in .cfg file; put this line in worldspawn in the .map/.bsp/.ent file instead:\n");
                                        print("  \"fog\" \"", s, "\"\n");
                                }
                                else if(argv(0) == "set")
                                {
-                                       print("Found ^1DEPRECATED^7 set command in .cfg file; put this line in mapinfo instead:\n");
+                                       print("Found ^1UNSUPPORTED^7 set command in .cfg file; put this line in mapinfo instead:\n");
                                        print("  clientsettemp_for_type all ", argv(1), " ", argv(2), "\n");
                                }
                                else if(argv(0) != "//")
                                {
-                                       print("Found ^1DEPRECATED^7 set command in .cfg file; put this line in mapinfo instead:\n");
+                                       print("Found ^1UNSUPPORTED^7 set command in .cfg file; put this line in mapinfo instead:\n");
                                        print("  clientsettemp_for_type all ", argv(0), " ", argv(1), "\n");
                                }
                        }
  
        WeaponStats_Init();
  
-       addstat(STAT_WEAPONS, AS_INT, weapons);
+       WEPSET_ADDSTAT();
        addstat(STAT_SWITCHWEAPON, AS_INT, switchweapon);
+       addstat(STAT_SWITCHINGWEAPON, AS_INT, switchingweapon);
        addstat(STAT_GAMESTARTTIME, AS_FLOAT, stat_game_starttime);
+       addstat(STAT_ROUNDSTARTTIME, AS_FLOAT, stat_round_starttime);
        addstat(STAT_ALLOW_OLDNEXBEAM, AS_INT, stat_allow_oldnexbeam);
        Nagger_Init();
  
        addstat(STAT_STRENGTH_FINISHED, AS_FLOAT, strength_finished);
        addstat(STAT_INVINCIBLE_FINISHED, AS_FLOAT, invincible_finished);
+       addstat(STAT_SUPERWEAPONS_FINISHED, AS_FLOAT, superweapons_finished);
        addstat(STAT_PRESSED_KEYS, AS_FLOAT, pressedkeys);
        addstat(STAT_FUEL, AS_INT, ammo_fuel);
        addstat(STAT_SHOTORG, AS_INT, stat_shotorg);
        addstat(STAT_LEADLIMIT, AS_FLOAT, stat_leadlimit);
-       addstat(STAT_BULLETS_LOADED, AS_INT, sniperrifle_bulletcounter);
+       addstat(STAT_WEAPON_CLIPLOAD, AS_INT, clip_load);
+       addstat(STAT_WEAPON_CLIPSIZE, AS_INT, clip_size);
        addstat(STAT_LAST_PICKUP, AS_FLOAT, last_pickup);
        addstat(STAT_HIT_TIME, AS_FLOAT, hit_time);
        addstat(STAT_TYPEHIT_TIME, AS_FLOAT, typehit_time);
        addstat(STAT_NEX_CHARGE, AS_FLOAT, nex_charge);
        addstat(STAT_NEX_CHARGEPOOL, AS_FLOAT, nex_chargepool_ammo);
  
-       if(g_ca || g_freezetag)
-       {
-               addstat(STAT_REDALIVE, AS_INT, redalive_stat);
-               addstat(STAT_BLUEALIVE, AS_INT, bluealive_stat);
-               addstat(STAT_YELLOWALIVE, AS_INT, yellowalive_stat);
-               addstat(STAT_PINKALIVE, AS_INT, pinkalive_stat);
-       }
-       if(g_freezetag)
-       {
-               addstat(STAT_FROZEN, AS_INT, freezetag_frozen);
-               addstat(STAT_REVIVE_PROGRESS, AS_FLOAT, freezetag_revive_progress);
-       }
+       addstat(STAT_HAGAR_LOAD, AS_INT, hagar_load);
  
        // g_movementspeed hack
        addstat(STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW, AS_FLOAT, stat_sv_airspeedlimit_nonqw);
        addstat(STAT_MOVEVARS_AIRACCEL_QW, AS_FLOAT, stat_sv_airaccel_qw);
        addstat(STAT_MOVEVARS_AIRSTRAFEACCEL_QW, AS_FLOAT, stat_sv_airstrafeaccel_qw);
  
+       // secrets
+       addstat(STAT_SECRETS_TOTAL, AS_FLOAT, stat_secrets_total);
+       addstat(STAT_SECRETS_FOUND, AS_FLOAT, stat_secrets_found);
+       // misc
+       addstat(STAT_RESPAWN_TIME, AS_FLOAT, stat_respawn_time);
        next_pingtime = time + 5;
  
        detect_maptype();
  
+       // set up information replies for clients and server to use
        lsmaps_reply = "^7Maps available: ";
        lsnewmaps_reply = "^7Maps without a record set: ";
        for(i = 0, j = 0; i < MapInfo_count; ++i)
        {
                if(MapInfo_Get_ByID(i))
-                       if not(MapInfo_Map_flags & (MAPINFO_FLAG_HIDDEN | MAPINFO_FLAG_FORBIDDEN))
+                       if not(MapInfo_Map_flags & MapInfo_ForbiddenFlags())
                        {
                                if(mod(i, 2))
                                        col = "^2";
                                else
                                        col = "^3";
                                ++j;
                                lsmaps_reply = strcat(lsmaps_reply, col, MapInfo_Map_bspname, " ");
                                if(g_race && !stof(db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, RACE_RECORD, "time"))))
                                        lsnewmaps_reply = strcat(lsnewmaps_reply, col, MapInfo_Map_bspname, " ");
                                else if(g_cts && !stof(db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, CTS_RECORD, "time"))))
                                        lsnewmaps_reply = strcat(lsnewmaps_reply, col, MapInfo_Map_bspname, " ");
                        }
        }
        lsmaps_reply = strzone(strcat(lsmaps_reply, "\n"));
-       if (!g_race && !g_cts)
-               lsnewmaps_reply = "Need to be playing race or CTS for lsnewmaps to work.";
-       lsnewmaps_reply = strzone(strcat(lsnewmaps_reply, "\n"));
+       lsnewmaps_reply = strzone(strcat(((!g_race && !g_cts) ? "Need to be playing race or CTS for lsnewmaps to work." : lsnewmaps_reply), "\n"));
  
        maplist_reply = "^7Maps in list: ";
        n = tokenize_console(autocvar_g_maplist);
  
        for(i = 0; i < 10; ++i)
        {
-               records_reply[i] = strzone(getrecords(i));
+               s = getrecords(i);
+               if (s)
+                       records_reply[i] = strzone(s);
        }
-       if(g_cts)
-               ladder_reply = strzone(getladder());
+       ladder_reply = strzone(getladder());
  
        rankings_reply = strzone(getrankings());
  
+       // begin other init
        ClientInit_Spawn();
        RandomSeed_Spawn();
        PingPLReport_Spawn();
        // fill sv_curl_serverpackages from .serverpackage files
        if(autocvar_sv_curl_serverpackages_auto)
        {
-               fd = search_begin("*.serverpackage", TRUE, FALSE);
                s = "";
+               n = tokenize_console(cvar_string("sv_curl_serverpackages"));
+               for(i = 0; i < n; ++i)
+                       if(substring(argv(i), -14, -1) != "-serverpackage.txt")
+                       if(substring(argv(i), -14, -1) != ".serverpackage") // OLD legacy
+                               s = strcat(s, " ", argv(i));
+               fd = search_begin("*-serverpackage.txt", TRUE, FALSE);
+               if(fd >= 0)
+               {
+                       j = search_getsize(fd);
+                       for(i = 0; i < j; ++i)
+                               s = strcat(s, " ", search_getfilename(fd, i));
+                       search_end(fd);
+               }
+               fd = search_begin("*.serverpackage", TRUE, FALSE);
                if(fd >= 0)
                {
                        j = search_getsize(fd);
                cvar_set("sv_curl_serverpackages", substring(s, 1, -1));
        }
  
-       PlayerStats_Init();
+       // MOD AUTHORS: change this, and possibly remove a few of the blocks below to ignore certain changes
+       modname = "Xonotic";
+       // physics/balance/config changes that count as mod
+       if(cvar_string("g_mod_physics") != cvar_defstring("g_mod_physics"))
+               modname = cvar_string("g_mod_physics");
+       if(cvar_string("g_mod_balance") != cvar_defstring("g_mod_balance"))
+               modname = cvar_string("g_mod_balance");
+       if(cvar_string("g_mod_config") != cvar_defstring("g_mod_config"))
+               modname = cvar_string("g_mod_config");
+       // extra mutators that deserve to count as mod
+       MUTATOR_CALLHOOK(SetModname);
+       // save it for later
+       modname = strzone(modname);
+       WinningConditionHelper(); // set worldstatus
  
        world_initialized = 1;
  }
@@@ -940,22 -935,9 +936,9 @@@ void spawnfunc_light (void
        remove(self);
  }
  
- float TryFile( string pFilename )
- {
-       local float lHandle;
-       dprint("TryFile(\"", pFilename, "\")\n");
-       lHandle = fopen( pFilename, FILE_READ );
-       if( lHandle != -1 ) {
-               fclose( lHandle );
-               return TRUE;
-       } else {
-               return FALSE;
-       }
- };
  string GetGametype()
  {
-       return GametypeNameFromType(game);
+       return MapInfo_Type_ToString(MapInfo_LoadedGametype);
  }
  
  string getmapname_stored;
@@@ -967,7 -949,7 +950,7 @@@ string GetMapname(
  float Map_Count, Map_Current;
  string Map_Current_Name;
  
- // NOTE: this now expects the map list to be already tokenize()d and the count in Map_Count
+ // NOTE: this now expects the map list to be already tokenized and the count in Map_Count
  float GetMaplistPosition()
  {
        float pos, idx;
@@@ -996,14 -978,12 +979,12 @@@ float MapHasRightSize(string map
        if(autocvar_g_maplist_check_waypoints)
        {
                dprint("checkwp "); dprint(map);
-               fh = fopen(strcat("maps/", map, ".waypoints"), FILE_READ);
-               if(fh < 0)
+               if(!fexists(strcat("maps/", map, ".waypoints")))
                {
                        dprint(": no waypoints\n");
                        return FALSE;
                }
                dprint(": has waypoints\n");
-               fclose(fh);
        }
  
        // open map size restriction file
@@@ -1105,16 -1085,9 +1086,9 @@@ void Map_Goto_SetFloat(float position
        Map_Goto_SetStr(argv(position));
  }
  
- void GameResetCfg()
- {
-       // settings persist, except...
-       localcmd("\nsettemp_restore\n");
- };
- void Map_Goto()
+ void Map_Goto(float reinit)
  {
-       GameResetCfg();
-       MapInfo_LoadMap(getmapname_stored);
+       MapInfo_LoadMap(getmapname_stored, reinit);
  }
  
  // return codes of map selectors:
@@@ -1203,7 -1176,7 +1177,7 @@@ void Maplist_Init(
        if(Map_Count == 0)
        {
                bprint( "Maplist is empty!  Resetting it to default map list.\n" );
-               cvar_set("g_maplist", MapInfo_ListAllowedMaps(MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags()));
+               cvar_set("g_maplist", MapInfo_ListAllAllowedMaps(MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags()));
                if(autocvar_g_maplist_shuffle)
                        ShuffleMaplist();
                localcmd("\nmenu_cmd sync\n");
@@@ -1248,9 -1221,9 +1222,9 @@@ string GetNextMap(
        }
  
        return "";
- };
+ }
  
- float DoNextMapOverride()
+ float DoNextMapOverride(float reinit)
  {
        if(autocvar_g_campaign)
        {
                alreadychangedlevel = TRUE;
                return TRUE;
        }
-       if (autocvar_samelevel) // if samelevel is set, stay on same level
+       if (!reinit && autocvar_samelevel) // if samelevel is set, stay on same level
        {
-               // this does not work because it tries to exec maps/nexdm01.mapcfg (which doesn't exist, it should be trying maps/dm_nexdm01.mapcfg for example)
-               //localcmd(strcat("exec \"maps/", mapname, ".mapcfg\"\n"));
-               // so instead just restart the current map using the restart command (DOES NOT WORK PROPERLY WITH exit_cfg STUFF)
                localcmd("restart\n");
-               //changelevel (mapname);
                alreadychangedlevel = TRUE;
                return TRUE;
        }
                if(MapInfo_CheckMap(autocvar_nextmap))
                {
                        Map_Goto_SetStr(autocvar_nextmap);
-                       Map_Goto();
+                       Map_Goto(reinit);
                        alreadychangedlevel = TRUE;
                        return TRUE;
                }
-       if(autocvar_lastlevel)
+       if(!reinit && autocvar_lastlevel)
        {
-               GameResetCfg();
-               localcmd("set lastlevel 0\ntogglemenu\n");
+               cvar_settemp_restore();
+               localcmd("set lastlevel 0\ntogglemenu 1\n");
                alreadychangedlevel = TRUE;
                return TRUE;
        }
        return FALSE;
- };
+ }
  
- void GotoNextMap()
+ void GotoNextMap(float reinit)
  {
-       //local string nextmap;
-       //local float n, nummaps;
-       //local string s;
+       //string nextmap;
+       //float n, nummaps;
+       //string s;
        if (alreadychangedlevel)
                return;
        alreadychangedlevel = TRUE;
                        if(allowReset)
                        {
                                bprint( "Maplist contains no single playable map!  Resetting it to default map list.\n" );
-                               cvar_set("g_maplist", MapInfo_ListAllowedMaps(MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags()));
+                               cvar_set("g_maplist", MapInfo_ListAllAllowedMaps(MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags()));
                                if(autocvar_g_maplist_shuffle)
                                        ShuffleMaplist();
                                localcmd("\nmenu_cmd sync\n");
                                error("Everything is broken - not even the default map list works. Please report this to the developers.");
                        }
                }
-               Map_Goto();
+               Map_Goto(reinit);
        }
- };
+ }
  
  
  /*
@@@ -1353,13 -1322,14 +1323,14 @@@ void IntermissionThink(
  {
        FixIntermissionClient(self);
  
-       if(autocvar_sv_autoscreenshot)
-       if(self.autoscreenshot > 0)
-       if(time > self.autoscreenshot)
+       float server_screenshot = (autocvar_sv_autoscreenshot && self.cvar_cl_autoscreenshot);
+       float client_screenshot = (self.cvar_cl_autoscreenshot == 2);
+       if( (server_screenshot || client_screenshot)
+               && ((self.autoscreenshot > 0) && (time > self.autoscreenshot)) )
        {
                self.autoscreenshot = -1;
-               if(clienttype(self) == CLIENTTYPE_REAL)
-                       stuffcmd(self, "\nscreenshot\necho \"^5A screenshot has been taken at request of the server.\"\n");
+               if(IS_REAL_CLIENT(self)) { stuffcmd(self, sprintf("\nscreenshot screenshots/autoscreenshot/%s-%s.jpg; echo \"^5A screenshot has been taken at request of the server.\"\n", GetMapname(), strftime(FALSE, "%s"))); }
                return;
        }
  
                return;
  
        if(!mapvote_initialized)
-               if (time < intermission_exittime + 10 && !self.BUTTON_ATCK && !self.BUTTON_JUMP && !self.BUTTON_ATCK2 && !self.BUTTON_HOOK && !self.BUTTON_USE)
+               if (time < intermission_exittime + 10 && !(self.BUTTON_ATCK || self.BUTTON_JUMP || self.BUTTON_ATCK2 || self.BUTTON_HOOK || self.BUTTON_USE))
                        return;
  
        MapVote_Start();
- };
+ }
  
  /*
  ============
@@@ -1418,7 -1388,7 +1389,7 @@@ entity FindIntermission(
  
        //objerror ("FindIntermission: no spot");
        return world;
- };
+ }
  */
  
  /*
@@@ -1437,7 -1407,6 +1408,6 @@@ void DumpStats(float final
        float to_eventlog;
        float to_file;
        float i;
-       entity e;
  
        to_console = autocvar_sv_logscores_console;
        to_eventlog = autocvar_sv_eventlog;
                print(s, "\n");
        if(to_eventlog)
                GameLogEcho(s);
+       file = -1;
        if(to_file)
        {
                file = fopen(autocvar_sv_logscores_filename, FILE_APPEND);
  
        FOR_EACH_CLIENT(other)
        {
-               if ((clienttype(other) == CLIENTTYPE_REAL) || (clienttype(other) == CLIENTTYPE_BOT && autocvar_sv_logscores_bots))
+               if ((IS_REAL_CLIENT(other)) || (IS_BOT_CLIENT(other) && autocvar_sv_logscores_bots))
                {
                        s = strcat(":player:see-labels:", GetPlayerScoreString(other, 0), ":");
                        s = strcat(s, ftos(rint(time - other.jointime)), ":");
-                       if(other.classname == "player" || g_arena || g_ca || g_lms)
+                       if(IS_PLAYER(other) || g_arena || other.caplayer == 1 || g_lms)
                                s = strcat(s, ftos(other.team), ":");
                        else
                                s = strcat(s, "spectator:");
                }
        }
  
-       if(teams_matter)
+       if(teamplay)
        {
                s = strcat(":labels:teamscores:", GetTeamScoreString(0, 0));
                if(to_console)
@@@ -1539,8 -1510,6 +1511,6 @@@ void FixIntermissionClient(entity e
        string s;
        if(!e.autoscreenshot) // initial call
        {
-               e.angles = e.v_angle;
-               e.angles_x = -e.angles_x;
                e.autoscreenshot = time + 0.8;  // used for autoscreenshot
                e.health = -2342;
                // first intermission phase; voting phase has positive health (used to decide whether to send SVC_FINALE or not)
                        if (e.weaponentity.weaponentity)
                                e.weaponentity.weaponentity.effects = EF_NODRAW;
                }
-               if(clienttype(e) == CLIENTTYPE_REAL)
+               if(IS_REAL_CLIENT(e))
                {
                        stuffcmd(e, "\nscr_printspeed 1000000\n");
                        s = autocvar_sv_intermission_cdtrack;
                        WriteByte(MSG_ONE, SVC_INTERMISSION);
                }
        }
-       //e.velocity = '0 0 0';
-       //e.fixangle = TRUE;
-       // TODO halt weapon animation
  }
  
  /*
  go to the next level for deathmatch
  only called if a time or frag limit has expired
@@@ -1606,6 -1569,9 +1570,9 @@@ void NextLevel(
        FOR_EACH_CLIENT(e)
                PlayerStats_AddGlobalInfo(e);
        PlayerStats_Shutdown();
+       WeaponStats_Shutdown();
+       
+       Kill_Notification(NOTIF_ALL, world, MSG_CENTER, 0); // kill all centerprints now
  
        if(autocvar_sv_eventlog)
                GameLogEcho(":gameover");
        if(autocvar_g_campaign)
                CampaignPreIntermission();
  
+       MUTATOR_CALLHOOK(MatchEnd);
        localcmd("\nsv_hook_gameend\n");
  }
  
@@@ -1641,7 -1609,7 +1610,7 @@@ void CheckRules_Player(
  
        // fixme: don't check players; instead check spawnfunc_dom_team and spawnfunc_ctf_team entities
        //   (div0: and that in CheckRules_World please)
- };
+ }
  
  float checkrules_equality;
  float checkrules_suddendeathwarning;
@@@ -1659,7 -1627,7 +1628,7 @@@ float InitiateSuddenDeath(
        // - for this timelimit_overtime needs to be >0 of course
        // - also check the winning condition calculated in the previous frame and only add normal overtime
        //   again, if at the point at which timelimit would be extended again, still no winner was found
-       if ((checkrules_overtimesadded >= 0) && (checkrules_overtimesadded < autocvar_timelimit_overtimes) && autocvar_timelimit_overtime && !(g_race && !g_race_qualifying))
+       if (!autocvar_g_campaign && (checkrules_overtimesadded >= 0) && (checkrules_overtimesadded < autocvar_timelimit_overtimes) && autocvar_timelimit_overtime && !(g_race && !g_race_qualifying))
        {
                return 1; // need to call InitiateOvertime later
        }
        {
                if(!checkrules_suddendeathend)
                {
-                       checkrules_suddendeathend = time + 60 * autocvar_timelimit_suddendeath;
+                       if(autocvar_g_campaign)
+                               checkrules_suddendeathend = time; // no suddendeath in campaign
+                       else
+                               checkrules_suddendeathend = time + 60 * autocvar_timelimit_suddendeath;
                        if(g_race && !g_race_qualifying)
                                race_StartCompleting();
                }
@@@ -1683,20 -1654,8 +1655,8 @@@ void InitiateOvertime() // ONLY call th
        tl = autocvar_timelimit;
        tl += autocvar_timelimit_overtime;
        cvar_set("timelimit", ftos(tl));
-       string minutesPlural;
-       if (autocvar_timelimit_overtime == 1)
-               minutesPlural = " ^3minute";
-       else
-               minutesPlural = " ^3minutes";
-       bcenterprint(
-               strcat(
-                       "^3Now playing ^1OVERTIME^3!\n\n^3Added ^1",
-                       ftos(autocvar_timelimit_overtime),
-                       minutesPlural,
-                       " to the game!"
-               )
-       );
+       Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_OVERTIME_TIME, autocvar_timelimit_overtime * 60);
  }
  
  float GetWinningCode(float fraglimitreached, float equality)
@@@ -1750,7 -1709,7 +1710,7 @@@ void ClearWinners(void
  float WinningCondition_Onslaught()
  {
        entity head;
-       local float t1, t2, t3, t4;
+       float t1, t2, t3, t4;
  
        WinningConditionHelper(); // set worldstatus
  
        {
                if (head.health > 0)
                {
-                       if (head.team == COLOR_TEAM1) t1 = 1;
-                       if (head.team == COLOR_TEAM2) t2 = 1;
-                       if (head.team == COLOR_TEAM3) t3 = 1;
-                       if (head.team == COLOR_TEAM4) t4 = 1;
+                       if (head.team == NUM_TEAM_1) t1 = 1;
+                       if (head.team == NUM_TEAM_2) t2 = 1;
+                       if (head.team == NUM_TEAM_3) t3 = 1;
+                       if (head.team == NUM_TEAM_4) t4 = 1;
                }
                head = find(head, classname, "onslaught_generator");
        }
        {
                // game over, only one team remains (or none)
                ClearWinners();
-               if (t1) SetWinners(team, COLOR_TEAM1);
-               if (t2) SetWinners(team, COLOR_TEAM2);
-               if (t3) SetWinners(team, COLOR_TEAM3);
-               if (t4) SetWinners(team, COLOR_TEAM4);
+               if (t1) SetWinners(team, NUM_TEAM_1);
+               if (t2) SetWinners(team, NUM_TEAM_2);
+               if (t3) SetWinners(team, NUM_TEAM_3);
+               if (t4) SetWinners(team, NUM_TEAM_4);
                dprint("Have a winner, ending game.\n");
                return WINNING_YES;
        }
        return WINNING_NO;
  }
  
- float LMS_NewPlayerLives()
- {
-       float fl;
-       fl = autocvar_fraglimit;
-       if(fl == 0)
-               fl = 999;
-       // first player has left the game for dying too much? Nobody else can get in.
-       if(lms_lowest_lives < 1)
-               return 0;
-       if(!autocvar_g_lms_join_anytime)
-               if(lms_lowest_lives < fl - autocvar_g_lms_last_join)
-                       return 0;
-       return bound(1, lms_lowest_lives, fl);
- }
  // Assault winning condition: If the attackers triggered a round end (by fulfilling all objectives)
  // they win. Otherwise the defending team wins once the timelimit passes.
  void assault_new_round();
  float WinningCondition_Assault()
  {
-       local float status;
+       float status;
  
        WinningConditionHelper(); // set worldstatus
  
        status = WINNING_NO;
        // as the timelimit has not yet passed just assume the defending team will win
-       if(assault_attacker_team == COLOR_TEAM1)
+       if(assault_attacker_team == NUM_TEAM_1)
        {
-               SetWinners(team, COLOR_TEAM2);
+               SetWinners(team, NUM_TEAM_2);
        }
        else
        {
-               SetWinners(team, COLOR_TEAM1);
+               SetWinners(team, NUM_TEAM_1);
        }
  
-       local entity ent;
+       entity ent;
        ent = find(world, classname, "target_assault_roundend");
        if(ent)
        {
                        }
                        else
                        {
-                               local entity oldself;
+                               entity oldself;
                                oldself = self;
                                self = ent;
                                assault_new_round();
@@@ -1946,12 -1887,12 +1888,12 @@@ float WinningCondition_Scores(float lim
        // TODO make everything use THIS winning condition (except LMS)
        WinningConditionHelper();
  
-       if(teams_matter)
+       if(teamplay)
        {
-               team1_score = TeamScore_GetCompareValue(COLOR_TEAM1);
-               team2_score = TeamScore_GetCompareValue(COLOR_TEAM2);
-               team3_score = TeamScore_GetCompareValue(COLOR_TEAM3);
-               team4_score = TeamScore_GetCompareValue(COLOR_TEAM4);
+               team1_score = TeamScore_GetCompareValue(NUM_TEAM_1);
+               team2_score = TeamScore_GetCompareValue(NUM_TEAM_2);
+               team3_score = TeamScore_GetCompareValue(NUM_TEAM_3);
+               team4_score = TeamScore_GetCompareValue(NUM_TEAM_4);
        }
  
        ClearWinners();
  
                        if (limit)
                        if (leaderfrags == limit - 1)
-                               Announce("1fragleft");
+                               Send_Notification(NOTIF_ALL, world, MSG_ANNCE, ANNCE_REMAINING_FRAG_1);
                        else if (leaderfrags == limit - 2)
-                               Announce("2fragsleft");
+                               Send_Notification(NOTIF_ALL, world, MSG_ANNCE, ANNCE_REMAINING_FRAG_2);
                        else if (leaderfrags == limit - 3)
-                               Announce("3fragsleft");
+                               Send_Notification(NOTIF_ALL, world, MSG_ANNCE, ANNCE_REMAINING_FRAG_3);
                }
        }
  
                        limitreached = (limitreached || leadlimitreached);
        }
  
+       if(limit)
+               game_completion_ratio = max(game_completion_ratio, bound(0, WinningConditionHelper_topscore / limit, 1));
        return GetWinningCode(
                WinningConditionHelper_topscore && limitreached,
                WinningConditionHelper_equality
@@@ -2031,10 -1975,8 +1976,8 @@@ float WinningCondition_Race(float fragl
                return WINNING_STARTSUDDENDEATHOVERTIME;
        else
                return WINNING_NEVER;
-       return wc;
  }
  
- void ReadyRestart();
  float WinningCondition_QualifyingThenRace(float limit)
  {
        float wc;
@@@ -2056,6 -1998,9 +1999,9 @@@ float WinningCondition_RanOutOfSpawns(
        if(have_team_spawns <= 0)
                return WINNING_NO;
  
+       if(autocvar_g_spawn_useallspawns <= 0)
+               return WINNING_NO;
        if(!some_spawn_has_been_used)
                return WINNING_NO;
  
  
        FOR_EACH_PLAYER(head) if(head.deadflag == DEAD_NO)
        {
-               if(head.team == COLOR_TEAM1)
+               if(head.team == NUM_TEAM_1)
                        team1_score = 1;
-               else if(head.team == COLOR_TEAM2)
+               else if(head.team == NUM_TEAM_2)
                        team2_score = 1;
-               else if(head.team == COLOR_TEAM3)
+               else if(head.team == NUM_TEAM_3)
                        team3_score = 1;
-               else if(head.team == COLOR_TEAM4)
+               else if(head.team == NUM_TEAM_4)
                        team4_score = 1;
        }
  
        for(head = world; (head = find(head, classname, "info_player_deathmatch")) != world; )
        {
-               if(head.team == COLOR_TEAM1)
+               if(head.team == NUM_TEAM_1)
                        team1_score = 1;
-               else if(head.team == COLOR_TEAM2)
+               else if(head.team == NUM_TEAM_2)
                        team2_score = 1;
-               else if(head.team == COLOR_TEAM3)
+               else if(head.team == NUM_TEAM_3)
                        team3_score = 1;
-               else if(head.team == COLOR_TEAM4)
+               else if(head.team == NUM_TEAM_4)
                        team4_score = 1;
        }
  
        else if(team1_score + team2_score + team3_score + team4_score == 1)
        {
                float t, i;
-               if(team1_score) t = COLOR_TEAM1;
-               if(team2_score) t = COLOR_TEAM2;
-               if(team3_score) t = COLOR_TEAM3;
-               if(team4_score) t = COLOR_TEAM4;
+               if(team1_score)
+                       t = NUM_TEAM_1;
+               else if(team2_score)
+                       t = NUM_TEAM_2;
+               else if(team3_score)
+                       t = NUM_TEAM_3;
+               else // if(team4_score)
+                       t = NUM_TEAM_4;
                CheckAllowedTeams(world);
                for(i = 0; i < MAX_TEAMSCORE; ++i)
                {
-                       if(t != COLOR_TEAM1) if(c1 >= 0) TeamScore_AddToTeam(COLOR_TEAM1, i, -1000);
-                       if(t != COLOR_TEAM2) if(c2 >= 0) TeamScore_AddToTeam(COLOR_TEAM2, i, -1000);
-                       if(t != COLOR_TEAM3) if(c3 >= 0) TeamScore_AddToTeam(COLOR_TEAM3, i, -1000);
-                       if(t != COLOR_TEAM4) if(c4 >= 0) TeamScore_AddToTeam(COLOR_TEAM4, i, -1000);
+                       if(t != NUM_TEAM_1) if(c1 >= 0) TeamScore_AddToTeam(NUM_TEAM_1, i, -1000);
+                       if(t != NUM_TEAM_2) if(c2 >= 0) TeamScore_AddToTeam(NUM_TEAM_2, i, -1000);
+                       if(t != NUM_TEAM_3) if(c3 >= 0) TeamScore_AddToTeam(NUM_TEAM_3, i, -1000);
+                       if(t != NUM_TEAM_4) if(c4 >= 0) TeamScore_AddToTeam(NUM_TEAM_4, i, -1000);
                }
  
                AddWinners(team, t);
@@@ -2121,6 -2070,7 +2071,7 @@@ CheckRules_Worl
  Exit deathmatch games upon conditions
  ============
  */
+ void ReadyRestart();
  void CheckRules_World()
  {
        float timelimit;
                leadlimit = 0; // no leadlimit for now
        }
  
-       if(g_onslaught)
-               timelimit = 0; // ONS has its own overtime rule
        if(timelimit > 0)
        {
                timelimit += game_starttime;
                return;
        }
  
+       if(g_onslaught)
+               timelimit = 0; // ONS has its own overtime rule
        float wantovertime;
        wantovertime = 0;
  
+       if(timelimit > game_starttime)
+               game_completion_ratio = (time - game_starttime) / (timelimit - game_starttime);
+       else
+               game_completion_ratio = 0;
        if(checkrules_suddendeathend)
        {
                if(!checkrules_suddendeathwarning)
                {
                        checkrules_suddendeathwarning = TRUE;
                        if(g_race && !g_race_qualifying)
-                               bcenterprint("^3Everyone, finish your lap! The race is over!");
+                               Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_RACE_FINISHLAP);
                        else
-                               bcenterprint("^3Now playing ^1OVERTIME^3!\n\n^3Keep fragging until we have a ^1winner^3!");
+                               Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_OVERTIME_FRAG);
                }
        }
        else
                //print("WINNING\n");
                NextLevel();
        }
- };
+ }
  
  float mapvote_nextthink;
  float mapvote_initialized;
@@@ -2316,9 -2271,8 +2272,8 @@@ string mapvote_maps_pakfile[MAPVOTE_COU
  float mapvote_maps_suggested[MAPVOTE_COUNT];
  string mapvote_suggestions[MAPVOTE_COUNT];
  float mapvote_suggestion_ptr;
- float mapvote_maxlen;
  float mapvote_voters;
- float mapvote_votes[MAPVOTE_COUNT];
+ float mapvote_selections[MAPVOTE_COUNT];
  float mapvote_run;
  float mapvote_detail;
  float mapvote_abstain;
@@@ -2340,7 -2294,7 +2295,7 @@@ string MapVote_Suggest(string m
        if(mapvote_initialized)
                return "Can't suggest - voting is already in progress!";
        m = MapInfo_FixName(m);
-       if(!m)
+       if not(m)
                return "The map you suggested is not available on this server.";
        if(!autocvar_g_maplist_votable_suggestions_override_mostrecent)
                if(Map_IsRecent(m))
@@@ -2378,11 -2332,14 +2333,14 @@@ void MapVote_AddVotable(string nextMap
        for(j = 0; j < mapvote_count; ++j)
                if(mapvote_maps[j] == nextMap)
                        return;
-       if(strlen(nextMap) > mapvote_maxlen)
-               mapvote_maxlen = strlen(nextMap);
+       // suggestions might be no longer valid/allowed after gametype switch!
+       if(isSuggestion)
+               if(!MapInfo_CheckMap(nextMap))
+                       return;
        mapvote_maps[mapvote_count] = strzone(nextMap);
        mapvote_maps_suggested[mapvote_count] = isSuggestion;
  
+       pakfile = string_null;
        for(i = 0; i < mapvote_screenshot_dirs_count; ++i)
        {
                mapfile = strcat(mapvote_screenshot_dirs[i], "/", mapvote_maps[i]);
@@@ -2441,7 -2398,7 +2399,7 @@@ void MapVote_Init(
        if(mapvote_count == 0)
        {
                bprint( "Maplist contains no single playable map!  Resetting it to default map list.\n" );
-               cvar_set("g_maplist", MapInfo_ListAllowedMaps(MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags()));
+               cvar_set("g_maplist", MapInfo_ListAllAllowedMaps(MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags()));
                if(autocvar_g_maplist_shuffle)
                        ShuffleMaplist();
                localcmd("\nmenu_cmd sync\n");
@@@ -2473,20 -2430,6 +2431,6 @@@ void MapVote_SendPicture(float id
        WritePicture(MSG_ONE, strcat(mapvote_screenshot_dirs[mapvote_maps_screenshot_dir[id]], "/", mapvote_maps[id]), 3072);
  }
  
- float GameCommand_MapVote(string cmd)
- {
-       if(!intermission_running)
-               return FALSE;
-       if(cmd == "mv_getpic")
-       {
-               MapVote_SendPicture(stof(argv(1)));
-               return TRUE;
-       }
-       return FALSE;
- }
  float MapVote_GetMapMask()
  {
        float mask, i, power;
@@@ -2554,7 -2497,7 +2498,7 @@@ float MapVote_SendEntity(entity to, flo
                if(mapvote_detail)
                        for(i = 0; i < mapvote_count; ++i)
                                if(mapvote_maps[i] != "")
-                                       WriteByte(MSG_ENTITY, mapvote_votes[i]);
+                                       WriteByte(MSG_ENTITY, mapvote_selections[i]);
  
                WriteByte(MSG_ENTITY, to.mapvote);
        }
@@@ -2586,16 -2529,16 +2530,16 @@@ float MapVote_Finished(float mappos
        if(autocvar_sv_eventlog)
        {
                result = strcat(":vote:finished:", mapvote_maps[mappos]);
-               result = strcat(result, ":", ftos(mapvote_votes[mappos]), "::");
+               result = strcat(result, ":", ftos(mapvote_selections[mappos]), "::");
                didntvote = mapvote_voters;
                for(i = 0; i < mapvote_count; ++i)
                        if(mapvote_maps[i] != "")
                        {
-                               didntvote -= mapvote_votes[i];
+                               didntvote -= mapvote_selections[i];
                                if(i != mappos)
                                {
                                        result = strcat(result, ":", mapvote_maps[i]);
-                                       result = strcat(result, ":", ftos(mapvote_votes[i]));
+                                       result = strcat(result, ":", ftos(mapvote_selections[i]));
                                }
                        }
                result = strcat(result, ":didn't vote:", ftos(didntvote));
                FixClientCvars(other);
  
        Map_Goto_SetStr(mapvote_maps[mappos]);
-       Map_Goto();
+       Map_Goto(0);
        alreadychangedlevel = TRUE;
        return TRUE;
  }
@@@ -2620,7 -2563,7 +2564,7 @@@ void MapVote_CheckRules_1(
        for(i = 0; i < mapvote_count; ++i) if(mapvote_maps[i] != "")
        {
                //dprint("Map ", ftos(i), ": "); dprint(mapvote_maps[i], "\n");
-               mapvote_votes[i] = 0;
+               mapvote_selections[i] = 0;
        }
  
        mapvote_voters = 0;
                {
                        i = other.mapvote - 1;
                        //dprint("Player ", other.netname, " vote = ", ftos(other.mapvote - 1), "\n");
-                       mapvote_votes[i] = mapvote_votes[i] + 1;
+                       mapvote_selections[i] = mapvote_selections[i] + 1;
                }
        }
  }
@@@ -2649,11 -2592,11 +2593,11 @@@ float MapVote_CheckRules_2(
  
        mapvote_voters_real = mapvote_voters;
        if(mapvote_abstain)
-               mapvote_voters_real -= mapvote_votes[mapvote_count - 1];
+               mapvote_voters_real -= mapvote_selections[mapvote_count - 1];
  
        RandomSelection_Init();
        for(i = 0; i < mapvote_count_real; ++i) if(mapvote_maps[i] != "")
-               RandomSelection_Add(world, i, string_null, 1, mapvote_votes[i]);
+               RandomSelection_Add(world, i, string_null, 1, mapvote_selections[i]);
        firstPlace = RandomSelection_chosen_float;
        firstPlaceVotes = RandomSelection_best_priority;
        //dprint("First place: ", ftos(firstPlace), "\n");
        RandomSelection_Init();
        for(i = 0; i < mapvote_count_real; ++i) if(mapvote_maps[i] != "")
                if(i != firstPlace)
-                       RandomSelection_Add(world, i, string_null, 1, mapvote_votes[i]);
+                       RandomSelection_Add(world, i, string_null, 1, mapvote_selections[i]);
        secondPlace = RandomSelection_chosen_float;
        secondPlaceVotes = RandomSelection_best_priority;
        //dprint("Second place: ", ftos(secondPlace), "\n");
                        for(i = 0; i < mapvote_count; ++i)
                                if(mapvote_maps[i] != "")
                                {
-                                       didntvote -= mapvote_votes[i];
+                                       didntvote -= mapvote_selections[i];
                                        if(i != firstPlace)
                                                if(i != secondPlace)
                                                {
                                                        result = strcat(result, ":", mapvote_maps[i]);
-                                                       result = strcat(result, ":", ftos(mapvote_votes[i]));
+                                                       result = strcat(result, ":", ftos(mapvote_selections[i]));
                                                        if(i < mapvote_count_real)
                                                        {
                                                                strunzone(mapvote_maps[i]);
@@@ -2729,7 -2672,7 +2673,7 @@@ void MapVote_Tick(
                {
                        other.health = 2342;
                        other.impulse = 0;
-                       if(clienttype(other) == CLIENTTYPE_REAL)
+                       if(IS_REAL_CLIENT(other))
                        {
                                msg_entity = other;
                                WriteByte(MSG_ONE, SVC_FINALE);
@@@ -2805,18 -2748,18 +2749,18 @@@ void MapVote_Think(
                }
  
                mapvote_initialized = TRUE;
-               if(DoNextMapOverride())
+               if(DoNextMapOverride(0))
                        return;
                if(!autocvar_g_maplist_votable || player_count <= 0)
                {
-                       GotoNextMap();
+                       GotoNextMap(0);
                        return;
                }
                MapVote_Init();
        }
  
        MapVote_Tick();
- };
+ }
  
  string GotoMap(string m)
  {
        cvar_set("timelimit", "-1");
        if(mapvote_initialized || alreadychangedlevel)
        {
-               if(DoNextMapOverride())
+               if(DoNextMapOverride(0))
                        return "Map switch initiated.";
                else
                        return "Hm... no. For some reason I like THIS map more.";
@@@ -2841,7 -2784,7 +2785,7 @@@ void EndFrame(
        float altime;
        FOR_EACH_REALCLIENT(self)
        {
-               if(self.classname == "spectator")
+               if(IS_SPEC(self))
                {
                        if(self.enemy.typehitsound)
                                self.typehit_time = time;
@@@ -2902,11 -2845,12 +2846,12 @@@ float RedirectionThink(
        clients_found = 0;
        FOR_EACH_REALCLIENT(self)
        {
+               // TODO add timer
                print("Redirecting: sending connect command to ", self.netname, "\n");
                if(redirection_target == "self")
-                       stuffcmd(self, "\ndisconnect; reconnect\n");
+                       stuffcmd(self, "\ndisconnect; defer ", ftos(autocvar_quit_and_redirect_timer), " reconnect\n");
                else
-                       stuffcmd(self, strcat("\ndisconnect; connect ", redirection_target, "\n"));
+                       stuffcmd(self, strcat("\ndisconnect; defer ", ftos(autocvar_quit_and_redirect_timer), " \"connect ", redirection_target, "\"\n"));
                ++clients_found;
        }
  
@@@ -2925,7 -2869,7 +2870,7 @@@ void RestoreGame(
        // some things then break, so let's work around them...
  
        // Progs DB (capture records)
-       ServerProgsDB = db_load("server.db");
+       ServerProgsDB = db_load(strcat("server.db", autocvar_sessionid));
  
        // Mapinfo
        MapInfo_Shutdown();
        TargetMusic_RestoreGame();
  }
  
- void SV_Shutdown()
+ void Shutdown()
  {
        entity e;
  
-       if(gameover > 1) // shutting down already?
-               return;
-       gameover = 2; // 2 = server shutting down
+       gameover = 2;
  
        if(world_initialized > 0)
        {
                if(!cheatcount_total)
                {
                        if(autocvar_sv_db_saveasdump)
-                               db_dump(ServerProgsDB, "server.db");
+                               db_dump(ServerProgsDB, strcat("server.db", autocvar_sessionid));
                        else
-                               db_save(ServerProgsDB, "server.db");
+                               db_save(ServerProgsDB, strcat("server.db", autocvar_sessionid));
                }
                if(autocvar_developer)
                {
diff --combined qcsrc/server/progs.src
index 13a4c64eb70c9eeaee6d4c433fc042635798a2de,df5623f0535a42bd3c5b1a4b04baa0b516aa57b8..5ebd833f8f1d8d311756762ddc60b4064aedd63f
@@@ -1,12 -1,10 +1,10 @@@
  ../../progs.dat // output filename
  
  ../common/util-pre.qh
- sys.qh
- pre-builtins.qh
- builtins.qh
- extensions.qh
- post-builtins.qh
+ sys-pre.qh
+ ../dpdefs/progsdefs.qc
+ ../dpdefs/dpextensions.qc
+ sys-post.qh
  
  ../warpzonelib/anglestransform.qh
  ../warpzonelib/mathlib.qh
  ../warpzonelib/server.qh
  
  ../common/constants.qh
+ ../common/teams.qh
  ../common/util.qh
+ ../common/counting.qh
  ../common/items.qh
+ ../common/explosion_equation.qh
+ ../common/urllib.qh
+ ../common/command/markup.qh
+ ../common/command/rpn.qh
+ ../common/command/generic.qh
+ ../common/command/shared_defs.qh
+ ../common/net_notice.qh
+ ../common/animdecide.qh
  
  autocvars.qh
  constants.qh
  defs.qh               // Should rename this, it has fields and globals
  
+ ../common/notifications.qh // must be after autocvars
+ ../common/deathtypes.qh // must be after notifications
  mutators/base.qh
  mutators/mutators.qh
+ mutators/gamemode_assault.qh
+ mutators/gamemode_arena.qh
+ mutators/gamemode_ca.qh
+ mutators/gamemode_ctf.qh
+ mutators/gamemode_domination.qh
  mutators/gamemode_keyhunt.qh // TODO fix this
+ mutators/gamemode_keepaway.qh
+ mutators/gamemode_nexball.qh 
+ mutators/gamemode_lms.qh
  mutators/mutator_dodging.qh
  
  //// tZork Turrets ////
  tturrets/include/turrets_early.qh
+ vehicles/vehicles_def.qh
  
  campaign.qh
  ../common/campaign_common.qh
  ../common/mapinfo.qh
- ../common/util.qc
+ command/common.qh
+ command/banning.qh
+ command/radarmap.qh
+ command/vote.qh
+ command/getreplies.qh
+ command/cmd.qh
+ command/sv_cmd.qh
  
  accuracy.qh
  csqcprojectile.qh
+ ../common/csqcmodel_settings.qh
+ ../csqcmodellib/common.qh
+ ../csqcmodellib/sv_model.qh
  csqceffects.qc
  
  anticheat.qh
@@@ -47,21 -77,26 +77,27 @@@ portals.q
  
  g_hook.qh
  w_electro.qh
 +w_lightning.qh
  w_laser.qh
  
  scores.qh
  
+ spawnpoints.qh
  ipban.qh
  
  race.qh
  
  antilag.qh
  
- vote.qh
  playerdemo.qh
  
+ round_handler.qh
+ // singleplayer stuff
+ item_key.qh
+ secret.qh
  scores_rules.qc
  
  miscfunctions.qc
@@@ -74,8 -109,7 +110,7 @@@ g_subs.q
  
  g_tetris.qc
  
- runematch.qc
- arena.qc
+ //runematch.qc
  
  g_violence.qc
  g_damage.qc
@@@ -96,11 -130,14 +131,14 @@@ t_jumppads.q
  t_teleporters.qc
  
  sv_main.qc
- sv_stats.qc
  
  g_triggers.qc
  g_models.qc
  
+ // singleplayer stuff
+ item_key.qc
+ secret.qc
  cl_weaponsystem.qc
  w_common.qc
  
@@@ -117,34 -154,38 +155,38 @@@ cl_client.q
  t_plats.qc
  antilag.qc
  
- ctf.qc
- domination.qc
- mode_onslaught.qc
- nexball.qc
//ctf.qc
//domination.qc
//mode_onslaught.qc
//nexball.qc
  g_hook.qc
  
  t_swamp.qc
  
- clientcommands.qc
- vote.qc
  campaign.qc
  ../common/campaign_file.qc
  ../common/campaign_setup.qc
+ ../common/urllib.qc
+ ../common/command/markup.qc
+ ../common/command/rpn.qc
+ ../common/command/generic.qc
+ ../common/net_notice.qc
  
- ../common/gamecommand.qc
- gamecommand.qc
+ command/common.qc
+ command/banning.qc
+ command/radarmap.qc
+ command/vote.qc
+ command/getreplies.qc
+ command/cmd.qc
+ command/sv_cmd.qc
  
- assault.qc
//assault.qc
  
  ipban.qc
  
  ../common/mapinfo.qc
  
  t_quake3.qc
  t_halflife.qc
  t_quake.qc
@@@ -158,6 -199,8 +200,8 @@@ vehicles/vehicles.q
  
  scores.qc
  
+ spawnpoints.qc
  portals.qc
  
  target_spawn.qc
@@@ -166,12 -209,9 +210,9 @@@ target_music.q
  
  ../common/items.qc
  
- monsters/defs.qc
- monsters/fight.qc
- monsters/ai.qc
- monsters/m_monsters.qc
- monsters/monster_zombie.qc
  accuracy.qc
+ ../csqcmodellib/sv_model.qc
  csqcprojectile.qc
  
  playerdemo.qc
@@@ -180,17 -220,43 +221,43 @@@ anticheat.q
  cheats.qc
  playerstats.qc
  
+ round_handler.qc
+ ../common/explosion_equation.qc
  mutators/base.qc
- mutators/gamemode_keyhunt.qc
+ mutators/gamemode_assault.qc
+ mutators/gamemode_arena.qc
+ mutators/gamemode_ca.qc
+ mutators/gamemode_ctf.qc
+ mutators/gamemode_domination.qc
  mutators/gamemode_freezetag.qc
+ mutators/gamemode_keyhunt.qc
  mutators/gamemode_keepaway.qc
+ mutators/gamemode_nexball.qc
+ mutators/gamemode_onslaught.qc
+ mutators/gamemode_lms.qc
+ mutators/mutator_invincibleproj.qc
+ mutators/mutator_new_toys.qc
  mutators/mutator_nix.qc
  mutators/mutator_dodging.qc
  mutators/mutator_rocketflying.qc
  mutators/mutator_vampire.qc
+ mutators/mutator_spawn_near_teammate.qc
+ mutators/mutator_physical_items.qc
+ mutators/sandbox.qc
+ mutators/mutator_superspec.qc
+ mutators/mutator_minstagib.qc
+ mutators/mutator_touchexplode.qc
  
  ../warpzonelib/anglestransform.qc
  ../warpzonelib/mathlib.qc
  ../warpzonelib/common.qc
  ../warpzonelib/util_server.qc
  ../warpzonelib/server.qc
+ ../common/animdecide.qc
+ ../common/util.qc
+ ../common/notifications.qc
+ ../common/if-this-file-errors-scroll-up-and-fix-the-warnings.fteqccfail
diff --combined qcsrc/server/t_quake3.qc
index 8ba0880f689145092c376ac3a084ed2400e5f0f1,7f8cb82921ee3ae2a3b068ac331bbff891a13949..50005d9c58ab0a8893785527d94f9cf42f407e64
@@@ -14,17 -14,17 +14,17 @@@ void spawnfunc_ammo_bullets()        { 
  // GL -> Mortar
  void spawnfunc_ammo_grenades()       { spawnfunc_item_rockets();        }
  
 -// LG -> Electro
 -void spawnfunc_weapon_lightning()    { spawnfunc_weapon_electro();      }
 +// LG -> Lightning
 +//void spawnfunc_weapon_lightning()    { spawnfunc_weapon_electro();      }
  void spawnfunc_ammo_lightning()      { spawnfunc_item_cells();          }
  
  // Plasma -> Hagar
  void spawnfunc_weapon_plasmagun()    { spawnfunc_weapon_hagar();        }
  void spawnfunc_ammo_cells()          { spawnfunc_item_rockets();        }
  
- // Rail -> Rifle
- void spawnfunc_weapon_railgun()      { spawnfunc_weapon_sniperrifle();  }
- void spawnfunc_ammo_slugs()          { spawnfunc_item_bullets();        }
+ // Rail -> Nex
+ void spawnfunc_weapon_railgun()      { spawnfunc_weapon_nex();          }
+ void spawnfunc_ammo_slugs()          { spawnfunc_item_cells();          }
  
  // BFG -> Crylink
  void spawnfunc_weapon_bfg()          { spawnfunc_weapon_crylink();      }
@@@ -122,12 -122,8 +122,8 @@@ void spawnfunc_target_give(
  //void spawnfunc_item_health_mega()  /* handled in t_items.qc */
  //void spawnfunc_item_invis()        /* not supported */
  //void spawnfunc_item_regen()        /* not supported */
- void spawnfunc_team_CTF_redflag()    { spawnfunc_item_flag_team1();    }
- void spawnfunc_team_CTF_blueflag()   { spawnfunc_item_flag_team2();    }
- void spawnfunc_team_CTF_redplayer()  { spawnfunc_info_player_team1();  }
- void spawnfunc_team_CTF_blueplayer() { spawnfunc_info_player_team2();  }
- void spawnfunc_team_CTF_redspawn()   { spawnfunc_info_player_team1();  }
- void spawnfunc_team_CTF_bluespawn()  { spawnfunc_info_player_team2();  }
+ // CTF spawnfuncs handled in mutators/gamemode_ctf.qc now
  
  void spawnfunc_item_flight()         { spawnfunc_item_jetpack();       }
  
@@@ -142,11 -138,11 +138,11 @@@ float DoesQ3ARemoveThisEntity(
        // Q3 style filters (DO NOT USE, THIS IS COMPAT ONLY)
  
        if(self.notq3a)
-               if(!teams_matter || g_tdm || g_ctf)
+               if(!teamplay || g_tdm || g_ctf)
                        return 1;
  
        if(self.notta)
-               if not(!teams_matter || g_tdm || g_ctf)
+               if not(!teamplay || g_tdm || g_ctf)
                        return 1;
  
        if(self.notsingle)
                        return 1;
  
        if(self.notteam)
-               if(teams_matter)
+               if(teamplay)
                        return 1;
  
        if(self.notfree)
-               if(!teams_matter)
+               if(!teamplay)
                        return 1;
  
        if(self.gametype)
        {
                string gametypename;
-               // static char *gametypeNames[] = {"ffa", "tournament", "single", "team", "ctf", "oneflag", "obelisk", "harvester", "teamtournament"};
+               // static char *gametypeNames[] = {"ffa", "tournament", "single", "team", "ctf", "oneflag", "obelisk", "harvester", "teamtournament"}
                gametypename = "ffa";
-               if(teams_matter)
+               if(teamplay)
                        gametypename = "team";
                if(g_arena)
                        gametypename = "tournament";
diff --combined qcsrc/server/w_all.qc
index c31edb7f1096a2678058da95a39d9b16dd0d2edc,ac4ef47ed3bc74c009b3b9d79e1433975102c3c7..46af3565e45f18101006185a19d0224383bdc211
@@@ -7,7 -7,6 +7,7 @@@
  #include "w_grenadelauncher.qc"
  #include "w_minelayer.qc"
  #include "w_electro.qc"
 +#include "w_lightning.qc"
  #include "w_crylink.qc"
  #include "w_nex.qc"
  #include "w_hagar.qc"
@@@ -17,6 -16,6 +17,6 @@@
  #include "w_hook.qc"
  #include "w_hlac.qc"
  #include "w_tuba.qc"
- #include "w_sniperrifle.qc"
+ #include "w_rifle.qc"
  #include "w_fireball.qc"
  #include "w_seeker.qc"
index 77477a23ee4393bffc866f7a215838c55965059a,649e72374ecc3754ffb6f29b84075854212739e2..0fb6b8898712af384d62413d419460d4a19271e9
@@@ -1,5 -1,15 +1,15 @@@
  #ifdef REGISTER_WEAPON
- REGISTER_WEAPON(ELECTRO, w_electro, IT_CELLS, 5, WEP_FLAG_NORMAL | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_MID, "electro", "electro", _("Electro"));
+ REGISTER_WEAPON(
+ /* WEP_##id  */ ELECTRO,
+ /* function  */ w_electro,
+ /* ammotype  */ IT_CELLS,
+ /* impulse   */ 5,
+ /* flags     */ WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH,
+ /* rating    */ BOT_PICKUP_RATING_MID,
+ /* model     */ "electro",
+ /* shortname */ "electro",
+ /* fullname  */ _("Electro")
+ );
  #else
  #ifdef SVQC
  .float electro_count;
@@@ -9,14 -19,14 +19,14 @@@ void W_Plasma_Explode_Combo (void)
  
  void W_Plasma_TriggerCombo(vector org, float rad, entity own)
  {
-       local entity e;
+       entity e;
        e = WarpZone_FindRadius(org, rad, TRUE);
        while (e)
        {
                if (e.classname == "plasma")
                {
                        // change owner to whoever caused the combo explosion
-                       e.owner = own;
+                       e.realowner = own;
                        e.takedamage = DAMAGE_NO;
                        e.classname = "plasma_chain";
                        e.think = W_Plasma_Explode_Combo;
  void W_Plasma_Explode (void)
  {
        if(other.takedamage == DAMAGE_AIM)
-               if(other.classname == "player")
-                       if(IsDifferentTeam(self.owner, other))
+               if(IS_PLAYER(other))
+                       if(IsDifferentTeam(self.realowner, other))
                                if(other.deadflag == DEAD_NO)
                                        if(IsFlying(other))
-                                               AnnounceTo(self.owner, "electrobitch");
+                                               Send_Notification(NOTIF_ONE, self.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_ELECTROBITCH);
  
-       self.event_damage = SUB_Null;
+       self.event_damage = func_null;
        self.takedamage = DAMAGE_NO;
        if (self.movetype == MOVETYPE_BOUNCE)
        {
-               RadiusDamage (self, self.owner, autocvar_g_balance_electro_secondary_damage, autocvar_g_balance_electro_secondary_edgedamage, autocvar_g_balance_electro_secondary_radius, world, autocvar_g_balance_electro_secondary_force, self.projectiledeathtype, other);
+               RadiusDamage (self, self.realowner, autocvar_g_balance_electro_secondary_damage, autocvar_g_balance_electro_secondary_edgedamage, autocvar_g_balance_electro_secondary_radius, world, autocvar_g_balance_electro_secondary_force, self.projectiledeathtype, other);
        }
        else
        {
-               W_Plasma_TriggerCombo(self.origin, autocvar_g_balance_electro_primary_comboradius, self.owner);
-               RadiusDamage (self, self.owner, autocvar_g_balance_electro_primary_damage, autocvar_g_balance_electro_primary_edgedamage, autocvar_g_balance_electro_primary_radius, world, autocvar_g_balance_electro_primary_force, self.projectiledeathtype, other);
+               W_Plasma_TriggerCombo(self.origin, autocvar_g_balance_electro_primary_comboradius, self.realowner);
+               RadiusDamage (self, self.realowner, autocvar_g_balance_electro_primary_damage, autocvar_g_balance_electro_primary_edgedamage, autocvar_g_balance_electro_primary_radius, world, autocvar_g_balance_electro_primary_force, self.projectiledeathtype, other);
        }
  
        remove (self);
  
  void W_Plasma_Explode_Combo (void)
  {
-       W_Plasma_TriggerCombo(self.origin, autocvar_g_balance_electro_combo_comboradius, self.owner);
+       W_Plasma_TriggerCombo(self.origin, autocvar_g_balance_electro_combo_comboradius, self.realowner);
  
-       self.event_damage = SUB_Null;
-       RadiusDamage (self, self.owner, autocvar_g_balance_electro_combo_damage, autocvar_g_balance_electro_combo_edgedamage, autocvar_g_balance_electro_combo_radius, world, autocvar_g_balance_electro_combo_force, WEP_ELECTRO | HITTYPE_BOUNCE, world); // use THIS type for a combo because primary can't bounce
+       self.event_damage = func_null;
+       RadiusDamage (self, self.realowner, autocvar_g_balance_electro_combo_damage, autocvar_g_balance_electro_combo_edgedamage, autocvar_g_balance_electro_combo_radius, world, autocvar_g_balance_electro_combo_force, WEP_ELECTRO | HITTYPE_BOUNCE, world); // use THIS type for a combo because primary can't bounce
        remove (self);
  }
  
@@@ -68,7 -78,7 +78,7 @@@ void W_Plasma_Touch (void
                W_Plasma_Explode ();
        } else {
                //UpdateCSQCProjectile(self);
-               spamsound (self, CHAN_PROJECTILE, "weapons/electro_bounce.wav", VOL_BASE, ATTN_NORM);
+               spamsound (self, CH_SHOTS, "weapons/electro_bounce.wav", VOL_BASE, ATTN_NORM);
                self.projectiledeathtype |= HITTYPE_BOUNCE;
        }
  }
@@@ -83,16 -93,22 +93,22 @@@ void W_Plasma_Damage (entity inflictor
  {
        if(self.health <= 0)
                return;
        // note: combos are usually triggered by W_Plasma_TriggerCombo, not damage
+       float is_combo = (inflictor.classname == "plasma_chain" || inflictor.classname == "plasma_prim");
+       
+       if (!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, (is_combo ? 1 : -1)))
+               return; // g_projectiles_damage says to halt    
+       
        self.health = self.health - damage;
        if (self.health <= 0)
        {
                self.takedamage = DAMAGE_NO;
                self.nextthink = time;
-               if (inflictor.classname == "plasma_chain" || inflictor.classname == "plasma_prim")
+               if (is_combo)
                {
                        // change owner to whoever caused the combo explosion
-                       self.owner = inflictor.owner;
+                       self.realowner = inflictor.realowner;
                        self.classname = "plasma_chain";
                        self.think = W_Plasma_Explode_Combo;
                        self.nextthink = time + min(autocvar_g_balance_electro_combo_radius, vlen(self.origin - inflictor.origin)) / autocvar_g_balance_electro_combo_speed; // delay combo chains, looks cooler
  
  void W_Electro_Attack()
  {
-       local entity proj;
+       entity proj;
+       W_DecreaseAmmo(ammo_cells, autocvar_g_balance_electro_primary_ammo, autocvar_g_balance_electro_reload_ammo);
  
-       W_SetupShot_ProjectileSize (self, '0 0 -3', '0 0 -3', FALSE, 2, "weapons/electro_fire.wav", CHAN_WEAPON, autocvar_g_balance_electro_primary_damage);
+       W_SetupShot_ProjectileSize (self, '0 0 -3', '0 0 -3', FALSE, 2, "weapons/electro_fire.wav", CH_WEAPON_A, autocvar_g_balance_electro_primary_damage);
  
        pointparticles(particleeffectnum("electro_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
  
        proj = spawn ();
        proj.classname = "plasma_prim";
-       proj.owner = self;
+       proj.owner = proj.realowner = self;
        proj.bot_dodge = TRUE;
        proj.bot_dodgerating = autocvar_g_balance_electro_primary_damage;
        proj.use = W_Plasma_Explode;
        proj.projectiledeathtype = WEP_ELECTRO;
        setorigin(proj, w_shotorg);
  
-       if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
-               self.ammo_cells = self.ammo_cells - autocvar_g_balance_electro_primary_ammo;
        proj.movetype = MOVETYPE_FLY;
        W_SETUPPROJECTILEVELOCITY(proj, g_balance_electro_primary);
        proj.angles = vectoangles(proj.velocity);
        proj.touch = W_Plasma_TouchExplode;
        setsize(proj, '0 0 -3', '0 0 -3');
        proj.flags = FL_PROJECTILE;
-       //sound (proj, CHAN_PAIN, "weapons/electro_fly.wav", VOL_BASE, ATTN_NORM);
-       //sounds bad
+       proj.missile_flags = MIF_SPLASH;
  
        CSQCProjectile(proj, TRUE, PROJECTILE_ELECTRO_BEAM, TRUE);
  
  
  void W_Electro_Attack2()
  {
-       local entity proj;
+       entity proj;
  
-       W_SetupShot_ProjectileSize (self, '0 0 -4', '0 0 -4', FALSE, 2, "weapons/electro_fire2.wav", CHAN_WEAPON, autocvar_g_balance_electro_secondary_damage);
+       W_DecreaseAmmo(ammo_cells, autocvar_g_balance_electro_secondary_ammo, autocvar_g_balance_electro_reload_ammo);
+       W_SetupShot_ProjectileSize (self, '0 0 -4', '0 0 -4', FALSE, 2, "weapons/electro_fire2.wav", CH_WEAPON_A, autocvar_g_balance_electro_secondary_damage);
  
        w_shotdir = v_forward; // no TrueAim for grenades please
  
  
        proj = spawn ();
        proj.classname = "plasma";
-       proj.owner = self;
+       proj.owner = proj.realowner = self;
        proj.use = W_Plasma_Explode;
        proj.think = adaptor_think2use_hittype_splash;
        proj.bot_dodge = TRUE;
        proj.projectiledeathtype = WEP_ELECTRO | HITTYPE_SECONDARY;
        setorigin(proj, w_shotorg);
  
-       if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
-               self.ammo_cells = self.ammo_cells - autocvar_g_balance_electro_secondary_ammo;
        //proj.glow_size = 50;
        //proj.glow_color = 45;
        proj.movetype = MOVETYPE_BOUNCE;
        proj.health = autocvar_g_balance_electro_secondary_health;
        proj.event_damage = W_Plasma_Damage;
        proj.flags = FL_PROJECTILE;
+       proj.damagedbycontents = (autocvar_g_balance_electro_secondary_damagedbycontents);
  
        proj.bouncefactor = autocvar_g_balance_electro_secondary_bouncefactor;
        proj.bouncestop = autocvar_g_balance_electro_secondary_bouncestop;
+       proj.missile_flags = MIF_SPLASH | MIF_ARC;
  
  #if 0
        entity p2;
        CSQCProjectile(proj, TRUE, PROJECTILE_ELECTRO, FALSE); // no culling, it has sound
  
        other = proj; MUTATOR_CALLHOOK(EditProjectile);
      }
+ }
  
  .vector hook_start, hook_end;
  float lgbeam_send(entity to, float sf)
  {
 -      WriteByte(MSG_ENTITY, ENT_CLIENT_LGBEAM);
 +      WriteByte(MSG_ENTITY, ENT_CLIENT_ELECTRO_BEAM);
        sf = sf & 0x7F;
-       if(sound_allowed(MSG_BROADCAST, self.owner))
+       if(sound_allowed(MSG_BROADCAST, self.realowner))
                sf |= 0x80;
        WriteByte(MSG_ENTITY, sf);
        if(sf & 1)
        {
-               WriteByte(MSG_ENTITY, num_for_edict(self.owner));
+               WriteByte(MSG_ENTITY, num_for_edict(self.realowner));
                WriteCoord(MSG_ENTITY, autocvar_g_balance_electro_primary_range);
        }
        if(sf & 2)
  }
  .entity lgbeam;
  .float prevlgfire;
+ float lgbeam_checkammo()
+ {
+       if(self.realowner.items & IT_UNLIMITED_WEAPON_AMMO)
+               return TRUE;
+       else if(autocvar_g_balance_electro_reload_ammo)
+               return self.realowner.clip_load > 0;
+       else
+               return self.realowner.ammo_cells > 0;
+ }
+ entity lgbeam_owner_ent;
  void lgbeam_think()
  {
-       self.owner.prevlgfire = time;
-       if (self != self.owner.lgbeam)
+       entity owner_player;
+       owner_player = self.realowner;
+       owner_player.prevlgfire = time;
+       if (self != owner_player.lgbeam)
        {
                remove(self);
                return;
        }
-       if (self.owner.weaponentity.state != WS_INUSE || (self.owner.ammo_cells <= 0 && !(self.owner.items & IT_UNLIMITED_WEAPON_AMMO)) || self.owner.deadflag != DEAD_NO || !self.owner.BUTTON_ATCK || self.owner.freezetag_frozen)
+       if (owner_player.weaponentity.state != WS_INUSE || !lgbeam_checkammo() || owner_player.deadflag != DEAD_NO || !owner_player.BUTTON_ATCK || owner_player.freezetag_frozen)
        {
-               if(self == self.owner.lgbeam)
-                       self.owner.lgbeam = world;
+               if(self == owner_player.lgbeam)
+                       owner_player.lgbeam = world;
                remove(self);
                return;
        }
  
        self.nextthink = time;
  
-       makevectors(self.owner.v_angle);
+       makevectors(owner_player.v_angle);
  
        float dt, f;
        dt = frametime;
-       if not(self.owner.items & IT_UNLIMITED_WEAPON_AMMO)
+       // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
+       if not(owner_player.items & IT_UNLIMITED_WEAPON_AMMO)
        {
                if(autocvar_g_balance_electro_primary_ammo)
                {
-                       dt = min(dt, self.owner.ammo_cells / autocvar_g_balance_electro_primary_ammo);
-                       self.owner.ammo_cells = max(0, self.owner.ammo_cells - autocvar_g_balance_electro_primary_ammo * frametime);
+                       if(autocvar_g_balance_electro_reload_ammo)
+                       {
+                               dt = min(dt, owner_player.clip_load / autocvar_g_balance_electro_primary_ammo);
+                               owner_player.clip_load = max(0, owner_player.clip_load - autocvar_g_balance_electro_primary_ammo * frametime);
+                               owner_player.(weapon_load[WEP_ELECTRO]) = owner_player.clip_load;
+                       }
+                       else
+                       {
+                               dt = min(dt, owner_player.ammo_cells / autocvar_g_balance_electro_primary_ammo);
+                               owner_player.ammo_cells = max(0, owner_player.ammo_cells - autocvar_g_balance_electro_primary_ammo * frametime);
+                       }
                }
        }
  
-       W_SetupShot_Range(self.owner, TRUE, 0, "", 0, autocvar_g_balance_electro_primary_damage * dt, autocvar_g_balance_electro_primary_range);
-       WarpZone_traceline_antilag(self.owner, w_shotorg, w_shotend, MOVE_NORMAL, self.owner, ANTILAG_LATENCY(self.owner));
+       W_SetupShot_Range(owner_player, TRUE, 0, "", 0, autocvar_g_balance_electro_primary_damage * dt, autocvar_g_balance_electro_primary_range);
+       if(!lgbeam_owner_ent)
+       {
+               lgbeam_owner_ent = spawn();
+               lgbeam_owner_ent.classname = "lgbeam_owner_ent";
+       }
+       WarpZone_traceline_antilag(lgbeam_owner_ent, w_shotorg, w_shotend, MOVE_NORMAL, lgbeam_owner_ent, ANTILAG_LATENCY(owner_player));
  
        // apply the damage
        if(trace_ent)
  
                f = ExponentialFalloff(autocvar_g_balance_electro_primary_falloff_mindist, autocvar_g_balance_electro_primary_falloff_maxdist, autocvar_g_balance_electro_primary_falloff_halflifedist, vlen(WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos) - w_shotorg));
  
-               if(accuracy_isgooddamage(self.owner, trace_ent))
-                       accuracy_add(self.owner, WEP_ELECTRO, 0, autocvar_g_balance_electro_primary_damage * dt * f);
-               Damage (trace_ent, self.owner, self.owner, autocvar_g_balance_electro_primary_damage * dt * f, WEP_ELECTRO, trace_endpos, force * dt);
+               if(accuracy_isgooddamage(owner_player, trace_ent))
+                       accuracy_add(owner_player, WEP_ELECTRO, 0, autocvar_g_balance_electro_primary_damage * dt * f);
+               Damage (trace_ent, owner_player, owner_player, autocvar_g_balance_electro_primary_damage * dt * f, WEP_ELECTRO, trace_endpos, force * dt);
        }
-       W_Plasma_TriggerCombo(trace_endpos, autocvar_g_balance_electro_primary_comboradius, self.owner);
+       W_Plasma_TriggerCombo(trace_endpos, autocvar_g_balance_electro_primary_comboradius, owner_player);
  
        // draw effect
        if(w_shotorg != self.hook_start)
@@@ -290,7 -337,7 +337,7 @@@ void W_Electro_Attack3 (void
  {
        // only play fire sound if 0.5 sec has passed since player let go the fire button
        if(time - self.prevlgfire > 0.5)
-               sound (self, CHAN_WEAPON, "weapons/lgbeam_fire.wav", VOL_BASE, ATTN_NORM);
+               sound (self, CH_WEAPON_A, "weapons/lgbeam_fire.wav", VOL_BASE, ATTN_NORM);
  
        entity beam, oldself;
  
        beam.classname = "lgbeam";
        beam.solid = SOLID_NOT;
        beam.think = lgbeam_think;
-       beam.owner = self;
+       beam.owner = beam.realowner = self;
        beam.movetype = MOVETYPE_NONE;
        beam.shot_spread = 0;
        beam.bot_dodge = TRUE;
@@@ -344,6 -391,7 +391,7 @@@ void w_electro_checkattack(
  .float BUTTON_ATCK_prev;
  float w_electro(float req)
  {
+       float ammo_amount;
        if (req == WR_AIM)
        {
                self.BUTTON_ATCK=FALSE;
        }
        else if (req == WR_THINK)
        {
+               if(autocvar_g_balance_electro_reload_ammo) // forced reload
+               {
+                       ammo_amount = 0;
+                       if(autocvar_g_balance_electro_lightning)
+                       {
+                               if(self.clip_load > 0)
+                                       ammo_amount = 1;
+                       }
+                       else if(self.clip_load >= autocvar_g_balance_electro_primary_ammo)
+                               ammo_amount = 1;
+                       if(self.clip_load >= autocvar_g_balance_electro_secondary_ammo)
+                               ammo_amount += 1;
+                       if(!ammo_amount)
+                       {
+                               weapon_action(self.weapon, WR_RELOAD);
+                               return FALSE;
+                       }
+               }
                if (self.BUTTON_ATCK)
                {
                        if(autocvar_g_balance_electro_lightning)
                                if(self.BUTTON_ATCK_prev)
-                               {
-                                       // prolong the animtime while the gun is being fired
-                                       if(self.animstate_startframe == self.anim_shoot_x && self.animstate_numframes == self.anim_shoot_y)
-                                               weapon_thinkf(WFRAME_DONTCHANGE, autocvar_g_balance_electro_primary_animtime, w_ready);
-                                       else
-                                               weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_electro_primary_animtime, w_ready);
-                               }
+                                       weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_electro_primary_animtime, w_ready);
                        if (weapon_prepareattack(0, (autocvar_g_balance_electro_lightning ? 0 : autocvar_g_balance_electro_primary_refire)))
                        {
                                if(autocvar_g_balance_electro_lightning)
                                }
                                self.BUTTON_ATCK_prev = 0;
                        }
-               }
  
-               if (self.BUTTON_ATCK2)
-               if (time >= self.electro_secondarytime)
-               if (weapon_prepareattack(1, autocvar_g_balance_electro_secondary_refire))
-               {
-                       W_Electro_Attack2();
-                       self.electro_count = autocvar_g_balance_electro_secondary_count;
-                       weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_electro_secondary_animtime, w_electro_checkattack);
-                       self.electro_secondarytime = time + autocvar_g_balance_electro_secondary_refire2 * W_WeaponRateFactor();
+                       if (self.BUTTON_ATCK2)
+                       {
+                               if (time >= self.electro_secondarytime)
+                               if (weapon_prepareattack(1, autocvar_g_balance_electro_secondary_refire))
+                               {
+                                       W_Electro_Attack2();
+                                       self.electro_count = autocvar_g_balance_electro_secondary_count;
+                                       weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_electro_secondary_animtime, w_electro_checkattack);
+                                       self.electro_secondarytime = time + autocvar_g_balance_electro_secondary_refire2 * W_WeaponRateFactor();
+                               }
+                       }
                }
        }
        else if (req == WR_PRECACHE)
                precache_sound ("weapons/electro_fire2.wav");
                precache_sound ("weapons/electro_impact.wav");
                precache_sound ("weapons/electro_impact_combo.wav");
+               //precache_sound ("weapons/reload.wav"); // until weapons have individual reload sounds, precache the reload sound somewhere else
                if(autocvar_g_balance_electro_lightning)
                {
                        precache_sound ("weapons/lgbeam_fire.wav");
                }
        }
        else if (req == WR_SETUP)
+       {
                weapon_setup(WEP_ELECTRO);
+               self.current_ammo = ammo_cells;
+       }
        else if (req == WR_CHECKAMMO1)
        {
                if(autocvar_g_balance_electro_lightning)
-                       return !autocvar_g_balance_electro_primary_ammo || (self.ammo_cells > 0);
+               {
+                       if(!autocvar_g_balance_electro_primary_ammo)
+                               ammo_amount = 1;
+                       else
+                               ammo_amount = self.ammo_cells > 0;
+                       ammo_amount += self.(weapon_load[WEP_ELECTRO]) > 0;
+               }
                else
-                       return self.ammo_cells >= autocvar_g_balance_electro_primary_ammo;
+               {
+                       ammo_amount = self.ammo_cells >= autocvar_g_balance_electro_primary_ammo;
+                       ammo_amount += self.(weapon_load[WEP_ELECTRO]) >= autocvar_g_balance_electro_primary_ammo;
+               }
+               return ammo_amount;
        }
        else if (req == WR_CHECKAMMO2)
-               return self.ammo_cells >= autocvar_g_balance_electro_secondary_ammo;
+       {
+               if(autocvar_g_balance_electro_combo_safeammocheck) // true if you can fire at least one secondary blob AND one primary shot after it, otherwise false.
+               {
+                       ammo_amount = self.ammo_cells >= autocvar_g_balance_electro_secondary_ammo + autocvar_g_balance_electro_primary_ammo;
+                       ammo_amount += self.(weapon_load[WEP_ELECTRO]) >= autocvar_g_balance_electro_secondary_ammo + autocvar_g_balance_electro_primary_ammo;
+               }
+               else
+               {
+                       ammo_amount = self.ammo_cells >= autocvar_g_balance_electro_secondary_ammo;
+                       ammo_amount += self.(weapon_load[WEP_ELECTRO]) >= autocvar_g_balance_electro_secondary_ammo;
+               }
+               return ammo_amount;
+       }
        else if (req == WR_RESETPLAYER)
        {
                self.electro_secondarytime = time;
        }
+       else if (req == WR_RELOAD)
+       {
+               W_Reload(min(autocvar_g_balance_electro_primary_ammo, autocvar_g_balance_electro_secondary_ammo), autocvar_g_balance_electro_reload_ammo, autocvar_g_balance_electro_reload_time, "weapons/reload.wav");
+       }
+       else if (req == WR_SUICIDEMESSAGE)
+       {
+               if(w_deathtype & HITTYPE_SECONDARY)
+                       return WEAPON_ELECTRO_SUICIDE_ORBS;
+               else
+                       return WEAPON_ELECTRO_SUICIDE_BOLT;
+       }
+       else if (req == WR_KILLMESSAGE)
+       {
+               if(w_deathtype & HITTYPE_SECONDARY)
+               {
+                       return WEAPON_ELECTRO_MURDER_ORBS;
+               }
+               else
+               {
+                       if(w_deathtype & HITTYPE_BOUNCE)
+                               return WEAPON_ELECTRO_MURDER_COMBO;
+                       else
+                               return WEAPON_ELECTRO_MURDER_BOLT;
+               }
+       }
        return TRUE;
- };
+ }
  #endif
  #ifdef CSQC
  float w_electro(float req)
                {
                        pointparticles(particleeffectnum("electro_ballexplode"), org2, '0 0 0', 1);
                        if(!w_issilent)
-                               sound(self, CHAN_PROJECTILE, "weapons/electro_impact.wav", VOL_BASE, ATTN_NORM);
+                               sound(self, CH_SHOTS, "weapons/electro_impact.wav", VOL_BASE, ATTN_NORM);
                }
                else
                {
                                // this is sent as "primary (w_deathtype & HITTYPE_BOUNCE)" to distinguish it from (w_deathtype & HITTYPE_SECONDARY) bounced balls
                                pointparticles(particleeffectnum("electro_combo"), org2, '0 0 0', 1);
                                if(!w_issilent)
-                                       sound(self, CHAN_PROJECTILE, "weapons/electro_impact_combo.wav", VOL_BASE, ATTN_NORM);
+                                       sound(self, CH_SHOTS, "weapons/electro_impact_combo.wav", VOL_BASE, ATTN_NORM);
                        }
                        else
                        {
                                pointparticles(particleeffectnum("electro_impact"), org2, '0 0 0', 1);
                                if(!w_issilent)
-                                       sound(self, CHAN_PROJECTILE, "weapons/electro_impact.wav", VOL_BASE, ATTN_NORM);
+                                       sound(self, CH_SHOTS, "weapons/electro_impact.wav", VOL_BASE, ATTN_NORM);
                        }
                }
        }
                precache_sound("weapons/electro_impact.wav");
                precache_sound("weapons/electro_impact_combo.wav");
        }
-       else if (req == WR_SUICIDEMESSAGE)
-       {
-               if(w_deathtype & HITTYPE_SECONDARY)
-                       w_deathtypestring = _("%s could not remember where they put plasma");
-               else
-                       w_deathtypestring = _("%s played with plasma");
-       }
-       else if (req == WR_KILLMESSAGE)
-       {
-               if(w_deathtype & HITTYPE_SECONDARY)
-               {
-                       if(w_deathtype & HITTYPE_SPLASH) // unchecked: BOUNCE
-                               w_deathtypestring = _("%s just noticed %s's blue ball");
-                       else // unchecked: BOUNCE
-                               w_deathtypestring = _("%s got in touch with %s's blue ball");
-               }
-               else
-               {
-                       if(w_deathtype & HITTYPE_BOUNCE) // combo
-                               w_deathtypestring = _("%s felt the electrifying air of %s's combo");
-                       else if(w_deathtype & HITTYPE_SPLASH)
-                               w_deathtypestring = _("%s got too close to %s's blue beam");
-                       else
-                               w_deathtypestring = _("%s was blasted by %s's blue beam");
-               }
-       }
        return TRUE;
  }
  #endif