]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge remote-tracking branch 'origin/master' into samual/weapons
authorSamual Lenks <samual@xonotic.org>
Fri, 6 Dec 2013 21:13:30 +0000 (16:13 -0500)
committerSamual Lenks <samual@xonotic.org>
Fri, 6 Dec 2013 21:13:30 +0000 (16:13 -0500)
Conflicts:
balanceXonotic.cfg
qcsrc/common/weapons/w_seeker.qc
qcsrc/server/cl_weapons.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/mutators/mutator_minstagib.qc
qcsrc/server/tturrets/units/unit_machinegun.qc
qcsrc/server/tturrets/units/unit_walker.qc
qcsrc/server/w_hagar.qc
qcsrc/server/w_hlac.qc
qcsrc/server/w_hook.qc
qcsrc/server/w_laser.qc
qcsrc/server/w_minstanex.qc
qcsrc/server/w_nex.qc
qcsrc/server/w_rifle.qc
qcsrc/server/w_shotgun.qc
qcsrc/server/w_uzi.qc
qcsrc/server/weapons/tracing.qc
qcsrc/server/weapons/weaponsystem.qc

55 files changed:
1  2 
balanceXonotic.cfg
oldbalanceXPM.cfg
qcsrc/client/Main.qc
qcsrc/client/View.qc
qcsrc/client/damage.qc
qcsrc/client/hook.qc
qcsrc/client/hud.qc
qcsrc/client/miscfunctions.qc
qcsrc/client/particles.qc
qcsrc/client/progs.src
qcsrc/client/weapons/projectile.qc
qcsrc/common/command/generic.qc
qcsrc/common/constants.qh
qcsrc/common/util.qc
qcsrc/common/util.qh
qcsrc/common/weapons/w_electro.qc
qcsrc/common/weapons/w_fireball.qc
qcsrc/common/weapons/w_seeker.qc
qcsrc/common/weapons/w_tuba.qc
qcsrc/common/weapons/weapons.qh
qcsrc/menu/progs.src
qcsrc/server/autocvars.qh
qcsrc/server/bot/havocbot/havocbot.qc
qcsrc/server/cheats.qc
qcsrc/server/cl_client.qc
qcsrc/server/cl_impulse.qc
qcsrc/server/cl_physics.qc
qcsrc/server/cl_player.qc
qcsrc/server/defs.qh
qcsrc/server/func_breakable.qc
qcsrc/server/g_damage.qc
qcsrc/server/g_hook.qc
qcsrc/server/g_world.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/mutators/gamemode_nexball.qc
qcsrc/server/mutators/mutator_minstagib.qc
qcsrc/server/mutators/mutator_nades.qc
qcsrc/server/mutators/mutator_nix.qc
qcsrc/server/mutators/mutator_touchexplode.qc
qcsrc/server/progs.src
qcsrc/server/t_items.qc
qcsrc/server/t_quake3.qc
qcsrc/server/tturrets/system/system_main.qc
qcsrc/server/tturrets/units/unit_flac.qc
qcsrc/server/tturrets/units/unit_machinegun.qc
qcsrc/server/tturrets/units/unit_walker.qc
qcsrc/server/vehicles/bumblebee.qc
qcsrc/server/vehicles/racer.qc
qcsrc/server/vehicles/raptor.qc
qcsrc/server/vehicles/spiderbot.qc
qcsrc/server/vehicles/vehicles.qc
qcsrc/server/weapons/accuracy.qc
qcsrc/server/weapons/csqcprojectile.qc
qcsrc/server/weapons/tracing.qc
qcsrc/server/weapons/weaponsystem.qc

diff --combined balanceXonotic.cfg
index dd68bea889b6533092349b70fc2c2709bf5bb5c4,cdf3f201354aaebeb4351ee1d83f4af9f6d44490..d4fb252a0df814411752a09b4b6124b1a241d918
@@@ -4,12 -4,12 +4,12 @@@ g_mod_balance Xonoti
  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_mortar -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_devastator -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"
@@@ -227,21 -227,6 +227,21 @@@ set g_balance_grapplehook_damagedbycont
  
  // {{{ weapon properties
  // {{{ laser
 +set g_balance_laser_melee_animtime 0.3
 +set g_balance_laser_melee_damage 80
 +set g_balance_laser_melee_delay 0.25
 +set g_balance_laser_melee_force 200
 +set g_balance_laser_melee_multihit 1
 +set g_balance_laser_melee_no_doubleslap 1
 +set g_balance_laser_melee_nonplayerdamage 40
 +set g_balance_laser_melee_range 120
 +set g_balance_laser_melee_refire 1.25
 +set g_balance_laser_melee_swing_side 120
 +set g_balance_laser_melee_swing_up 30
 +set g_balance_laser_melee_time 0.15
 +set g_balance_laser_melee_traces 10
 +
 +set g_balance_laser_primary 0 // 0 = shockwave attack, 1 = projectile primary
  set g_balance_laser_primary_damage 25
  set g_balance_laser_primary_edgedamage 12.5
  set g_balance_laser_primary_force 300
@@@ -253,11 -238,11 +253,11 @@@ set g_balance_laser_primary_animtime 0.
  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 2 // 0 = switch away to last used weapon, 1 = projectile secondary, 2 = melee secondary
  set g_balance_laser_secondary_damage 25
  set g_balance_laser_secondary_edgedamage 12.5
  set g_balance_laser_secondary_force 400
@@@ -269,39 -254,10 +269,39 @@@ set g_balance_laser_secondary_animtime 
  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_shockwave_damage 20
 +set g_balance_laser_shockwave_distance 2000
 +set g_balance_laser_shockwave_edgedamage 0
 +set g_balance_laser_shockwave_force 200
 +set g_balance_laser_shockwave_force_forwardbias 50
 +set g_balance_laser_shockwave_force_zscale 2
 +set g_balance_laser_shockwave_jump_damage 20
 +set g_balance_laser_shockwave_jump_edgedamage 0
 +set g_balance_laser_shockwave_jump_force 300
 +set g_balance_laser_shockwave_jump_force_velocitybias 0
 +set g_balance_laser_shockwave_jump_force_zscale 1.25
 +set g_balance_laser_shockwave_jump_multiplier_accuracy 0.5
 +set g_balance_laser_shockwave_jump_multiplier_distance 0.5
 +set g_balance_laser_shockwave_jump_multiplier_min 0
 +set g_balance_laser_shockwave_jump_radius 150
 +set g_balance_laser_shockwave_multiplier_accuracy 0.5
 +set g_balance_laser_shockwave_multiplier_distance 0.5
 +set g_balance_laser_shockwave_multiplier_min 0
 +set g_balance_laser_shockwave_splash_damage 15
 +set g_balance_laser_shockwave_splash_edgedamage 0
 +set g_balance_laser_shockwave_splash_force 100
 +set g_balance_laser_shockwave_splash_force_forwardbias 50
 +set g_balance_laser_shockwave_splash_multiplier_accuracy 0.5
 +set g_balance_laser_shockwave_splash_multiplier_distance 0.5
 +set g_balance_laser_shockwave_splash_multiplier_min 0
 +set g_balance_laser_shockwave_splash_radius 70
 +set g_balance_laser_shockwave_spread_max 120
 +set g_balance_laser_shockwave_spread_min 25
 +
  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
@@@ -374,51 -330,51 +374,51 @@@ set g_balance_uzi_reload_ammo 60 //defa
  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_mortar_primary_type 0
 +set g_balance_mortar_primary_damage 50
 +set g_balance_mortar_primary_edgedamage 25
 +set g_balance_mortar_primary_force 250
 +set g_balance_mortar_primary_radius 120
 +set g_balance_mortar_primary_speed 1900
 +set g_balance_mortar_primary_speed_up 225
 +set g_balance_mortar_primary_speed_z 0
 +set g_balance_mortar_primary_spread 0
 +set g_balance_mortar_primary_lifetime 5
 +set g_balance_mortar_primary_lifetime2 1
 +set g_balance_mortar_primary_refire 0.8
 +set g_balance_mortar_primary_animtime 0.3
 +set g_balance_mortar_primary_ammo 2
 +set g_balance_mortar_primary_health 15
 +set g_balance_mortar_primary_damageforcescale 0
 +set g_balance_mortar_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_mortar_secondary_type 1
 +set g_balance_mortar_secondary_damage 60
 +set g_balance_mortar_secondary_edgedamage 30
 +set g_balance_mortar_secondary_force 250
 +set g_balance_mortar_secondary_radius 120
 +set g_balance_mortar_secondary_speed 1400
 +set g_balance_mortar_secondary_speed_up 150
 +set g_balance_mortar_secondary_speed_z 0
 +set g_balance_mortar_secondary_spread 0
 +set g_balance_mortar_secondary_lifetime 5
 +set g_balance_mortar_secondary_lifetime_bounce 0.5
 +set g_balance_mortar_secondary_lifetime_stick 0
 +set g_balance_mortar_secondary_refire 0.7
 +set g_balance_mortar_secondary_animtime 0.3
 +set g_balance_mortar_secondary_ammo 2
 +set g_balance_mortar_secondary_health 30
 +set g_balance_mortar_secondary_damageforcescale 4
 +set g_balance_mortar_secondary_remote_detonateprimary 0
  
 -set g_balance_grenadelauncher_bouncefactor 0.5
 -set g_balance_grenadelauncher_bouncestop 0.075
 +set g_balance_mortar_bouncefactor 0.5
 +set g_balance_mortar_bouncestop 0.075
  
 -set g_balance_grenadelauncher_switchdelay_drop 0.2
 -set g_balance_grenadelauncher_switchdelay_raise 0.2
 +set g_balance_mortar_switchdelay_drop 0.2
 +set g_balance_mortar_switchdelay_raise 0.2
  
 -set g_balance_grenadelauncher_reload_ammo 0 //default: 12
 -set g_balance_grenadelauncher_reload_time 2
 +set g_balance_mortar_reload_ammo 0 //default: 12
 +set g_balance_mortar_reload_time 2
  // }}}
  // {{{ electro
  set g_balance_electro_lightning 0
@@@ -469,37 -425,7 +469,37 @@@ set g_balance_electro_switchdelay_rais
  set g_balance_electro_reload_ammo 0 //default: 20
  set g_balance_electro_reload_time 2
  // }}}
 -// {{{ crylink
 +// {{{ 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
@@@ -551,8 -477,8 +551,8 @@@ set g_balance_crylink_secondary_linkexp
  
  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_secondary_other_lifetime 5 
 +set g_balance_crylink_secondary_other_fadetime 5
  
  set g_balance_crylink_switchdelay_drop 0.2
  set g_balance_crylink_switchdelay_raise 0.2
@@@ -572,6 -498,8 +572,6 @@@ set g_balance_nex_primary_damagefalloff
  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
@@@ -657,34 -585,34 +657,34 @@@ set g_balance_hagar_switchdelay_raise 0
  set g_balance_hagar_reload_ammo 0 //default: 25
  set g_balance_hagar_reload_time 2
  // }}}
 -// {{{ rocketlauncher
 -set g_balance_rocketlauncher_damage 70
 -set g_balance_rocketlauncher_edgedamage 35
 -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.2
 -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 70 // 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.3
 -set g_balance_rocketlauncher_switchdelay_raise 0.2
 -set g_balance_rocketlauncher_reload_ammo 0 //default: 25
 -set g_balance_rocketlauncher_reload_time 2
 +// {{{ devastator
- set g_balance_devastator_damage 80
- set g_balance_devastator_edgedamage 40
++set g_balance_devastator_damage 70
++set g_balance_devastator_edgedamage 35
 +set g_balance_devastator_force 450
 +set g_balance_devastator_radius 110
 +set g_balance_devastator_speed 1300
 +set g_balance_devastator_speedaccel 1300
 +set g_balance_devastator_speedstart 1000
 +set g_balance_devastator_lifetime 10
- set g_balance_devastator_refire 1.1
++set g_balance_devastator_refire 1.2
 +set g_balance_devastator_animtime 0.4
 +set g_balance_devastator_ammo 4
 +set g_balance_devastator_health 30 // 30 // 5 hitpoints above maximum laser value -- this way lasers can't blow it up, but mortar still can most the time.
 +set g_balance_devastator_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_devastator_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_devastator_guiderate 90 // max degrees per second
++set g_balance_devastator_guiderate 70 // max degrees per second
 +set g_balance_devastator_guideratedelay 0.01 // immediate
 +set g_balance_devastator_guidegoal 512 // goal distance for (non-laser) guiding (higher = less control, lower = erratic)
 +set g_balance_devastator_guidedelay 0.2 // delay before guiding kicks in
 +set g_balance_devastator_guidestop 0 // stop guiding when firing again
 +set g_balance_devastator_remote_damage 70
 +set g_balance_devastator_remote_edgedamage 35
 +set g_balance_devastator_remote_radius 110
 +set g_balance_devastator_remote_force 400
- set g_balance_devastator_switchdelay_drop 0.2
++set g_balance_devastator_switchdelay_drop 0.3
 +set g_balance_devastator_switchdelay_raise 0.2
 +set g_balance_devastator_reload_ammo 0 //default: 25
 +set g_balance_devastator_reload_time 2
  // }}}
  // {{{ porto
  set g_balance_porto_primary_refire 1.5
@@@ -702,12 -630,12 +702,12 @@@ set g_balance_portal_health 200 // thes
  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_ammo 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_primary_hooked_ammo 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
diff --combined oldbalanceXPM.cfg
index 3b6dd989714be115bd091f71dae466309e926e11,0000000000000000000000000000000000000000..9c90e04aca12a53a753ef851475ba0fdc6ae079f
mode 100644,000000..100644
--- /dev/null
@@@ -1,781 -1,0 +1,781 @@@
- set g_balance_rocketlauncher_damage 80
- set g_balance_rocketlauncher_edgedamage 40
 +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_melee_animtime 0.3
 +set g_balance_laser_melee_damage 80
 +set g_balance_laser_melee_delay 0.25
 +set g_balance_laser_melee_force 200
 +set g_balance_laser_melee_multihit 1
 +set g_balance_laser_melee_no_doubleslap 1
 +set g_balance_laser_melee_nonplayerdamage 40
 +set g_balance_laser_melee_range 120
 +set g_balance_laser_melee_refire 1.25
 +set g_balance_laser_melee_swing_side 120
 +set g_balance_laser_melee_swing_up 30
 +set g_balance_laser_melee_time 0.15
 +set g_balance_laser_melee_traces 10
 +
 +set g_balance_laser_primary 0 // 0 = shockwave attack, 1 = projectile primary
 +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_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 2 // 0 = switch away to last used weapon, 1 = projectile secondary, 2 = melee secondary
 +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_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_shockwave_damage 20
 +set g_balance_laser_shockwave_distance 2000
 +set g_balance_laser_shockwave_edgedamage 0
 +set g_balance_laser_shockwave_force 200
 +set g_balance_laser_shockwave_force_forwardbias 50
 +set g_balance_laser_shockwave_force_zscale 2
 +set g_balance_laser_shockwave_jump_damage 20
 +set g_balance_laser_shockwave_jump_edgedamage 0
 +set g_balance_laser_shockwave_jump_force 300
 +set g_balance_laser_shockwave_jump_force_velocitybias 0
 +set g_balance_laser_shockwave_jump_force_zscale 1.25
 +set g_balance_laser_shockwave_jump_multiplier_accuracy 0.5
 +set g_balance_laser_shockwave_jump_multiplier_distance 0.5
 +set g_balance_laser_shockwave_jump_multiplier_min 0
 +set g_balance_laser_shockwave_jump_radius 150
 +set g_balance_laser_shockwave_multiplier_accuracy 0.5
 +set g_balance_laser_shockwave_multiplier_distance 0.5
 +set g_balance_laser_shockwave_multiplier_min 0
 +set g_balance_laser_shockwave_splash_damage 15
 +set g_balance_laser_shockwave_splash_edgedamage 0
 +set g_balance_laser_shockwave_splash_force 100
 +set g_balance_laser_shockwave_splash_force_forwardbias 50
 +set g_balance_laser_shockwave_splash_multiplier_accuracy 0.5
 +set g_balance_laser_shockwave_splash_multiplier_distance 0.5
 +set g_balance_laser_shockwave_splash_multiplier_min 0
 +set g_balance_laser_shockwave_splash_radius 70
 +set g_balance_laser_shockwave_spread_max 120
 +set g_balance_laser_shockwave_spread_min 25
 +
 +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 300
 +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_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_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.25
 +
 +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_refire 1.1
++set g_balance_rocketlauncher_damage 70
++set g_balance_rocketlauncher_edgedamage 35
 +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_guiderate 90 // max degrees per second
++set g_balance_rocketlauncher_refire 1.2
 +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_switchdelay_drop 0.2
++set g_balance_rocketlauncher_guiderate 70 // 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.3
 +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 qcsrc/client/Main.qc
index 74e9f0407026e6b251f918b1e4549eb47cf94ec4,a06eb5e6584e3ac96f48c489b762ee748ce9a127..ca0c467768da675680410888c683a0c49117c724
@@@ -5,7 -5,7 +5,7 @@@
  entity clearentity_ent;
  void clearentity(entity e)
  {
-       if not(clearentity_ent)
+       if (!clearentity_ent)
        {
                clearentity_ent = spawn();
                clearentity_ent.classname = "clearentity";
@@@ -81,7 -81,7 +81,7 @@@ void CSQC_Init(void
        //registercommand("hud_configure");
        //registercommand("hud_save");
        //registercommand("menu_action");
-       
        ConsoleCommand_macro_init();
  
        registercvar("hud_usecsqc", "1");
        Hook_Precache();
        GibSplash_Precache();
        Casings_Precache();
 -      DamageInfo_Precache();
        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;
@@@ -186,11 -187,11 +186,11 @@@ void Shutdown(void
        if(autocvar_chase_active < 0)
                cvar_set("chase_active", "0");
  
-       if not(isdemo())
+       if (!isdemo())
        {
-               if not(calledhooks & HOOK_START)
+               if (!(calledhooks & HOOK_START))
                        localcmd("\n_cl_hook_gamestart nop\n");
-               if not(calledhooks & HOOK_END)
+               if (!(calledhooks & HOOK_END))
                        localcmd("\ncl_hook_gameend\n");
        }
  }
@@@ -246,7 -247,7 +246,7 @@@ float SetTeam(entity o, float Team
        }
        else
        {
-               if not(o.has_team)
+               if (!o.has_team)
                {
                        o.team = Team;
                        tm = GetTeam(Team, true);
@@@ -287,10 -288,10 +287,10 @@@ void Playerchecker_Think(
                }
                else
                {
-                       if not(e.sort_prev)
+                       if (!e.sort_prev)
                        {
                                // player connected
-                               if not(e)
+                               if (!e)
                                        playerslots[i] = e = spawn();
                                e.sv_entnum = i;
                                e.ping = 0;
@@@ -432,13 -433,13 +432,13 @@@ void Ent_ReadPlayerScore(
  
        self.sv_entnum = n;
  
-       if not(playerslots[self.sv_entnum])
+       if (!(playerslots[self.sv_entnum]))
                playerslots[self.sv_entnum] = spawn();
        o = self.owner = playerslots[self.sv_entnum];
        o.sv_entnum = self.sv_entnum;
        o.gotscores = 1;
  
-       //if not(o.sort_prev)
+       //if (!o.sort_prev)
        //      RegisterPlayer(o);
        //playerchecker will do this for us later, if it has not already done so
  
@@@ -587,7 -588,7 +587,7 @@@ void Ent_Nagger(
                {
                        f = ReadByte();
                        for(j = i-1, b = 1; b < 256; b *= 2, ++j)
-                               if not(f & b)
+                               if (!(f & b))
                                        if(playerslots[j])
                                                playerslots[j].ready = 0;
                }
@@@ -650,7 -651,7 +650,7 @@@ void Ent_ReadSpawnPoint(float is_new) /
        spn_origin_x = ReadShort();
        spn_origin_y = ReadShort();
        spn_origin_z = ReadShort();
-       
        if(is_new)
        {
                self.origin = spn_origin;
                                }
                        }
                        else { self.cnt = particleeffectnum("spawn_point_neutral"); }
-                       
                        self.draw = Spawn_Draw;
                }
        }
@@@ -695,7 -696,7 +695,7 @@@ void Ent_ReadSpawnEvent(float is_new
        // 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();
                        }
                }
        }
-       
        // local spawn actions
        if(is_new && (!entnum || (entnum == player_localentnum)))
        {
                        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));
  }
  
@@@ -817,13 -818,13 +817,13 @@@ void CSQC_Ent_Update(float bIsNewEntity
                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_GAUNTLET: Ent_ReadHook(bIsNewEntity, ENT_CLIENT_GAUNTLET); break;
 +              case ENT_CLIENT_ELECTRO_BEAM: Ent_ReadHook(bIsNewEntity, ENT_CLIENT_ELECTRO_BEAM); break;
 +              case ENT_CLIENT_ARC_BEAM: Ent_ReadHook(bIsNewEntity, ENT_CLIENT_ARC_BEAM); 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_TURRET: ent_turret(); break;
                case ENT_CLIENT_MODEL: CSQCModel_Read(bIsNewEntity); break;
-               case ENT_CLIENT_ITEM: ItemRead(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;
@@@ -881,7 -882,7 +881,7 @@@ void CSQC_Ent_Remove(
  
  void Gamemode_Init()
  {
-       if not(isdemo())
+       if (!isdemo())
        {
                if(!(calledhooks & HOOK_START))
                        localcmd("\n_cl_hook_gamestart ", MapInfo_Type_ToString(gametype), "\n");
@@@ -958,10 -959,10 +958,10 @@@ void Ent_Init(
        electro_shotorigin[1] = decompressShotOrigin(ReadInt24_t());
        electro_shotorigin[2] = decompressShotOrigin(ReadInt24_t());
        electro_shotorigin[3] = decompressShotOrigin(ReadInt24_t());
 -      gauntlet_shotorigin[0] = decompressShotOrigin(ReadInt24_t());
 -      gauntlet_shotorigin[1] = decompressShotOrigin(ReadInt24_t());
 -      gauntlet_shotorigin[2] = decompressShotOrigin(ReadInt24_t());
 -      gauntlet_shotorigin[3] = decompressShotOrigin(ReadInt24_t());
 +      arc_shotorigin[0] = decompressShotOrigin(ReadInt24_t());
 +      arc_shotorigin[1] = decompressShotOrigin(ReadInt24_t());
 +      arc_shotorigin[2] = decompressShotOrigin(ReadInt24_t());
 +      arc_shotorigin[3] = decompressShotOrigin(ReadInt24_t());
  
        if(forcefog)
                strunzone(forcefog);
@@@ -1158,7 -1159,7 +1158,7 @@@ void Net_ReadPingPLReport(
        pi = ReadShort();
        pl = ReadByte();
        ml = ReadByte();
-       if not(playerslots[e])
+       if (!(playerslots[e]))
                return;
        playerslots[e].ping = pi;
        playerslots[e].ping_packetloss = pl / 255.0;
@@@ -1227,8 -1228,8 +1227,8 @@@ float CSQC_Parse_TempEntity(
                        Net_TeamNagger();
                        bHandled = true;
                        break;
 -              case TE_CSQC_LIGHTNINGARC:
 -                      Net_ReadLightningarc();
 +              case TE_CSQC_ARC:
 +                      Net_ReadArc();
                        bHandled = true;
                        break;
                case TE_CSQC_PINGPLREPORT:
                        cl_notice_read();
                        bHandled = true;
                        break;
 +              case TE_CSQC_SHOCKWAVEPARTICLE:
 +                      Net_ReadShockwaveParticle();
 +                      bHandled = true;
 +                      break;
                default:
                        // No special logic for this temporary entity; return 0 so the engine can handle it
                        bHandled = false;
diff --combined qcsrc/client/View.qc
index 5af8b303b02e5ea91c083c9c8add71015368fd5a,8c9d59dd91f9a77e421d746a0b8193a8c449fb0f..d18eba00624e3360a28bc2bfdba6377a1abb31a2
@@@ -127,8 -127,8 +127,8 @@@ vector GetCurrentFov(float fov
        else if(autocvar_cl_spawnzoom && zoomin_effect)
        {
                float spawnzoomfactor = bound(1, autocvar_cl_spawnzoom_factor, 16);
-               
-               current_viewzoom += (autocvar_cl_spawnzoom_speed * (spawnzoomfactor - current_viewzoom) * drawframetime); 
+               current_viewzoom += (autocvar_cl_spawnzoom_speed * (spawnzoomfactor - current_viewzoom) * drawframetime);
                current_viewzoom = bound(1 / spawnzoomfactor, current_viewzoom, 1);
                if(current_viewzoom == 1) { zoomin_effect = 0; }
        }
                setsensitivityscale(pow(current_viewzoom, 1 - zoomsensitivity));
        else
                setsensitivityscale(1);
-               
        makevectors(view_angles);
  
        if(autocvar_cl_velocityzoom && autocvar_cl_velocityzoom_type) // _type = 0 disables velocity zoom too
                                case 1: default: curspeed = vlen(v); break;
                        }
                }
-               
                velocityzoom = bound(0, drawframetime / max(0.000000001, autocvar_cl_velocityzoom_time), 1); // speed at which the zoom adapts to player velocity
                avgspeed = avgspeed * (1 - velocityzoom) + (curspeed / autocvar_cl_velocityzoom_speed) * velocityzoom;
                velocityzoom = exp(float2range11(avgspeed * -autocvar_cl_velocityzoom / 1) * 1);
-               
                //print(ftos(avgspeed), " avgspeed, ", ftos(curspeed), " curspeed, ", ftos(velocityzoom), " return\n"); // for debugging
        }
        else
@@@ -269,7 -269,7 +269,7 @@@ float TrueAimCheck(
        ta = trueaim;
        mv = MOVE_NOMONSTERS;
  
 -      switch(activeweapon)
 +      switch(activeweapon) // WEAPONTODO
        {
                case WEP_TUBA: // no aim
                case WEP_PORTO: // shoots from eye
                                return EnemyHitCheck();
                        }
                        break;
 -              case WEP_ROCKET_LAUNCHER: // projectile has a size!
 +              case WEP_DEVASTATOR: // projectile has a size!
                        mi = '-3 -3 -3';
                        ma = '3 3 3';
                        break;
@@@ -745,7 -745,7 +745,7 @@@ void CSQC_UpdateView(float w, float h
        drawstring('0 0 0', "", '1 1 0', '1 1 1', 0, 0);
  
        if(autocvar_r_fakelight >= 2 || autocvar_r_fullbright)
-       if not(serverflags & SERVERFLAG_ALLOW_FULLBRIGHT)
+       if (!(serverflags & SERVERFLAG_ALLOW_FULLBRIGHT))
        {
                // apply night vision effect
                vector tc_00, tc_01, tc_10, tc_11;
                R_PolygonVertex(autocvar_vid_conheight * '0 1 0', tc_01, rgb, a);
                R_EndPolygon();
        }
-         
        // Draw the aiming reticle for weapons that use it
        // reticle_type is changed to the item we are zooming / aiming with, to decide which reticle to use
        // It must be a persisted float for fading out to work properly (you let go of the zoom button for
                reticle_type = 1; // normal zoom
        else if((activeweapon == WEP_NEX) && button_attack2)
                reticle_type = 2; // nex zoom
-     
        if(reticle_type && autocvar_cl_reticle)
        {
                if(autocvar_cl_reticle_stretch)
                        old_bluralpha = 0;
                }
  
-               // edge detection postprocess handling done second (used by hud_powerup) 
+               // edge detection postprocess handling done second (used by hud_powerup)
                float sharpen_intensity = 0, strength_finished = getstatf(STAT_STRENGTH_FINISHED), invincible_finished = getstatf(STAT_INVINCIBLE_FINISHED);
                if (strength_finished - time > 0) { sharpen_intensity += (strength_finished - time); }
                if (invincible_finished - time > 0) { sharpen_intensity += (invincible_finished - time); }
-               
                sharpen_intensity = bound(0, ((getstati(STAT_HEALTH) > 0) ? sharpen_intensity : 0), 5); // Check to see if player is alive (if not, set 0) - also bound to fade out starting at 5 seconds.
-               
                if(autocvar_hud_powerup && sharpen_intensity > 0)
                {
                        if(sharpen_intensity != old_sharpen_intensity) // reduce cvar_set spam as much as possible
        {
                if(time - hit_time < MAX_TIME_DIFF) // don't play the sound if it's too old.
                        sound(world, CH_INFO, "misc/hit.wav", VOL_BASE, ATTEN_NONE);
-                       
                nextsound_hit_time = time + autocvar_cl_hitsound_antispam_time;
        }
        typehit_time = getstatf(STAT_TYPEHIT_TIME);
-       if(typehit_time > nextsound_typehit_time) 
+       if(typehit_time > nextsound_typehit_time)
        {
                if(time - typehit_time < MAX_TIME_DIFF) // don't play the sound if it's too old.
                        sound(world, CH_INFO, "misc/typehit.wav", VOL_BASE, ATTEN_NONE);
-                       
                nextsound_typehit_time = time + autocvar_cl_hitsound_antispam_time;
        }
  
                                CSQC_common_hud();
  
                // crosshair goes VERY LAST
-               if(!scoreboard_active && !camera_active && intermission != 2 && spectatee_status != -1 && hud == HUD_NORMAL) 
+               if(!scoreboard_active && !camera_active && intermission != 2 && spectatee_status != -1 && hud == HUD_NORMAL)
                {
-                       if not(autocvar_crosshair_enabled) // main toggle for crosshair rendering
+                       if (!autocvar_crosshair_enabled) // main toggle for crosshair rendering
                                return;
-                               
                        string wcross_style;
                        float wcross_alpha, wcross_resolution;
                        wcross_style = autocvar_crosshair;
                        if(autocvar_crosshair_pickup)
                        {
                                float stat_pickup_time = getstatf(STAT_LAST_PICKUP);
-                               
                                if(pickup_crosshair_time < stat_pickup_time)
                                {
                                        if(time - stat_pickup_time < MAX_TIME_DIFF) // don't trigger the animation if it's too old
                                                pickup_crosshair_size = 1;
-                                               
                                        pickup_crosshair_time = stat_pickup_time;
                                }
  
                        if(autocvar_crosshair_hitindication)
                        {
                                vector hitindication_color = ((autocvar_crosshair_color_special == 1) ? stov(autocvar_crosshair_hitindication_per_weapon_color) : stov(autocvar_crosshair_hitindication_color));
-                               
                                if(hitindication_crosshair_time < hit_time)
                                {
                                        if(time - hit_time < MAX_TIME_DIFF) // don't trigger the animation if it's too old
                                                hitindication_crosshair_size = 1;
-                                               
                                        hitindication_crosshair_time = hit_time;
                                }
  
                                        // handle the values
                                        if (autocvar_crosshair_ring && activeweapon == WEP_NEX && nex_charge && autocvar_crosshair_ring_nex) // ring around crosshair representing velocity-dependent damage for the nex
                                        {
-                                               if (nex_chargepool || use_nex_chargepool) { 
-                                                       use_nex_chargepool = 1; 
+                                               if (nex_chargepool || use_nex_chargepool) {
+                                                       use_nex_chargepool = 1;
                                                        ring_inner_value = nex_chargepool;
-                                               } else { 
+                                               } else {
                                                        nex_charge_movingavg = (1 - autocvar_crosshair_ring_nex_currentcharge_movingavg_rate) * nex_charge_movingavg + autocvar_crosshair_ring_nex_currentcharge_movingavg_rate * nex_charge;
-                                                       ring_inner_value = bound(0, autocvar_crosshair_ring_nex_currentcharge_scale * (nex_charge - nex_charge_movingavg), 1); 
+                                                       ring_inner_value = bound(0, autocvar_crosshair_ring_nex_currentcharge_scale * (nex_charge - nex_charge_movingavg), 1);
                                                }
  
                                                ring_inner_alpha = autocvar_crosshair_ring_nex_inner_alpha;
                                                ring_rgb = wcross_color;
                                                ring_image = "gfx/crosshair_ring_nexgun.tga";
                                        }
-                                       else if (autocvar_crosshair_ring && activeweapon == WEP_MINE_LAYER && minelayer_maxmines && autocvar_crosshair_ring_minelayer) 
+                                       else if (autocvar_crosshair_ring && activeweapon == WEP_MINE_LAYER && minelayer_maxmines && autocvar_crosshair_ring_minelayer)
                                        {
                                                ring_value = bound(0, getstati(STAT_LAYED_MINES) / minelayer_maxmines, 1); // if you later need to use the count of bullets in another place, then add a float for it. For now, no need to.
                                                ring_alpha = autocvar_crosshair_ring_minelayer_alpha;
                                                ring_image = "gfx/crosshair_ring.tga";
                                        }
  
-                                       if(autocvar_crosshair_ring_reload && weapon_clipsize) // forces there to be only an ammo ring 
+                                       if(autocvar_crosshair_ring_reload && weapon_clipsize) // forces there to be only an ammo ring
                                        {
                                                ring_value = bound(0, weapon_clipload / weapon_clipsize, 1);
                                                ring_scale = autocvar_crosshair_ring_reload_size;
                                        if(autocvar_crosshair_effect_time > 0)
                                        {
                                                f = (time - wcross_name_changestarttime) / autocvar_crosshair_effect_time;
-                                               if not(f < 1)
+                                               if (!(f < 1))
                                                {
                                                        wcross_ring_prev = ((ring_image) ? TRUE : FALSE);
                                                }
-                                               
                                                if(wcross_ring_prev)
                                                {
                                                        if(f < 1)
                                {
                                        vector wcross_color_old;
                                        wcross_color_old = wcross_color;
-                                       
                                        if((autocvar_crosshair_dot_color_custom) && (autocvar_crosshair_dot_color != "0"))
                                                wcross_color = stov(autocvar_crosshair_dot_color);
-                                               
                                        CROSSHAIR_DRAW(wcross_resolution * autocvar_crosshair_dot_size, "gfx/crosshairdot.tga", f * autocvar_crosshair_dot_alpha);
                                        // FIXME why don't we use wcross_alpha here?cl_notice_run();
                                        wcross_color = wcross_color_old;
  
        if(autocvar__hud_configure)
                HUD_Panel_Mouse();
-     
      if(hud && !intermission)
-     {        
+     {
          if(hud == HUD_SPIDERBOT)
              CSQC_SPIDER_HUD();
          else if(hud == HUD_WAKIZASHI)
          else if(hud == HUD_BUMBLEBEE_GUN)
              CSQC_BUMBLE_GUN_HUD();
      }
-       
        cl_notice_run();
-       
        // let's reset the view back to normal for the end
        setproperty(VF_MIN, '0 0 0');
        setproperty(VF_SIZE, '1 0 0' * w + '0 1 0' * h);
diff --combined qcsrc/client/damage.qc
index 126d27add93bc943cab4be08363977abbc83b806,cc3653db4d2deb21a79aaa188112f83b7e3ae6ec..66f1359fd396f1d367bd93af2a7bee82cbc77e8f
@@@ -85,7 -85,7 +85,7 @@@ void DamageEffect(vector hitorg, float 
        e = get_weaponinfo(type);
  
        effectname = strcat("damage_", e.netname);
-       
        // if damage was dealt with a bullet weapon, our effect is blood
        // since blood is species dependent, include the species tag
        if(type == WEP_SHOTGUN || type == WEP_UZI || type == WEP_RIFLE)
@@@ -133,7 -133,7 +133,7 @@@ void Ent_DamageInfo(float isNew
        force = decompressShortVector(ReadShort());
        species = ReadByte();
  
-       if not(isNew)
+       if (!isNew)
                return;
  
        if(rad < 0)
        }
        else
                forcemul = 1;
-       
        for(self = findradius(w_org, rad + MAX_DAMAGEEXTRARADIUS); self; self = self.chain)
        {
                // attached ents suck
        }
  
        self = oldself;
-       
        if(DEATH_ISVEHICLE(w_deathtype))
        {
                traceline(w_org - normalize(force) * 16, w_org + normalize(force) * 16, MOVE_NOMONSTERS, world);
                        w_backoff = trace_plane_normal;
                else
                        w_backoff = -1 * normalize(w_org - (w_org + normalize(force) * 16));
-               
                setorigin(self, w_org + w_backoff * 2); // for sound() calls
-               
                switch(w_deathtype)
                {
                        case DEATH_VH_CRUSH:
                                break;
-                               
                        // spiderbot
                        case DEATH_VH_SPID_MINIGUN:
                                string _snd;
                                sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_MIN);
                                pointparticles(particleeffectnum("explosion_big"), self.origin, w_backoff * 1000, 1);
                                break;
-             
                        case DEATH_VH_WAKI_GUN:
                                sound(self, CH_SHOTS, "weapons/laserimpact.wav", VOL_BASE, ATTEN_NORM);
                                pointparticles(particleeffectnum("wakizashi_gun_impact"), self.origin, w_backoff * 1000, 1);
                                sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_MIN);
                                pointparticles(particleeffectnum("explosion_big"), self.origin, w_backoff * 1000, 1);
                                break;
-                               
                        case DEATH_VH_RAPT_CANNON:
                                sound(self, CH_SHOTS, "weapons/laserimpact.wav", VOL_BASE, ATTEN_NORM);
                                pointparticles(particleeffectnum("raptor_cannon_impact"), self.origin, w_backoff * 1000, 1);
                                break;
                }
        }
-       
-       
        if(DEATH_ISTURRET(w_deathtype))
        {
                string _snd;
                        w_backoff = trace_plane_normal;
                else
                        w_backoff = -1 * normalize(w_org - (w_org + normalize(force) * 16));
-               
                setorigin(self, w_org + w_backoff * 2); // for sound() calls
-               
                switch(w_deathtype)
-               {   
+               {
                         case DEATH_TURRET_EWHEEL:
                                sound(self, CH_SHOTS, "weapons/laserimpact.wav", VOL_BASE, ATTEN_MIN);
                                pointparticles(particleeffectnum("laser_impact"), self.origin, w_backoff * 1000, 1);
                                break;
-                        
                         case DEATH_TURRET_FLAC:
                                pointparticles(particleeffectnum("hagar_explode"), w_org, '0 0 0', 1);
                                _snd = strcat("weapons/hagexp", ftos(1 + rint(random() * 2)), ".waw");
                                sound(self, CH_SHOTS, _snd, VOL_BASE, ATTEN_NORM);
                                break;
-                               
                         case DEATH_TURRET_MLRS:
                         case DEATH_TURRET_HK:
                         case DEATH_TURRET_WALK_ROCKET:
                                sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_MIN);
                                pointparticles(particleeffectnum("rocket_explode"), self.origin, w_backoff * 1000, 1);
                                break;
-                        
                         case DEATH_TURRET_MACHINEGUN:
                         case DEATH_TURRET_WALK_GUN:
                                _snd = strcat("weapons/ric", ftos(1 + rint(random() * 2)), ".waw");
                                sound(self, CH_SHOTS, _snd, VOL_BASE, ATTEN_NORM);
                                pointparticles(particleeffectnum("machinegun_impact"), self.origin, w_backoff * 1000, 1);
                                break;
-                                                 
                         case DEATH_TURRET_PLASMA:
                                sound(self, CH_SHOTS, "weapons/electro_impact.wav", VOL_BASE, ATTEN_MIN);
                                pointparticles(particleeffectnum("electro_impact"), self.origin, w_backoff * 1000, 1);
                                break;
-                                                 
                         case DEATH_TURRET_WALK_MEELE:
                                sound(self, CH_SHOTS, "weapons/ric1.wav", VOL_BASE, ATTEN_MIN);
                                pointparticles(particleeffectnum("TE_SPARK"), self.origin, w_backoff * 1000, 1);
  
                         case DEATH_TURRET_PHASER:
                                break;
-                               
                         case DEATH_TURRET_TESLA:
                                te_smallflash(self.origin);
                                break;
  
                }
        }
-       
        // TODO spawn particle effects and sounds based on w_deathtype
        if(!DEATH_ISSPECIAL(w_deathtype))
-       if not(hitplayer && !rad) // don't show ground impacts for hitscan weapons if a player was hit
+       if(!hitplayer || rad) // don't show ground impacts for hitscan weapons if a player was hit
        {
                float hitwep;
  
                        w_backoff = -1 * normalize(force);
                setorigin(self, w_org + w_backoff * 2); // for sound() calls
  
 -              (get_weaponinfo(hitwep)).weapon_func(WR_IMPACTEFFECT);
 +              WEP_ACTION(hitwep, WR_IMPACTEFFECT);
        }
  }
 -
 -void DamageInfo_Precache()
 -{
 -      float i;
 -      for(i = WEP_FIRST; i <= WEP_LAST; ++i)
 -              (get_weaponinfo(i)).weapon_func(WR_PRECACHE);
 -}
diff --combined qcsrc/client/hook.qc
index 162063427149c9c3cf8c925d4cd7966d53ac73fe,196730a72dde016cbe3fd28308955ed2c2de6ee1..8beacac88befc88132a24d36e4f3fa3b0b0967c3
@@@ -8,7 -8,7 +8,7 @@@ void Draw_CylindricLine(vector from, ve
  {
        // I want to draw a quad...
        // from and to are MIDPOINTS.
-       
        vector axis, thickdir, A, B, C, D;
        float length_tex;
  
@@@ -75,11 -75,11 +75,11 @@@ void Draw_GrapplingHook(
                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_GAUNTLET:
 -                      vs = gauntlet_shotorigin[s];
 +              case ENT_CLIENT_ARC_BEAM:
 +                      vs = lightning_shotorigin[s];
                        break;
        }
  
@@@ -92,8 -92,8 +92,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_GAUNTLET:
 +                      case ENT_CLIENT_ELECTRO_BEAM:
 +                      case ENT_CLIENT_ARC_BEAM:
                                if(self.HookRange)
                                        b = view_origin + view_forward * self.HookRange;
                                else
                                a = self.velocity;
                                b = self.origin;
                                break;
 -                      case ENT_CLIENT_LGBEAM:
 -                      case ENT_CLIENT_GAUNTLET:
 +                      case ENT_CLIENT_ELECTRO_BEAM:
 +                      case ENT_CLIENT_ARC_BEAM:
                                a = self.origin;
                                b = self.velocity;
                                break;
                                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_GAUNTLET:
 -                      intensity = 1;
 -                      offset = Noise_White(self, frametime);
 -                      tex = "particles/gauntletbeam";
 +              case ENT_CLIENT_ARC_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";
                        rgb = '1 1 1';
                        break;
        }
                                self.drawmask = 0;
                        }
                        break;
 -              case ENT_CLIENT_LGBEAM:
 -              case ENT_CLIENT_GAUNTLET:
 +              case ENT_CLIENT_ELECTRO_BEAM:
 +              case ENT_CLIENT_ARC_BEAM:
                        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_GAUNTLET:
 -                      pointparticles(particleeffectnum("gauntlet_lightning"), b, normalize(a - b), frametime * intensity);
 +              case ENT_CLIENT_ARC_BEAM:
 +                      pointparticles(particleeffectnum("electro_lightning"), trace_endpos, normalize(atrans - trace_endpos), frametime * intensity); // todo: new effect
                        break;
        }
  }
@@@ -237,10 -237,10 +237,10 @@@ void Ent_ReadHook(float bIsNew, float t
                {
                        default:
                        case ENT_CLIENT_HOOK:
 -                      case ENT_CLIENT_GAUNTLET:
                                self.HookRange = 0;
                                break;
 -                      case ENT_CLIENT_LGBEAM:
 +                      case ENT_CLIENT_ELECTRO_BEAM:
 +                      case ENT_CLIENT_ARC_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, CH_SHOTS_SINGLE, "weapons/lgbeam_fly.wav", VOL_BASE, ATTEN_NORM);
                                break;
 -                      case ENT_CLIENT_GAUNTLET:
 -                              sound (self, CH_SHOTS_SINGLE, "weapons/gauntletbeam_fly.wav", VOL_BASE, ATTEN_NORM);
 +                      case ENT_CLIENT_ARC_BEAM:
 +                              sound (self, CH_SHOTS_SINGLE, "weapons/lgbeam_fly.wav", VOL_BASE, ATTEN_NORM);
                                break;
                }
        }
  void Hook_Precache()
  {
        precache_sound("weapons/lgbeam_fly.wav");
 -      precache_sound("weapons/gauntletbeam_fly.wav");
        precache_model("models/hook.md3");
  }
  
diff --combined qcsrc/client/hud.qc
index cef9b701c3d1ed19067540f705a753c5a78c4404,a78177b1991c5783e5e9b185cc5225d6a0d447d3..b9e3ca6f1f2a73f9ac579bb1958b4ffb04517463
@@@ -142,16 -142,16 +142,16 @@@ float stringwidth_nocolors(string s, ve
        return stringwidth(s, FALSE, theSize);
  }
  
- void drawstringright(vector position, string text, vector scale, vector rgb, float theAlpha, float flag)
+ void drawstringright(vector position, string text, vector theScale, vector rgb, float theAlpha, float flag)
  {
-       position_x -= 2 / 3 * strlen(text) * scale_x;
-       drawstring(position, text, scale, rgb, theAlpha, flag);
+       position_x -= 2 / 3 * strlen(text) * theScale_x;
+       drawstring(position, text, theScale, rgb, theAlpha, flag);
  }
  
- void drawstringcenter(vector position, string text, vector scale, vector rgb, float theAlpha, float flag)
+ void drawstringcenter(vector position, string text, vector theScale, vector rgb, float theAlpha, float flag)
  {
-       position_x = 0.5 * (vid_conwidth - 0.6025 * strlen(text) * scale_x);
-       drawstring(position, text, scale, rgb, theAlpha, flag);
+       position_x = 0.5 * (vid_conwidth - 0.6025 * strlen(text) * theScale_x);
+       drawstring(position, text, theScale, rgb, theAlpha, flag);
  }
  
  // return the string of the onscreen race timer
@@@ -242,7 -242,7 +242,7 @@@ float GetPlayerColorForce(float i
  
  float GetPlayerColor(float i)
  {
-       if not(playerslots[i].gotscores) // unconnected
+       if(!playerslots[i].gotscores) // unconnected
                return NUM_SPECTATOR;
        else if(stof(getplayerkeyvalue(i, "frags")) == FRAGS_SPECTATOR)
                return NUM_SPECTATOR;
@@@ -421,7 -421,7 +421,7 @@@ float GetAmmoStat(float i
        }
  }
  
 -float GetAmmoTypeForWep(float i)
 +float GetAmmoTypeForWep(float i) // WEAPONTODO
  {
        switch(i)
        {
                case WEP_NEX: return 3;
                case WEP_RIFLE: return 1;
                case WEP_HAGAR: return 2;
 -              case WEP_ROCKET_LAUNCHER: return 2;
 +              case WEP_DEVASTATOR: return 2;
                case WEP_SEEKER: return 2;
                case WEP_FIREBALL: return 4;
                case WEP_HOOK: return 3;
@@@ -734,12 -734,12 +734,12 @@@ void HUD_Weapons(void
  
                // skip this weapon if we don't own it (and onlyowned is enabled)-- or if weapons_complainbubble is showing for this weapon
                if(autocvar_hud_panel_weapons_onlyowned)
-               if not((weapons_stat & WepSet_FromWeapon(self.weapon)) || (self.weapon == complain_weapon))
+               if (!((weapons_stat & WepSet_FromWeapon(self.weapon)) || (self.weapon == complain_weapon)))
                        continue;
  
                // figure out the drawing position of weapon
-               weapon_pos = (panel_pos 
-                       + eX * column * weapon_size_x 
+               weapon_pos = (panel_pos
+                       + eX * column * weapon_size_x
                        + eY * row * weapon_size_y);
  
                // draw background behind currently selected weapon
@@@ -1133,7 -1133,7 +1133,7 @@@ void HUD_Powerups(void
        {
                if(!autocvar_hud_panel_powerups) return;
                if(spectatee_status == -1) return;
-               if not(getstati(STAT_ITEMS, 0, 24) & (IT_STRENGTH | IT_INVINCIBLE | IT_SUPERWEAPON)) return;
+               if(!(getstati(STAT_ITEMS, 0, 24) & (IT_STRENGTH | IT_INVINCIBLE | IT_SUPERWEAPON))) return;
                if (getstati(STAT_HEALTH) <= 0) return;
  
                strength_time = bound(0, getstatf(STAT_STRENGTH_FINISHED) - time, 99);
@@@ -1416,7 -1416,7 +1416,7 @@@ void HUD_HealthArmor(void
        if(autocvar_hud_panel_healtharmor == 2) // combined health and armor display
        {
                vector v;
-               v = healtharmor_maxdamage(health, armor, armorblockpercent);
+               v = healtharmor_maxdamage(health, armor, armorblockpercent, DEATH_WEAPON);
  
                float x;
                x = floor(v_x + 1);
                                        {
                                                float BLINK_FACTOR = 0.15;
                                                float BLINK_BASE = 0.85;
-                                               float BLINK_FREQ = 9; 
+                                               float BLINK_FREQ = 9;
                                                pain_health_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ);
                                        }
                                }
@@@ -1664,7 -1664,7 +1664,7 @@@ void HUD_Notify(void
        float entries, height;
        entries = bound(1, floor(KN_MAX_ENTRIES * mySize_y/mySize_x), KN_MAX_ENTRIES);
        height = mySize_y/entries;
-       
        vector fontsize;
        float fontheight = height * autocvar_hud_panel_notify_fontsize;
        fontsize = '0.5 0.5 0' * fontheight;
                        {
                                break;
                        }
-                       
                        attacker = notify_attackers[j];
                        victim = notify_victims[j];
                        icon = notify_icon[j];
@@@ -1865,10 -1865,10 +1865,10 @@@ void HUD_Radar(void
                panel_size_y = bound(0.2, panel_size_y, 1) * vid_conheight;
                panel_pos_x = (vid_conwidth - panel_size_x) / 2;
                panel_pos_y = (vid_conheight - panel_size_y) / 2;
-               
                panel_bg = strcat(hud_skin_path, "/border_default"); // always use the default border when maximized
                if(precache_pic(panel_bg) == "") { panel_bg = "gfx/hud/default/border_default"; } // fallback
-               
                switch(hud_panel_radar_maximized_zoommode)
                {
                        default:
                                f = 1;
                                break;
                }
-               
                switch(hud_panel_radar_maximized_rotation)
                {
                        case 0:
                                f = 1;
                                break;
                }
-               
                switch(hud_panel_radar_rotation)
                {
                        case 0:
@@@ -2297,7 -2297,7 +2297,7 @@@ void HUD_Score(void
                        score = tm.(teamscores[ts_primary]);
                        if(autocvar__hud_configure)
                                score = 123;
-                       
                        if (score > max_fragcount)
                                max_fragcount = score;
  
@@@ -2752,7 -2752,7 +2752,7 @@@ void HUD_Mod_CTF(vector pos, vector myS
        stat_items = getstati(STAT_ITEMS, 0, 24);
        redflag = (stat_items/IT_RED_FLAG_TAKEN) & 3;
        blueflag = (stat_items/IT_BLUE_FLAG_TAKEN) & 3;
-       
        if(redflag || blueflag)
                mod_active = 1;
        else
@@@ -3029,29 -3029,29 +3029,29 @@@ void HUD_Mod_KH(vector pos, vector mySi
  float kaball_prevstatus; // last remembered status
  float kaball_statuschange_time; // time when the status changed
  
- // we don't need to reset for keepaway since it immediately 
+ // we don't need to reset for keepaway since it immediately
  // autocorrects prevstatus as to if the player has the ball or not
  
  void HUD_Mod_Keepaway(vector pos, vector mySize)
  {
        mod_active = 1; // keepaway should always show the mod HUD
-       
        float BLINK_FACTOR = 0.15;
        float BLINK_BASE = 0.85;
-       float BLINK_FREQ = 5; 
+       float BLINK_FREQ = 5;
        float kaball_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ);
-       
        float stat_items = getstati(STAT_ITEMS, 0, 24);
        float kaball = (stat_items/IT_KEY1) & 1;
-       
        if(kaball != kaball_prevstatus)
        {
                kaball_statuschange_time = time;
                kaball_prevstatus = kaball;
        }
-       
        vector kaball_pos, kaball_size;
-       
        if(mySize_x > mySize_y) {
                kaball_pos = pos + eX * 0.25 * mySize_x;
                kaball_size = eX * 0.5 * mySize_x + eY * mySize_y;
                kaball_pos = pos + eY * 0.25 * mySize_y;
                kaball_size = eY * 0.5 * mySize_y + eX * mySize_x;
        }
-       
        float kaball_statuschange_elapsedtime = time - kaball_statuschange_time;
        float f = bound(0, kaball_statuschange_elapsedtime*2, 1);
-       
        if(kaball_prevstatus && f < 1)
                drawpic_aspect_skin_expanding(kaball_pos, "keepawayball_carrying", kaball_size, '1 1 1', panel_fg_alpha * kaball_alpha, DRAWFLAG_NORMAL, f);
-       
        if(kaball)
                drawpic_aspect_skin(pos, "keepawayball_carrying", eX * mySize_x + eY * mySize_y, '1 1 1', panel_fg_alpha * kaball_alpha * f, DRAWFLAG_NORMAL);
  }
@@@ -3123,7 -3123,7 +3123,7 @@@ void HUD_Mod_Race(vector pos, vector my
        float f; // yet another function has this
        score = me.(scores[ps_primary]);
  
-       if not((scores_flags[ps_primary] & SFL_TIME) && !teamplay) // race/cts record display on HUD
+       if(!(scores_flags[ps_primary] & SFL_TIME) || teamplay) // race/cts record display on HUD
                return; // no records in the actual race
  
        // clientside personal record
@@@ -3591,7 -3591,7 +3591,7 @@@ void HUD_EngineInfo(void
                frametimeavg = (frametimeavg + frametimeavg1 + frametimeavg2 + currentframetime)/4; // average three frametimes into framecounter for slightly more stable fps readings :P
                frametimeavg2 = frametimeavg1;
                frametimeavg1 = frametimeavg;
-               
                float weight;
                weight = cvar("hud_panel_engineinfo_framecounter_exponentialmovingaverage_new_weight");
                if(currentframetime > 0.0001) // filter out insane values which sometimes seem to occur and throw off the average? If you are getting 10,000 fps or more, then you don't need a framerate counter.
@@@ -3669,7 -3669,7 +3669,7 @@@ void HUD_InfoMessages(void
  
        vector fontsize;
        fontsize = '0.20 0.20 0' * mySize_y;
-       
        float a;
        a = panel_fg_alpha;
  
                        s = sprintf(_("^1Press ^3%s^1 for gamemode info"), getcommandkey("server info", "+show_info"));
                        drawInfoMessage(s)
  
-                       if(gametype == MAPINFO_TYPE_ARENA)
-                               s = _("^1Wait for your turn to join");
-                       else if(gametype == MAPINFO_TYPE_LMS)
+                       if(gametype == MAPINFO_TYPE_LMS)
                        {
                                entity sk;
                                sk = playerslots[player_localnum];
                        }
                }
        }
-       else 
+       else
        {
                s = _("^7Press ^3ESC ^7to show HUD options.");
                drawInfoMessage(s)
@@@ -3871,7 -3869,7 +3869,7 @@@ void HUD_Physics(void
                        conversion_factor = 0.0254 * 1.943844492; // 1 m/s = 1.943844492 knots, because 1 knot = 1.852 km/h
                        break;
        }
-       
        vector vel = (csqcplayer ? csqcplayer.velocity : pmove_vel);
  
        float max_speed = floor( autocvar_hud_panel_physics_speed_max * conversion_factor + 0.5 );
                        acceleration = (vlen(vel) - vlen(acc_prevspeed));
                else
                        acceleration = (vlen(vel - '0 0 1' * vel_z) - vlen(acc_prevspeed - '0 0 1' * acc_prevspeed_z));
-               
                acceleration = acceleration * (1 / max(0.0001, f)) * (0.0254 / 9.80665);
-               
                acc_prevspeed = vel;
                acc_prevtime = time;
  
@@@ -4229,9 -4227,9 +4227,9 @@@ void HUD_CenterPrint (void
                if (scoreboard_bottom >= 0.96 * vid_conheight)
                        return;
                vector target_pos;
-               
                target_pos = eY * scoreboard_bottom + eX * 0.5 * (vid_conwidth - panel_size_x);
-               
                if(target_pos_y > panel_pos_y)
                {
                        panel_pos = panel_pos + (target_pos - panel_pos) * sqrt(scoreboard_fade_alpha);
                }
  
  
-               // fade the centerprint_hud in/out 
+               // fade the centerprint_hud in/out
                if(centerprint_time[j] < 0)
                        a = bound(0, (time - centerprint_expire_time[j]) / max(0.0001, autocvar_hud_panel_centerprint_fade_in), 1);
                else if(centerprint_expire_time[j] - autocvar_hud_panel_centerprint_fade_out > time)
                        a = (centerprint_expire_time[j] - time) / max(0.0001, autocvar_hud_panel_centerprint_fade_out);
                else
                        a = 0;
-               
                // set the size from fading in/out before subsequent fading
-               sz = autocvar_hud_panel_centerprint_fade_minfontsize + a * (1 - autocvar_hud_panel_centerprint_fade_minfontsize); 
-               
+               sz = autocvar_hud_panel_centerprint_fade_minfontsize + a * (1 - autocvar_hud_panel_centerprint_fade_minfontsize);
                // also fade it based on positioning
                if(autocvar_hud_panel_centerprint_fade_subsequent)
                {
                        a = a * bound(autocvar_hud_panel_centerprint_fade_subsequent_passone_minalpha, (1 - (g / max(1, autocvar_hud_panel_centerprint_fade_subsequent_passone))), 1); // pass one: all messages after the first have half theAlpha
                        a = a * bound(autocvar_hud_panel_centerprint_fade_subsequent_passtwo_minalpha, (1 - (g / max(1, autocvar_hud_panel_centerprint_fade_subsequent_passtwo))), 1); // pass two: after that, gradually lower theAlpha even more for each message
                }
-               
                // finally set the size based on the new theAlpha from subsequent fading
-               sz = sz * (autocvar_hud_panel_centerprint_fade_subsequent_minfontsize + a * (1 - autocvar_hud_panel_centerprint_fade_subsequent_minfontsize)); 
+               sz = sz * (autocvar_hud_panel_centerprint_fade_subsequent_minfontsize + a * (1 - autocvar_hud_panel_centerprint_fade_subsequent_minfontsize));
                drawfontscale = sz * '1 1 0';
-               
                if (centerprint_countdown_num[j])
                        n = tokenizebyseparator(strreplace("^COUNT", count_seconds(centerprint_countdown_num[j]), centerprint_messages[j]), "\n");
                else
                        }
                }
  
-               ++g; // move next position number up 
-               
+               ++g; // move next position number up
                msg_size = pos_y - msg_size;
                if (autocvar_hud_panel_centerprint_flip)
                {
                        pos_y = current_msg_pos_y - CENTERPRINT_SPACING * fontsize_y;
                        if (a < 1 && centerprint_msgID[j] == 0) // messages with id can be replaced just after they are faded out, so never move over them the next messages
                                pos_y += (msg_size + CENTERPRINT_SPACING * fontsize_y) * (1 - sqrt(sz));
-                               
                        if (pos_y < panel_pos_y) // check if the next message can be shown
                        {
                                drawfontscale = '1 1 0';
                        pos_y += CENTERPRINT_SPACING * fontsize_y;
                        if (a < 1 && centerprint_msgID[j] == 0) // messages with id can be replaced just after they are faded out, so never move over them the next messages
                                pos_y -= (msg_size + CENTERPRINT_SPACING * fontsize_y) * (1 - sqrt(sz));
-                               
                        if(pos_y > panel_pos_y + panel_size_y - fontsize_y) // check if the next message can be shown
                        {
                                drawfontscale = '1 1 0';
index 81b8def2796208cf3bb1c1bd57a0c054bf02db71,2c2fc56df0983219934ebbdd062dda2ca767fc6e..569073694db352e60653334104b6ba971e3dee4a
@@@ -111,7 -111,7 +111,7 @@@ entity GetTeam(float Team, float add
        num = (Team == NUM_SPECTATOR) ? 16 : Team;
        if(teamslots[num])
                return teamslots[num];
-       if not(add)
+       if (!add)
                return world;
        tm = spawn();
        tm.team = Team;
@@@ -302,18 -302,18 +302,18 @@@ var string _drawpic_picpath
                _drawpic_picpath = string_null;\
        } while(0)
  
- void drawpic_aspect_skin_expanding(vector position, string pic, vector scale, vector rgb, float theAlpha, float flag, float fadelerp)
+ void drawpic_aspect_skin_expanding(vector position, string pic, vector theScale, vector rgb, float theAlpha, float flag, float fadelerp)
  {
        float sz;
        sz = expandingbox_sizefactor_from_fadelerp(fadelerp);
  
-       drawpic_aspect_skin(position + expandingbox_resize_centered_box_offset(sz, scale, 1), pic, scale * sz, rgb, theAlpha * (1 - fadelerp), flag);
+       drawpic_aspect_skin(position + expandingbox_resize_centered_box_offset(sz, theScale, 1), pic, theScale * sz, rgb, theAlpha * (1 - fadelerp), flag);
  }
  
- void drawpic_aspect_skin_expanding_two(vector position, string pic, vector scale, vector rgb, float theAlpha, float flag, float fadelerp)
+ void drawpic_aspect_skin_expanding_two(vector position, string pic, vector theScale, vector rgb, float theAlpha, float flag, float fadelerp)
  {
-       drawpic_aspect_skin_expanding(position, pic, scale, rgb, theAlpha, flag, fadelerp);
-       drawpic_skin(position, pic, scale, rgb, theAlpha * fadelerp, flag);
+       drawpic_aspect_skin_expanding(position, pic, theScale, rgb, theAlpha, flag, fadelerp);
+       drawpic_skin(position, pic, theScale, rgb, theAlpha * fadelerp, flag);
  }
  #define SET_POS_AND_SZ_Y_ASPECT(allow_colors)\
        float textaspect, oldsz;\
@@@ -341,14 -341,14 +341,14 @@@ void drawcolorcodedstring_aspect(vecto
  }
  
  vector drawfontscale;
- void drawstring_expanding(vector position, string text, vector scale, vector rgb, float theAlpha, float flag, float fadelerp)
+ void drawstring_expanding(vector position, string text, vector theScale, vector rgb, float theAlpha, float flag, float fadelerp)
  {
        float sz;
        sz = expandingbox_sizefactor_from_fadelerp(fadelerp);
  
        drawfontscale = sz * '1 1 0';
        dummyfunction(0, 0, 0, 0, 0, 0, 0, 0);
-       drawstring(position + expandingbox_resize_centered_box_offset(sz, scale, stringwidth(text, FALSE, scale * (sz / drawfontscale_x)) / (scale_x * sz)), text, scale * (sz / drawfontscale_x), rgb, theAlpha * (1 - fadelerp), flag);
+       drawstring(position + expandingbox_resize_centered_box_offset(sz, theScale, stringwidth(text, FALSE, theScale * (sz / drawfontscale_x)) / (theScale_x * sz)), text, theScale * (sz / drawfontscale_x), rgb, theAlpha * (1 - fadelerp), flag);
        // width parameter:
        //    (scale_x * sz / drawfontscale_x) * drawfontscale_x * SIZE1 / (scale_x * sz)
        //    SIZE1
@@@ -361,14 -361,14 +361,14 @@@ void drawstring_aspect_expanding(vecto
        drawstring_expanding(pos, text, '1 1 0' * sz_y, color, theAlpha, drawflag, fadelerp);
  }
  
- void drawcolorcodedstring_expanding(vector position, string text, vector scale, float theAlpha, float flag, float fadelerp)
+ void drawcolorcodedstring_expanding(vector position, string text, vector theScale, float theAlpha, float flag, float fadelerp)
  {
        float sz;
        sz = expandingbox_sizefactor_from_fadelerp(fadelerp);
  
        drawfontscale = sz * '1 1 0';
        dummyfunction(0, 0, 0, 0, 0, 0, 0, 0);
-       drawcolorcodedstring(position + expandingbox_resize_centered_box_offset(sz, scale, stringwidth(text, TRUE, scale * (sz / drawfontscale_x)) / (scale_x * sz)), text, scale * (sz / drawfontscale_x), theAlpha * (1 - fadelerp), flag);
+       drawcolorcodedstring(position + expandingbox_resize_centered_box_offset(sz, theScale, stringwidth(text, TRUE, theScale * (sz / drawfontscale_x)) / (theScale_x * sz)), text, theScale * (sz / drawfontscale_x), theAlpha * (1 - fadelerp), flag);
        drawfontscale = '1 1 0';
  }
  
@@@ -385,7 -385,7 +385,7 @@@ float PolyDrawModelSurface(entity e, fl
        vector tri;
        string tex;
        tex = getsurfacetexture(e, i_s);
-       if not(tex)
+       if (!tex)
                return 0; // this is beyond the last one
        n_t = getsurfacenumtriangles(e, i_s);
        for(i_t = 0; i_t < n_t; ++i_t)
@@@ -573,28 -573,14 +573,28 @@@ vector getplayerorigin(float pl
        return GETPLAYERORIGIN_ERROR;
  }
  
 +vector getcsqcplayercolor(float pl)
 +{
 +      entity e;
 +      
 +      e = CSQCModel_server2csqc(pl);
 +      if(e)
 +      {
 +              if(e.colormap > 0)
 +                      return colormapPaletteColor(((e.colormap >= 1024) ? e.colormap : stof(getplayerkeyvalue(e.colormap - 1, "colors"))) & 0x0F, TRUE);
 +      }
 +      
 +      return '1 1 1';
 +}
 +
  float getplayerisdead(float pl)
  {
        entity e;
-       
        e = CSQCModel_server2csqc(pl + 1);
        if(e)
                return e.csqcmodel_isdead;
-       
        return FALSE;
  }
  
index 4d729905aae1bb53050b24971396849c30f71d93,ce8b6dd7f9ecbe612a0aeb52d87650633d6228e7..2f05e1d1c4f00c8106a34154b386099dcefcb7fe
@@@ -290,9 -290,9 +290,9 @@@ void Net_ReadNexgunBeamParticle(
        shotorg_x = ReadCoord(); shotorg_y = ReadCoord(); shotorg_z = ReadCoord();
        endpos_x = ReadCoord(); endpos_y = ReadCoord(); endpos_z = ReadCoord();
        charge = ReadByte() / 255.0;
-       
        pointparticles(particleeffectnum("nex_muzzleflash"), shotorg, normalize(endpos - shotorg) * 1000, 1);
-       
        //draw either the old v2.3 beam or the new beam
        charge = sqrt(charge); // divide evenly among trail spacing and alpha
        particles_alphamin = particles_alphamax = particles_fade = charge;
        else
                WarpZone_TrailParticles_WithMultiplier(world, particleeffectnum("nex_beam"), shotorg, endpos, 1, PARTICLES_USEALPHA | PARTICLES_USEFADE);
  }
 +
 +.vector sw_shotorg;
 +.vector sw_endpos;
 +.float sw_spread_max;
 +.float sw_spread_min;
 +.float sw_time;
 +
 +void Draw_Shockwave()
 +{
 +      float a = bound(0, (0.5 - ((time - self.sw_time) / 0.4)), 0.5);
 +
 +      if not(a) { remove(self); }
 +      
 +      vector deviation, angle;
 +
 +      vector sw_color = getcsqcplayercolor(self.sv_entnum); // GetTeamRGB(GetPlayerColor(self.sv_entnum));
 +
 +      vector first_min_end = '0 0 0', prev_min_end = '0 0 0', new_min_end = '0 0 0';
 +      vector first_max_end = '0 0 0', prev_max_end = '0 0 0', new_max_end = '0 0 0';
 +
 +      float new_max_dist, new_min_dist;
 +      
 +      vector shotdir = normalize(self.sw_endpos - self.sw_shotorg);
 +      vectorvectors(shotdir);
 +      vector right = v_right;
 +      vector up = v_up;
 +      
 +      float counter, dist_before_normal = 200, shots = 20;
 +      
 +      vector min_end = ((self.sw_shotorg + (shotdir * dist_before_normal)) + (up * self.sw_spread_min));
 +      vector max_end = (self.sw_endpos + (up * self.sw_spread_max));
 +      
 +      float spread_to_min = vlen(normalize(min_end - self.sw_shotorg) - shotdir);
 +      float spread_to_max = vlen(normalize(max_end - min_end) - shotdir);
 +      
 +      for(counter = 0; counter < shots; ++counter)
 +      {
 +              // perfect circle effect lines
 +              angle = '0 0 0';
 +              makevectors('0 360 0' * (0.75 + (counter - 0.5) / shots));
 +              angle_y = v_forward_x;
 +              angle_z = v_forward_y;
 +
 +              // first do the spread_to_min effect
 +              deviation = angle * spread_to_min;
 +              deviation = ((shotdir + (right * deviation_y) + (up * deviation_z)));
 +              new_min_dist = dist_before_normal;
 +              new_min_end = (self.sw_shotorg + (deviation * new_min_dist));
 +              //te_lightning2(world, new_min_end, self.sw_shotorg);
 +
 +              // then calculate spread_to_max effect
 +              deviation = angle * spread_to_max;
 +              deviation = ((shotdir + (right * deviation_y) + (up * deviation_z)));
 +              new_max_dist = vlen(new_min_end - self.sw_endpos);
 +              new_max_end = (new_min_end + (deviation * new_max_dist));
 +              //te_lightning2(world, new_end, prev_min_end);
 +              
 +
 +              if(counter == 0)
 +              {
 +                      first_min_end = new_min_end;
 +                      first_max_end = new_max_end;
 +              }
 +
 +              if(counter >= 1)
 +              {
 +                      R_BeginPolygon("", DRAWFLAG_NORMAL);
 +                      R_PolygonVertex(prev_min_end, '0 0 0', sw_color, a);
 +                      R_PolygonVertex(new_min_end, '0 0 0', sw_color, a);
 +                      R_PolygonVertex(self.sw_shotorg, '0 0 0', sw_color, a);
 +                      R_EndPolygon();
 +
 +                      R_BeginPolygon("", DRAWFLAG_NORMAL);
 +                      R_PolygonVertex(new_min_end, '0 0 0', sw_color, a);
 +                      R_PolygonVertex(prev_min_end, '0 0 0', sw_color, a);
 +                      R_PolygonVertex(prev_max_end, '0 0 0', sw_color, a);
 +                      R_PolygonVertex(new_max_end, '0 0 0', sw_color, a);
 +                      R_EndPolygon();
 +              }
 +
 +              prev_min_end = new_min_end;
 +              prev_max_end = new_max_end;
 +
 +              if((counter + 1) == shots)
 +              {
 +                      R_BeginPolygon("", DRAWFLAG_NORMAL);
 +                      R_PolygonVertex(prev_min_end, '0 0 0', sw_color, a);
 +                      R_PolygonVertex(first_min_end, '0 0 0', sw_color, a);
 +                      R_PolygonVertex(self.sw_shotorg, '0 0 0', sw_color, a);
 +                      R_EndPolygon();
 +
 +                      R_BeginPolygon("", DRAWFLAG_NORMAL);
 +                      R_PolygonVertex(first_min_end, '0 0 0', sw_color, a);
 +                      R_PolygonVertex(prev_min_end, '0 0 0', sw_color, a);
 +                      R_PolygonVertex(prev_max_end, '0 0 0', sw_color, a);
 +                      R_PolygonVertex(first_max_end, '0 0 0', sw_color, a);
 +                      R_EndPolygon();
 +              }
 +      }
 +}
 +
 +void Net_ReadShockwaveParticle()
 +{
 +      entity shockwave;
 +      shockwave = spawn();
 +      shockwave.draw = Draw_Shockwave;
 +      
 +      shockwave.sw_shotorg_x = ReadCoord(); shockwave.sw_shotorg_y = ReadCoord(); shockwave.sw_shotorg_z = ReadCoord();
 +      shockwave.sw_endpos_x  = ReadCoord(); shockwave.sw_endpos_y  = ReadCoord(); shockwave.sw_endpos_z  = ReadCoord();
 +      
 +      shockwave.sw_spread_max = ReadByte();
 +      shockwave.sw_spread_min = ReadByte();
 +
 +      shockwave.sv_entnum = ReadByte();
 +
 +      shockwave.sw_time = time;
 +}
 +
diff --combined qcsrc/client/progs.src
index d0c503b12388ffe00a16e46a2cdbf98b5d2281ec,fa61033f653b48f75947c6b95ea7a2e062ae8f0b..3449ae258c31b7b2bc2f77c6dd6cd3ea8c910be2
@@@ -18,7 -18,8 +18,7 @@@ Defs.q
  ../common/util.qh
  ../common/test.qh
  ../common/counting.qh
 -../common/items.qh
 -../common/explosion_equation.qh
 +../common/weapons/weapons.qh // TODO
  ../common/mapinfo.qh
  ../common/command/markup.qh
  ../common/command/rpn.qh
@@@ -53,12 -54,11 +53,12 @@@ vehicles/vehicles.q
  ../csqcmodellib/common.qh
  ../csqcmodellib/cl_model.qh
  ../csqcmodellib/cl_player.qh
 -projectile.qh
 +weapons/projectile.qh // TODO
  player_skeleton.qh
  
  sortlist.qc
  miscfunctions.qc
 +../server/t_items.qh
  ../server/t_items.qc
  
  teamradar.qc
@@@ -73,7 -73,7 +73,7 @@@ rubble.q
  hook.qc
  particles.qc
  laser.qc
 -projectile.qc
 +weapons/projectile.qc // TODO
  gibs.qc
  damage.qc
  casings.qc
@@@ -107,7 -107,9 +107,7 @@@ noise.q
  ../common/command/rpn.qc
  ../common/command/generic.qc
  ../common/mapinfo.qc
 -../common/items.qc
 -../server/w_all.qc
 -../common/explosion_equation.qc
 +../common/weapons/weapons.qc // TODO
  ../common/urllib.qc
  command/cl_cmd.qc
  
@@@ -119,5 -121,3 +119,3 @@@ tturrets.q
  
  player_skeleton.qc
  ../common/animdecide.qc
- ../common/if-this-file-errors-scroll-up-and-fix-the-warnings.fteqccfail
index b86c234bdbba9062e6b121cb745efc96050a6351,0000000000000000000000000000000000000000..52f6e2324b5ecd578a15b1556e9ce90279fefc45
mode 100644,000000..100644
--- /dev/null
@@@ -1,535 -1,0 +1,529 @@@
-                               rot = self.avelocity; 
 +.vector iorigin1, iorigin2;
 +.float spawntime;
 +.vector trail_oldorigin;
 +.float trail_oldtime;
 +.float fade_time, fade_rate;
 +
 +void SUB_Stop()
 +{
 +      self.move_velocity = self.move_avelocity = '0 0 0';
 +      self.move_movetype = MOVETYPE_NONE;
 +}
 +
 +.float alphamod;
 +.float count; // set if clientside projectile
 +.float cnt; // sound index
 +.float gravity;
 +.float snd_looping;
 +.float silent;
 +
 +void Projectile_ResetTrail(vector to)
 +{
 +      self.trail_oldorigin = to;
 +      self.trail_oldtime = time;
 +}
 +
 +void Projectile_DrawTrail(vector to)
 +{
 +      vector from;
 +      float t0;
 +
 +      from = self.trail_oldorigin;
 +      t0 = self.trail_oldtime;
 +      self.trail_oldorigin = to;
 +      self.trail_oldtime = time;
 +
 +      // force the effect even for stationary firemine
 +      if(self.cnt == PROJECTILE_FIREMINE)
 +              if(from == to)
 +                      from_z += 1;
 +
 +      if (self.traileffect)
 +      {
 +              particles_alphamin = particles_alphamax = particles_fade = sqrt(self.alpha);
 +              boxparticles(self.traileffect, self, from, to, self.velocity, self.velocity, 1, PARTICLES_USEALPHA | PARTICLES_USEFADE | PARTICLES_DRAWASTRAIL);
 +      }
 +}
 +
 +void Projectile_Draw()
 +{
 +      vector rot;
 +      vector trailorigin;
 +      float f;
 +      float drawn;
 +      float t;
 +      float a;
 +
 +      f = self.move_flags;
 +
 +      if(self.count & 0x80)
 +      {
 +              //self.move_flags &= ~FL_ONGROUND;
 +              if(self.move_movetype == MOVETYPE_NONE || self.move_movetype == MOVETYPE_FLY)
 +                      Movetype_Physics_NoMatchServer();
 +                      // the trivial movetypes do not have to match the
 +                      // server's ticrate as they are ticrate independent
 +                      // NOTE: this assumption is only true if MOVETYPE_FLY
 +                      // projectiles detonate on impact. If they continue
 +                      // moving, we might still be ticrate dependent.
 +              else
 +                      Movetype_Physics_MatchServer(autocvar_cl_projectiles_sloppy);
 +              if(!(self.move_flags & FL_ONGROUND))
 +                      if(self.velocity != '0 0 0')
 +                              self.move_angles = self.angles = vectoangles(self.velocity);
 +      }
 +      else
 +      {
 +              InterpolateOrigin_Do();
 +      }
 +
 +      if(self.count & 0x80)
 +      {
 +              drawn = (time >= self.spawntime - 0.02);
 +              t = max(time, self.spawntime);
 +      }
 +      else
 +      {
 +              drawn = (self.iflags & IFLAG_VALID);
 +              t = time;
 +      }
 +
 +      if(!(f & FL_ONGROUND))
 +      {
 +              rot = '0 0 0';
 +              switch(self.cnt)
 +              {
 +                      /*
 +                      case PROJECTILE_GRENADE:
 +                              rot = '-2000 0 0'; // forward
 +                              break;
 +                      */
 +                      case PROJECTILE_GRENADE_BOUNCING:
 +                              rot = '0 -1000 0'; // sideways
 +                              break;
 +                      case PROJECTILE_NADE_RED_BURN:
 +                      case PROJECTILE_NADE_RED:
 +                      case PROJECTILE_NADE_BLUE_BURN:
 +                      case PROJECTILE_NADE_BLUE:
 +                      case PROJECTILE_NADE_YELLOW_BURN:
 +                      case PROJECTILE_NADE_YELLOW:
 +                      case PROJECTILE_NADE_PINK_BURN:
 +                      case PROJECTILE_NADE_PINK:
 +                      case PROJECTILE_NADE_BURN:
 +                      case PROJECTILE_NADE:
-               case PROJECTILE_BULLET_GLOWING:
-               case PROJECTILE_BULLET_GLOWING_TRACER:
-                       adddynamiclight(self.origin, 50 * a, '1 1 0');
-                       break;
++                              rot = self.avelocity;
 +                              break;
 +                      case PROJECTILE_HOOKBOMB:
 +                              rot = '1000 0 0'; // forward
 +                              break;
 +                      default:
 +                              break;
 +              }
 +              self.angles = AnglesTransform_ToAngles(AnglesTransform_Multiply(AnglesTransform_FromAngles(self.angles), rot * (t - self.spawntime)));
 +      }
 +
 +      vector ang;
 +      ang = self.angles;
 +      ang_x = -ang_x;
 +      makevectors(ang);
 +
 +      a = 1 - (time - self.fade_time) * self.fade_rate;
 +      self.alpha = bound(0, self.alphamod * a, 1);
 +      if(self.alpha <= 0)
 +              drawn = 0;
 +      self.renderflags = 0;
 +
 +      trailorigin = self.origin;
 +      switch(self.cnt)
 +      {
 +          case PROJECTILE_NADE_RED_BURN:
 +              case PROJECTILE_NADE_RED:
 +              case PROJECTILE_NADE_BLUE_BURN:
 +              case PROJECTILE_NADE_BLUE:
 +              case PROJECTILE_NADE_YELLOW_BURN:
 +              case PROJECTILE_NADE_YELLOW:
 +              case PROJECTILE_NADE_PINK_BURN:
 +              case PROJECTILE_NADE_PINK:
 +              case PROJECTILE_NADE_BURN:
 +              case PROJECTILE_NADE:
 +                      trailorigin += v_up * 4;
 +                      break;
 +              case PROJECTILE_GRENADE:
 +              case PROJECTILE_GRENADE_BOUNCING:
 +                      trailorigin += v_right * 1 + v_forward * -10;
 +                      break;
 +              default:
 +                      break;
 +      }
 +      if(drawn)
 +              Projectile_DrawTrail(trailorigin);
 +      else
 +              Projectile_ResetTrail(trailorigin);
 +
 +      self.drawmask = 0;
 +
 +      if(!drawn)
 +              return;
 +
 +      switch(self.cnt)
 +      {
-                       case PROJECTILE_BULLET: setmodel(self, "models/tracer.mdl");self.traileffect = particleeffectnum("tr_bullet"); break;
-                       case PROJECTILE_BULLET_GLOWING: setmodel(self, "models/tracer.mdl");self.traileffect = particleeffectnum("tr_rifle_weak"); break;
-                       case PROJECTILE_BULLET_GLOWING_TRACER: setmodel(self, "models/tracer.mdl");self.traileffect = particleeffectnum("tr_rifle"); break;
++              // Possibly add dlights here.
 +              default:
 +                      break;
 +      }
 +
 +      self.drawmask = MASK_NORMAL;
 +}
 +
 +void loopsound(entity e, float ch, string samp, float vol, float attn)
 +{
 +      if(self.silent)
 +              return;
 +
 +      sound(e, ch, samp, vol, attn);
 +      e.snd_looping = ch;
 +}
 +
 +void Ent_RemoveProjectile()
 +{
 +      if(self.count & 0x80)
 +      {
 +              tracebox(self.origin, self.mins, self.maxs, self.origin + self.velocity * 0.05, MOVE_NORMAL, self);
 +              Projectile_DrawTrail(trace_endpos);
 +      }
 +}
 +
 +void Ent_Projectile()
 +{
 +      float f;
 +
 +      // projectile properties:
 +      //   kind (interpolated, or clientside)
 +      //
 +      //   modelindex
 +      //   origin
 +      //   scale
 +      //   if clientside:
 +      //     velocity
 +      //     gravity
 +      //   soundindex (hardcoded list)
 +      //   effects
 +      //
 +      // projectiles don't send angles, because they always follow the velocity
 +
 +      f = ReadByte();
 +      self.count = (f & 0x80);
 +      self.iflags = (self.iflags & IFLAG_INTERNALMASK) | IFLAG_AUTOANGLES | IFLAG_ANGLES | IFLAG_ORIGIN;
 +      self.solid = SOLID_TRIGGER;
 +      //self.effects = EF_NOMODELFLAGS;
 +
 +      // this should make collisions with bmodels more exact, but it leads to
 +      // projectiles no longer being able to lie on a bmodel
 +      self.move_nomonsters = MOVE_WORLDONLY;
 +      if(f & 0x40)
 +              self.move_flags |= FL_ONGROUND;
 +      else
 +              self.move_flags &= ~FL_ONGROUND;
 +
 +      if(!self.move_time)
 +      {
 +              // for some unknown reason, we don't need to care for
 +              // sv_gameplayfix_delayprojectiles here.
 +              self.move_time = time;
 +              self.spawntime = time;
 +      }
 +      else
 +              self.move_time = max(self.move_time, time);
 +
 +      if(!(self.count & 0x80))
 +              InterpolateOrigin_Undo();
 +
 +      if(f & 1)
 +      {
 +              self.origin_x = ReadCoord();
 +              self.origin_y = ReadCoord();
 +              self.origin_z = ReadCoord();
 +              setorigin(self, self.origin);
 +              if(self.count & 0x80)
 +              {
 +                      self.velocity_x = ReadCoord();
 +                      self.velocity_y = ReadCoord();
 +                      self.velocity_z = ReadCoord();
 +                      if(f & 0x10)
 +                              self.gravity = ReadCoord();
 +                      else
 +                              self.gravity = 0; // none
 +                      self.move_origin = self.origin;
 +                      self.move_velocity = self.velocity;
 +              }
 +
 +              if(time == self.spawntime || (self.count & 0x80) || (f & 0x08))
 +              {
 +                      self.trail_oldorigin = self.origin;
 +                      if(!(self.count & 0x80))
 +                              InterpolateOrigin_Reset();
 +              }
 +
 +              if(f & 0x20)
 +              {
 +                      self.fade_time = time + ReadByte() * ticrate;
 +                      self.fade_rate = 1 / (ReadByte() * ticrate);
 +              }
 +              else
 +              {
 +                      self.fade_time = 0;
 +                      self.fade_rate = 0;
 +              }
 +      }
 +
 +      if(f & 2)
 +      {
 +              self.cnt = ReadByte();
 +
 +              self.silent = (self.cnt & 0x80);
 +              self.cnt = (self.cnt & 0x7F);
 +
 +              self.scale = 1;
 +              self.traileffect = 0;
 +              switch(self.cnt)
 +              {
 +                      case PROJECTILE_ELECTRO: setmodel(self, "models/ebomb.mdl");self.traileffect = particleeffectnum("TR_NEXUIZPLASMA"); break;
 +                      case PROJECTILE_ROCKET: setmodel(self, "models/rocket.md3");self.traileffect = particleeffectnum("TR_ROCKET"); self.scale = 2; break;
-                       
 +                      case PROJECTILE_CRYLINK: setmodel(self, "models/plasmatrail.mdl");self.traileffect = particleeffectnum("TR_CRYLINKPLASMA"); break;
 +                      case PROJECTILE_CRYLINK_BOUNCING: setmodel(self, "models/plasmatrail.mdl");self.traileffect = particleeffectnum("TR_CRYLINKPLASMA"); break;
 +                      case PROJECTILE_ELECTRO_BEAM: setmodel(self, "models/elaser.mdl");self.traileffect = particleeffectnum("TR_NEXUIZPLASMA"); break;
 +                      case PROJECTILE_GRENADE: setmodel(self, "models/grenademodel.md3");self.traileffect = particleeffectnum("TR_GRENADE"); break;
 +                      case PROJECTILE_GRENADE_BOUNCING: setmodel(self, "models/grenademodel.md3");self.traileffect = particleeffectnum("TR_GRENADE"); break;
 +                      case PROJECTILE_MINE: setmodel(self, "models/mine.md3");self.traileffect = particleeffectnum("TR_GRENADE"); break;
 +                      case PROJECTILE_LASER: setmodel(self, "models/laser.mdl");self.traileffect = particleeffectnum(""); break;
 +                      case PROJECTILE_HLAC: setmodel(self, "models/hlac_bullet.md3");self.traileffect = particleeffectnum(""); break;
 +                      case PROJECTILE_PORTO_RED: setmodel(self, "models/grenademodel.md3");self.traileffect = particleeffectnum("TR_WIZSPIKE"); self.scale = 4; break;
 +                      case PROJECTILE_PORTO_BLUE: setmodel(self, "models/grenademodel.md3");self.traileffect = particleeffectnum("TR_WIZSPIKE"); self.scale = 4; break;
 +                      case PROJECTILE_HOOKBOMB: setmodel(self, "models/grenademodel.md3");self.traileffect = particleeffectnum("TR_KNIGHTSPIKE"); break;
 +                      case PROJECTILE_HAGAR: setmodel(self, "models/hagarmissile.mdl");self.traileffect = particleeffectnum("tr_hagar"); self.scale = 0.75; break;
 +                      case PROJECTILE_HAGAR_BOUNCING: setmodel(self, "models/hagarmissile.mdl");self.traileffect = particleeffectnum("tr_hagar"); self.scale = 0.75; break;
 +                      case PROJECTILE_FIREBALL: self.model = ""; self.modelindex = 0; self.traileffect = particleeffectnum("fireball"); break; // particle effect is good enough
 +                      case PROJECTILE_FIREMINE: self.model = ""; self.modelindex = 0; self.traileffect = particleeffectnum("firemine"); break; // particle effect is good enough
 +                      case PROJECTILE_TAG: setmodel(self, "models/laser.mdl"); self.traileffect = particleeffectnum("TR_ROCKET"); break;
 +                      case PROJECTILE_FLAC: setmodel(self, "models/hagarmissile.mdl"); self.scale = 0.4; self.traileffect = particleeffectnum("TR_SEEKER"); break;
 +                      case PROJECTILE_SEEKER: setmodel(self, "models/tagrocket.md3"); self.traileffect = particleeffectnum("TR_SEEKER"); break;
 +
 +                      case PROJECTILE_RAPTORBOMB:    setmodel(self, "models/vehicles/clusterbomb.md3"); self.gravity = 1; self.avelocity = '0 0 180'; self.traileffect = particleeffectnum(""); break;
 +                      case PROJECTILE_RAPTORBOMBLET: setmodel(self, "models/vehicles/bomblet.md3");     self.gravity = 1; self.avelocity = '0 0 180'; self.traileffect = particleeffectnum(""); break;
 +                      case PROJECTILE_RAPTORCANNON:  setmodel(self, "models/plasmatrail.mdl"); self.traileffect = particleeffectnum("TR_CRYLINKPLASMA"); break;
 +
 +                      case PROJECTILE_SPIDERROCKET: setmodel(self, "models/vehicles/rocket02.md3"); self.traileffect = particleeffectnum("spiderbot_rocket_thrust"); break;
 +                      case PROJECTILE_WAKIROCKET:   setmodel(self, "models/vehicles/rocket01.md3");  self.traileffect = particleeffectnum("wakizashi_rocket_thrust"); break;
 +                      case PROJECTILE_WAKICANNON:   setmodel(self, "models/laser.mdl");  self.traileffect = particleeffectnum(""); break;
 +
 +                      case PROJECTILE_BUMBLE_GUN: setmodel(self, "models/elaser.mdl");self.traileffect = particleeffectnum("TR_NEXUIZPLASMA"); break;
 +                      case PROJECTILE_BUMBLE_BEAM: setmodel(self, "models/elaser.mdl");self.traileffect = particleeffectnum("TR_NEXUIZPLASMA"); break;
-                               break;            
++
 +                      case PROJECTILE_NADE_RED: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_red"); break;
 +                      case PROJECTILE_NADE_RED_BURN: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_red_burn"); break;
 +                      case PROJECTILE_NADE_BLUE: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_blue"); break;
 +                      case PROJECTILE_NADE_BLUE_BURN: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_blue_burn"); break;
 +                      case PROJECTILE_NADE_YELLOW: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_yellow"); break;
 +                      case PROJECTILE_NADE_YELLOW_BURN: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_yellow_burn"); break;
 +                      case PROJECTILE_NADE_PINK: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_pink"); break;
 +                      case PROJECTILE_NADE_PINK_BURN: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_pink_burn"); break;
 +                      case PROJECTILE_NADE: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade"); break;
 +                      case PROJECTILE_NADE_BURN: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_burn"); break;
 +
 +                      default:
 +                              error("Received invalid CSQC projectile, can't work with this!");
 +                              break;
 +              }
 +
 +              self.mins = '0 0 0';
 +              self.maxs = '0 0 0';
 +              self.colormod = '0 0 0';
 +              self.move_touch = SUB_Stop;
 +              self.move_movetype = MOVETYPE_TOSS;
 +              self.alphamod = 1;
 +
 +              switch(self.cnt)
 +              {
 +                      case PROJECTILE_ELECTRO:
 +                              // only new engines support sound moving with object
 +                              loopsound(self, CH_SHOTS_SINGLE, "weapons/electro_fly.wav", VOL_BASE, ATTEN_NORM);
 +                              self.mins = '0 0 -4';
 +                              self.maxs = '0 0 -4';
 +                              self.move_movetype = MOVETYPE_BOUNCE;
 +                              self.move_touch = func_null;
 +                              self.move_bounce_factor = g_balance_electro_secondary_bouncefactor;
 +                              self.move_bounce_stopspeed = g_balance_electro_secondary_bouncestop;
 +                              break;
 +                      case PROJECTILE_ROCKET:
 +                              loopsound(self, CH_SHOTS_SINGLE, "weapons/rocket_fly.wav", VOL_BASE, ATTEN_NORM);
 +                              self.mins = '-3 -3 -3';
 +                              self.maxs = '3 3 3';
 +                              break;
 +                      case PROJECTILE_GRENADE:
 +                              self.mins = '-3 -3 -3';
 +                              self.maxs = '3 3 3';
 +                              break;
 +                      case PROJECTILE_NADE_RED_BURN:
 +                      case PROJECTILE_NADE_RED:
 +                      case PROJECTILE_NADE_BLUE_BURN:
 +                      case PROJECTILE_NADE_BLUE:
 +                              self.mins = '-3 -3 -3';
 +                              self.maxs = '3 3 3';
 +                              self.move_movetype = MOVETYPE_BOUNCE;
 +                              self.move_touch = func_null;
 +                              self.scale = 1.5;
 +                              self.avelocity = randomvec() * 720;
 +                              break;
 +                      case PROJECTILE_GRENADE_BOUNCING:
 +                              self.mins = '-3 -3 -3';
 +                              self.maxs = '3 3 3';
 +                              self.move_movetype = MOVETYPE_BOUNCE;
 +                              self.move_touch = func_null;
 +                              self.move_bounce_factor = g_balance_grenadelauncher_bouncefactor;
 +                              self.move_bounce_stopspeed = g_balance_grenadelauncher_bouncestop;
 +                              break;
 +                      case PROJECTILE_NADE_RED_BURN:
 +                      case PROJECTILE_NADE_RED:
 +                      case PROJECTILE_NADE_BLUE_BURN:
 +                      case PROJECTILE_NADE_BLUE:
 +                      case PROJECTILE_NADE_YELLOW_BURN:
 +                      case PROJECTILE_NADE_YELLOW:
 +                      case PROJECTILE_NADE_PINK_BURN:
 +                      case PROJECTILE_NADE_PINK:
 +                      case PROJECTILE_NADE_BURN:
 +                      case PROJECTILE_NADE:
 +                              self.mins = '-16 -16 -16';
 +                              self.maxs = '16 16 16';
 +                              self.move_movetype = MOVETYPE_BOUNCE;
 +                              self.move_touch = func_null;
 +                              self.scale = 1.5;
 +                              self.avelocity = randomvec() * 720;
 +                              break;
 +                      case PROJECTILE_MINE:
 +                              self.mins = '-4 -4 -4';
 +                              self.maxs = '4 4 4';
 +                              break;
 +                      case PROJECTILE_PORTO_RED:
 +                              self.colormod = '2 1 1';
 +                              self.alphamod = 0.5;
 +                              self.move_movetype = MOVETYPE_BOUNCE;
 +                              self.move_touch = func_null;
 +                              break;
 +                      case PROJECTILE_PORTO_BLUE:
 +                              self.colormod = '1 1 2';
 +                              self.alphamod = 0.5;
 +                              self.move_movetype = MOVETYPE_BOUNCE;
 +                              self.move_touch = func_null;
 +                              break;
 +                      case PROJECTILE_HAGAR_BOUNCING:
 +                              self.move_movetype = MOVETYPE_BOUNCE;
 +                              self.move_touch = func_null;
 +                              break;
 +                      case PROJECTILE_CRYLINK_BOUNCING:
 +                              self.move_movetype = MOVETYPE_BOUNCE;
 +                              self.move_touch = func_null;
 +                              break;
 +                      case PROJECTILE_FIREBALL:
 +                              loopsound(self, CH_SHOTS_SINGLE, "weapons/fireball_fly2.wav", VOL_BASE, ATTEN_NORM);
 +                              self.mins = '-16 -16 -16';
 +                              self.maxs = '16 16 16';
 +                              break;
 +                      case PROJECTILE_FIREMINE:
 +                              loopsound(self, CH_SHOTS_SINGLE, "weapons/fireball_fly.wav", VOL_BASE, ATTEN_NORM);
 +                              self.move_movetype = MOVETYPE_BOUNCE;
 +                              self.move_touch = func_null;
 +                              self.mins = '-4 -4 -4';
 +                              self.maxs = '4 4 4';
 +                              break;
 +                      case PROJECTILE_TAG:
 +                              self.mins = '-2 -2 -2';
 +                              self.maxs = '2 2 2';
 +                              break;
 +                      case PROJECTILE_FLAC:
 +                              self.mins = '-2 -2 -2';
 +                              self.maxs = '2 2 2';
 +                              break;
 +                      case PROJECTILE_SEEKER:
 +                              loopsound(self, CH_SHOTS_SINGLE, "weapons/tag_rocket_fly.wav", VOL_BASE, ATTEN_NORM);
 +                              self.mins = '-4 -4 -4';
 +                              self.maxs = '4 4 4';
 +                              break;
 +            case PROJECTILE_RAPTORBOMB:
 +                              self.mins = '-3 -3 -3';
 +                              self.maxs = '3 3 3';
 +                              break;
 +            case PROJECTILE_RAPTORBOMBLET:
 +                              break;
 +            case PROJECTILE_RAPTORCANNON:
 +                              break;
 +            case PROJECTILE_SPIDERROCKET:
 +                loopsound(self, CH_SHOTS_SINGLE, "weapons/tag_rocket_fly.wav", VOL_BASE, ATTEN_NORM);
 +                              break;
 +            case PROJECTILE_WAKIROCKET:
 +                loopsound(self, CH_SHOTS_SINGLE, "weapons/tag_rocket_fly.wav", VOL_BASE, ATTEN_NORM);
-       
++                              break;
 +            /*
 +            case PROJECTILE_WAKICANNON:
 +                              break;
 +                      case PROJECTILE_BUMBLE_GUN:
 +                              // only new engines support sound moving with object
 +                              loopsound(self, CH_SHOTS_SINGLE, "weapons/electro_fly.wav", VOL_BASE, ATTEN_NORM);
 +                              self.mins = '0 0 -4';
 +                              self.maxs = '0 0 -4';
 +                              self.move_movetype = MOVETYPE_BOUNCE;
 +                              self.move_touch = func_null;
 +                              self.move_bounce_factor = g_balance_electro_secondary_bouncefactor;
 +                              self.move_bounce_stopspeed = g_balance_electro_secondary_bouncestop;
 +                              break;
 +                      */
 +                      default:
 +                              break;
 +              }
 +              setsize(self, self.mins, self.maxs);
 +      }
 +
 +      if(self.gravity)
 +      {
 +              if(self.move_movetype == MOVETYPE_FLY)
 +                      self.move_movetype = MOVETYPE_TOSS;
 +              if(self.move_movetype == MOVETYPE_BOUNCEMISSILE)
 +                      self.move_movetype = MOVETYPE_BOUNCE;
 +      }
 +      else
 +      {
 +              if(self.move_movetype == MOVETYPE_TOSS)
 +                      self.move_movetype = MOVETYPE_FLY;
 +              if(self.move_movetype == MOVETYPE_BOUNCE)
 +                      self.move_movetype = MOVETYPE_BOUNCEMISSILE;
 +      }
 +
 +      if(!(self.count & 0x80))
 +              InterpolateOrigin_Note();
 +
 +      self.draw = Projectile_Draw;
 +      self.entremove = Ent_RemoveProjectile;
 +}
 +
 +void Projectile_Precache()
 +{
 +      precache_model("models/ebomb.mdl");
 +      precache_model("models/elaser.mdl");
 +      precache_model("models/grenademodel.md3");
 +      precache_model("models/mine.md3");
 +      precache_model("models/hagarmissile.mdl");
 +      precache_model("models/hlac_bullet.md3");
 +      precache_model("models/laser.mdl");
 +      precache_model("models/plasmatrail.mdl");
 +      precache_model("models/rocket.md3");
 +      precache_model("models/tagrocket.md3");
 +      precache_model("models/tracer.mdl");
++
 +      precache_model("models/weapons/v_ok_grenade.md3");
 +
 +      precache_sound("weapons/electro_fly.wav");
 +      precache_sound("weapons/rocket_fly.wav");
 +      precache_sound("weapons/fireball_fly.wav");
 +      precache_sound("weapons/fireball_fly2.wav");
 +      precache_sound("weapons/tag_rocket_fly.wav");
 +
 +}
index f45ffdfc375a378d89bcf7e363a83781196c8f56,5e8accbd2912ece956d6e9bc36cb1e0092b03afd..1c32c86befbeefdfd74f35f48608a396fdeb1234
@@@ -41,7 -41,7 +41,7 @@@ void Curl_URI_Get_Callback(float id, fl
                strunzone(do_cvar);
        }
        if(!do_exec)
-               if not(do_cvar)
+               if (!do_cvar)
                        print(data);
  }
  
@@@ -57,12 -57,12 +57,12 @@@ void GenericCommand_addtolist(float req
                case CMD_REQUEST_COMMAND:
                {
                        float i;
-                       
                        if(argc >= 2)
                        {
                                string original_cvar = argv(1);
                                string tmp_string = argv(2);
-                               
                                if(cvar_string(original_cvar) == "") // cvar was empty
                                {
                                        cvar_set(original_cvar, tmp_string);
                                else // add it to the end of the list if the list doesn't already have it
                                {
                                        argc = tokenizebyseparator(cvar_string(original_cvar), " ");
-                                       
                                        for(i = 0; i < argc; ++i)
                                                if(argv(i) == tmp_string)
                                                        return; // already in list
-                                                       
                                        cvar_set(original_cvar, strcat(tmp_string, " ", cvar_string(original_cvar)));
                                }
                                return;
                        }
                }
-                       
                default:
                        print("Incorrect parameters for ^2addtolist^7\n");
                case CMD_REQUEST_USAGE:
@@@ -162,7 -162,7 +162,7 @@@ void GenericCommand_qc_curl(float reque
  
                        return;
                }
-                       
                default:
                case CMD_REQUEST_USAGE:
                {
@@@ -181,33 -181,33 +181,33 @@@ void GenericCommand_dumpcommands(float 
                        float fh;
                        string filename = strcat(GetProgramCommandPrefix(), "_dump.txt");
                        fh = fopen(filename, FILE_WRITE);
-                       
                        if(fh >= 0)
                        {
                                #ifdef SVQC
                                        CMD_Write("dump of server console commands:\n");
                                        GameCommand_macro_write_aliases(fh);
-                                       
                                        CMD_Write("\ndump of networked client only commands:\n");
                                        ClientCommand_macro_write_aliases(fh);
-                                       
                                        CMD_Write("\ndump of common commands:\n");
                                        CommonCommand_macro_write_aliases(fh);
  
                                        CMD_Write("\ndump of ban commands:\n");
                                        BanCommand_macro_write_aliases(fh);
                                #endif
-                                                               
                                #ifdef CSQC
                                        CMD_Write("dump of client commands:\n");
                                        LocalCommand_macro_write_aliases(fh);
                                #endif
-                               
                                CMD_Write("\ndump of generic commands:\n");
                                GenericCommand_macro_write_aliases(fh);
-                               
                                print("Completed dump of aliases in ^2data/data/", GetProgramCommandPrefix(), "_dump.txt^7.\n");
-                               
                                fclose(fh);
                        }
                        else
                        }
                        return;
                }
-                       
                default:
                case CMD_REQUEST_USAGE:
                {
@@@ -236,19 -236,19 +236,19 @@@ void GenericCommand_dumpnotifs(float re
                        #ifndef MENUQC
                        float fh, alsoprint = FALSE;
                        string filename = argv(1);
-                       
                        if(filename == "")
                        {
 -                              filename = "notifications.cfg";
 +                              filename = "notifications_dump.cfg";
                                alsoprint = FALSE;
                        }
                        else if(filename == "-")
                        {
 -                              filename = "notifications.cfg";
 +                              filename = "notifications_dump.cfg";
                                alsoprint = TRUE;
                        }
                        fh = fopen(filename, FILE_WRITE);
-                       
                        if(fh >= 0)
                        {
                                Dump_Notifications(fh, alsoprint);
                        #endif
                        return;
                }
-                       
                default:
                case CMD_REQUEST_USAGE:
                {
                        print(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " dumpnotifs [filename]"));
 -                      print("  Where 'filename' is the file to write (default is notifications.cfg),\n");
 +                      print("  Where 'filename' is the file to write (default is notifications_dump.cfg),\n");
 +                      print("  if supplied with '-' output to console as well as default,\n");
 +                      print("  if left blank, it will only write to default.\n");
 +                      return;
 +              }
 +      }
 +}
 +
 +void GenericCommand_dumpweapons(float request) // WEAPONTODO: make this work with other progs than just server
 +{
 +      switch(request)
 +      {
 +              case CMD_REQUEST_COMMAND:
 +              {
 +                      #ifdef SVQC
 +                      wep_config_file = -1;
 +                      wep_config_alsoprint = -1;
 +                      string filename = argv(1);
 +                      
 +                      if(filename == "")
 +                      {
 +                              filename = "weapons_dump.cfg";
 +                              wep_config_alsoprint = FALSE;
 +                      }
 +                      else if(filename == "-")
 +                      {
 +                              filename = "weapons_dump.cfg";
 +                              wep_config_alsoprint = TRUE;
 +                      }
 +                      wep_config_file = fopen(filename, FILE_WRITE);
 +                      
 +                      if(wep_config_file >= 0)
 +                      {
 +                              Dump_Weapon_Settings();
 +                              print(sprintf("Dumping weapons... File located in ^2data/data/%s^7.\n", filename));
 +                              fclose(wep_config_file);
 +                              wep_config_file = -1;
 +                              wep_config_alsoprint = -1;
 +                      }
 +                      else
 +                      {
 +                              print(sprintf("^1Error: ^7Could not open file '%s'!\n", filename));
 +                      }
 +                      #else
 +                      print(_("Weapons dump command only works with sv_cmd.\n"));
 +                      #endif
 +                      return;
 +              }
 +                      
 +              default:
 +              case CMD_REQUEST_USAGE:
 +              {
 +                      print(strcat("\nUsage:^3 ", GetProgramCommandPrefix(), " dumpweapons [filename]"));
 +                      print("  Where 'filename' is the file to write (default is weapons_dump.cfg),\n");
                        print("  if supplied with '-' output to console as well as default,\n");
                        print("  if left blank, it will only write to default.\n");
                        return;
@@@ -338,7 -285,7 +338,7 @@@ void GenericCommand_maplist(float reque
                {
                        string tmp_string;
                        float i;
-                       
                        switch(argv(1))
                        {
                                case "add": // appends new maps to the maplist
                                                        print("maplist: ERROR: ", argv(2), " does not exist!\n");
                                                        break;
                                                }
-                                               
                                                if(cvar_string("g_maplist") == "")
                                                        cvar_set("g_maplist", argv(2));
                                                else
                                                        cvar_set("g_maplist", strcat(argv(2), " ", cvar_string("g_maplist")));
-                                                       
                                                return;
                                        }
                                        break; // go to usage
                                }
-                               
                                case "cleanup": // scans maplist and only adds back the ones which are really usable
                                {
                                        MapInfo_Enumerate();
                                        MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
                                        argc = tokenizebyseparator(cvar_string("g_maplist"), " ");
-                                       
                                        tmp_string = "";
                                        for(i = 0; i < argc; ++i)
                                                if(MapInfo_CheckMap(argv(i)))
                                                        tmp_string = strcat(tmp_string, " ", argv(i));
-                                                       
                                        tmp_string = substring(tmp_string, 1, strlen(tmp_string) - 1);
                                        cvar_set("g_maplist", tmp_string);
-                                       
                                        return;
                                }
-                               
                                case "remove": // scans maplist and only adds back whatever maps were not provided in argv(2)
                                {
                                        if(argc == 3)
                                        {
                                                argc = tokenizebyseparator(cvar_string("g_maplist"), " ");
-                                               
                                                tmp_string = "";
                                                for(i = 0; i < argc; ++i)
                                                        if(argv(i) != argv(2))
                                                                tmp_string = strcat(tmp_string, " ", argv(i));
-                                                               
                                                tmp_string = substring(tmp_string, 1, strlen(tmp_string) - 1);
                                                cvar_set("g_maplist", tmp_string);
-                                               
                                                return;
                                        }
                                        break; // go to usage
                                }
-                               
                                case "shuffle": // randomly shuffle the maplist
                                {
                                        cvar_set("g_maplist", shufflewords(cvar_string("g_maplist")));
                                        return;
                                }
-                                       
                                default: break;
                        }
                }
-                       
                default:
                        print("Incorrect parameters for ^2maplist^7\n");
                case CMD_REQUEST_USAGE:
@@@ -429,7 -376,7 +429,7 @@@ void GenericCommand_nextframe(float req
                        queue_to_execute_next_frame(substring(command, argv_start_index(1), argv_end_index(-1) - argv_start_index(1)));
                        return;
                }
-                       
                default:
                case CMD_REQUEST_USAGE:
                {
@@@ -452,21 -399,21 +452,21 @@@ void GenericCommand_removefromlist(floa
                                string original_cvar = argv(1);
                                string removal = argv(2);
                                string tmp_string;
-                               
                                argc = tokenizebyseparator(cvar_string(original_cvar), " ");
-                               
                                tmp_string = "";
                                for(i = 0; i < argc; ++i)
                                        if(argv(i) != removal)
                                                tmp_string = strcat(tmp_string, " ", argv(i));
-                                               
                                tmp_string = substring(tmp_string, 1, strlen(tmp_string) - 1);
                                cvar_set(original_cvar, tmp_string);
-                               
                                return;
                        }
                }
-                       
                default:
                        print("Incorrect parameters for ^2removefromlist^7\n");
                case CMD_REQUEST_USAGE:
@@@ -503,7 -450,7 +503,7 @@@ void GenericCommand_restartnotifs(floa
                                NOTIF_CENTER_COUNT,
                                NOTIF_MULTI_COUNT,
                                NOTIF_CHOICE_COUNT
-                       ));     
+                       ));
                        Destroy_All_Notifications();
                        CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
                        #else
                        #endif
                        return;
                }
-                       
                default:
                case CMD_REQUEST_USAGE:
                {
@@@ -532,7 -479,7 +532,7 @@@ void GenericCommand_settemp(float reque
                        {
                                float f = cvar_settemp(argv(1), argv(2));
                                if(f == 1)
-                                       dprint("Creating new settemp tracker for ", argv(1), " and setting it to \"", argv(2), "\" temporarily.\n"); 
+                                       dprint("Creating new settemp tracker for ", argv(1), " and setting it to \"", argv(2), "\" temporarily.\n");
                                else if(f == -1)
                                        dprint("Already had a tracker for ", argv(1), ", updating it to \"", argv(2), "\".\n");
                                // else cvar_settemp itself errors out
@@@ -560,15 -507,15 +560,15 @@@ void GenericCommand_settemp_restore(flo
                case CMD_REQUEST_COMMAND:
                {
                        float i = cvar_settemp_restore();
-                       
                        if(i)
                                dprint("Restored ", ftos(i), " temporary cvar settings to their original values.\n");
                        else
                                dprint("Nothing to restore.\n");
-                       
                        return;
                }
-                       
                default:
                case CMD_REQUEST_USAGE:
                {
@@@ -596,7 -543,7 +596,7 @@@ void GenericCommand_runtest(float reque
                                TEST_RunAll();
                        return;
                }
-                       
                default:
                case CMD_REQUEST_USAGE:
                {
@@@ -614,10 -561,10 +614,10 @@@ void GenericCommand_(float request
        {
                case CMD_REQUEST_COMMAND:
                {
-                       
                        return;
                }
-                       
                default:
                case CMD_REQUEST_USAGE:
                {
        GENERIC_COMMAND("addtolist", GenericCommand_addtolist(request, arguments), "Add a string to a cvar") \
        GENERIC_COMMAND("dumpcommands", GenericCommand_dumpcommands(request), "Dump all commands on the program to *_cmd_dump.txt") \
        GENERIC_COMMAND("dumpnotifs", GenericCommand_dumpnotifs(request), "Dump all notifications into notifications_dump.txt") \
 +      GENERIC_COMMAND("dumpweapons", GenericCommand_dumpweapons(request), "Dump all weapons into weapons_dump.txt") \
        GENERIC_COMMAND("maplist", GenericCommand_maplist(request, arguments), "Automatic control of maplist") \
        GENERIC_COMMAND("nextframe", GenericCommand_nextframe(request, arguments, command), "Execute the given command next frame of this VM") \
        GENERIC_COMMAND("qc_curl", GenericCommand_qc_curl(request, arguments), "Queries a URL") \
@@@ -654,10 -600,10 +654,10 @@@ void GenericCommand_macro_help(
  {
        #define GENERIC_COMMAND(name,function,description) \
                { print("  ^2", name, "^7: ", description, "\n"); }
-               
        GENERIC_COMMANDS(0, 0, "")
        #undef GENERIC_COMMAND
-       
        return;
  }
  
@@@ -665,10 -611,10 +665,10 @@@ float GenericCommand_macro_command(floa
  {
        #define GENERIC_COMMAND(name,function,description) \
                { if(name == strtolower(argv(0))) { function; return TRUE; } }
-               
        GENERIC_COMMANDS(CMD_REQUEST_COMMAND, argc, command)
        #undef GENERIC_COMMAND
-       
        return FALSE;
  }
  
@@@ -676,10 -622,10 +676,10 @@@ float GenericCommand_macro_usage(float 
  {
        #define GENERIC_COMMAND(name,function,description) \
                { if(name == strtolower(argv(1))) { function; return TRUE; } }
-               
        GENERIC_COMMANDS(CMD_REQUEST_USAGE, argc, "")
        #undef GENERIC_COMMAND
-       
        return FALSE;
  }
  
@@@ -687,18 -633,18 +687,18 @@@ void GenericCommand_macro_write_aliases
  {
        #define GENERIC_COMMAND(name,function,description) \
                { CMD_Write_Alias("qc_cmd_svmenu", name, description); }
-       
        GENERIC_COMMANDS(0, 0, "")
        #undef GENERIC_COMMAND
-       
        return;
  }
-       
  
  // ===========================================
  //  Main Common Function For Generic Commands
  // ===========================================
- // Commands spread out among all programs (menu, client, and server) 
+ // Commands spread out among all programs (menu, client, and server)
  
  float GenericCommand(string command)
  {
  
        // Guide for working with argc arguments by example:
        // argc:   1    - 2      - 3     - 4
-       // argv:   0    - 1      - 2     - 3 
+       // argv:   0    - 1      - 2     - 3
        // cmd     vote - master - login - password
-       
        if(GenericCommand_macro_command(argc, command)) // continue as usual and scan for normal commands
        {
                return TRUE; // handled by one of the above GenericCommand_* functions
                // test case for terencehill's color codes
                s = strdecolorize(substring(command, argv_start_index(2), argv_end_index(-1) - argv_start_index(2)));
                s2 = "";
-               
                n = strlen(s);
                j = ((6 * max(1, floor(strlen(s)/32 + random() * 2 - 1))) / n) * (1 - 2 * (random() > 0.5));
                f = random() * 6;
index 822d61a72f3bbe0c358d148a2932a664aa270c3a,55d16953f6a04d4a5e4f9bc8c289b5981654704e..1cb3038b17e8f94806074005bc0c569bc20a29f7
@@@ -32,7 -32,7 +32,7 @@@ const float TE_CSQC_PICTURE = 100
  const float TE_CSQC_RACE = 101;
  const float TE_CSQC_ZCURVEPARTICLES = 102;
  const float TE_CSQC_NEXGUNBEAMPARTICLE = 103;
 -const float TE_CSQC_LIGHTNINGARC = 104;
 +const float TE_CSQC_ARC = 104;
  const float TE_CSQC_TEAMNAGGER = 105;
  const float TE_CSQC_PINGPLREPORT = 106;
  const float TE_CSQC_TARGET_MUSIC = 107;
@@@ -42,7 -42,6 +42,7 @@@ const float TE_CSQC_MINELAYER_MAXMINES 
  const float TE_CSQC_HAGAR_MAXROCKETS = 111;
  const float TE_CSQC_VEHICLESETUP = 112;
  const float TE_CSQC_SVNOTICE = 113;
 +const float TE_CSQC_SHOCKWAVEPARTICLE = 114;
  
  const float RACE_NET_CHECKPOINT_HIT_QUALIFYING = 0; // byte checkpoint, short time, short recordtime, string recordholder
  const float RACE_NET_CHECKPOINT_CLEAR = 1;
@@@ -87,8 -86,8 +87,8 @@@ 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_ELECTRO_BEAM = 28;
 +const float ENT_CLIENT_ARC_BEAM = 29;
  const float ENT_CLIENT_ACCURACY = 30;
  const float ENT_CLIENT_SHOWNAMES = 31;
  const float ENT_CLIENT_WARPZONE_TELEPORTED = 32;
@@@ -328,7 -327,6 +328,6 @@@ const float ATTEN_MAX = 3.984375
  const float PROJECTILE_ELECTRO = 1;
  const float PROJECTILE_ROCKET = 2;
  const float PROJECTILE_TAG = 3;
- const float PROJECTILE_BULLET = 4;
  const float PROJECTILE_CRYLINK = 5;
  const float PROJECTILE_ELECTRO_BEAM = 6;
  const float PROJECTILE_GRENADE = 7;
@@@ -343,11 -341,9 +342,9 @@@ const float PROJECTILE_PORTO_BLUE = 15
  const float PROJECTILE_HOOKBOMB = 16;
  const float PROJECTILE_HAGAR = 17;
  const float PROJECTILE_HAGAR_BOUNCING = 18;
- const float PROJECTILE_BULLET_GLOWING = 19;
  const float PROJECTILE_CRYLINK_BOUNCING = 20;
  const float PROJECTILE_FIREBALL = 21;
  const float PROJECTILE_FIREMINE = 22;
- const float PROJECTILE_BULLET_GLOWING_TRACER = 23;
  
  const float PROJECTILE_RAPTORCANNON = 24;
  const float PROJECTILE_RAPTORBOMB = 25;
@@@ -389,6 -385,25 +386,6 @@@ const float WATERLEVEL_NONE = 0
  const float WATERLEVEL_WETFEET = 1;
  const float WATERLEVEL_SWIMMING = 2;
  const float WATERLEVEL_SUBMERGED = 3;
 -
 -const float MAX_SHOT_DISTANCE = 32768;
 -
 -// weapon requests
 -const float WR_SETUP = 1; // (SVQC) setup weapon data
 -const float WR_THINK = 2; // (SVQC) logic to run every frame
 -const float WR_CHECKAMMO1 = 3; // (SVQC) checks ammo for weapon
 -const float WR_CHECKAMMO2 = 4; // (SVQC) checks ammo for weapon
 -const float WR_AIM = 5; // (SVQC) runs bot aiming code for this weapon
 -const float WR_PRECACHE = 6; // (CSQC and SVQC) precaches models/sounds used by this weapon
 -const float WR_SUICIDEMESSAGE = 7; // (SVQC) notification number for suicide message (may inspect w_deathtype for details)
 -const float WR_KILLMESSAGE = 8; // (SVQC) notification number for kill message (may inspect w_deathtype for details)
 -const float WR_RELOAD = 9; // (SVQC) does not need to do anything
 -const float WR_RESETPLAYER = 10; // (SVQC) does not need to do anything
 -const float WR_IMPACTEFFECT = 11; // (CSQC) impact effect
 -const float WR_SWITCHABLE = 12; // (CSQC) impact effect
 -const float WR_PLAYERDEATH = 13; // (SVQC) does not need to do anything
 -const 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
diff --combined qcsrc/common/util.qc
index c4cbaa7bb18a7a44414fe940da1907995dac5050,d1503a7b6b8bae9ea53c37c7bce2717ac64931f4..f2f6505679ca8c11167f451730b0a85a3c1945b5
@@@ -148,7 -148,7 +148,7 @@@ void wordwrap_cb(string s, float l, voi
  float dist_point_line(vector p, vector l0, vector ldir)
  {
        ldir = normalize(ldir);
-       
        // remove the component in line direction
        p = p - (p * ldir) * ldir;
  
@@@ -241,7 -241,7 +241,7 @@@ vector colormapPaletteColor(float c, fl
  string fstrunzone(string s)
  {
        string sc;
-       if not(s)
+       if (!s)
                return s;
        sc = strcat(s, "");
        strunzone(s);
@@@ -264,7 -264,7 +264,7 @@@ void db_save(float db, string pFilename
  {
        float fh, i, n;
        fh = fopen(pFilename, FILE_WRITE);
-       if(fh < 0) 
+       if(fh < 0)
        {
                print(strcat("^1Can't write DB to ", pFilename));
                return;
@@@ -458,7 -458,7 +458,7 @@@ string ScoreString(float pFlags, float 
                valstr = TIME_ENCODED_TOSTRING(pValue);
        else
                valstr = ftos(pValue);
-       
        return valstr;
  }
  
@@@ -664,7 -664,7 +664,7 @@@ string fixPriorityList(string order, fl
                                neworder = strcat(neworder, ftos(w), " ");
                }
        }
-       
        return substring(neworder, 0, strlen(neworder) - 1);
  }
  
@@@ -677,7 -677,7 +677,7 @@@ string mapPriorityList(string order, st
        neworder = "";
        for(i = 0; i < n; ++i)
                neworder = strcat(neworder, mapfunc(argv(i)), " ");
-       
        return substring(neworder, 0, strlen(neworder) - 1);
  }
  
@@@ -702,7 -702,7 +702,7 @@@ string swapInPriorityList(string order
                }
                return substring(s, 0, strlen(s) - 1);
        }
-       
        return order;
  }
  
@@@ -866,7 -866,7 +866,7 @@@ float cvar_settemp(string tmp_cvar, str
  
        created_saved_value = 0;
  
-       if not(tmp_cvar || tmp_value)
+       if (!(tmp_cvar || tmp_value))
        {
                dprint("Error: Invalid usage of cvar_settemp(string, string); !\n");
                return 0;
@@@ -1100,7 -1100,7 +1100,7 @@@ vector rgb_to_hsv(vector rgb
                hsv_y = 0;
        else
                hsv_y = 1 - mi/ma;
-       
        return hsv;
  }
  
@@@ -1118,7 -1118,7 +1118,7 @@@ vector rgb_to_hsl(vector rgb
        ma = max(rgb_x, rgb_y, rgb_z);
  
        hsl_x = rgb_mi_ma_to_hue(rgb, mi, ma);
-       
        hsl_z = 0.5 * (mi + ma);
        if(mi == ma)
                hsl_y = 0;
                hsl_y = (ma - mi) / (2*hsl_z);
        else // if(hsl_z > 0.5)
                hsl_y = (ma - mi) / (2 - 2*hsl_z);
-       
        return hsl;
  }
  
@@@ -1138,7 -1138,7 +1138,7 @@@ vector hsl_to_rgb(vector hsl
                maminusmi = hsl_y * 2 * hsl_z;
        else
                maminusmi = hsl_y * (2 - 2 * hsl_z);
-       
        // hsl_z     = 0.5 * mi + 0.5 * ma
        // maminusmi =     - mi +       ma
        mi = hsl_z - 0.5 * maminusmi;
@@@ -1199,7 -1199,7 +1199,7 @@@ float textLengthUpToWidth(string theTex
                // terminate, as the range still halves each time - but nevertheless, it is
                // guaranteed that it finds ONE valid cutoff place (where "left" is in
                // range, and "right" is outside).
-               
                // terencehill: the following code detects truncated ^xrgb tags (e.g. ^x or ^x4)
                // and decrease left on the basis of the chars detected of the truncated tag
                // Even if the ^xrgb tag is not complete/correct, left is decreased
                                }
                        }
        }
-       
        return left;
  }
  
@@@ -1263,7 -1263,7 +1263,7 @@@ float textLengthUpToLength(string theTe
                // terminate, as the range still halves each time - but nevertheless, it is
                // guaranteed that it finds ONE valid cutoff place (where "left" is in
                // range, and "right" is outside).
-               
                // terencehill: the following code detects truncated ^xrgb tags (e.g. ^x or ^x4)
                // and decrease left on the basis of the chars detected of the truncated tag
                // Even if the ^xrgb tag is not complete/correct, left is decreased
                                }
                        }
        }
-       
        return left;
  }
  
@@@ -1338,7 -1338,7 +1338,7 @@@ string getWrappedLine(float w, vector t
        string s;
  
        s = getWrappedLine_remaining;
-       
        if(w <= 0)
        {
                getWrappedLine_remaining = string_null;
@@@ -1384,7 -1384,7 +1384,7 @@@ string getWrappedLineLen(float w, textL
        string s;
  
        s = getWrappedLine_remaining;
-       
        if(w <= 0)
        {
                getWrappedLine_remaining = string_null;
@@@ -1476,7 -1476,7 +1476,7 @@@ float isGametypeInFilter(float gt, floa
                if(strstrofs(strcat(",", pattern, ","), subpattern2, 0) < 0)
                if(strstrofs(strcat(",", pattern, ","), subpattern3, 0) < 0)
                {
-                       if not(subpattern4)
+                       if (!subpattern4)
                                return 0;
                        if(strstrofs(strcat(",", pattern, ","), subpattern4, 0) < 0)
                                return 0;
@@@ -1712,7 -1712,7 +1712,7 @@@ void check_unacceptable_compiler_bugs(
                error("fteqcc bug introduced with revision 3178 detected. Please upgrade fteqcc to a later revision, downgrade fteqcc to revision 3177, or pester Spike until he fixes it. You can set _allow_unacceptable_compiler_bugs 1 to skip this check, but expect stuff to be horribly broken then.");
  
        string s = "";
-       if not(s)
+       if (!s)
                error("The empty string counts as false. We do not want that!");
  }
  
@@@ -1831,10 -1831,13 +1831,13 @@@ void RandomSelection_Add(entity e, floa
        }
  }
  
- vector healtharmor_maxdamage(float h, float a, float armorblock)
+ #ifndef MENUQC
+ vector healtharmor_maxdamage(float h, float a, float armorblock, float deathtype)
  {
        // NOTE: we'll always choose the SMALLER value...
        float healthdamage, armordamage, armorideal;
+       if (deathtype == DEATH_DROWN)  // Why should armor help here...
+               armorblock = 0;
        vector v;
        healthdamage = (h - 1) / (1 - armorblock); // damage we can take if we could use more health
        armordamage = a + (h - 1); // damage we can take if we could use more armor
        return v;
  }
  
- vector healtharmor_applydamage(float a, float armorblock, float damage)
+ vector healtharmor_applydamage(float a, float armorblock, float deathtype, float damage)
  {
        vector v;
+       if (deathtype == DEATH_DROWN)  // Why should armor help here...
+               armorblock = 0;
        v_y = bound(0, damage * armorblock, a); // save
        v_x = bound(0, damage - v_y, damage); // take
        v_z = 0;
        return v;
  }
+ #endif
  
  string getcurrentmod()
  {
@@@ -2046,7 -2052,7 +2052,7 @@@ float get_model_parameters(string m, fl
        }
        get_model_parameters_fixbone = 0;
  
-       if not(m)
+       if (!m)
                return 1;
  
        if(substring(m, -9, 5) == "_lod1" || substring(m, -9, 5) == "_lod2")
@@@ -2317,12 -2323,12 +2323,12 @@@ float InterpretBoolean(string input
                case "true":
                case "on":
                        return TRUE;
-               
                case "no":
                case "false":
                case "off":
                        return FALSE;
-               
                default: return stof(input);
        }
  }
@@@ -2453,7 -2459,7 +2459,7 @@@ float cubic_speedfunc_is_sane(float sta
        /*
        // if this is the case, the possible zeros of the first derivative are outside
        // 0..1
-       We can calculate this condition as condition 
+       We can calculate this condition as condition
        if(se <= 3)
                return TRUE;
        */
        // (3, [0..3])
        // (3.5, [0.2..2.3])
        // (4, 1)
+       /*
+          On another note:
+          inflection point is always at (2s + e - 3) / (3s + 3e - 6).
+          s + e - 2 == 0: no inflection
+          s + e > 2:
+          0 < inflection < 1 if:
+          0 < 2s + e - 3 < 3s + 3e - 6
+          2s + e > 3 and 2e + s > 3
+          s + e < 2:
+          0 < inflection < 1 if:
+          0 > 2s + e - 3 > 3s + 3e - 6
+          2s + e < 3 and 2e + s < 3
+          Therefore: there is an inflection point iff:
+          e outside (3 - s)/2 .. 3 - s*2
+          in other words, if (s,e) in triangle (1,1)(0,3)(0,1.5) or in triangle (1,1)(3,0)(1.5,0)
+       */
  }
  
  .float FindConnectedComponent_processing;
@@@ -2530,30 -2558,6 +2558,30 @@@ void FindConnectedComponent(entity e, .
                queue_start.FindConnectedComponent_processing = 0;
  }
  
 +#ifdef SVQC
 +vector combine_to_vector(float x, float y, float z)
 +{
 +      vector result; result_x = x; result_y = y; result_z = z;
 +      return result;
 +}
 +
 +vector get_corner_position(entity box, float corner)
 +{
 +      switch(corner)
 +      {
 +              case 1: return combine_to_vector(box.absmin_x, box.absmin_y, box.absmin_z);
 +              case 2: return combine_to_vector(box.absmax_x, box.absmin_y, box.absmin_z);
 +              case 3: return combine_to_vector(box.absmin_x, box.absmax_y, box.absmin_z);
 +              case 4: return combine_to_vector(box.absmin_x, box.absmin_y, box.absmax_z);
 +              case 5: return combine_to_vector(box.absmax_x, box.absmax_y, box.absmin_z);
 +              case 6: return combine_to_vector(box.absmin_x, box.absmax_y, box.absmax_z);
 +              case 7: return combine_to_vector(box.absmax_x, box.absmin_y, box.absmax_z);
 +              case 8: return combine_to_vector(box.absmax_x, box.absmax_y, box.absmax_z);
 +              default: return '0 0 0';
 +      }
 +}
 +#endif
 +
  // todo: this sucks, lets find a better way to do backtraces?
  #ifndef MENUQC
  void backtrace(string msg)
  string CCR(string input)
  {
        // See the autocvar declarations in util.qh for default values
-       
        // foreground/normal colors
-       input = strreplace("^F1", strcat("^", autocvar_hud_colorset_foreground_1), input); 
-       input = strreplace("^F2", strcat("^", autocvar_hud_colorset_foreground_2), input); 
-       input = strreplace("^F3", strcat("^", autocvar_hud_colorset_foreground_3), input); 
-       input = strreplace("^F4", strcat("^", autocvar_hud_colorset_foreground_4), input); 
+       input = strreplace("^F1", strcat("^", autocvar_hud_colorset_foreground_1), input);
+       input = strreplace("^F2", strcat("^", autocvar_hud_colorset_foreground_2), input);
+       input = strreplace("^F3", strcat("^", autocvar_hud_colorset_foreground_3), input);
+       input = strreplace("^F4", strcat("^", autocvar_hud_colorset_foreground_4), input);
  
        // "kill" colors
        input = strreplace("^K1", strcat("^", autocvar_hud_colorset_kill_1), input);
@@@ -2647,15 -2651,15 +2675,15 @@@ float Announcer_PickNumber(float type, 
                        switch(num)
                        {
                                case 10: return ANNCE_NUM_GAMESTART_10;
-                               case 9:  return ANNCE_NUM_GAMESTART_9; 
-                               case 8:  return ANNCE_NUM_GAMESTART_8; 
-                               case 7:  return ANNCE_NUM_GAMESTART_7; 
-                               case 6:  return ANNCE_NUM_GAMESTART_6; 
-                               case 5:  return ANNCE_NUM_GAMESTART_5; 
-                               case 4:  return ANNCE_NUM_GAMESTART_4; 
-                               case 3:  return ANNCE_NUM_GAMESTART_3; 
-                               case 2:  return ANNCE_NUM_GAMESTART_2; 
-                               case 1:  return ANNCE_NUM_GAMESTART_1; 
+                               case 9:  return ANNCE_NUM_GAMESTART_9;
+                               case 8:  return ANNCE_NUM_GAMESTART_8;
+                               case 7:  return ANNCE_NUM_GAMESTART_7;
+                               case 6:  return ANNCE_NUM_GAMESTART_6;
+                               case 5:  return ANNCE_NUM_GAMESTART_5;
+                               case 4:  return ANNCE_NUM_GAMESTART_4;
+                               case 3:  return ANNCE_NUM_GAMESTART_3;
+                               case 2:  return ANNCE_NUM_GAMESTART_2;
+                               case 1:  return ANNCE_NUM_GAMESTART_1;
                        }
                        break;
                }
                        switch(num)
                        {
                                case 10: return ANNCE_NUM_IDLE_10;
-                               case 9:  return ANNCE_NUM_IDLE_9; 
-                               case 8:  return ANNCE_NUM_IDLE_8; 
-                               case 7:  return ANNCE_NUM_IDLE_7; 
-                               case 6:  return ANNCE_NUM_IDLE_6; 
-                               case 5:  return ANNCE_NUM_IDLE_5; 
-                               case 4:  return ANNCE_NUM_IDLE_4; 
-                               case 3:  return ANNCE_NUM_IDLE_3; 
-                               case 2:  return ANNCE_NUM_IDLE_2; 
-                               case 1:  return ANNCE_NUM_IDLE_1; 
+                               case 9:  return ANNCE_NUM_IDLE_9;
+                               case 8:  return ANNCE_NUM_IDLE_8;
+                               case 7:  return ANNCE_NUM_IDLE_7;
+                               case 6:  return ANNCE_NUM_IDLE_6;
+                               case 5:  return ANNCE_NUM_IDLE_5;
+                               case 4:  return ANNCE_NUM_IDLE_4;
+                               case 3:  return ANNCE_NUM_IDLE_3;
+                               case 2:  return ANNCE_NUM_IDLE_2;
+                               case 1:  return ANNCE_NUM_IDLE_1;
                        }
                        break;
                }
                        switch(num)
                        {
                                case 10: return ANNCE_NUM_KILL_10;
-                               case 9:  return ANNCE_NUM_KILL_9; 
-                               case 8:  return ANNCE_NUM_KILL_8; 
-                               case 7:  return ANNCE_NUM_KILL_7; 
-                               case 6:  return ANNCE_NUM_KILL_6; 
-                               case 5:  return ANNCE_NUM_KILL_5; 
-                               case 4:  return ANNCE_NUM_KILL_4; 
-                               case 3:  return ANNCE_NUM_KILL_3; 
-                               case 2:  return ANNCE_NUM_KILL_2; 
-                               case 1:  return ANNCE_NUM_KILL_1; 
+                               case 9:  return ANNCE_NUM_KILL_9;
+                               case 8:  return ANNCE_NUM_KILL_8;
+                               case 7:  return ANNCE_NUM_KILL_7;
+                               case 6:  return ANNCE_NUM_KILL_6;
+                               case 5:  return ANNCE_NUM_KILL_5;
+                               case 4:  return ANNCE_NUM_KILL_4;
+                               case 3:  return ANNCE_NUM_KILL_3;
+                               case 2:  return ANNCE_NUM_KILL_2;
+                               case 1:  return ANNCE_NUM_KILL_1;
                        }
                        break;
                }
                        switch(num)
                        {
                                case 10: return ANNCE_NUM_RESPAWN_10;
-                               case 9:  return ANNCE_NUM_RESPAWN_9; 
-                               case 8:  return ANNCE_NUM_RESPAWN_8; 
-                               case 7:  return ANNCE_NUM_RESPAWN_7; 
-                               case 6:  return ANNCE_NUM_RESPAWN_6; 
-                               case 5:  return ANNCE_NUM_RESPAWN_5; 
-                               case 4:  return ANNCE_NUM_RESPAWN_4; 
-                               case 3:  return ANNCE_NUM_RESPAWN_3; 
-                               case 2:  return ANNCE_NUM_RESPAWN_2; 
-                               case 1:  return ANNCE_NUM_RESPAWN_1; 
+                               case 9:  return ANNCE_NUM_RESPAWN_9;
+                               case 8:  return ANNCE_NUM_RESPAWN_8;
+                               case 7:  return ANNCE_NUM_RESPAWN_7;
+                               case 6:  return ANNCE_NUM_RESPAWN_6;
+                               case 5:  return ANNCE_NUM_RESPAWN_5;
+                               case 4:  return ANNCE_NUM_RESPAWN_4;
+                               case 3:  return ANNCE_NUM_RESPAWN_3;
+                               case 2:  return ANNCE_NUM_RESPAWN_2;
+                               case 1:  return ANNCE_NUM_RESPAWN_1;
                        }
                        break;
                }
                        switch(num)
                        {
                                case 10: return ANNCE_NUM_ROUNDSTART_10;
-                               case 9:  return ANNCE_NUM_ROUNDSTART_9; 
-                               case 8:  return ANNCE_NUM_ROUNDSTART_8; 
-                               case 7:  return ANNCE_NUM_ROUNDSTART_7; 
-                               case 6:  return ANNCE_NUM_ROUNDSTART_6; 
-                               case 5:  return ANNCE_NUM_ROUNDSTART_5; 
-                               case 4:  return ANNCE_NUM_ROUNDSTART_4; 
-                               case 3:  return ANNCE_NUM_ROUNDSTART_3; 
-                               case 2:  return ANNCE_NUM_ROUNDSTART_2; 
-                               case 1:  return ANNCE_NUM_ROUNDSTART_1; 
+                               case 9:  return ANNCE_NUM_ROUNDSTART_9;
+                               case 8:  return ANNCE_NUM_ROUNDSTART_8;
+                               case 7:  return ANNCE_NUM_ROUNDSTART_7;
+                               case 6:  return ANNCE_NUM_ROUNDSTART_6;
+                               case 5:  return ANNCE_NUM_ROUNDSTART_5;
+                               case 4:  return ANNCE_NUM_ROUNDSTART_4;
+                               case 3:  return ANNCE_NUM_ROUNDSTART_3;
+                               case 2:  return ANNCE_NUM_ROUNDSTART_2;
+                               case 1:  return ANNCE_NUM_ROUNDSTART_1;
                        }
                        break;
                }
                        switch(num)
                        {
                                case 10: return ANNCE_NUM_10;
-                               case 9:  return ANNCE_NUM_9; 
-                               case 8:  return ANNCE_NUM_8; 
-                               case 7:  return ANNCE_NUM_7; 
-                               case 6:  return ANNCE_NUM_6; 
-                               case 5:  return ANNCE_NUM_5; 
-                               case 4:  return ANNCE_NUM_4; 
-                               case 3:  return ANNCE_NUM_3; 
-                               case 2:  return ANNCE_NUM_2; 
-                               case 1:  return ANNCE_NUM_1; 
+                               case 9:  return ANNCE_NUM_9;
+                               case 8:  return ANNCE_NUM_8;
+                               case 7:  return ANNCE_NUM_7;
+                               case 6:  return ANNCE_NUM_6;
+                               case 5:  return ANNCE_NUM_5;
+                               case 4:  return ANNCE_NUM_4;
+                               case 3:  return ANNCE_NUM_3;
+                               case 2:  return ANNCE_NUM_2;
+                               case 1:  return ANNCE_NUM_1;
                        }
                        break;
                }
diff --combined qcsrc/common/util.qh
index 7aee1aa1997046aa4273f57df5c26cb231710a88,a9f9095c7a40492e6615258364cc0ca059c08620..0239c18af638f519de47a539a3e6a87192aae463
@@@ -6,6 -6,12 +6,12 @@@
  // a dummy macro that prevents the "hanging ;" warning
  #define ENDS_WITH_CURLY_BRACE
  
+ #ifdef GMQCC
+ # define ACCUMULATE_FUNCTION(func,otherfunc) \
+       [[accumulate]] void func() { otherfunc(); }
+ # define CALL_ACCUMULATED_FUNCTION(func) \
+       func()
+ #else
  #ifdef HAVE_YO_DAWG_CPP
  // TODO make ascii art pic of xzibit
  // YO DAWG!
@@@ -24,7 -30,7 +30,7 @@@
        func()
  #else
  # define ACCUMULATE_FUNCTION(func,otherfunc) \
-       .void _ACCUMULATE_##func##__##otherfunc;
+       .float _ACCUMULATE_##func##__##otherfunc
  void ACCUMULATE_call(string func)
  {
        float i;
  # define CALL_ACCUMULATED_FUNCTION(func) \
        ACCUMULATE_call(#func)
  #endif
+ #endif
  
  // used for simplifying ACCUMULATE_FUNCTIONs
  #define SET_FIRST_OR_LAST(input,first,count) if(!input) { input = (first + count); }
  #define SET_FIELD_COUNT(field,first,count) if(!field) { field = (first + count); ++count; }
- #define CHECK_MAX_COUNT(name,max,count,type) if(count == max) { error(strcat("Maximum ", type, " hit: ", #name, ": ", ftos(count), ".\n")); }
+ #define CHECK_MAX_COUNT(name,max,count,type) if(count > max) { error(strcat("Maximum ", type, " hit: ", #name, ": ", ftos(count), ".\n")); }
  
  // this returns a tempstring containing a copy of s with additional \n newlines added, it also replaces \n in the text with a real newline
  // NOTE: s IS allowed to be a tempstring
@@@ -94,7 -101,7 +101,7 @@@ void buf_save(float buf, string filenam
  
  // modulo function
  #ifndef MENUQC
- float mod(float a, float b) { return a - (floor(a / b) * b); }   
+ float mod(float a, float b) { return a - (floor(a / b) * b); }
  #endif
  
  #define TIME_TO_NTHS(t,n) floor((t) * (n) + 0.4)
@@@ -220,8 -227,10 +227,10 @@@ string RandomSelection_chosen_string
  void RandomSelection_Init();
  void RandomSelection_Add(entity e, float f, string s, float weight, float priority);
  
- vector healtharmor_maxdamage(float h, float a, float armorblock); // returns vector: maxdamage, armorideal, 1 if fully armored
- vector healtharmor_applydamage(float a, float armorblock, float damage); // returns vector: take, save, 0
+ #ifndef MENUQC
+ vector healtharmor_maxdamage(float h, float a, float armorblock, float deathtype); // returns vector: maxdamage, armorideal, 1 if fully armored
+ vector healtharmor_applydamage(float a, float armorblock, float deathtype, float damage); // returns vector: take, save, 0
+ #endif
  
  string getcurrentmod();
  
@@@ -355,10 -364,6 +364,10 @@@ typedef entity(entity cur, entity near
  typedef float(entity a, entity b, entity pass) isConnectedFunction_t;
  void FindConnectedComponent(entity e, .entity fld, findNextEntityNearFunction_t nxt, isConnectedFunction_t iscon, entity pass);
  
 +#ifdef SVQC
 +vector get_corner_position(entity box, float corner);
 +#endif
 +
  // expand multiple arguments into one argument by stripping parenthesis
  #define XPD(...) __VA_ARGS__
  
index 548058baf58514f507b732522d5927333d76e055,0000000000000000000000000000000000000000..75ddd79ef9fde07ac4ab7bb044ab1f56aa5ca59a
mode 100644,000000..100644
--- /dev/null
@@@ -1,644 -1,0 +1,644 @@@
-       
 +#ifdef REGISTER_WEAPON
 +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",
 +/* netname  */ "electro",
 +/* fullname */ _("Electro")
 +);
 +
 +#ifdef SVQC
 +void ElectroInit();
 +vector electro_shotorigin[4];
 +var float autocvar_g_balance_electro_combo_comboradius_thruwall = 200;
 +#endif
 +#else
 +#ifdef SVQC
 +void spawnfunc_weapon_electro() { weapon_defaultspawnfunc(WEP_ELECTRO); }
 +
 +.float electro_count;
 +.float electro_secondarytime;
 +
 +void W_Plasma_Explode_Combo (void);
 +
 +void W_Plasma_TriggerCombo(vector org, float rad, entity own)
 +{
 +      entity e;
 +      e = WarpZone_FindRadius(org, rad, !autocvar_g_balance_electro_combo_comboradius_thruwall);
 +      while (e)
 +      {
 +              if (e.classname == "plasma")
 +              {
 +                      // change owner to whoever caused the combo explosion
 +                      WarpZone_TraceLine(org, e.origin, MOVE_NOMONSTERS, e);
 +
 +                      if((trace_fraction == 1) || (autocvar_g_balance_electro_combo_comboradius_thruwall > e.WarpZone_findradius_dist))
 +                      {
 +                              e.realowner = own;
 +                              e.takedamage = DAMAGE_NO;
 +                              e.classname = "plasma_chain";
 +                              e.think = W_Plasma_Explode_Combo;
 +                              e.nextthink = time + vlen(e.WarpZone_findradius_dist) / autocvar_g_balance_electro_combo_speed; // delay combo chains, looks cooler
 +                      }
 +              }
 +              e = e.chain;
 +      }
 +}
 +
 +void W_Plasma_Explode (void)
 +{
 +      if(other.takedamage == DAMAGE_AIM)
 +              if(IS_PLAYER(other))
 +                      if(DIFF_TEAM(self.realowner, other))
 +                              if(other.deadflag == DEAD_NO)
 +                                      if(IsFlying(other))
 +                                              Send_Notification(NOTIF_ONE, self.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_ELECTROBITCH);
 +
 +      self.event_damage = func_null;
 +      self.takedamage = DAMAGE_NO;
 +      if (self.movetype == MOVETYPE_BOUNCE)
 +      {
 +              RadiusDamage (self, self.realowner, autocvar_g_balance_electro_secondary_damage, autocvar_g_balance_electro_secondary_edgedamage, autocvar_g_balance_electro_secondary_radius, world, world, autocvar_g_balance_electro_secondary_force, self.projectiledeathtype, other);
 +      }
 +      else
 +      {
 +              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, 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.realowner);
 +
 +      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, 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);
 +}
 +
 +void W_Plasma_Touch (void)
 +{
 +      //self.velocity = self.velocity  * 0.1;
 +
 +      PROJECTILE_TOUCH;
 +      if (other.takedamage == DAMAGE_AIM) {
 +              W_Plasma_Explode ();
 +      } else {
 +              //UpdateCSQCProjectile(self);
 +              spamsound (self, CH_SHOTS, "weapons/electro_bounce.wav", VOL_BASE, ATTEN_NORM);
 +              self.projectiledeathtype |= HITTYPE_BOUNCE;
 +      }
 +}
 +
 +void W_Plasma_TouchExplode (void)
 +{
 +      PROJECTILE_TOUCH;
 +      W_Plasma_Explode ();
 +}
 +
 +void W_Plasma_Damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
 +{
 +      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");
-               return; // g_projectiles_damage says to halt    
-       
++
 +      if (!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, (is_combo ? 1 : -1)))
-       if not(owner_player.items & IT_UNLIMITED_WEAPON_AMMO)
++              return; // g_projectiles_damage says to halt
++
 +      self.health = self.health - damage;
 +      if (self.health <= 0)
 +      {
 +              self.takedamage = DAMAGE_NO;
 +              self.nextthink = time;
 +              if (is_combo)
 +              {
 +                      // change owner to whoever caused the combo explosion
 +                      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
 +                              //                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ bounding the length, because inflictor may be in a galaxy far far away (warpzones)
 +              }
 +              else
 +              {
 +                      self.use = W_Plasma_Explode;
 +                      self.think = adaptor_think2use; // not _hittype_splash, as this runs "immediately"
 +              }
 +      }
 +}
 +
 +void W_Electro_Attack()
 +{
 +      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", 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 = proj.realowner = self;
 +      proj.bot_dodge = TRUE;
 +      proj.bot_dodgerating = autocvar_g_balance_electro_primary_damage;
 +      proj.use = W_Plasma_Explode;
 +      proj.think = adaptor_think2use_hittype_splash;
 +      proj.nextthink = time + autocvar_g_balance_electro_primary_lifetime;
 +      PROJECTILE_MAKETRIGGER(proj);
 +      proj.projectiledeathtype = WEP_ELECTRO;
 +      setorigin(proj, w_shotorg);
 +
 +      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;
 +      proj.missile_flags = MIF_SPLASH;
 +
 +      CSQCProjectile(proj, TRUE, PROJECTILE_ELECTRO_BEAM, TRUE);
 +
 +      other = proj; MUTATOR_CALLHOOK(EditProjectile);
 +}
 +
 +void W_Electro_Attack2()
 +{
 +      entity proj;
 +
 +      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
 +
 +      pointparticles(particleeffectnum("electro_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
 +
 +      proj = spawn ();
 +      proj.classname = "plasma";
 +      proj.owner = proj.realowner = self;
 +      proj.use = W_Plasma_Explode;
 +      proj.think = adaptor_think2use_hittype_splash;
 +      proj.bot_dodge = TRUE;
 +      proj.bot_dodgerating = autocvar_g_balance_electro_secondary_damage;
 +      proj.nextthink = time + autocvar_g_balance_electro_secondary_lifetime;
 +      PROJECTILE_MAKETRIGGER(proj);
 +      proj.projectiledeathtype = WEP_ELECTRO | HITTYPE_SECONDARY;
 +      setorigin(proj, w_shotorg);
 +
 +      //proj.glow_size = 50;
 +      //proj.glow_color = 45;
 +      proj.movetype = MOVETYPE_BOUNCE;
 +      W_SETUPPROJECTILEVELOCITY_UP(proj, g_balance_electro_secondary);
 +      proj.touch = W_Plasma_Touch;
 +      setsize(proj, '0 0 -4', '0 0 -4');
 +      proj.takedamage = DAMAGE_YES;
 +      proj.damageforcescale = autocvar_g_balance_electro_secondary_damageforcescale;
 +      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;
 +      p2 = spawn();
 +      copyentity(proj, p2);
 +      setmodel(p2, "models/ebomb.mdl");
 +      setsize(p2, proj.mins, proj.maxs);
 +#endif
 +
 +      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_ELECTRO_BEAM);
 +      sf = sf & 0x7F;
 +      if(sound_allowed(MSG_BROADCAST, self.realowner))
 +              sf |= 0x80;
 +      WriteByte(MSG_ENTITY, sf);
 +      if(sf & 1)
 +      {
 +              WriteByte(MSG_ENTITY, num_for_edict(self.realowner));
 +              WriteCoord(MSG_ENTITY, autocvar_g_balance_electro_primary_range);
 +      }
 +      if(sf & 2)
 +      {
 +              WriteCoord(MSG_ENTITY, self.hook_start_x);
 +              WriteCoord(MSG_ENTITY, self.hook_start_y);
 +              WriteCoord(MSG_ENTITY, self.hook_start_z);
 +      }
 +      if(sf & 4)
 +      {
 +              WriteCoord(MSG_ENTITY, self.hook_end_x);
 +              WriteCoord(MSG_ENTITY, self.hook_end_y);
 +              WriteCoord(MSG_ENTITY, self.hook_end_z);
 +      }
 +      return TRUE;
 +}
 +.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()
 +{
 +      entity owner_player;
 +      owner_player = self.realowner;
 +
 +      owner_player.prevlgfire = time;
 +      if (self != owner_player.lgbeam)
 +      {
 +              remove(self);
 +              return;
 +      }
 +
 +      if (owner_player.weaponentity.state != WS_INUSE || !lgbeam_checkammo() || owner_player.deadflag != DEAD_NO || !owner_player.BUTTON_ATCK || owner_player.freezetag_frozen)
 +      {
 +              if(self == owner_player.lgbeam)
 +                      owner_player.lgbeam = world;
 +              remove(self);
 +              return;
 +      }
 +
 +      self.nextthink = time;
 +
 +      makevectors(owner_player.v_angle);
 +
 +      float dt, f;
 +      dt = frametime;
 +
 +      // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
++      if (!(owner_player.items & IT_UNLIMITED_WEAPON_AMMO))
 +      {
 +              if(autocvar_g_balance_electro_primary_ammo)
 +              {
 +                      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(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)
 +      {
 +              vector force;
 +              force = w_shotdir * autocvar_g_balance_electro_primary_force + '0 0 1' * autocvar_g_balance_electro_primary_force_up;
 +
 +              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(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, owner_player);
 +
 +      // draw effect
 +      if(w_shotorg != self.hook_start)
 +      {
 +              self.SendFlags |= 2;
 +              self.hook_start = w_shotorg;
 +      }
 +      if(w_shotend != self.hook_end)
 +      {
 +              self.SendFlags |= 4;
 +              self.hook_end = w_shotend;
 +      }
 +}
 +
 +// experimental lightning gun
 +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, CH_WEAPON_A, "weapons/lgbeam_fire.wav", VOL_BASE, ATTEN_NORM);
 +
 +      entity beam, oldself;
 +
 +      self.lgbeam = beam = spawn();
 +      beam.classname = "lgbeam";
 +      beam.solid = SOLID_NOT;
 +      beam.think = lgbeam_think;
 +      beam.owner = beam.realowner = self;
 +      beam.movetype = MOVETYPE_NONE;
 +      beam.shot_spread = 0;
 +      beam.bot_dodge = TRUE;
 +      beam.bot_dodgerating = autocvar_g_balance_electro_primary_damage;
 +      Net_LinkEntity(beam, FALSE, 0, lgbeam_send);
 +
 +      oldself = self;
 +      self = beam;
 +      self.think();
 +      self = oldself;
 +}
 +
 +void ElectroInit()
 +{
 +      WEP_ACTION(WEP_ELECTRO, WR_INIT);
 +      electro_shotorigin[0] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ELECTRO), FALSE, FALSE, 1);
 +      electro_shotorigin[1] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ELECTRO), FALSE, FALSE, 2);
 +      electro_shotorigin[2] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ELECTRO), FALSE, FALSE, 3);
 +      electro_shotorigin[3] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ELECTRO), FALSE, FALSE, 4);
 +}
 +
 +void w_electro_checkattack()
 +{
 +      if(self.electro_count > 1)
 +      if(self.BUTTON_ATCK2)
 +      if(weapon_prepareattack(1, -1))
 +      {
 +              W_Electro_Attack2();
 +              self.electro_count -= 1;
 +              weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_electro_secondary_animtime, w_electro_checkattack);
 +              return;
 +      }
 +
 +      w_ready();
 +}
 +
 +.float bot_secondary_electromooth;
 +.float BUTTON_ATCK_prev;
 +float w_electro(float req)
 +{
 +      float ammo_amount;
 +      switch(req)
 +      {
 +              case WR_AIM:
 +              {
 +                      self.BUTTON_ATCK=FALSE;
 +                      self.BUTTON_ATCK2=FALSE;
 +                      if(vlen(self.origin-self.enemy.origin) > 1000)
 +                              self.bot_secondary_electromooth = 0;
 +                      if(self.bot_secondary_electromooth == 0)
 +                      {
 +                              float shoot;
 +
 +                              if(autocvar_g_balance_electro_primary_speed)
 +                                      shoot = bot_aim(autocvar_g_balance_electro_primary_speed, 0, autocvar_g_balance_electro_primary_lifetime, FALSE);
 +                              else
 +                                      shoot = bot_aim(1000000, 0, 0.001, FALSE);
 +
 +                              if(shoot)
 +                              {
 +                                      self.BUTTON_ATCK = TRUE;
 +                                      if(random() < 0.01) self.bot_secondary_electromooth = 1;
 +                              }
 +                      }
 +                      else
 +                      {
 +                              if(bot_aim(autocvar_g_balance_electro_secondary_speed, autocvar_g_balance_mortar_secondary_speed_up, autocvar_g_balance_electro_secondary_lifetime, TRUE)) // WHAT THE ACTUAL FUUUUUUUUUCK?!?!? WEAPONTODO
 +                              {
 +                                      self.BUTTON_ATCK2 = TRUE;
 +                                      if(random() < 0.03) self.bot_secondary_electromooth = 0;
 +                              }
 +                      }
 +                      
 +                      return TRUE;
 +              }
 +              case 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)
 +                              {
 +                                      WEP_ACTION(self.weapon, WR_RELOAD);
 +                                      return FALSE;
 +                              }
 +                              
 +                              return TRUE;
 +                      }
 +                      if (self.BUTTON_ATCK)
 +                      {
 +                              if(autocvar_g_balance_electro_lightning)
 +                                      if(self.BUTTON_ATCK_prev)
 +                                              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)
 +                                      {
 +                                              if ((!self.lgbeam) || wasfreed(self.lgbeam))
 +                                              {
 +                                                      W_Electro_Attack3();
 +                                              }
 +                                              if(!self.BUTTON_ATCK_prev)
 +                                              {
 +                                                      weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_electro_primary_animtime, w_ready);
 +                                                      self.BUTTON_ATCK_prev = 1;
 +                                              }
 +                                      }
 +                                      else
 +                                      {
 +                                              W_Electro_Attack();
 +                                              weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_electro_primary_animtime, w_ready);
 +                                      }
 +                              }
 +                      } else {
 +                              if(autocvar_g_balance_electro_lightning)
 +                              {
 +                                      if (self.BUTTON_ATCK_prev != 0)
 +                                      {
 +                                              weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_electro_primary_animtime, w_ready);
 +                                              ATTACK_FINISHED(self) = time + autocvar_g_balance_electro_primary_refire * W_WeaponRateFactor();
 +                                      }
 +                                      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();
 +                                      }
 +                              }
 +                      }
 +                      
 +                      return TRUE;
 +              }
 +              case WR_INIT:
 +              {
 +                      precache_model ("models/weapons/g_electro.md3");
 +                      precache_model ("models/weapons/v_electro.md3");
 +                      precache_model ("models/weapons/h_electro.iqm");
 +                      precache_sound ("weapons/electro_bounce.wav");
 +                      precache_sound ("weapons/electro_fire.wav");
 +                      precache_sound ("weapons/electro_fire2.wav");
 +                      precache_sound ("weapons/electro_impact.wav");
 +                      precache_sound ("weapons/electro_impact_combo.wav");
 +                      
 +                      if(autocvar_g_balance_electro_lightning)
 +                              precache_sound ("weapons/lgbeam_fire.wav");
 +                              
 +                      return TRUE;
 +              }
 +              case WR_SETUP:
 +              {
 +                      self.current_ammo = ammo_cells;
 +                      return TRUE;
 +              }
 +              case WR_CHECKAMMO1:
 +              {
 +                      if(autocvar_g_balance_electro_lightning)
 +                      {
 +                              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
 +                      {
 +                              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;
 +              }
 +              case WR_CHECKAMMO2:
 +              {
 +                      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;
 +              }
 +              case WR_RESETPLAYER:
 +              {
 +                      self.electro_secondarytime = time;
 +                      return TRUE;
 +              }
 +              case WR_RELOAD:
 +              {
 +                      W_Reload(min(autocvar_g_balance_electro_primary_ammo, autocvar_g_balance_electro_secondary_ammo), "weapons/reload.wav");
 +                      return TRUE;
 +              }
 +              case WR_SUICIDEMESSAGE:
 +              {
 +                      if(w_deathtype & HITTYPE_SECONDARY)
 +                              return WEAPON_ELECTRO_SUICIDE_ORBS;
 +                      else
 +                              return WEAPON_ELECTRO_SUICIDE_BOLT;
 +              }
 +              case 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)
 +{
 +      switch(req)
 +      {
 +              case WR_IMPACTEFFECT:
 +              {
 +                      vector org2;
 +                      org2 = w_org + w_backoff * 6;
 +                      if(w_deathtype & HITTYPE_SECONDARY)
 +                      {
 +                              pointparticles(particleeffectnum("electro_ballexplode"), org2, '0 0 0', 1);
 +                              if(!w_issilent)
 +                                      sound(self, CH_SHOTS, "weapons/electro_impact.wav", VOL_BASE, ATTEN_NORM);
 +                      }
 +                      else
 +                      {
 +                              if(w_deathtype & HITTYPE_BOUNCE)
 +                              {
 +                                      // 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, CH_SHOTS, "weapons/electro_impact_combo.wav", VOL_BASE, ATTEN_NORM);
 +                              }
 +                              else
 +                              {
 +                                      pointparticles(particleeffectnum("electro_impact"), org2, '0 0 0', 1);
 +                                      if(!w_issilent)
 +                                              sound(self, CH_SHOTS, "weapons/electro_impact.wav", VOL_BASE, ATTEN_NORM);
 +                              }
 +                      }
 +                      
 +                      return TRUE;
 +              }
 +              case WR_INIT:
 +              {
 +                      precache_sound("weapons/electro_impact.wav");
 +                      precache_sound("weapons/electro_impact_combo.wav");
 +                      return TRUE;
 +              }
 +      }
 +      return TRUE;
 +}
 +#endif
 +#endif
index 466158441a96ba4ed37101df6950fa055785e8f5,0000000000000000000000000000000000000000..ebdfa2bbe734cb9b67916e334ba45e8115f94d63
mode 100644,000000..100644
--- /dev/null
@@@ -1,471 -1,0 +1,471 @@@
-               
 +#ifdef REGISTER_WEAPON
 +REGISTER_WEAPON(
 +/* WEP_##id */ FIREBALL,
 +/* function */ w_fireball,
 +/* ammotype */ 0,
 +/* impulse  */ 9,
 +/* flags    */ WEP_FLAG_SUPERWEAPON | WEP_TYPE_SPLASH,
 +/* rating   */ BOT_PICKUP_RATING_MID,
 +/* model    */ "fireball",
 +/* netname  */ "fireball",
 +/* fullname */ _("Fireball")
 +);
 +#define FIREBALL_SETTINGS(weapon) \
 +      WEP_ADD_CVAR(weapon, MO_BOTH, animtime) \
 +      WEP_ADD_CVAR(weapon, MO_BOTH, refire) \
 +      WEP_ADD_CVAR(weapon, MO_BOTH, damage) \
 +      WEP_ADD_CVAR(weapon, MO_BOTH, damageforcescale) \
 +      WEP_ADD_CVAR(weapon, MO_BOTH, speed) \
 +      WEP_ADD_CVAR(weapon, MO_BOTH, lifetime) \
 +      WEP_ADD_CVAR(weapon, MO_BOTH, laserburntime) \
 +      WEP_ADD_CVAR(weapon, MO_BOTH, laserdamage) \
 +      WEP_ADD_CVAR(weapon, MO_BOTH, laseredgedamage) \
 +      WEP_ADD_CVAR(weapon, MO_BOTH, laserradius) \
 +      WEP_ADD_CVAR(weapon, MO_PRI,  edgedamage) \
 +      WEP_ADD_CVAR(weapon, MO_PRI,  force) \
 +      WEP_ADD_CVAR(weapon, MO_PRI,  radius) \
 +      WEP_ADD_CVAR(weapon, MO_PRI,  health) \
 +      WEP_ADD_CVAR(weapon, MO_PRI,  refire2) \
 +      WEP_ADD_CVAR(weapon, MO_PRI,  bfgdamage) \
 +      WEP_ADD_CVAR(weapon, MO_PRI,  bfgforce) \
 +      WEP_ADD_CVAR(weapon, MO_PRI,  bfgradius) \
 +      WEP_ADD_CVAR(weapon, MO_SEC,  damagetime) \
 +      WEP_ADD_CVAR(weapon, MO_SEC,  speed_up) \
 +      WEP_ADD_PROP(weapon, reloading_ammo, reload_ammo) \
 +      WEP_ADD_PROP(weapon, reloading_time, reload_time) \
 +      WEP_ADD_PROP(weapon, switchdelay_raise, switchdelay_raise) \
 +      WEP_ADD_PROP(weapon, switchdelay_drop, switchdelay_drop)
 +
 +#ifdef SVQC
 +FIREBALL_SETTINGS(fireball)
 +.float bot_primary_fireballmooth; // whatever a mooth is
 +.vector fireball_impactvec;
 +.float fireball_primarytime;
 +#endif
 +#else
 +#ifdef SVQC
 +void spawnfunc_weapon_fireball() { weapon_defaultspawnfunc(WEP_FIREBALL); }
 +
 +void W_Fireball_Explode (void)
 +{
 +      entity e;
 +      float dist;
 +      float points;
 +      vector dir;
 +      float d;
 +
 +      self.event_damage = func_null;
 +      self.takedamage = DAMAGE_NO;
 +
 +      // 1. dist damage
 +      d = (self.realowner.health + self.realowner.armorvalue);
 +      RadiusDamage (self, self.realowner, WEP_CVAR_PRI(fireball, damage), WEP_CVAR_PRI(fireball, edgedamage), WEP_CVAR_PRI(fireball, radius), world, world, WEP_CVAR_PRI(fireball, force), self.projectiledeathtype, other);
 +      if(self.realowner.health + self.realowner.armorvalue >= d)
 +      if(!self.cnt)
 +      {
 +              modeleffect_spawn("models/sphere/sphere.md3", 0, 0, self.origin, '0 0 0', '0 0 0', '0 0 0', 0, WEP_CVAR_PRI(fireball, bfgradius), 0.2, 0.05, 0.25);
 +
 +              // 2. bfg effect
 +              // NOTE: this cannot be made warpzone aware by design. So, better intentionally ignore warpzones here.
 +              for(e = findradius(self.origin, WEP_CVAR_PRI(fireball, bfgradius)); e; e = e.chain)
 +              if(e != self.realowner) if(e.takedamage == DAMAGE_AIM) if(!IS_PLAYER(e) || !self.realowner || DIFF_TEAM(e, self))
 +              {
 +                      // can we see fireball?
 +                      traceline(e.origin + e.view_ofs, self.origin, MOVE_NORMAL, e);
 +                      if(/* trace_startsolid || */ trace_fraction != 1) // startsolid should be never happening anyway
 +                              continue;
 +                      // can we see player who shot fireball?
 +                      traceline(e.origin + e.view_ofs, self.realowner.origin + self.realowner.view_ofs, MOVE_NORMAL, e);
 +                      if(trace_ent != self.realowner)
 +                      if(/* trace_startsolid || */ trace_fraction != 1)
 +                              continue;
 +                      dist = vlen(self.origin - e.origin - e.view_ofs);
 +                      points = (1 - sqrt(dist / WEP_CVAR_PRI(fireball, bfgradius)));
 +                      if(points <= 0)
 +                              continue;
 +                      dir = normalize(e.origin + e.view_ofs - self.origin);
 +
 +                      if(accuracy_isgooddamage(self.realowner, e))
 +                              accuracy_add(self.realowner, WEP_FIREBALL, 0, WEP_CVAR_PRI(fireball, bfgdamage) * points);
 +
 +                      Damage(e, self, self.realowner, WEP_CVAR_PRI(fireball, bfgdamage) * points, self.projectiledeathtype | HITTYPE_BOUNCE | HITTYPE_SPLASH, e.origin + e.view_ofs, WEP_CVAR_PRI(fireball, bfgforce) * dir);
 +                      pointparticles(particleeffectnum("fireball_bfgdamage"), e.origin, -1 * dir, 1);
 +              }
 +      }
 +
 +      remove (self);
 +}
 +
 +void W_Fireball_TouchExplode (void)
 +{
 +      PROJECTILE_TOUCH;
 +      W_Fireball_Explode ();
 +}
 +
 +void W_Fireball_LaserPlay(float dt, float dist, float damage, float edgedamage, float burntime)
 +{
 +      entity e;
 +      float d;
 +      vector p;
 +
 +      if(damage <= 0)
 +              return;
 +
 +      RandomSelection_Init();
 +      for(e = WarpZone_FindRadius(self.origin, dist, TRUE); e; e = e.chain)
 +      if(e != self.realowner) if(e.takedamage == DAMAGE_AIM) if(!IS_PLAYER(e) || !self.realowner || DIFF_TEAM(e, self))
 +      {
 +              p = e.origin;
 +              p_x += e.mins_x + random() * (e.maxs_x - e.mins_x);
 +              p_y += e.mins_y + random() * (e.maxs_y - e.mins_y);
 +              p_z += e.mins_z + random() * (e.maxs_z - e.mins_z);
 +              d = vlen(WarpZone_UnTransformOrigin(e, self.origin) - p);
 +              if(d < dist)
 +              {
 +                      e.fireball_impactvec = p;
 +                      RandomSelection_Add(e, 0, string_null, 1 / (1 + d), !Fire_IsBurning(e));
 +              }
 +      }
 +      if(RandomSelection_chosen_ent)
 +      {
 +              d = vlen(WarpZone_UnTransformOrigin(RandomSelection_chosen_ent, self.origin) - RandomSelection_chosen_ent.fireball_impactvec);
 +              d = damage + (edgedamage - damage) * (d / dist);
 +              Fire_AddDamage(RandomSelection_chosen_ent, self.realowner, d * burntime, burntime, self.projectiledeathtype | HITTYPE_BOUNCE);
 +              //trailparticles(self, particleeffectnum("fireball_laser"), self.origin, RandomSelection_chosen_ent.fireball_impactvec);
 +              pointparticles(particleeffectnum("fireball_laser"), self.origin, RandomSelection_chosen_ent.fireball_impactvec - self.origin, 1);
 +      }
 +}
 +
 +void W_Fireball_Think()
 +{
 +      if(time > self.pushltime)
 +      {
 +              self.cnt = 1;
 +              self.projectiledeathtype |= HITTYPE_SPLASH;
 +              W_Fireball_Explode();
 +              return;
 +      }
 +
 +      W_Fireball_LaserPlay(0.1, WEP_CVAR_PRI(fireball, laserradius), WEP_CVAR_PRI(fireball, laserdamage), WEP_CVAR_PRI(fireball, laseredgedamage), WEP_CVAR_PRI(fireball, laserburntime));
 +
 +      self.nextthink = time + 0.1;
 +}
 +
 +void W_Fireball_Damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
 +{
 +      if(self.health <= 0)
 +              return;
-               
++
 +      if (!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, -1)) // no exceptions
 +              return; // g_projectiles_damage says to halt
-     
++
 +      self.health = self.health - damage;
 +      if (self.health <= 0)
 +      {
 +              self.cnt = 1;
 +              W_PrepareExplosionByDamage(attacker, W_Fireball_Explode);
 +      }
 +}
 +
 +void W_Fireball_Attack1()
 +{
 +      entity proj;
 +
 +      W_SetupShot_ProjectileSize (self, '-16 -16 -16', '16 16 16', FALSE, 2, "weapons/fireball_fire2.wav", CH_WEAPON_A, WEP_CVAR_PRI(fireball, damage) + WEP_CVAR_PRI(fireball, bfgdamage));
 +
 +      pointparticles(particleeffectnum("fireball_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
 +
 +      proj = spawn ();
 +      proj.classname = "plasma_prim";
 +      proj.owner = proj.realowner = self;
 +      proj.bot_dodge = TRUE;
 +      proj.bot_dodgerating = WEP_CVAR_PRI(fireball, damage);
 +      proj.pushltime = time + WEP_CVAR_PRI(fireball, lifetime);
 +      proj.use = W_Fireball_Explode;
 +      proj.think = W_Fireball_Think;
 +      proj.nextthink = time;
 +      proj.health = WEP_CVAR_PRI(fireball, health);
 +      proj.team = self.team;
 +      proj.event_damage = W_Fireball_Damage;
 +      proj.takedamage = DAMAGE_YES;
 +      proj.damageforcescale = WEP_CVAR_PRI(fireball, damageforcescale);
 +      PROJECTILE_MAKETRIGGER(proj);
 +      proj.projectiledeathtype = WEP_FIREBALL;
 +      setorigin(proj, w_shotorg);
 +
 +      proj.movetype = MOVETYPE_FLY;
 +      W_SETUPPROJECTILEVELOCITY(proj, g_balance_fireball_primary);
 +      proj.angles = vectoangles(proj.velocity);
 +      proj.touch = W_Fireball_TouchExplode;
 +      setsize(proj, '-16 -16 -16', '16 16 16');
 +      proj.flags = FL_PROJECTILE;
 +    proj.missile_flags = MIF_SPLASH | MIF_PROXY;
-     
++
 +      CSQCProjectile(proj, TRUE, PROJECTILE_FIREBALL, TRUE);
 +
 +      other = proj; MUTATOR_CALLHOOK(EditProjectile);
 +}
 +
 +void W_Fireball_AttackEffect(float i, vector f_diff)
 +{
 +      W_SetupShot_ProjectileSize (self, '-16 -16 -16', '16 16 16', FALSE, 0, "", 0, 0);
 +      w_shotorg += f_diff_x * v_up + f_diff_y * v_right;
 +      pointparticles(particleeffectnum("fireball_preattack_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
 +}
 +
 +void W_Fireball_Attack1_Frame4()
 +{
 +      W_Fireball_Attack1();
 +      weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(fireball, animtime), w_ready);
 +}
 +
 +void W_Fireball_Attack1_Frame3()
 +{
 +      W_Fireball_AttackEffect(0, '+1.25 +3.75 0');
 +      weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(fireball, animtime), W_Fireball_Attack1_Frame4);
 +}
 +
 +void W_Fireball_Attack1_Frame2()
 +{
 +      W_Fireball_AttackEffect(0, '-1.25 +3.75 0');
 +      weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(fireball, animtime), W_Fireball_Attack1_Frame3);
 +}
 +
 +void W_Fireball_Attack1_Frame1()
 +{
 +      W_Fireball_AttackEffect(1, '+1.25 -3.75 0');
 +      weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(fireball, animtime), W_Fireball_Attack1_Frame2);
 +}
 +
 +void W_Fireball_Attack1_Frame0()
 +{
 +      W_Fireball_AttackEffect(0, '-1.25 -3.75 0');
 +      sound (self, CH_WEAPON_SINGLE, "weapons/fireball_prefire2.wav", VOL_BASE, ATTEN_NORM);
 +      weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(fireball, animtime), W_Fireball_Attack1_Frame1);
 +}
 +
 +void W_Firemine_Think()
 +{
 +      if(time > self.pushltime)
 +      {
 +              remove(self);
 +              return;
 +      }
 +
 +      // make it "hot" once it leaves its owner
 +      if(self.owner)
 +      {
 +              if(vlen(self.origin - self.owner.origin - self.owner.view_ofs) > WEP_CVAR_SEC(fireball, laserradius))
 +              {
 +                      self.cnt += 1;
 +                      if(self.cnt == 3)
 +                              self.owner = world;
 +              }
 +              else
 +                      self.cnt = 0;
 +      }
 +
 +      W_Fireball_LaserPlay(0.1, WEP_CVAR_SEC(fireball, laserradius), WEP_CVAR_SEC(fireball, laserdamage), WEP_CVAR_SEC(fireball, laseredgedamage), WEP_CVAR_SEC(fireball, laserburntime));
 +
 +      self.nextthink = time + 0.1;
 +}
 +
 +void W_Firemine_Touch (void)
 +{
 +      PROJECTILE_TOUCH;
 +      if (other.takedamage == DAMAGE_AIM)
 +      if(Fire_AddDamage(other, self.realowner, WEP_CVAR_SEC(fireball, damage), WEP_CVAR_SEC(fireball, damagetime), self.projectiledeathtype) >= 0)
 +      {
 +              remove(self);
 +              return;
 +      }
 +      self.projectiledeathtype |= HITTYPE_BOUNCE;
 +}
 +
 +void W_Fireball_Attack2()
 +{
 +      entity proj;
 +      vector f_diff;
 +      float c;
 +
 +      c = mod(self.bulletcounter, 4);
 +      switch(c)
 +      {
 +              case 0:
 +                      f_diff = '-1.25 -3.75 0';
 +                      break;
 +              case 1:
 +                      f_diff = '+1.25 -3.75 0';
 +                      break;
 +              case 2:
 +                      f_diff = '-1.25 +3.75 0';
 +                      break;
 +              case 3:
 +              default:
 +                      f_diff = '+1.25 +3.75 0';
 +                      break;
 +      }
 +      W_SetupShot_ProjectileSize(self, '-4 -4 -4', '4 4 4', FALSE, 2, "weapons/fireball_fire.wav", CH_WEAPON_A, WEP_CVAR_SEC(fireball, damage));
 +      traceline(w_shotorg, w_shotorg + f_diff_x * v_up + f_diff_y * v_right, MOVE_NORMAL, self);
 +      w_shotorg = trace_endpos;
 +
 +      pointparticles(particleeffectnum("fireball_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
 +
 +      proj = spawn ();
 +      proj.owner = proj.realowner = self;
 +      proj.classname = "grenade";
 +      proj.bot_dodge = TRUE;
 +      proj.bot_dodgerating = WEP_CVAR_SEC(fireball, damage);
 +      proj.movetype = MOVETYPE_BOUNCE;
 +      proj.projectiledeathtype = WEP_FIREBALL | HITTYPE_SECONDARY;
 +      proj.touch = W_Firemine_Touch;
 +      PROJECTILE_MAKETRIGGER(proj);
 +      setsize(proj, '-4 -4 -4', '4 4 4');
 +      setorigin(proj, w_shotorg);
 +      proj.think = W_Firemine_Think;
 +      proj.nextthink = time;
 +      proj.damageforcescale = WEP_CVAR_SEC(fireball, damageforcescale);
 +      proj.pushltime = time + WEP_CVAR_SEC(fireball, lifetime);
 +      W_SETUPPROJECTILEVELOCITY_UP(proj, g_balance_fireball_secondary);
 +
 +      proj.angles = vectoangles(proj.velocity);
 +      proj.flags = FL_PROJECTILE;
 +    proj.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_ARC;
++
 +      CSQCProjectile(proj, TRUE, PROJECTILE_FIREMINE, TRUE);
 +
 +      other = proj; MUTATOR_CALLHOOK(EditProjectile);
 +}
 +
 +float w_fireball(float req)
 +{
 +      switch(req)
 +      {
 +              case WR_AIM:
 +              {
 +                      self.BUTTON_ATCK = FALSE;
 +                      self.BUTTON_ATCK2 = FALSE;
 +                      if (self.bot_primary_fireballmooth == 0)
 +                      {
 +                              if(bot_aim(WEP_CVAR_PRI(fireball, speed), 0, WEP_CVAR_PRI(fireball, lifetime), FALSE))
 +                              {
 +                                      self.BUTTON_ATCK = TRUE;
 +                                      if(random() < 0.02) self.bot_primary_fireballmooth = 0;
 +                              }
 +                      }
 +                      else
 +                      {
 +                              if(bot_aim(WEP_CVAR_SEC(fireball, speed), WEP_CVAR_SEC(fireball, speed_up), WEP_CVAR_SEC(fireball, lifetime), TRUE))
 +                              {
 +                                      self.BUTTON_ATCK2 = TRUE;
 +                                      if(random() < 0.01) self.bot_primary_fireballmooth = 1;
 +                              }
 +                      }
 +                      
 +                      return TRUE;
 +              }
 +              case WR_THINK:
 +              {
 +                      if (self.BUTTON_ATCK)
 +                      {
 +                              if (time >= self.fireball_primarytime)
 +                              if (weapon_prepareattack(0, WEP_CVAR_PRI(fireball, refire)))
 +                              {
 +                                      W_Fireball_Attack1_Frame0();
 +                                      self.fireball_primarytime = time + WEP_CVAR_PRI(fireball, refire2) * W_WeaponRateFactor();
 +                              }
 +                      }
 +                      else if (self.BUTTON_ATCK2)
 +                      {
 +                              if (weapon_prepareattack(1, WEP_CVAR_SEC(fireball, refire)))
 +                              {
 +                                      W_Fireball_Attack2();
 +                                      weapon_thinkf(WFRAME_FIRE2, WEP_CVAR_SEC(fireball, animtime), w_ready);
 +                              }
 +                      }
 +                      
 +                      return TRUE;
 +              }
 +              case WR_INIT:
 +              {
 +                      precache_model ("models/weapons/g_fireball.md3");
 +                      precache_model ("models/weapons/v_fireball.md3");
 +                      precache_model ("models/weapons/h_fireball.iqm");
 +                      precache_model ("models/sphere/sphere.md3");
 +                      precache_sound ("weapons/fireball_fire.wav");
 +                      precache_sound ("weapons/fireball_fire2.wav");
 +                      precache_sound ("weapons/fireball_prefire2.wav");
 +                      WEP_SET_PROPS(FIREBALL_SETTINGS(fireball), WEP_FIREBALL)
 +                      return TRUE;
 +              }
 +              case WR_SETUP:
 +              {
 +                      self.current_ammo = ammo_none;
 +                      return TRUE;
 +              }
 +              case WR_CHECKAMMO1:
 +              case WR_CHECKAMMO2:
 +              {
 +                      return TRUE; // fireball has infinite ammo
 +              }
 +              case WR_CONFIG:
 +              {
 +                      WEP_CONFIG_SETTINGS(FIREBALL_SETTINGS(fireball))
 +                      return TRUE;
 +              }
 +              case WR_RESETPLAYER:
 +              {
 +                      self.fireball_primarytime = time;
 +                      return TRUE;
 +              }
 +              case WR_SUICIDEMESSAGE:
 +              {
 +                      if(w_deathtype & HITTYPE_SECONDARY)
 +                              return WEAPON_FIREBALL_SUICIDE_FIREMINE;
 +                      else
 +                              return WEAPON_FIREBALL_SUICIDE_BLAST;
 +              }
 +              case WR_KILLMESSAGE:
 +              {
 +                      if(w_deathtype & HITTYPE_SECONDARY)
 +                              return WEAPON_FIREBALL_MURDER_FIREMINE;
 +                      else
 +                              return WEAPON_FIREBALL_MURDER_BLAST;
 +              }
 +      }
 +      return TRUE;
 +}
 +#endif
 +#ifdef CSQC
 +float w_fireball(float req)
 +{
 +      switch(req)
 +      {
 +              case WR_IMPACTEFFECT:
 +              {
 +                      vector org2;
 +                      if(w_deathtype & HITTYPE_SECONDARY)
 +                      {
 +                              // firemine goes out silently
 +                      }
 +                      else
 +                      {
 +                              org2 = w_org + w_backoff * 16;
 +                              pointparticles(particleeffectnum("fireball_explode"), org2, '0 0 0', 1);
 +                              if(!w_issilent)
 +                                      sound(self, CH_SHOTS, "weapons/fireball_impact2.wav", VOL_BASE, ATTEN_NORM * 0.25); // long range boom
 +                      }
 +                      
 +                      return TRUE;
 +              }
 +              case WR_INIT:
 +              {
 +                      precache_sound("weapons/fireball_impact2.wav");
 +                      return TRUE;
 +              }
 +      }
 +
 +      return TRUE;
 +}
 +#endif
 +#endif
index aa3d69dc5d455fc2b9b8a42090fd3cd7291bf9eb,0000000000000000000000000000000000000000..5a8f8d52e30c96a3bc24837ee8a670e2ef6a3fa1
mode 100644,000000..100644
--- /dev/null
@@@ -1,779 -1,0 +1,775 @@@
-               
 +#ifdef REGISTER_WEAPON
 +REGISTER_WEAPON(
 +/* WEP_##id */ SEEKER,
 +/* function */ w_seeker,
 +/* ammotype */ IT_ROCKETS,
 +/* impulse  */ 8,
 +/* flags    */ WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH,
 +/* rating   */ BOT_PICKUP_RATING_MID,
 +/* model    */ "seeker",
 +/* netname  */ "seeker",
 +/* fullname */ _("T.A.G. Seeker")
 +);
 +
 +#define SEEKER_SETTINGS(weapon) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, type) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, flac_ammo) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, flac_animtime) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, flac_damage) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, flac_edgedamage) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, flac_force) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, flac_lifetime) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, flac_lifetime_rand) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, flac_radius) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, flac_refire) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, missile_accel) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, missile_ammo) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, missile_animtime) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, missile_count) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, missile_damage) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, missile_damageforcescale) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, missile_decel) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, missile_delay) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, missile_edgedamage) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, missile_force) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, missile_health) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, missile_lifetime) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, missile_proxy) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, missile_proxy_delay) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, missile_proxy_maxrange) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, missile_radius) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, missile_refire) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, missile_smart) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, missile_smart_mindist) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, missile_smart_trace_max) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, missile_smart_trace_min) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, missile_speed_max) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, missile_turnrate) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, tag_ammo) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, tag_animtime) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, tag_damageforcescale) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, tag_health) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, tag_lifetime) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, tag_refire) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, tag_speed) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, tag_tracker_lifetime) \
 +      WEP_ADD_PROP(weapon, reloading_ammo, reload_ammo) \
 +      WEP_ADD_PROP(weapon, reloading_time, reload_time) \
 +      WEP_ADD_PROP(weapon, switchdelay_raise, switchdelay_raise) \
 +      WEP_ADD_PROP(weapon, switchdelay_drop, switchdelay_drop)
 +
 +#ifdef SVQC
 +SEEKER_SETTINGS(seeker)
 +.entity tag_target, wps_tag_tracker;
 +.float tag_time;
 +#endif
 +#else
 +#ifdef SVQC
 +void spawnfunc_weapon_seeker (void) { weapon_defaultspawnfunc(WEP_SEEKER); }
 +
 +// ============================
 +// Begin: Missile functions, these are general functions to be manipulated by other code
 +// ============================
 +void Seeker_Missile_Explode ()
 +{
 +      self.event_damage = func_null;
 +      RadiusDamage (self, self.realowner, WEP_CVAR(seeker, missile_damage), WEP_CVAR(seeker, missile_edgedamage), WEP_CVAR(seeker, missile_radius), world, world, WEP_CVAR(seeker, missile_force), self.projectiledeathtype, other);
 +
 +      remove (self);
 +}
 +
 +void Seeker_Missile_Touch()
 +{
 +      PROJECTILE_TOUCH;
 +
 +      Seeker_Missile_Explode();
 +}
 +
 +void Seeker_Missile_Think()
 +{
 +      entity e;
 +      vector desireddir, olddir, newdir, eorg;
 +      float turnrate;
 +      float dist;
 +      float spd;
 +
 +      if (time > self.cnt)
 +      {
 +              self.projectiledeathtype |= HITTYPE_SPLASH;
 +              Seeker_Missile_Explode();
 +      }
 +
 +      spd = vlen(self.velocity);
 +      spd = bound(
 +              spd - WEP_CVAR(seeker, missile_decel) * frametime,
 +              WEP_CVAR(seeker, missile_speed_max),
 +              spd + WEP_CVAR(seeker, missile_accel) * frametime
 +      );
 +
 +      if (self.enemy != world)
 +              if (self.enemy.takedamage != DAMAGE_AIM || self.enemy.deadflag != DEAD_NO)
 +                      self.enemy = world;
 +
 +      if (self.enemy != world)
 +      {
 +              e               = self.enemy;
 +              eorg            = 0.5 * (e.absmin + e.absmax);
 +              turnrate        = WEP_CVAR(seeker, missile_turnrate); // how fast to turn
 +              desireddir      = normalize(eorg - self.origin);
 +              olddir          = normalize(self.velocity); // get my current direction
 +              dist            = vlen(eorg - self.origin);
 +
 +              // Do evasive maneuvers for world objects? ( this should be a cpu hog. :P )
 +              if (WEP_CVAR(seeker, missile_smart) && (dist > WEP_CVAR(seeker, missile_smart_mindist)))
 +              {
 +                      // Is it a better idea (shorter distance) to trace to the target itself?
 +                      if ( vlen(self.origin + olddir * self.wait) < dist)
 +                              traceline(self.origin, self.origin + olddir * self.wait, FALSE, self);
 +                      else
 +                              traceline(self.origin, eorg, FALSE, self);
 +
 +                      // Setup adaptive tracelength
 +                      self.wait = bound(WEP_CVAR(seeker, missile_smart_trace_min), vlen(self.origin - trace_endpos), self.wait = WEP_CVAR(seeker, missile_smart_trace_max));
 +
 +                      // Calc how important it is that we turn and add this to the desierd (enemy) dir.
 +                      desireddir  = normalize(((trace_plane_normal * (1 - trace_fraction)) + (desireddir * trace_fraction)) * 0.5);
 +              }
-               
++
 +              newdir = normalize(olddir + desireddir * turnrate); // take the average of the 2 directions; not the best method but simple & easy
 +              self.velocity = newdir * spd; // make me fly in the new direction at my flight speed
 +      }
 +      else
 +              dist = 0;
 +
 +      // Proxy
 +      if (WEP_CVAR(seeker, missile_proxy))
 +      {
 +              if ( dist <= WEP_CVAR(seeker, missile_proxy_maxrange))
 +              {
 +                      if (self.autoswitch == 0)
 +                      {
 +                              self.autoswitch = time + WEP_CVAR(seeker, missile_proxy_delay);
 +                      }
 +                      else
 +                      {
 +                              if (self.autoswitch <= time)
 +                              {
 +                                      Seeker_Missile_Explode();
 +                                      self.autoswitch = 0;
 +                              }
 +                      }
 +              }
 +              else
 +              {
 +                      if (self.autoswitch != 0)
 +                              self.autoswitch = 0;
 +              }
 +      }
 +      ///////////////
 +
 +      if (self.enemy.deadflag != DEAD_NO)
 +      {
 +              self.enemy = world;
 +              self.cnt = time + 1 + (random() * 4);
 +              self.nextthink = self.cnt;
 +              return;
 +      }
 +
 +      //self.angles = vectoangles(self.velocity);                     // turn model in the new flight direction
 +      self.nextthink = time;// + 0.05; // csqc projectiles
 +      UpdateCSQCProjectile(self);
 +}
 +
 +
 +
 +void Seeker_Missile_Damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
 +{
 +      if (self.health <= 0)
 +              return;
-               
++
 +      if (!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, -1)) // no exceptions
 +              return; // g_projectiles_damage says to halt
 +
 +      if (self.realowner == attacker)
 +              self.health = self.health - (damage * 0.25);
 +      else
 +              self.health = self.health - damage;
-       
++
 +      if (self.health <= 0)
 +              W_PrepareExplosionByDamage(attacker, Seeker_Missile_Explode);
 +}
 +
 +/*
 +void Seeker_Missile_Animate()
 +{
 +      self.frame = self.frame +1;
 +      self.nextthink = time + 0.05;
 +
 +      if (self.enemy != world)
 +              if (self.enemy.takedamage != DAMAGE_AIM || self.enemy.deadflag != DEAD_NO)
 +                      self.enemy = world;
 +
 +      if(self.frame == 5)
 +      {
 +              self.think           = Seeker_Missile_Think;
 +              self.nextthink       = time;// + cvar("g_balance_seeker_missile_activate_delay"); // cant dealy with csqc projectiles
 +
 +              if (autocvar_g_balance_seeker_missile_proxy)
 +                      self.movetype    = MOVETYPE_BOUNCEMISSILE;
 +              else
 +                      self.movetype    = MOVETYPE_FLYMISSILE;
 +      }
 +
 +      UpdateCSQCProjectile(self);
 +}
 +*/
 +
 +void Seeker_Fire_Missile(vector f_diff, entity m_target)
 +{
 +      entity missile;
 +
 +      W_DecreaseAmmo(ammo_rockets, WEP_CVAR(seeker, missile_ammo), autocvar_g_balance_seeker_reload_ammo);
 +
 +      makevectors(self.v_angle);
 +      W_SetupShot_ProjectileSize (self, '-2 -2 -2', '2 2 2', FALSE, 2, "weapons/seeker_fire.wav", CH_WEAPON_A, 0);
 +      w_shotorg += f_diff;
 +      pointparticles(particleeffectnum("seeker_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
 +
 +      //self.detornator         = FALSE;
 +
 +      missile                 = spawn();
 +      missile.owner           = missile.realowner = self;
 +      missile.classname       = "seeker_missile";
 +      missile.bot_dodge       = TRUE;
 +      missile.bot_dodgerating = WEP_CVAR(seeker, missile_damage);
 +
 +      missile.think           = Seeker_Missile_Think;
 +      missile.touch           = Seeker_Missile_Touch;
 +      missile.event_damage    = Seeker_Missile_Damage;
 +      missile.nextthink       = time;// + 0.2;// + cvar("g_balance_seeker_missile_activate_delay");
 +      missile.cnt             = time + WEP_CVAR(seeker, missile_lifetime);
 +      missile.enemy           = m_target;
 +      missile.solid           = SOLID_BBOX;
 +      missile.scale           = 2;
 +      missile.takedamage      = DAMAGE_YES;
 +      missile.health          = WEP_CVAR(seeker, missile_health);
 +      missile.damageforcescale = WEP_CVAR(seeker, missile_damageforcescale);
 +      missile.damagedbycontents = TRUE;
 +      //missile.think           = Seeker_Missile_Animate; // csqc projectiles.
-       else 
++
 +      if (missile.enemy != world)
 +              missile.projectiledeathtype = WEP_SEEKER | HITTYPE_SECONDARY;
-       
++      else
 +              missile.projectiledeathtype = WEP_SEEKER;
 +
 +
 +      setorigin (missile, w_shotorg);
 +      setsize (missile, '-4 -4 -4', '4 4 4');
 +      missile.movetype    = MOVETYPE_FLYMISSILE;
 +      missile.flags       = FL_PROJECTILE;
 +      missile.missile_flags = MIF_SPLASH | MIF_GUIDED_TAG;
- // Begin: FLAC, close range attack meant for defeating rockets which are coming at you. 
++
 +      W_SETUPPROJECTILEVELOCITY_UP(missile, g_balance_seeker_missile);
 +
 +      missile.angles = vectoangles (missile.velocity);
 +
 +      CSQCProjectile(missile, FALSE, PROJECTILE_SEEKER, TRUE);
 +
 +      other = missile; MUTATOR_CALLHOOK(EditProjectile);
 +}
 +
 +// ============================
-       missile.use                     = Seeker_Flac_Explode; 
++// Begin: FLAC, close range attack meant for defeating rockets which are coming at you.
 +// ============================
 +void Seeker_Flac_Explode ()
 +{
 +      self.event_damage = func_null;
 +
 +      RadiusDamage (self, self.realowner, WEP_CVAR(seeker, flac_damage), WEP_CVAR(seeker, flac_edgedamage), WEP_CVAR(seeker, flac_radius), world, world, WEP_CVAR(seeker, flac_force), self.projectiledeathtype, other);
 +
 +      remove (self);
 +}
 +
 +void Seeker_Flac_Touch()
 +{
 +      PROJECTILE_TOUCH;
 +
 +      Seeker_Flac_Explode();
 +}
 +
 +void Seeker_Fire_Flac()
 +{
 +      entity missile;
 +      vector f_diff;
 +      float c;
 +
 +      W_DecreaseAmmo(ammo_rockets, WEP_CVAR(seeker, flac_ammo), autocvar_g_balance_seeker_reload_ammo);
 +
 +      c = mod(self.bulletcounter, 4);
 +      switch(c)
 +      {
 +              case 0:
 +                      f_diff = '-1.25 -3.75 0';
 +                      break;
 +              case 1:
 +                      f_diff = '+1.25 -3.75 0';
 +                      break;
 +              case 2:
 +                      f_diff = '-1.25 +3.75 0';
 +                      break;
 +              case 3:
 +              default:
 +                      f_diff = '+1.25 +3.75 0';
 +                      break;
 +      }
 +      W_SetupShot_ProjectileSize (self, '-2 -2 -2', '2 2 2', FALSE, 2, "weapons/flac_fire.wav", CH_WEAPON_A, WEP_CVAR(seeker, flac_damage));
 +      w_shotorg += f_diff;
 +
 +      pointparticles(particleeffectnum("hagar_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
 +
 +      missile                                 = spawn ();
 +      missile.owner                   = missile.realowner = self;
 +      missile.classname               = "missile";
 +      missile.bot_dodge               = TRUE;
 +      missile.bot_dodgerating = WEP_CVAR(seeker, flac_damage);
 +      missile.touch                   = Seeker_Flac_Explode;
-       missile.movetype                = MOVETYPE_FLY; 
++      missile.use                     = Seeker_Flac_Explode;
 +      missile.think                   = adaptor_think2use_hittype_splash;
 +      missile.nextthink               = time + WEP_CVAR(seeker, flac_lifetime) + WEP_CVAR(seeker, flac_lifetime_rand);
 +      missile.solid                   = SOLID_BBOX;
-       missile.missile_flags       = MIF_SPLASH; 
-       
++      missile.movetype                = MOVETYPE_FLY;
 +      missile.projectiledeathtype = WEP_SEEKER;
 +      missile.projectiledeathtype = WEP_SEEKER | HITTYPE_SECONDARY;
 +      missile.flags                           = FL_PROJECTILE;
-       //missile.angles                                = vectoangles (missile.velocity);       
-       //missile.scale = 0.4; // BUG: the model is too big 
-       
++      missile.missile_flags       = MIF_SPLASH;
++
 +      // csqc projectiles
-               
++      //missile.angles                                = vectoangles (missile.velocity);
++      //missile.scale = 0.4; // BUG: the model is too big
++
 +      setorigin (missile, w_shotorg);
 +      setsize (missile, '-2 -2 -2', '2 2 2');
- // Begin: Tag and rocket controllers 
++
 +      W_SETUPPROJECTILEVELOCITY_UP(missile, g_balance_seeker_flac);
 +      CSQCProjectile(missile, TRUE, PROJECTILE_FLAC, TRUE);
 +
 +      other = missile; MUTATOR_CALLHOOK(EditProjectile);
 +}
 +
 +// ============================
-       for(tag = world; (tag = find(tag, classname, "tag_tracker")); ) 
++// Begin: Tag and rocket controllers
 +// ============================
 +entity Seeker_Tagged_Info(entity isowner, entity istarget)
 +{
 +      entity tag;
-               
++      for(tag = world; (tag = find(tag, classname, "tag_tracker")); )
 +              if ((tag.realowner == isowner) && (tag.tag_target == istarget))
 +                      return tag;
-       
++
 +      return world;
 +}
 +
 +void Seeker_Attack()
 +{
 +      entity tracker, closest_target;
-               else 
++
 +      closest_target = world;
 +      for(tracker = world; (tracker = find(tracker, classname, "tag_tracker")); ) if (tracker.realowner == self)
 +      {
 +              if (closest_target)
 +              {
 +                      if (vlen(self.origin - tracker.tag_target.origin) < vlen(self.origin - closest_target.origin))
 +                              closest_target = tracker.tag_target;
 +              }
-               
++              else
 +                      closest_target = tracker.tag_target;
 +      }
-       
++
 +      traceline(self.origin + self.view_ofs, closest_target.origin, MOVE_NOMONSTERS, self);
 +      if ((!closest_target) || ((trace_fraction < 1) && (trace_ent != closest_target)))
 +              closest_target = world;
-       
++
 +      Seeker_Fire_Missile('0 0 0', closest_target);
 +}
 +
 +void Seeker_Vollycontroller_Think() // TODO: Merge this with Seeker_Attack
 +{
 +      float c;
 +      entity oldself,oldenemy;
 +      self.cnt = self.cnt - 1;
 +
 +      if((!(self.realowner.items & IT_UNLIMITED_AMMO) && self.realowner.ammo_rockets < WEP_CVAR(seeker, missile_ammo)) || (self.cnt <= -1) || (self.realowner.deadflag != DEAD_NO) || (self.realowner.switchweapon != WEP_SEEKER))
 +      {
 +              remove(self);
 +              return;
 +      }
 +
 +      self.nextthink = time + WEP_CVAR(seeker, missile_delay) * W_WeaponRateFactor();
-       
++
 +      oldself = self;
 +      self = self.realowner;
-       
++
 +      oldenemy = self.enemy;
 +      self.enemy = oldself.enemy;
- void Seeker_Tracker_Think() 
++
 +      c = mod(self.cnt, 4);
 +      switch(c)
 +      {
 +              case 0:
 +                      Seeker_Fire_Missile('-1.25 -3.75 0', self.enemy);
 +                      break;
 +              case 1:
 +                      Seeker_Fire_Missile('+1.25 -3.75 0', self.enemy);
 +                      break;
 +              case 2:
 +                      Seeker_Fire_Missile('-1.25 +3.75 0', self.enemy);
 +                      break;
 +              case 3:
 +              default:
 +                      Seeker_Fire_Missile('+1.25 +3.75 0', self.enemy);
 +                      break;
 +      }
 +
 +      self.enemy = oldenemy;
 +      self = oldself;
 +}
 +
-       
++void Seeker_Tracker_Think()
 +{
 +      // commit suicide if: You die OR target dies OR you switch away from the seeker OR commit suicide if lifetime is up
 +      if ((self.realowner.deadflag != DEAD_NO) || (self.tag_target.deadflag != DEAD_NO) || (self.realowner.switchweapon != WEP_SEEKER)
 +      || (time > self.tag_time + WEP_CVAR(seeker, tag_tracker_lifetime)))
 +      {
 +              if (self)
 +              {
 +                      WaypointSprite_Kill(self.tag_target.wps_tag_tracker);
 +                      remove(self);
 +              }
 +              return;
 +      }
- // Begin: Tag projectile 
++
 +      // Update the think method information
 +      self.nextthink = time;
 +}
 +
 +// ============================
-       
++// Begin: Tag projectile
 +// ============================
 +void Seeker_Tag_Explode ()
 +{
 +      //if(other==self.realowner)
 +      //    return;
 +      Damage_DamageInfo(self.origin, 0, 0, 0, self.velocity, WEP_SEEKER | HITTYPE_BOUNCE, other.species, self);
 +
 +      remove (self);
 +}
 +
 +void Seeker_Tag_Damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
 +{
 +      if (self.health <= 0)
 +              return;
 +      self.health = self.health - damage;
 +      if (self.health <= 0)
 +              Seeker_Tag_Explode();
 +}
 +
 +void Seeker_Tag_Touch()
 +{
 +      vector dir;
 +      vector org2;
 +      entity e;
-               
++
 +      PROJECTILE_TOUCH;
 +
 +      dir     = normalize (self.realowner.origin - self.origin);
 +      org2    = findbetterlocation (self.origin, 8);
 +
 +      te_knightspike(org2);
 +
 +      self.event_damage = func_null;
 +      Damage_DamageInfo(self.origin, 0, 0, 0, self.velocity, WEP_SEEKER | HITTYPE_BOUNCE | HITTYPE_SECONDARY, other.species, self);
 +
 +      if (other.takedamage == DAMAGE_AIM && other.deadflag == DEAD_NO)
 +      {
 +              // check to see if this person is already tagged by me
 +              entity tag = Seeker_Tagged_Info(self.realowner, other);
-                               
++
 +              if (tag != world)
 +              {
 +                      if (other.wps_tag_tracker && (WEP_CVAR(seeker, type) == 1)) // don't attach another waypointsprite without killing the old one first
 +                              WaypointSprite_Kill(other.wps_tag_tracker);
-               {               
++
 +                      tag.tag_time = time;
 +              }
 +              else
-                       
-                       if      (WEP_CVAR(seeker, type) == 1)
++              {
 +                      //sprint(self.realowner, strcat("You just tagged ^2", other.netname, "^7 with a tracking device!\n"));
 +                      e             = spawn();
 +                      e.cnt         = WEP_CVAR(seeker, missile_count);
 +                      e.classname   = "tag_tracker";
 +                      e.owner       = self.owner;
 +                      e.realowner   = self.realowner;
-                       else 
++
++                      if(WEP_CVAR(seeker, type) == 1)
 +                      {
 +                              e.tag_target  = other;
 +                              e.tag_time    = time;
 +                              e.think       = Seeker_Tracker_Think;
 +                      }
-                       
++                      else
 +                      {
 +                              e.enemy     = other;
 +                              e.think     = Seeker_Vollycontroller_Think;
 +                      }
-               
-               if      (WEP_CVAR(seeker, type) == 1)
++
 +                      e.nextthink   = time;
 +              }
-       //missile.missile_flags = MIF_..?; 
++
++              if(WEP_CVAR(seeker, type) == 1)
 +              {
 +                      WaypointSprite_Spawn("tagged-target", WEP_CVAR(seeker, tag_tracker_lifetime), 0, other, '0 0 64', self.realowner, 0, other, wps_tag_tracker, TRUE, RADARICON_TAGGED, '0.5 1 0');
 +                      WaypointSprite_UpdateRule(other.wps_tag_tracker, 0, SPRITERULE_DEFAULT);
 +              }
 +      }
 +
 +      remove(self);
 +      return;
 +}
 +
 +void Seeker_Fire_Tag()
 +{
 +      entity missile;
 +      W_DecreaseAmmo(ammo_rockets, WEP_CVAR(seeker, tag_ammo), autocvar_g_balance_seeker_reload_ammo);
 +
 +      W_SetupShot_ProjectileSize (self, '-2 -2 -2', '2 2 2', FALSE, 2, "weapons/tag_fire.wav", CH_WEAPON_A, WEP_CVAR(seeker, missile_damage) * WEP_CVAR(seeker, missile_count));
 +
 +      missile                 = spawn();
 +      missile.owner           = missile.realowner = self;
 +      missile.classname       = "seeker_tag";
 +      missile.bot_dodge       = TRUE;
 +      missile.bot_dodgerating = 50;
 +      missile.touch           = Seeker_Tag_Touch;
 +      missile.think           = SUB_Remove;
 +      missile.nextthink       = time + WEP_CVAR(seeker, tag_lifetime);
 +      missile.movetype        = MOVETYPE_FLY;
 +      missile.solid           = SOLID_BBOX;
 +
 +      missile.takedamage       = DAMAGE_YES;
 +      missile.event_damage     = Seeker_Tag_Damage;
 +      missile.health           = WEP_CVAR(seeker, tag_health);
 +      missile.damageforcescale = WEP_CVAR(seeker, tag_damageforcescale);
 +
 +      setorigin (missile, w_shotorg);
 +      setsize (missile, '-2 -2 -2', '2 2 2');
 +
 +      missile.flags       = FL_PROJECTILE;
-                       if (WEP_CVAR(seeker, type) == 1) 
++      //missile.missile_flags = MIF_..?;
 +
 +      missile.movetype    = MOVETYPE_FLY;
 +      W_SETUPPROJECTILEVELOCITY(missile, g_balance_seeker_tag);
 +      missile.angles = vectoangles (missile.velocity);
 +
 +      CSQCProjectile(missile, TRUE, PROJECTILE_TAG, FALSE); // has sound
 +
 +      other = missile; MUTATOR_CALLHOOK(EditProjectile);
 +}
 +
 +// ============================
 +// Begin: Genereal weapon functions
 +// ============================
 +
 +float w_seeker(float req)
 +{
 +      float ammo_amount;
 +
 +      switch(req)
 +      {
 +              case WR_AIM:
 +              {
-                               
++                      if (WEP_CVAR(seeker, type) == 1)
 +                              if (Seeker_Tagged_Info(self, self.enemy) != world)
 +                                      self.BUTTON_ATCK = bot_aim(WEP_CVAR(seeker, missile_speed_max), 0, WEP_CVAR(seeker, missile_lifetime), FALSE);
 +                              else
 +                                      self.BUTTON_ATCK2 = bot_aim(WEP_CVAR(seeker, tag_speed), 0, WEP_CVAR(seeker, tag_lifetime), FALSE);
 +                      else
 +                              self.BUTTON_ATCK = bot_aim(WEP_CVAR(seeker, tag_speed), 0, WEP_CVAR(seeker, tag_lifetime), FALSE);
-                               
 +                      return TRUE;
 +              }
 +              case WR_THINK:
 +              {
 +                      if(autocvar_g_balance_seeker_reload_ammo && self.clip_load < min(WEP_CVAR(seeker, missile_ammo), WEP_CVAR(seeker, tag_ammo))) // forced reload
 +                              WEP_ACTION(self.weapon, WR_RELOAD);
-                               if (WEP_CVAR(seeker, type) == 1) 
++
 +                      else if (self.BUTTON_ATCK)
 +                      {
-                               else 
++                              if (WEP_CVAR(seeker, type) == 1)
 +                              {
 +                                      if (weapon_prepareattack(0, WEP_CVAR(seeker, missile_refire)))
 +                                      {
 +                                              Seeker_Attack();
 +                                              weapon_thinkf(WFRAME_FIRE2, WEP_CVAR(seeker, missile_animtime), w_ready);
 +                                      }
 +                              }
-                               if (WEP_CVAR(seeker, type) == 1) 
++                              else
 +                              {
 +                                      if (weapon_prepareattack(0, WEP_CVAR(seeker, tag_refire)))
 +                                      {
 +                                              Seeker_Fire_Tag();
 +                                              weapon_thinkf(WFRAME_FIRE2, WEP_CVAR(seeker, tag_animtime), w_ready);
 +                                      }
 +                              }
 +                      }
 +
 +                      else if (self.BUTTON_ATCK2)
 +                      {
-                               else 
++                              if (WEP_CVAR(seeker, type) == 1)
 +                              {
 +                                      if (weapon_prepareattack(0, WEP_CVAR(seeker, tag_refire)))
 +                                      {
 +                                              Seeker_Fire_Tag();
 +                                              weapon_thinkf(WFRAME_FIRE2, WEP_CVAR(seeker, tag_animtime), w_ready);
 +                                      }
 +                              }
-                       
++                              else
 +                              {
 +                                      if (weapon_prepareattack(0, WEP_CVAR(seeker, flac_refire)))
 +                                      {
 +                                              Seeker_Fire_Flac();
 +                                              weapon_thinkf(WFRAME_FIRE2, WEP_CVAR(seeker, flac_animtime), w_ready);
 +                                      }
 +                              }
 +                      }
-                       if (WEP_CVAR(seeker, type) == 1) 
++
 +                      return TRUE;
 +              }
 +              case WR_INIT:
 +              {
 +                      precache_model ("models/weapons/g_seeker.md3");
 +                      precache_model ("models/weapons/v_seeker.md3");
 +                      precache_model ("models/weapons/h_seeker.iqm");
 +                      precache_sound ("weapons/tag_fire.wav");
 +                      precache_sound ("weapons/flac_fire.wav");
 +                      precache_sound ("weapons/seeker_fire.wav");
 +                      WEP_SET_PROPS(SEEKER_SETTINGS(seeker), WEP_SEEKER)
 +                      return TRUE;
 +              }
 +              case WR_SETUP:
 +              {
 +                      self.current_ammo = ammo_rockets;
 +                      return TRUE;
 +              }
 +              case WR_CHECKAMMO1:
 +              {
-                       
++                      if (WEP_CVAR(seeker, type) == 1)
 +                      {
 +                              ammo_amount = self.ammo_rockets >= WEP_CVAR(seeker, missile_ammo);
 +                              ammo_amount += self.(weapon_load[WEP_SEEKER]) >= WEP_CVAR(seeker, missile_ammo);
 +                      }
 +                      else
 +                      {
 +                              ammo_amount = self.ammo_rockets >= WEP_CVAR(seeker, tag_ammo);
 +                              ammo_amount += self.(weapon_load[WEP_SEEKER]) >= WEP_CVAR(seeker, tag_ammo);
 +                      }
-                       if (WEP_CVAR(seeker, type) == 1) 
 +                      return ammo_amount;
 +              }
 +              case WR_CHECKAMMO2:
 +              {
-                       
++                      if (WEP_CVAR(seeker, type) == 1)
 +                      {
 +                              ammo_amount = self.ammo_rockets >= WEP_CVAR(seeker, tag_ammo);
 +                              ammo_amount += self.(weapon_load[WEP_SEEKER]) >= WEP_CVAR(seeker, tag_ammo);
 +                      }
 +                      else
 +                      {
 +                              ammo_amount = self.ammo_rockets >= WEP_CVAR(seeker, flac_ammo);
 +                              ammo_amount += self.(weapon_load[WEP_SEEKER]) >= WEP_CVAR(seeker, flac_ammo);
 +                      }
-                       
 +                      return ammo_amount;
 +              }
 +              case WR_CONFIG:
 +              {
 +                      WEP_CONFIG_SETTINGS(SEEKER_SETTINGS(seeker))
 +                      return TRUE;
 +              }
 +              case WR_RELOAD:
 +              {
 +                      W_Reload(min(WEP_CVAR(seeker, missile_ammo), WEP_CVAR(seeker, tag_ammo)), "weapons/reload.wav");
 +                      return TRUE;
 +              }
 +              case WR_SUICIDEMESSAGE:
 +              {
 +                      return WEAPON_SEEKER_SUICIDE;
 +              }
 +              case WR_KILLMESSAGE:
 +              {
 +                      if(w_deathtype & HITTYPE_SECONDARY)
 +                              return WEAPON_SEEKER_MURDER_TAG;
 +                      else
 +                              return WEAPON_SEEKER_MURDER_SPRAY;
 +              }
 +      }
 +      return TRUE;
 +}
 +#endif
 +#ifdef CSQC
 +float w_seeker(float req)
 +{
 +      switch(req)
 +      {
 +              case WR_IMPACTEFFECT:
 +              {
 +                      vector org2;
 +                      org2 = w_org + w_backoff * 6;
 +                      if(w_deathtype & HITTYPE_BOUNCE)
 +                      {
 +                              if(w_deathtype & HITTYPE_SECONDARY)
 +                              {
 +                                      if(!w_issilent)
 +                                              sound(self, CH_SHOTS, "weapons/tag_impact.wav", 1, ATTEN_NORM);
 +                              }
 +                              else
 +                              {
 +                                      pointparticles(particleeffectnum("hagar_explode"), org2, '0 0 0', 1);
 +                                      if(!w_issilent)
 +                                      {
 +                                              if (w_random<0.15)
 +                                                      sound(self, CH_SHOTS, "weapons/tagexp1.wav", 1, ATTEN_NORM);
 +                                              else if (w_random<0.7)
 +                                                      sound(self, CH_SHOTS, "weapons/tagexp2.wav", 1, ATTEN_NORM);
 +                                              else
 +                                                      sound(self, CH_SHOTS, "weapons/tagexp3.wav", 1, ATTEN_NORM);
 +                                      }
 +                              }
 +                      }
 +                      else
 +                      {
 +                              pointparticles(particleeffectnum("hagar_explode"), org2, '0 0 0', 1);
 +                              if(!w_issilent)
 +                              {
 +                                      if (w_random<0.15)
 +                                              sound(self, CH_SHOTS, "weapons/seekerexp1.wav", 1, ATTEN_NORM);
 +                                      else if (w_random<0.7)
 +                                              sound(self, CH_SHOTS, "weapons/seekerexp2.wav", 1, ATTEN_NORM);
 +                                      else
 +                                              sound(self, CH_SHOTS, "weapons/seekerexp3.wav", 1, ATTEN_NORM);
 +                              }
 +                      }
-       
 +                      return TRUE;
 +              }
 +              case WR_INIT:
 +              {
 +                      precache_sound("weapons/seekerexp1.wav");
 +                      precache_sound("weapons/seekerexp2.wav");
 +                      precache_sound("weapons/seekerexp3.wav");
 +                      precache_sound("weapons/tagexp1.wav");
 +                      precache_sound("weapons/tagexp2.wav");
 +                      precache_sound("weapons/tagexp3.wav");
 +                      precache_sound("weapons/tag_impact.wav");
 +                      return TRUE;
 +              }
 +      }
++
 +      return TRUE;
 +}
 +#endif
 +#endif
index 4f777d72979893352842c4304cfa5bfcac8f0eb7,0000000000000000000000000000000000000000..cf194dacb352353db29157ed3e91e262bd306676
mode 100644,000000..100644
--- /dev/null
@@@ -1,491 -1,0 +1,491 @@@
-       
 +#ifdef REGISTER_WEAPON
 +REGISTER_WEAPON(
 +/* WEP_##id */ TUBA,
 +/* function */ w_tuba,
 +/* ammotype */ 0,
 +/* impulse  */ 1,
 +/* flags    */ WEP_FLAG_HIDDEN | WEP_TYPE_SPLASH,
 +/* rating   */ BOT_PICKUP_RATING_MID,
 +/* model    */ "tuba",
 +/* netname  */ "tuba",
 +/* xgettext:no-c-format */
 +/* fullname  */ _("@!#%'n Tuba")
 +);
 +
 +#define TUBA_SETTINGS(weapon) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, animtime) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, attenuation) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, damage) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, edgedamage) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, force) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, radius) \
 +      WEP_ADD_CVAR(weapon, MO_NONE, refire) \
 +      WEP_ADD_PROP(weapon, reloading_ammo, reload_ammo) \
 +      WEP_ADD_PROP(weapon, reloading_time, reload_time) \
 +      WEP_ADD_PROP(weapon, switchdelay_raise, switchdelay_raise) \
 +      WEP_ADD_PROP(weapon, switchdelay_drop, switchdelay_drop)
 +
 +#ifdef SVQC
 +TUBA_SETTINGS(tuba)
 +.entity tuba_note;
 +.float tuba_smoketime;
 +.float tuba_instrument;
 +
 +#define MAX_TUBANOTES 32
 +.float tuba_lastnotes_last;
 +.float tuba_lastnotes_cnt; // over
 +.vector tuba_lastnotes[MAX_TUBANOTES];
 +#endif
 +#else
 +#ifdef SVQC
 +void spawnfunc_weapon_tuba (void) { weapon_defaultspawnfunc(WEP_TUBA); }
 +
 +float W_Tuba_HasPlayed(entity pl, string melody, float instrument, float ignorepitch, float mintempo, float maxtempo)
 +{
 +      float i, j, mmin, mmax, nolength;
 +      float n = tokenize_console(melody);
 +      if(n > pl.tuba_lastnotes_cnt)
 +              return FALSE;
 +      float pitchshift = 0;
 +
 +      if(instrument >= 0)
 +              if(pl.tuba_instrument != instrument)
 +                      return FALSE;
 +
 +      // verify notes...
 +      nolength = FALSE;
 +      for(i = 0; i < n; ++i)
 +      {
 +              vector v = pl.(tuba_lastnotes[mod(pl.tuba_lastnotes_last - i + MAX_TUBANOTES, MAX_TUBANOTES)]);
 +              float ai = stof(argv(n - i - 1));
 +              float np = floor(ai);
 +              if(ai == np)
 +                      nolength = TRUE;
 +              // n counts the last played notes BACKWARDS
 +              // _x is start
 +              // _y is end
 +              // _z is note pitch
 +              if(ignorepitch && i == 0)
 +              {
 +                      pitchshift = np - v_z;
 +              }
 +              else
 +              {
 +                      if(v_z + pitchshift != np)
 +                              return FALSE;
 +              }
 +      }
 +
 +      // now we know the right NOTES were played
 +      if(!nolength)
 +      {
 +              // verify rhythm...
 +              float ti = 0;
 +              if(maxtempo > 0)
 +                      mmin = 240 / maxtempo; // 60 = "0.25 means 1 sec", at 120 0.5 means 1 sec, at 240 1 means 1 sec
 +              else
 +                      mmin = 0;
 +              if(mintempo > 0)
 +                      mmax = 240 / mintempo; // 60 = "0.25 means 1 sec", at 120 0.5 means 1 sec, at 240 1 means 1 sec
 +              else
 +                      mmax = 240; // you won't try THAT hard... (tempo 1)
 +              //print(sprintf("initial tempo rules: %f %f\n", mmin, mmax));
 +
 +              for(i = 0; i < n; ++i)
 +              {
 +                      vector vi = pl.(tuba_lastnotes[mod(pl.tuba_lastnotes_last - i + MAX_TUBANOTES, MAX_TUBANOTES)]);
 +                      float ai = stof(argv(n - i - 1));
 +                      ti -= 1 / (ai - floor(ai));
 +                      float tj = ti;
 +                      for(j = i+1; j < n; ++j)
 +                      {
 +                              vector vj = pl.(tuba_lastnotes[mod(pl.tuba_lastnotes_last - j + MAX_TUBANOTES, MAX_TUBANOTES)]);
 +                              float aj = stof(argv(n - j - 1));
 +                              tj -= (aj - floor(aj));
 +
 +                              // note i should be at m*ti+b
 +                              // note j should be at m*tj+b
 +                              // so:
 +                              // we have a LINE l, so that
 +                              // vi_x <= l(ti) <= vi_y
 +                              // vj_x <= l(tj) <= vj_y
 +                              // what is m?
 +
 +                              // vi_x <= vi_y <= vj_x <= vj_y
 +                              // ti <= tj
 +                              //print(sprintf("first note: %f to %f, should be %f\n", vi_x, vi_y, ti));
 +                              //print(sprintf("second note: %f to %f, should be %f\n", vj_x, vj_y, tj));
 +                              //print(sprintf("m1 = %f\n", (vi_x - vj_y) / (ti - tj)));
 +                              //print(sprintf("m2 = %f\n", (vi_y - vj_x) / (ti - tj)));
 +                              mmin = max(mmin, (vi_x - vj_y) / (ti - tj)); // lower bound
 +                              mmax = min(mmax, (vi_y - vj_x) / (ti - tj)); // upper bound
 +                      }
 +              }
 +
 +              if(mmin > mmax) // rhythm fail
 +                      return FALSE;
 +      }
 +
 +      pl.tuba_lastnotes_cnt = 0;
 +
 +      return TRUE;
 +}
 +
 +void W_Tuba_NoteOff()
 +{
 +      // we have a note:
 +      //   on: self.spawnshieldtime
 +      //   off: time
 +      //   note: self.cnt
 +      if(self.owner.tuba_note == self)
 +      {
 +              self.owner.tuba_lastnotes_last = mod(self.owner.tuba_lastnotes_last + 1, MAX_TUBANOTES);
 +              self.owner.(tuba_lastnotes[self.owner.tuba_lastnotes_last]) = eX * self.spawnshieldtime + eY * time + eZ * self.cnt;
 +              self.owner.tuba_note = world;
 +              self.owner.tuba_lastnotes_cnt = bound(0, self.owner.tuba_lastnotes_cnt + 1, MAX_TUBANOTES);
 +
 +              string s;
 +              s = trigger_magicear_processmessage_forallears(self.owner, 0, world, string_null);
 +              if(s != "")
 +              {
 +                      // simulate a server message
 +                      switch(self.tuba_instrument)
 +                      {
 +                              default:
 +                              case 0: // Tuba
 +                                      bprint(strcat("\{1}\{13}* ^3", self.owner.netname, "^3 played on the @!#%'n Tuba: ^7", s, "\n"));
 +                                      break;
 +                              case 1:
 +                                      bprint(strcat("\{1}\{13}* ^3", self.owner.netname, "^3 played on the @!#%'n Accordeon: ^7", s, "\n"));
 +                                      break;
 +                              case 2:
 +                                      bprint(strcat("\{1}\{13}* ^3", self.owner.netname, "^3 played on the @!#%'n Klein Bottle: ^7", s, "\n"));
 +                                      break;
 +                      }
 +              }
 +      }
 +      remove(self);
 +}
 +
 +float Tuba_GetNote(entity pl, float hittype)
 +{
 +      float note;
 +      float movestate;
 +      movestate = 5;
 +      if(pl.movement_x < 0) movestate -= 3;
 +      if(pl.movement_x > 0) movestate += 3;
 +      if(pl.movement_y < 0) movestate -= 1;
 +      if(pl.movement_y > 0) movestate += 1;
 +#ifdef GMQCC
 +      note = 0;
 +#endif
 +      switch(movestate)
 +      {
 +      // layout: originally I wanted
 +      //   eb e  e#=f
 +      //   B  c  d
 +      //   Gb G  G#
 +      // but then you only use forward and right key. So to make things more
 +      // interesting, I swapped B with e#. Har har har...
 +      //   eb e  B
 +      // f=e# c  d
 +      //   Gb G  G#
 +              case 1: note = -6; break; // Gb
 +              case 2: note = -5; break; // G
 +              case 3: note = -4; break; // G#
 +              case 4: note = +5; break; // e#
 +              default:
 +              case 5: note =  0; break; // c
 +              case 6: note = +2; break; // d
 +              case 7: note = +3; break; // eb
 +              case 8: note = +4; break; // e
 +              case 9: note = -1; break; // B
 +      }
 +      if(pl.BUTTON_CROUCH)
 +              note -= 12;
 +      if(pl.BUTTON_JUMP)
 +              note += 12;
 +      if(hittype & HITTYPE_SECONDARY)
 +              note += 7;
-       
++
 +      // we support two kinds of tubas, those tuned in Eb and those tuned in C
 +      // kind of tuba currently is player slot number, or team number if in
 +      // teamplay
 +      // that way, holes in the range of notes are "plugged"
 +      if(teamplay)
 +      {
 +              if(pl.team == NUM_TEAM_2 || pl.team == NUM_TEAM_4)
 +                      note += 3;
 +      }
 +      else
 +      {
 +              if(pl.clientcolors & 1)
 +                      note += 3;
 +      }
-       if not(self.tuba_note)
++
 +      // total range of notes:
 +      //                       0
 +      //                 ***  ** ****
 +      //                        ***  ** ****
 +      //     ***  ** ****
 +      //            ***  ** ****
 +      //     ***  ********************* ****
 +      //     -18.........................+12
 +      //        ***  ********************* ****
 +      //     -18............................+15
 +      //     with jump: ... +24
 +      //     ... +27
 +      return note;
 +}
 +
 +float W_Tuba_NoteSendEntity(entity to, float sf)
 +{
 +      float f;
 +
 +      msg_entity = to;
 +      if(!sound_allowed(MSG_ONE, self.realowner))
 +              return FALSE;
 +
 +      WriteByte(MSG_ENTITY, ENT_CLIENT_TUBANOTE);
 +      WriteByte(MSG_ENTITY, sf);
 +      if(sf & 1)
 +      {
 +              WriteChar(MSG_ENTITY, self.cnt);
 +              f = 0;
 +              if(self.realowner != to)
 +                      f |= 1;
 +              f |= 2 * self.tuba_instrument;
 +              WriteByte(MSG_ENTITY, f);
 +      }
 +      if(sf & 2)
 +      {
 +              WriteCoord(MSG_ENTITY, self.origin_x);
 +              WriteCoord(MSG_ENTITY, self.origin_y);
 +              WriteCoord(MSG_ENTITY, self.origin_z);
 +      }
 +      return TRUE;
 +}
 +
 +void W_Tuba_NoteThink()
 +{
 +      float dist_mult;
 +      float vol0, vol1;
 +      vector dir0, dir1;
 +      vector v;
 +      entity e;
 +      if(time > self.teleport_time)
 +      {
 +              W_Tuba_NoteOff();
 +              return;
 +      }
 +      self.nextthink = time;
 +      dist_mult = WEP_CVAR(tuba, attenuation) / autocvar_snd_soundradius;
 +      FOR_EACH_REALCLIENT(e)
 +      if(e != self.realowner)
 +      {
 +              v = self.origin - (e.origin + e.view_ofs);
 +              vol0 = max(0, 1 - vlen(v) * dist_mult);
 +              dir0 = normalize(v);
 +              v = self.realowner.origin - (e.origin + e.view_ofs);
 +              vol1 = max(0, 1 - vlen(v) * dist_mult);
 +              dir1 = normalize(v);
 +              if(fabs(vol0 - vol1) > 0.005) // 0.5 percent change in volume
 +              {
 +                      setorigin(self, self.realowner.origin);
 +                      self.SendFlags |= 2;
 +                      break;
 +              }
 +              if(dir0 * dir1 < 0.9994) // 2 degrees change in angle
 +              {
 +                      setorigin(self, self.realowner.origin);
 +                      self.SendFlags |= 2;
 +                      break;
 +              }
 +      }
 +}
 +
 +void W_Tuba_NoteOn(float hittype)
 +{
 +      vector o;
 +      float n;
 +
 +      W_SetupShot(self, FALSE, 2, "", 0, WEP_CVAR(tuba, damage));
 +
 +      n = Tuba_GetNote(self, hittype);
 +
 +      hittype = 0;
 +      if(self.tuba_instrument & 1)
 +              hittype |= HITTYPE_SECONDARY;
 +      if(self.tuba_instrument & 2)
 +              hittype |= HITTYPE_BOUNCE;
 +
 +      if(self.tuba_note)
 +      {
 +              if(self.tuba_note.cnt != n || self.tuba_note.tuba_instrument != self.tuba_instrument)
 +              {
 +                      entity oldself = self;
 +                      self = self.tuba_note;
 +                      W_Tuba_NoteOff();
 +                      self = oldself;
 +              }
 +      }
 +
++      if (!self.tuba_note)
 +      {
 +              self.tuba_note = spawn();
 +              self.tuba_note.owner = self.tuba_note.realowner = self;
 +              self.tuba_note.cnt = n;
 +              self.tuba_note.tuba_instrument = self.tuba_instrument;
 +              self.tuba_note.think = W_Tuba_NoteThink;
 +              self.tuba_note.nextthink = time;
 +              self.tuba_note.spawnshieldtime = time;
 +              Net_LinkEntity(self.tuba_note, FALSE, 0, W_Tuba_NoteSendEntity);
 +      }
 +
 +      self.tuba_note.teleport_time = time + WEP_CVAR(tuba, refire) * 2 * W_WeaponRateFactor(); // so it can get prolonged safely
 +
 +      //sound(self, c, TUBA_NOTE(n), bound(0, VOL_BASE * cvar("g_balance_tuba_volume"), 1), autocvar_g_balance_tuba_attenuation);
 +      RadiusDamage(self, self, WEP_CVAR(tuba, damage), WEP_CVAR(tuba, edgedamage), WEP_CVAR(tuba, radius), world, world, WEP_CVAR(tuba, force), hittype | WEP_TUBA, world);
 +
 +      o = gettaginfo(self.exteriorweaponentity, 0);
 +      if(time > self.tuba_smoketime)
 +      {
 +              pointparticles(particleeffectnum("smoke_ring"), o + v_up * 45 + v_right * -6 + v_forward * 8, v_up * 100, 1);
 +              self.tuba_smoketime = time + 0.25;
 +      }
 +}
 +
 +float w_tuba(float req)
 +{
 +      switch(req)
 +      {
 +              case WR_AIM:
 +              {
 +                      // bots cannot play the Tuba well yet
 +                      // I think they should start with the recorder first
 +                      if(vlen(self.origin - self.enemy.origin) < WEP_CVAR(tuba, radius))
 +                      {
 +                              if(random() > 0.5)
 +                                      self.BUTTON_ATCK = 1;
 +                              else
 +                                      self.BUTTON_ATCK2 = 1;
 +                      }
 +                      
 +                      return TRUE;
 +              }
 +              case WR_THINK:
 +              {
 +                      if (self.BUTTON_ATCK)
 +                      if (weapon_prepareattack(0, WEP_CVAR(tuba, refire)))
 +                      {
 +                              W_Tuba_NoteOn(0);
 +                              //weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_tuba_animtime, w_ready);
 +                              weapon_thinkf(WFRAME_IDLE, WEP_CVAR(tuba, animtime), w_ready);
 +                      }
 +                      if (self.BUTTON_ATCK2)
 +                      if (weapon_prepareattack(1, WEP_CVAR(tuba, refire)))
 +                      {
 +                              W_Tuba_NoteOn(HITTYPE_SECONDARY);
 +                              //weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_tuba_animtime, w_ready);
 +                              weapon_thinkf(WFRAME_IDLE, WEP_CVAR(tuba, animtime), w_ready);
 +                      }
 +                      if(self.tuba_note)
 +                      {
 +                              if(!self.BUTTON_ATCK && !self.BUTTON_ATCK2)
 +                              {
 +                                      entity oldself = self;
 +                                      self = self.tuba_note;
 +                                      W_Tuba_NoteOff();
 +                                      self = oldself;
 +                              }
 +                      }
 +                      
 +                      return TRUE;
 +              }
 +              case WR_INIT:
 +              {
 +                      precache_model ("models/weapons/g_tuba.md3");
 +                      precache_model ("models/weapons/v_tuba.md3");
 +                      precache_model ("models/weapons/h_tuba.iqm");
 +                      precache_model ("models/weapons/v_akordeon.md3");
 +                      precache_model ("models/weapons/h_akordeon.iqm");
 +                      precache_model ("models/weapons/v_kleinbottle.md3");
 +                      precache_model ("models/weapons/h_kleinbottle.iqm");
 +                      WEP_SET_PROPS(TUBA_SETTINGS(tuba), WEP_TUBA)
 +                      return TRUE;
 +              }
 +              case WR_SETUP:
 +              {
 +                      self.current_ammo = ammo_none;
 +                      self.tuba_instrument = 0;
 +                      return TRUE;
 +              }
 +              case WR_RELOAD:
 +              {
 +                      // switch to alternate instruments :)
 +                      if(self.weaponentity.state == WS_READY)
 +                      {
 +                              switch(self.tuba_instrument)
 +                              {
 +                                      case 0:
 +                                              self.tuba_instrument = 1;
 +                                              self.weaponname = "akordeon";
 +                                              break;
 +                                      case 1:
 +                                              self.tuba_instrument = 2;
 +                                              self.weaponname = "kleinbottle";
 +                                              break;
 +                                      case 2:
 +                                              self.tuba_instrument = 0;
 +                                              self.weaponname = "tuba";
 +                                              break;
 +                              }
 +                              W_SetupShot(self, FALSE, 0, "", 0, 0);
 +                              pointparticles(particleeffectnum("teleport"), w_shotorg, '0 0 0', 1);
 +                              self.weaponentity.state = WS_INUSE;
 +                              weapon_thinkf(WFRAME_RELOAD, 0.5, w_ready);
 +                      }
 +                      
 +                      return TRUE;
 +              }
 +              case WR_CHECKAMMO1:
 +              case WR_CHECKAMMO2:
 +              {
 +                      return TRUE; // tuba has infinite ammo
 +              }
 +              case WR_CONFIG:
 +              {
 +                      WEP_CONFIG_SETTINGS(TUBA_SETTINGS(tuba))
 +                      return TRUE;
 +              }
 +              case WR_SUICIDEMESSAGE:
 +              {
 +                      if(w_deathtype & HITTYPE_BOUNCE)
 +                              return WEAPON_KLEINBOTTLE_SUICIDE;
 +                      else if(w_deathtype & HITTYPE_SECONDARY)
 +                              return WEAPON_ACCORDEON_SUICIDE;
 +                      else
 +                              return WEAPON_TUBA_SUICIDE;
 +              }
 +              case WR_KILLMESSAGE:
 +              {
 +                      if(w_deathtype & HITTYPE_BOUNCE)
 +                              return WEAPON_KLEINBOTTLE_MURDER;
 +                      else if(w_deathtype & HITTYPE_SECONDARY)
 +                              return WEAPON_ACCORDEON_MURDER;
 +                      else
 +                              return WEAPON_TUBA_MURDER;
 +              }
 +      }
 +      return TRUE;
 +}
 +#endif
 +#ifdef CSQC
 +float w_tuba(float req)
 +{
 +      // nothing to do here; particles of tuba are handled differently
 +
 +      return TRUE;
 +}
 +#endif
 +#endif
index 362a3d84a113c50fba09e147eab50ccafcbb38f4,0000000000000000000000000000000000000000..75a1a673228825ab590e7c54bab521c99d2dae87
mode 100644,000000..100644
--- /dev/null
@@@ -1,238 -1,0 +1,238 @@@
- ACCUMULATE_FUNCTION(RegisterWeapons, register_weapons_done)
 +#ifndef MENUQC
 +#include "calculations.qh"
 +#endif
 +
 +const float BOT_PICKUP_RATING_LOW     = 2500;
 +const float BOT_PICKUP_RATING_MID     = 5000;
 +const float BOT_PICKUP_RATING_HIGH    = 10000;
 +
 +const float WEP_TYPE_OTHER          =  0x00; // not for damaging people
 +const float WEP_TYPE_SPLASH         =  0x01; // splash damage
 +const float WEP_TYPE_HITSCAN        =  0x02; // hitscan
 +const float WEP_TYPEMASK            =  0x0F;
 +const float WEP_FLAG_CANCLIMB       =  0x10; // can be used for movement
 +const float WEP_FLAG_NORMAL         =  0x20; // in "most weapons" set
 +const float WEP_FLAG_HIDDEN         =  0x40; // hides from menu
 +const float WEP_FLAG_RELOADABLE     =  0x80; // can has reload
 +const float WEP_FLAG_SUPERWEAPON    = 0x100; // powerup timer
 +const float WEP_FLAG_MUTATORBLOCKED = 0x200; // hides from impulse 99 etc. (mutators are allowed to clear this flag)
 +
 +const float MAX_SHOT_DISTANCE = 32768;
 +
 +// weapon requests // WEAPONTODO
 +#define WR_SETUP          1 // (SERVER) setup weapon data
 +#define WR_THINK          2 // (SERVER) logic to run every frame
 +#define WR_CHECKAMMO1     3 // (SERVER) checks ammo for weapon
 +#define WR_CHECKAMMO2     4 // (SERVER) checks ammo for weapon
 +#define WR_AIM            5 // (SERVER) runs bot aiming code for this weapon
 +#define WR_INIT           6 // (BOTH) precaches models/sounds used by this weapon
 +#define WR_SUICIDEMESSAGE 7 // (SERVER) notification number for suicide message (may inspect w_deathtype for details)
 +#define WR_KILLMESSAGE    8 // (SERVER) notification number for kill message (may inspect w_deathtype for details)
 +#define WR_RELOAD         9 // (SERVER) does not need to do anything
 +#define WR_RESETPLAYER    10 // (SERVER) does not need to do anything
 +#define WR_IMPACTEFFECT   11 // (CLIENT) impact effect
 +#define WR_SWITCHABLE     12 // (CLIENT) impact effect
 +#define WR_PLAYERDEATH    13 // (SERVER) does not need to do anything
 +#define WR_GONETHINK      14 // (SERVER) logic to run every frame, also if no longer having the weapon as long as the switch away has not been performed
 +#define WR_CONFIG         15 // (ALL) 
 +
 +// WEAPONTODO
 +const float   IT_UNLIMITED_WEAPON_AMMO     = 1;
 +// when this bit is set, using a weapon does not reduce ammo. Checkpoints can give this powerup.
 +const float   IT_UNLIMITED_SUPERWEAPONS    = 2;
 +// when this bit is set, superweapons don't expire. Checkpoints can give this powerup.
 +const float   IT_CTF_SHIELDED              = 4; // set for the flag shield
 +const float   IT_USING_JETPACK             = 8; // confirmation that button is pressed
 +const float   IT_JETPACK                   = 16; // actual item
 +const float   IT_FUEL_REGEN                = 32; // fuel regeneration trigger
 +WANT_CONST float   IT_SHELLS                    = 256;
 +WANT_CONST float   IT_NAILS                     = 512;
 +WANT_CONST float   IT_ROCKETS                   = 1024;
 +WANT_CONST float   IT_CELLS                     = 2048;
 +const float   IT_SUPERWEAPON               = 4096;
 +const float   IT_FUEL                      = 128;
 +const float   IT_STRENGTH                  = 8192;
 +const float   IT_INVINCIBLE                = 16384;
 +const float   IT_HEALTH                    = 32768;
 +// union:
 +      // for items:
 +      WANT_CONST float        IT_KEY1                                 = 131072;
 +      WANT_CONST float        IT_KEY2                                 = 262144;
 +      // for players:
 +      const float     IT_RED_FLAG_TAKEN               = 32768;
 +      const float     IT_RED_FLAG_LOST                = 65536;
 +      const float     IT_RED_FLAG_CARRYING            = 98304;
 +      const float     IT_BLUE_FLAG_TAKEN              = 131072;
 +      const float     IT_BLUE_FLAG_LOST               = 262144;
 +      const float     IT_BLUE_FLAG_CARRYING   = 393216;
 +// end
 +const float   IT_5HP                       = 524288;
 +const float   IT_25HP                      = 1048576;
 +const float   IT_ARMOR_SHARD               = 2097152;
 +const float   IT_ARMOR                     = 4194304;
 +
 +const float   IT_AMMO                      = 3968; // IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS | IT_FUEL;
 +const float   IT_PICKUPMASK                = 51; // IT_FUEL_REGEN | IT_JETPACK | IT_UNLIMITED_AMMO; // strength and invincible are handled separately
 +const float   IT_UNLIMITED_AMMO            = 3; // IT_UNLIMITED_SUPERWEAPONS | IT_UNLIMITED_WEAPON_AMMO;
 +
 +const float AMMO_COUNT = 4; // amount of ammo types to show in the inventory panel
 +
 +// variables:
 +string weaponorder_byid;
 +
 +// Weapon sets
 +typedef vector WepSet;
 +WepSet WepSet_FromWeapon(float a);
 +#ifdef SVQC
 +void WepSet_AddStat();
 +void WriteWepSet(float dest, WepSet w);
 +#endif
 +#ifdef CSQC
 +WepSet WepSet_GetFromStat();
 +WepSet ReadWepSet();
 +#endif
 +
 +// Weapon name macros
 +#define WEP_FIRST 1
 +#define WEP_MAXCOUNT 24 // Increase as needed. Can be up to three times as much.
 +float WEP_COUNT;
 +float WEP_LAST;
 +WepSet WEPSET_ALL;
 +WepSet WEPSET_SUPERWEAPONS;
 +
 +// functions:
 +entity get_weaponinfo(float id);
 +string W_FixWeaponOrder(string order, float complete);
 +string W_NameWeaponOrder(string order);
 +string W_NumberWeaponOrder(string order);
 +
 +// ammo types
 +.float ammo_shells;
 +.float ammo_nails;
 +.float ammo_rockets;
 +.float ammo_cells;
 +.float ammo_fuel;
 +.float ammo_batteries; // dummy
 +
 +// entity properties of weaponinfo:
 +.float weapon; // WEP_...
 +.WepSet weapons; // WEPSET_...
 +.string netname; // short name
 +.string message; // human readable name
 +.float items; // IT_...
 +.float(float) weapon_func; // w_...
 +.string mdl; // modelname without g_, v_, w_
 +.string model; // full name of g_ model
 +.float spawnflags; // WEPSPAWNFLAG_... combined
 +.float impulse; // weapon impulse
 +.float bot_pickupbasevalue; // bot weapon priority
 +.string model2; // wpn- sprite name
 +..float ammo_field; // main ammo field
 +
 +// other useful macros
 +#define WEP_ACTION(wpn,wrequest) (get_weaponinfo(wpn)).weapon_func(wrequest)
 +
 +// =====================
 +//  Weapon Registration
 +// =====================
 +
 +float w_null(float dummy);
 +void register_weapon(float id, WepSet bit, float(float) func, float ammotype, float i, float weapontype, float pickupbasevalue, string modelname, string shortname, string wname);
 +void register_weapons_done();
 +
 +// note: the fabs call is just there to hide "if result is constant" warning
 +#define REGISTER_WEAPON_2(id,bit,func,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname) \
 +      float id; \
 +      WepSet bit; \
 +      float func(float); \
 +      void RegisterWeapons_##id() \
 +      { \
 +              WEP_LAST = (id = WEP_FIRST + WEP_COUNT); \
 +              bit = WepSet_FromWeapon(id); \
 +              WEPSET_ALL |= bit; \
 +              if((weapontype) & WEP_FLAG_SUPERWEAPON) \
 +                      WEPSET_SUPERWEAPONS |= bit; \
 +              ++WEP_COUNT; \
 +              register_weapon(id,bit,func,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname); \
 +      } \
 +      ACCUMULATE_FUNCTION(RegisterWeapons, RegisterWeapons_##id)
 +#ifdef MENUQC
 +#define REGISTER_WEAPON(id,func,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname) \
 +      REGISTER_WEAPON_2(WEP_##id,WEPSET_##id,w_null,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname)
 +#else
 +#define REGISTER_WEAPON(id,func,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname) \
 +      REGISTER_WEAPON_2(WEP_##id,WEPSET_##id,func,ammotype,i,weapontype,pickupbasevalue,modelname,shortname,wname)
 +#endif
 +
 +#define MO_NONE 0
 +#define MO_PRI 1
 +#define MO_SEC 2
 +#define MO_BOTH 3
 +
 +#define WEP_DUPECHECK(dupecheck,cvar) \
 +      #ifndef dupecheck \
 +              #define dupecheck \
 +              float cvar; \
 +      #else \
 +              #error DUPLICATE WEAPON CVAR: cvar \
 +      #endif
 +
 +/*
 +#define WEP_CLEAN_DUPECHECK(dupecheck) \
 +      #ifdef WEP_CVAR_##weapon##_##name \
 +              #undef WEP_CVAR_##weapon##_##name \
 +      #endif
 +*/
 +
 +#define WEP_ADD_CVAR(weapon,mode,name) \
 +      #if mode == MO_PRI \
 +              WEP_DUPECHECK(WEP_CVAR_P_##weapon##_##name, autocvar_g_balance_##weapon##_primary_##name) \
 +      #endif \
 +      #if mode == MO_SEC \
 +              WEP_DUPECHECK(WEP_CVAR_S_##weapon##_##name, autocvar_g_balance_##weapon##_secondary_##name) \
 +      #endif \
 +      #if mode == MO_BOTH \
 +              WEP_DUPECHECK(WEP_CVAR_P_##weapon##_##name, autocvar_g_balance_##weapon##_primary_##name) \
 +              WEP_DUPECHECK(WEP_CVAR_S_##weapon##_##name, autocvar_g_balance_##weapon##_secondary_##name) \
 +      #endif \
 +      #if mode == MO_NONE \
 +              WEP_DUPECHECK(WEP_CVAR_##weapon##_##name, autocvar_g_balance_##weapon##_##name) \
 +      #endif
 +
 +#define WEP_CVAR(weapon,name) autocvar_g_balance_##weapon##_##name
 +#define WEP_CVAR_PRI(weapon,name) WEP_CVAR(weapon, primary_##name)
 +#define WEP_CVAR_SEC(weapon,name) WEP_CVAR(weapon, secondary_##name)
 +#define WEP_CVAR_BOTH(weapon,mode,name) ((mode == MO_PRI) ? WEP_CVAR_PRI(weapon, name) : WEP_CVAR_SEC(weapon, name))
 +
 +#define WEP_ADD_PROP(weapon,prop,name) \
 +      .float ##prop; \
 +      WEP_DUPECHECK(WEP_CVAR_##weapon##_##name, autocvar_g_balance_##weapon##_##name)
 +
 +#define WEP_SET_PROP(wepid,weapon,prop,name) get_weaponinfo(##wepid).##prop = autocvar_g_balance_##weapon##_##name;
 +
 +#define WEP_SET_PROPS(wepsettings,wepid) \
 +      #define WEP_ADD_CVAR(weapon,mode,name) \
 +      #define WEP_ADD_PROP(weapon,prop,name) WEP_SET_PROP(wepid,weapon,prop,name) \
 +      wepsettings \
 +      #undef WEP_ADD_CVAR \
 +      #undef WEP_ADD_PROP
 +
 +#include "all.qh"
 +
 +#undef WEP_ADD_CVAR
 +#undef WEP_ADD_PROP
 +#undef REGISTER_WEAPON
++ACCUMULATE_FUNCTION(RegisterWeapons, register_weapons_done);
 +
 +string W_FixWeaponOrder(string order, float complete);
 +string W_NumberWeaponOrder(string order);
 +string W_NameWeaponOrder(string order);
 +string W_FixWeaponOrder_BuildImpulseList(string o);
 +string W_FixWeaponOrder_AllowIncomplete(string order);
 +string W_FixWeaponOrder_ForceComplete(string order);
 +
 +void W_RandomWeapons(entity e, float n);
 +
 +string W_Name(float weaponid);
 +
 +float W_AmmoItemCode(float wpn);
diff --combined qcsrc/menu/progs.src
index 4cb011411695bd20468f5848e8ea160ded628781,4900b9d96bb52db193c8aaf82771634c94279755..61e3ecba8d3aa8e522650856ad7bb2e3e55b3d19
@@@ -18,7 -18,7 +18,7 @@@ oo/base.
  ../common/constants.qh
  ../common/mapinfo.qh
  ../common/campaign_common.qh
 -../common/items.qh
 +../common/weapons/weapons.qh // TODO
  ../common/counting.qh
  ../common/command/markup.qh
  ../common/command/rpn.qh
@@@ -50,9 -50,7 +50,7 @@@ xonotic/util.q
  ../common/campaign_file.qc
  ../common/campaign_setup.qc
  ../common/mapinfo.qc
 -../common/items.qc
 +../common/weapons/weapons.qc // TODO
  ../common/urllib.qc
  
  ../warpzonelib/mathlib.qc
- ../common/if-this-file-errors-scroll-up-and-fix-the-warnings.fteqccfail
index eb31d7b9a15d5e63e1b07652940e4bc41d8b36e3,19187a39deeab1c16cab1a8b05834d997dcb35d0..97996ce22fcc18396ddad4513b6e803975face6f
@@@ -70,14 -70,7 +70,7 @@@ float autocvar_ekg
  #define autocvar_fraglimit_override cvar("fraglimit_override")
  float autocvar_g_allow_oldnexbeam;
  float autocvar_g_antilag;
- float autocvar_g_antilag_bullets;
  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_roundbased;
- float autocvar_g_arena_round_timelimit;
- float autocvar_g_arena_warmup;
  float autocvar_g_balance_armor_blockpercent;
  float autocvar_g_balance_armor_limit;
  float autocvar_g_balance_armor_regen;
@@@ -87,7 -80,37 +80,7 @@@ 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_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;
@@@ -95,8 -118,58 +88,8 @@@ float autocvar_g_balance_contents_playe
  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;
 -float autocvar_g_balance_crylink_primary_bounces;
 -float autocvar_g_balance_crylink_primary_damage;
 -float autocvar_g_balance_crylink_primary_edgedamage;
 -float autocvar_g_balance_crylink_primary_force;
 -float autocvar_g_balance_crylink_primary_joindelay;
 -float autocvar_g_balance_crylink_primary_joinexplode;
 -float autocvar_g_balance_crylink_primary_joinexplode_damage;
 -float autocvar_g_balance_crylink_primary_joinexplode_edgedamage;
 -float autocvar_g_balance_crylink_primary_joinexplode_force;
 -float autocvar_g_balance_crylink_primary_joinexplode_radius;
 -float autocvar_g_balance_crylink_primary_joinspread;
 -float autocvar_g_balance_crylink_primary_linkexplode;
 -float autocvar_g_balance_crylink_primary_middle_fadetime;
 -float autocvar_g_balance_crylink_primary_middle_lifetime;
 -float autocvar_g_balance_crylink_primary_other_fadetime;
 -float autocvar_g_balance_crylink_primary_other_lifetime;
 -float autocvar_g_balance_crylink_primary_radius;
 -float autocvar_g_balance_crylink_primary_refire;
 -float autocvar_g_balance_crylink_primary_shots;
 -float autocvar_g_balance_crylink_primary_speed;
 -float autocvar_g_balance_crylink_primary_spread;
  float autocvar_g_balance_crylink_secondary;
 -float autocvar_g_balance_crylink_secondary_ammo;
 -float autocvar_g_balance_crylink_secondary_animtime;
 -float autocvar_g_balance_crylink_secondary_bouncedamagefactor;
 -float autocvar_g_balance_crylink_secondary_bounces;
 -float autocvar_g_balance_crylink_secondary_damage;
 -float autocvar_g_balance_crylink_secondary_edgedamage;
 -float autocvar_g_balance_crylink_secondary_force;
 -float autocvar_g_balance_crylink_secondary_joindelay;
 -float autocvar_g_balance_crylink_secondary_joinexplode;
 -float autocvar_g_balance_crylink_secondary_joinexplode_damage;
 -float autocvar_g_balance_crylink_secondary_joinexplode_edgedamage;
 -float autocvar_g_balance_crylink_secondary_joinexplode_force;
 -float autocvar_g_balance_crylink_secondary_joinexplode_radius;
 -float autocvar_g_balance_crylink_secondary_joinspread;
 -float autocvar_g_balance_crylink_secondary_line_fadetime;
 -float autocvar_g_balance_crylink_secondary_line_lifetime;
 -float autocvar_g_balance_crylink_secondary_linkexplode;
 -float autocvar_g_balance_crylink_secondary_middle_fadetime;
 -float autocvar_g_balance_crylink_secondary_middle_lifetime;
 -float autocvar_g_balance_crylink_secondary_radius;
 -float autocvar_g_balance_crylink_secondary_refire;
 -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_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;
@@@ -138,10 -211,41 +131,10 @@@ float autocvar_g_balance_electro_second
  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_animtime;
 -float autocvar_g_balance_fireball_primary_bfgdamage;
 -float autocvar_g_balance_fireball_primary_bfgforce;
 -float autocvar_g_balance_fireball_primary_bfgradius;
 -float autocvar_g_balance_fireball_primary_damage;
 -float autocvar_g_balance_fireball_primary_damageforcescale;
 -float autocvar_g_balance_fireball_primary_edgedamage;
 -float autocvar_g_balance_fireball_primary_force;
 -float autocvar_g_balance_fireball_primary_health;
 -float autocvar_g_balance_fireball_primary_laserburntime;
 -float autocvar_g_balance_fireball_primary_laserdamage;
 -float autocvar_g_balance_fireball_primary_laseredgedamage;
 -float autocvar_g_balance_fireball_primary_laserradius;
 -float autocvar_g_balance_fireball_primary_lifetime;
 -float autocvar_g_balance_fireball_primary_radius;
 -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_animtime;
 -float autocvar_g_balance_fireball_secondary_damage;
 -float autocvar_g_balance_fireball_secondary_damageforcescale;
 -float autocvar_g_balance_fireball_secondary_damagetime;
 -float autocvar_g_balance_fireball_secondary_laserburntime;
 -float autocvar_g_balance_fireball_secondary_laserdamage;
 -float autocvar_g_balance_fireball_secondary_laseredgedamage;
 -float autocvar_g_balance_fireball_secondary_laserradius;
 -float autocvar_g_balance_fireball_secondary_lifetime;
 -float autocvar_g_balance_fireball_secondary_refire;
 -float autocvar_g_balance_fireball_secondary_speed;
 -float autocvar_g_balance_fireball_secondary_speed_up;
  float autocvar_g_balance_firetransfer_damage;
  float autocvar_g_balance_firetransfer_time;
  float autocvar_g_balance_fuel_limit;
@@@ -160,7 -264,75 +153,7 @@@ float autocvar_g_balance_grapplehook_sp
  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;
 -float autocvar_g_balance_grenadelauncher_primary_animtime;
 -float autocvar_g_balance_grenadelauncher_primary_damage;
 -float autocvar_g_balance_grenadelauncher_primary_damageforcescale;
 -float autocvar_g_balance_grenadelauncher_primary_edgedamage;
 -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_lifetime_stick;
 -float autocvar_g_balance_grenadelauncher_primary_radius;
 -float autocvar_g_balance_grenadelauncher_primary_refire;
 -float autocvar_g_balance_grenadelauncher_primary_remote_minbouncecnt;
 -float autocvar_g_balance_grenadelauncher_primary_speed;
 -float autocvar_g_balance_grenadelauncher_primary_speed_up;
 -float autocvar_g_balance_grenadelauncher_primary_type;
 -float autocvar_g_balance_grenadelauncher_secondary_ammo;
 -float autocvar_g_balance_grenadelauncher_secondary_animtime;
 -float autocvar_g_balance_grenadelauncher_secondary_damage;
 -float autocvar_g_balance_grenadelauncher_secondary_damageforcescale;
 -float autocvar_g_balance_grenadelauncher_secondary_edgedamage;
 -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_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;
@@@ -169,7 -341,54 +162,7 @@@ float autocvar_g_balance_health_rot
  float autocvar_g_balance_health_rotlinear;
  float autocvar_g_balance_health_rotstable;
  float autocvar_g_balance_health_start;
 -float autocvar_g_balance_hlac_primary_ammo;
 -float autocvar_g_balance_hlac_primary_animtime;
 -float autocvar_g_balance_hlac_primary_damage;
 -float autocvar_g_balance_hlac_primary_edgedamage;
 -float autocvar_g_balance_hlac_primary_force;
 -float autocvar_g_balance_hlac_primary_lifetime;
 -float autocvar_g_balance_hlac_primary_radius;
 -float autocvar_g_balance_hlac_primary_refire;
 -float autocvar_g_balance_hlac_primary_speed;
 -float autocvar_g_balance_hlac_primary_spread_add;
 -float autocvar_g_balance_hlac_primary_spread_crouchmod;
 -float autocvar_g_balance_hlac_primary_spread_max;
 -float autocvar_g_balance_hlac_primary_spread_min;
 -float autocvar_g_balance_hlac_secondary;
 -float autocvar_g_balance_hlac_secondary_ammo;
 -float autocvar_g_balance_hlac_secondary_animtime;
 -float autocvar_g_balance_hlac_secondary_damage;
 -float autocvar_g_balance_hlac_secondary_edgedamage;
 -float autocvar_g_balance_hlac_secondary_force;
 -float autocvar_g_balance_hlac_secondary_lifetime;
 -float autocvar_g_balance_hlac_secondary_radius;
 -float autocvar_g_balance_hlac_secondary_refire;
 -float autocvar_g_balance_hlac_secondary_shots;
 -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;
 -float autocvar_g_balance_hook_primary_hooked_time_free;
 -float autocvar_g_balance_hook_primary_hooked_time_max;
 -float autocvar_g_balance_hook_primary_refire;
 -float autocvar_g_balance_hook_secondary_ammo;
 -float autocvar_g_balance_hook_secondary_animtime;
 -float autocvar_g_balance_hook_secondary_damage;
 -float autocvar_g_balance_hook_secondary_duration;
 -float autocvar_g_balance_hook_secondary_edgedamage;
 -float autocvar_g_balance_hook_secondary_force;
 -float autocvar_g_balance_hook_secondary_gravity;
 -float autocvar_g_balance_hook_secondary_lifetime;
 -float autocvar_g_balance_hook_secondary_power;
 -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_return;
@@@ -187,76 -406,55 +180,76 @@@ float autocvar_g_balance_keyhunt_score_
  float autocvar_g_balance_keyhunt_throwvelocity;
  float autocvar_g_balance_kill_delay;
  float autocvar_g_balance_kill_antispam;
 +float autocvar_g_balance_laser_melee_animtime;
 +float autocvar_g_balance_laser_melee_damage;
 +float autocvar_g_balance_laser_melee_delay;
 +float autocvar_g_balance_laser_melee_force;
 +float autocvar_g_balance_laser_melee_multihit;
 +float autocvar_g_balance_laser_melee_no_doubleslap;
 +float autocvar_g_balance_laser_melee_nonplayerdamage;
 +float autocvar_g_balance_laser_melee_range;
 +float autocvar_g_balance_laser_melee_refire;
 +float autocvar_g_balance_laser_melee_swing_side;
 +float autocvar_g_balance_laser_melee_swing_up;
 +float autocvar_g_balance_laser_melee_time;
 +float autocvar_g_balance_laser_melee_traces;
 +float autocvar_g_balance_laser_primary;
  float autocvar_g_balance_laser_primary_animtime;
  float autocvar_g_balance_laser_primary_damage;
  float autocvar_g_balance_laser_primary_delay;
  float autocvar_g_balance_laser_primary_edgedamage;
  float autocvar_g_balance_laser_primary_force;
 -float autocvar_g_balance_laser_primary_force_other_scale;
 -float autocvar_g_balance_laser_primary_force_velocitybias;
 -float autocvar_g_balance_laser_primary_force_zscale;
 +//float autocvar_g_balance_laser_primary_force_other_scale;
 +//float autocvar_g_balance_laser_primary_force_velocitybias;
 +//float autocvar_g_balance_laser_primary_force_zscale;
  float autocvar_g_balance_laser_primary_lifetime;
  float autocvar_g_balance_laser_primary_radius;
  float autocvar_g_balance_laser_primary_refire;
  float autocvar_g_balance_laser_primary_shotangle;
  float autocvar_g_balance_laser_primary_speed;
 +//float autocvar_g_balance_laser_primary_spread;
 +float autocvar_g_balance_laser_reload_ammo;
  float autocvar_g_balance_laser_secondary;
  float autocvar_g_balance_laser_secondary_animtime;
  float autocvar_g_balance_laser_secondary_damage;
  float autocvar_g_balance_laser_secondary_edgedamage;
  float autocvar_g_balance_laser_secondary_force;
 -float autocvar_g_balance_laser_secondary_force_other_scale;
 -float autocvar_g_balance_laser_secondary_force_velocitybias;
 -float autocvar_g_balance_laser_secondary_force_zscale;
 +//float autocvar_g_balance_laser_secondary_force_other_scale;
 +//float autocvar_g_balance_laser_secondary_force_velocitybias;
 +//float autocvar_g_balance_laser_secondary_force_zscale;
  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_minelayer_ammo;
 -float autocvar_g_balance_minelayer_animtime;
 -float autocvar_g_balance_minelayer_damage;
 -float autocvar_g_balance_minelayer_damageforcescale;
 -float autocvar_g_balance_minelayer_detonatedelay;
 -float autocvar_g_balance_minelayer_edgedamage;
 -float autocvar_g_balance_minelayer_force;
 -float autocvar_g_balance_minelayer_health;
 -float autocvar_g_balance_minelayer_lifetime;
 -float autocvar_g_balance_minelayer_lifetime_countdown;
 -float autocvar_g_balance_minelayer_limit;
 -float autocvar_g_balance_minelayer_protection;
 -float autocvar_g_balance_minelayer_proximityradius;
 -float autocvar_g_balance_minelayer_radius;
 -float autocvar_g_balance_minelayer_refire;
 -float autocvar_g_balance_minelayer_remote_damage;
 -float autocvar_g_balance_minelayer_remote_edgedamage;
 -float autocvar_g_balance_minelayer_remote_force;
 -float autocvar_g_balance_minelayer_remote_radius;
 -float autocvar_g_balance_minelayer_speed;
 -float autocvar_g_balance_minelayer_time;
 +float autocvar_g_balance_laser_secondary_refire;
 +//float autocvar_g_balance_laser_secondary_speed;
 +float autocvar_g_balance_laser_shockwave_damage;
 +float autocvar_g_balance_laser_shockwave_distance;
 +float autocvar_g_balance_laser_shockwave_edgedamage;
 +float autocvar_g_balance_laser_shockwave_force;
 +float autocvar_g_balance_laser_shockwave_force_forwardbias;
 +float autocvar_g_balance_laser_shockwave_force_zscale;
 +float autocvar_g_balance_laser_shockwave_jump_damage;
 +float autocvar_g_balance_laser_shockwave_jump_edgedamage;
 +float autocvar_g_balance_laser_shockwave_jump_force;
 +float autocvar_g_balance_laser_shockwave_jump_force_velocitybias;
 +float autocvar_g_balance_laser_shockwave_jump_force_zscale;
 +float autocvar_g_balance_laser_shockwave_jump_multiplier_accuracy;
 +float autocvar_g_balance_laser_shockwave_jump_multiplier_distance;
 +float autocvar_g_balance_laser_shockwave_jump_multiplier_min;
 +float autocvar_g_balance_laser_shockwave_jump_radius;
 +float autocvar_g_balance_laser_shockwave_multiplier_accuracy;
 +float autocvar_g_balance_laser_shockwave_multiplier_distance;
 +float autocvar_g_balance_laser_shockwave_multiplier_min;
 +float autocvar_g_balance_laser_shockwave_splash_damage;
 +float autocvar_g_balance_laser_shockwave_splash_edgedamage;
 +float autocvar_g_balance_laser_shockwave_splash_force;
 +float autocvar_g_balance_laser_shockwave_splash_force_forwardbias;
 +float autocvar_g_balance_laser_shockwave_splash_multiplier_accuracy;
 +float autocvar_g_balance_laser_shockwave_splash_multiplier_distance;
 +float autocvar_g_balance_laser_shockwave_splash_multiplier_min;
 +float autocvar_g_balance_laser_shockwave_splash_radius;
 +float autocvar_g_balance_laser_shockwave_spread_max;
 +float autocvar_g_balance_laser_shockwave_spread_min;
  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;
@@@ -264,7 -462,46 +257,7 @@@ float autocvar_g_balance_minstanex_lase
  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;
 -float autocvar_g_balance_nex_charge_maxspeed;
 -float autocvar_g_balance_nex_charge_mindmg;
 -float autocvar_g_balance_nex_charge_minspeed;
 -float autocvar_g_balance_nex_charge_rate;
 -float autocvar_g_balance_nex_charge_rot_pause;
 -float autocvar_g_balance_nex_charge_rot_rate;
 -float autocvar_g_balance_nex_charge_shot_multiplier;
 -float autocvar_g_balance_nex_charge_start;
 -float autocvar_g_balance_nex_charge_velocity_rate;
 -float autocvar_g_balance_nex_primary_ammo;
 -float autocvar_g_balance_nex_primary_animtime;
 -float autocvar_g_balance_nex_primary_damage;
 -float autocvar_g_balance_nex_primary_damagefalloff_forcehalflife;
 -float autocvar_g_balance_nex_primary_damagefalloff_halflife;
 -float autocvar_g_balance_nex_primary_damagefalloff_maxdist;
 -float autocvar_g_balance_nex_primary_damagefalloff_mindist;
 -float autocvar_g_balance_nex_primary_force;
 -float autocvar_g_balance_nex_primary_refire;
 -float autocvar_g_balance_nex_secondary;
 -float autocvar_g_balance_nex_secondary_ammo;
 -float autocvar_g_balance_nex_secondary_animtime;
 -float autocvar_g_balance_nex_secondary_charge;
 -float autocvar_g_balance_nex_secondary_charge_rate;
 -float autocvar_g_balance_nex_secondary_chargepool;
 -float autocvar_g_balance_nex_secondary_chargepool_pause_health_regen;
 -float autocvar_g_balance_nex_secondary_chargepool_pause_regen;
 -float autocvar_g_balance_nex_secondary_chargepool_regen;
 -float autocvar_g_balance_nex_secondary_damage;
 -float autocvar_g_balance_nex_secondary_damagefalloff_forcehalflife;
 -float autocvar_g_balance_nex_secondary_damagefalloff_halflife;
 -float autocvar_g_balance_nex_secondary_damagefalloff_maxdist;
 -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;
@@@ -296,6 -533,15 +289,6 @@@ float autocvar_g_balance_pause_health_r
  float autocvar_g_balance_pause_health_rot_spawn;
  float autocvar_g_balance_portal_health;
  float autocvar_g_balance_portal_lifetime;
 -float autocvar_g_balance_porto_primary_animtime;
 -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;
@@@ -304,7 -550,74 +297,7 @@@ float autocvar_g_balance_powerup_streng
  float autocvar_g_balance_powerup_strength_selfforce;
  float autocvar_g_balance_powerup_strength_time;
  float autocvar_g_balance_superweapons_time;
 -float autocvar_g_balance_rocketlauncher_ammo;
 -float autocvar_g_balance_rocketlauncher_animtime;
 -float autocvar_g_balance_rocketlauncher_damage;
 -float autocvar_g_balance_rocketlauncher_damageforcescale;
 -float autocvar_g_balance_rocketlauncher_detonatedelay;
 -float autocvar_g_balance_rocketlauncher_edgedamage;
 -float autocvar_g_balance_rocketlauncher_force;
 -float autocvar_g_balance_rocketlauncher_guidedelay;
 -float autocvar_g_balance_rocketlauncher_guidegoal;
 -float autocvar_g_balance_rocketlauncher_guiderate;
 -float autocvar_g_balance_rocketlauncher_guideratedelay;
 -float autocvar_g_balance_rocketlauncher_guidestop;
 -float autocvar_g_balance_rocketlauncher_health;
 -float autocvar_g_balance_rocketlauncher_lifetime;
 -float autocvar_g_balance_rocketlauncher_radius;
 -float autocvar_g_balance_rocketlauncher_refire;
 -float autocvar_g_balance_rocketlauncher_remote_damage;
 -float autocvar_g_balance_rocketlauncher_remote_edgedamage;
 -float autocvar_g_balance_rocketlauncher_remote_force;
 -float autocvar_g_balance_rocketlauncher_remote_radius;
 -float autocvar_g_balance_rocketlauncher_speed;
 -float autocvar_g_balance_rocketlauncher_speedaccel;
 -float autocvar_g_balance_rocketlauncher_speedstart;
 -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;
 -float autocvar_g_balance_seeker_flac_edgedamage;
 -float autocvar_g_balance_seeker_flac_force;
 -float autocvar_g_balance_seeker_flac_lifetime;
 -float autocvar_g_balance_seeker_flac_lifetime_rand;
 -float autocvar_g_balance_seeker_flac_radius;
 -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;
 -float autocvar_g_balance_seeker_missile_decel;
 -float autocvar_g_balance_seeker_missile_delay;
 -float autocvar_g_balance_seeker_missile_edgedamage;
 -float autocvar_g_balance_seeker_missile_force;
 -float autocvar_g_balance_seeker_missile_health;
 -float autocvar_g_balance_seeker_missile_lifetime;
 -float autocvar_g_balance_seeker_missile_proxy;
 -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;
 -float autocvar_g_balance_seeker_missile_smart_trace_min;
 -float autocvar_g_balance_seeker_missile_speed_max;
 -float autocvar_g_balance_seeker_missile_turnrate;
 -float autocvar_g_balance_seeker_tag_ammo;
 -float autocvar_g_balance_seeker_tag_animtime;
 -float autocvar_g_balance_seeker_tag_damageforcescale;
 -float autocvar_g_balance_seeker_tag_health;
 -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;
@@@ -330,10 -643,42 +323,10 @@@ float autocvar_g_balance_shotgun_second
  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_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;
 -float autocvar_g_balance_tuba_edgedamage;
 -float autocvar_g_balance_tuba_force;
 -float autocvar_g_balance_tuba_radius;
 -float autocvar_g_balance_tuba_refire;
 -float autocvar_g_balance_uzi_bulletconstant;
 -float autocvar_g_balance_uzi_burst;
 -float autocvar_g_balance_uzi_burst_ammo;
 -float autocvar_g_balance_uzi_burst_animtime;
 -float autocvar_g_balance_uzi_burst_refire;
 -float autocvar_g_balance_uzi_burst_refire2;
 -float autocvar_g_balance_uzi_burst_spread;
 -float autocvar_g_balance_uzi_first;
 -float autocvar_g_balance_uzi_first_ammo;
 -float autocvar_g_balance_uzi_first_damage;
 -float autocvar_g_balance_uzi_first_force;
 -float autocvar_g_balance_uzi_first_refire;
 -float autocvar_g_balance_uzi_first_spread;
 -float autocvar_g_balance_uzi_mode;
 -float autocvar_g_balance_uzi_speed;
 -float autocvar_g_balance_uzi_spread_add;
 -float autocvar_g_balance_uzi_spread_max;
 -float autocvar_g_balance_uzi_spread_min;
 -float autocvar_g_balance_uzi_sustained_ammo;
 -float autocvar_g_balance_uzi_sustained_damage;
 -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_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;
@@@ -456,6 -801,7 +449,7 @@@ float autocvar_g_domination_point_leadl
  float autocvar_g_domination_point_rate;
  float autocvar_g_domination_teams_override;
  float autocvar_g_forced_respawn;
+ float autocvar_g_respawn_delay_max;
  string autocvar_g_forced_team_blue;
  string autocvar_g_forced_team_otherwise;
  string autocvar_g_forced_team_pink;
@@@ -852,7 -1198,6 +846,6 @@@ float autocvar_timelimit_overtimes
  float autocvar_timelimit_suddendeath;
  #define autocvar_utf8_enable cvar("utf8_enable")
  float autocvar_waypoint_benchmark;
- float autocvar_welcome_message_time;
  float autocvar_sv_gameplayfix_gravityunaffectedbyticrate;
  float autocvar_g_trueaim_minrange;
  float autocvar_g_debug_defaultsounds;
index 31631454e842489bea282c86eadf1a2ca78174e9,a0e6bfffd42926004503c8e9f63b8e9eaaa07836..fb79a3318c37748721e5da4bcf4e7beff7990629
@@@ -20,7 -20,7 +20,7 @@@ void havocbot_ai(
                }
                else
                {
-                       if not(self.jumppadcount)
+                       if (!self.jumppadcount)
                                self.havocbot_role();
                }
  
@@@ -92,7 -92,7 +92,7 @@@
  
                if(self.weapons)
                {
 -                      weapon_action(self.weapon, WR_AIM);
 +                      WEP_ACTION(self.weapon, WR_AIM);
                        if (autocvar_bot_nofire || IS_INDEPENDENT_PLAYER(self))
                        {
                                self.BUTTON_ATCK = FALSE;
        havocbot_movetogoal();
  
        // if the bot is not attacking, consider reloading weapons
-       if not(self.aistatus & AI_STATUS_ATTACKING)
+       if (!(self.aistatus & AI_STATUS_ATTACKING))
        {
                float i;
                entity e;
@@@ -316,7 -316,7 +316,7 @@@ void havocbot_bunnyhop(vector dir
  
                                        if(self.aistatus & AI_STATUS_ROAMING)
                                        if(self.goalcurrent.classname=="waypoint")
-                                       if not(self.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL)
+                                       if (!(self.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL))
                                        if(fabs(gco_z - self.origin_z) < self.maxs_z - self.mins_z)
                                        if(self.goalstack01!=world)
                                        {
@@@ -422,7 -422,7 +422,7 @@@ void havocbot_movetogoal(
                }
  
                // Take off
-               if not(self.aistatus & AI_STATUS_JETPACK_FLYING)
+               if (!(self.aistatus & AI_STATUS_JETPACK_FLYING))
                {
                        // Brake almost completely so it can get a good direction
                        if(vlen(self.velocity)>10)
        else if(self.aistatus & AI_STATUS_OUT_JUMPPAD)
                self.aistatus &= ~AI_STATUS_OUT_JUMPPAD;
  
 -      // If there is a trigger_hurt right below try to use the jetpack or make a rocketjump
 +      // If there is a trigger_hurt right below try to use the jetpack or make a rocketjump // WEAPONTODO: move this to bot think!
        if(skill>6)
-       if not(self.flags & FL_ONGROUND)
+       if (!(self.flags & FL_ONGROUND))
        {
                tracebox(self.origin, self.mins, self.maxs, self.origin + '0 0 -65536', MOVE_NOMONSTERS, self);
                if(tracebox_hits_trigger_hurt(self.origin, self.mins, self.maxs, trace_endpos ))
  
                        return;
                }
 -              else if(self.health>autocvar_g_balance_rocketlauncher_damage*0.5)
 +              else if(self.health>WEP_CVAR(devastator, damage)*0.5)
                {
                        if(self.velocity_z < 0)
 -                      if(client_hasweapon(self, WEP_ROCKET_LAUNCHER, TRUE, FALSE))
 +                      if(client_hasweapon(self, WEP_DEVASTATOR, TRUE, FALSE))
                        {
                                self.movement_x = maxspeed;
  
                                        return;
                                }
  
 -                              self.switchweapon = WEP_ROCKET_LAUNCHER;
 +                              self.switchweapon = WEP_DEVASTATOR;
                                self.v_angle_x = 90;
                                self.BUTTON_ATCK = TRUE;
 -                              self.rocketjumptime = time + autocvar_g_balance_rocketlauncher_detonatedelay;
 +                              self.rocketjumptime = time + WEP_CVAR(devastator, detonatedelay);
                                return;
                        }
                }
@@@ -956,7 -956,7 +956,7 @@@ float havocbot_chooseweapon_checkreload
                for(i = WEP_FIRST; i <= WEP_LAST; ++i)
                {
                        // if we are out of ammo for all other weapons, it's an emergency to switch to anything else
 -                      if (weapon_action(i, WR_CHECKAMMO1) + weapon_action(i, WR_CHECKAMMO2))
 +                      if (WEP_ACTION(i, WR_CHECKAMMO1) + WEP_ACTION(i, WR_CHECKAMMO2))
                                other_weapon_available = TRUE;
                }
                if(other_weapon_available)
diff --combined qcsrc/server/cheats.qc
index 8805d0ebc4c887f0b4ad7d97353e92760cb7ba5b,5bd3b49a3ab8021b2d305912f8f662ae78adb990..189eeea839caff1e3adebd31f75b7e1f5c02aee8
@@@ -50,7 -50,7 +50,7 @@@ float CheatsAllowed(float i, float argc
                return 0;
        if(gamestart_sv_cheats < 2 && !IS_PLAYER(self))
                return 0;
-       
        // sv_clones
        if(i == CHIMPULSE_CLONE_MOVING || i == CHIMPULSE_CLONE_STANDING)
                if(self.lip < sv_clones)
@@@ -59,7 -59,7 +59,7 @@@
        // haha
        if(self.maycheat)
                return 1;
-       
        // sv_cheats
        if(gamestart_sv_cheats && autocvar_sv_cheats)
                return 1;
@@@ -190,7 -190,7 +190,7 @@@ float CheatImpulse(float i
                                        self.oldvelocity = self.velocity = self.personal.velocity;
                                        self.angles = self.personal.v_angle;
                                        self.fixangle = TRUE;
-                                       
                                        MUTATOR_CALLHOOK(AbortSpeedrun);
                                }
  
  
                        e2 = spawn();
                        setorigin(e2, e.origin);
 -                      RadiusDamage(e2, self, 1000, 0, 128, world, 500, DEATH_CHEAT, e);
 +                      RadiusDamage(e2, self, 1000, 0, 128, world, world, 500, DEATH_CHEAT, e);
                        remove(e2);
  
                        print("404 Sportsmanship not found.\n");
@@@ -718,7 -718,7 +718,7 @@@ float CheatCommand(float argc
        END_CHEAT_FUNCTION();
  }
  
- float Drag(entity e, float grab, float ischeat);
+ float Drag(float force_allow_pick, float ischeat);
  void Drag_Begin(entity dragger, entity draggee, vector touchpoint);
  void Drag_Finish(entity dragger);
  float Drag_IsDraggable(entity draggee);
@@@ -748,40 -748,11 +748,11 @@@ float CheatFrame(
                        {
                                // use cheat dragging if cheats are enabled
                                crosshair_trace_plusvisibletriggers(self);
-                               Drag(trace_ent, TRUE, TRUE);
+                               Drag(TRUE, TRUE);
                        }
                        else
                        {
-                               // drag is TRUE if the object can be picked up. While an object is being carried, the Drag() function
-                               // must execute for it either way, otherwise it would cause bugs if it went out of the player's trace.
-                               // This also makes sure that an object can only pe picked up if in range, but does not get dropped if
-                               // it goes out of range while slinging it around.
-                               float drag;
-                               crosshair_trace_plusvisibletriggers(self);
-                               drag = FALSE;
-                               if(vlen(self.origin - trace_ent.origin) <= autocvar_g_grab_range)
-                               {
-                                       switch(trace_ent.grab)
-                                       {
-                                               case 0: // can't grab
-                                                       break;
-                                               case 1: // owner can grab
-                                                       if(trace_ent.owner == self || trace_ent.realowner == self)
-                                                               drag = TRUE;
-                                                       break;
-                                               case 2: // owner and team mates can grab
-                                                       if(SAME_TEAM(trace_ent.owner, self) || SAME_TEAM(trace_ent.realowner, self) || trace_ent.team == self.team)
-                                                               drag = TRUE;
-                                                       break;
-                                               case 3: // anyone can grab
-                                                       drag = TRUE;
-                                                       break;
-                                               default:
-                                                       break;
-                                       }
-                               }
-                               Drag(trace_ent, drag, FALSE); // execute dragging
+                               Drag(FALSE, FALSE); // execute dragging
                        }
                        break;
        }
  
  // ENTITY DRAGGING
  
- float Drag(entity e, float pick, float ischeat)
+ float Drag(float force_allow_pick, float ischeat)
  {
        BEGIN_CHEAT_FUNCTION();
  
                        else
                        {
                                if(Drag_CanDrag(self))
-                                       if(self.BUTTON_DRAG && pick)
+                                       if(self.BUTTON_DRAG)
                                        {
-                                               if(e)
+                                               crosshair_trace_plusvisibletriggers(self);
+                                               entity e = trace_ent;
+                                               float pick = force_allow_pick;
+                                               if (e && !pick)
+                                               {
+                                                       // pick is TRUE if the object can be picked up. While an object is being carried, the Drag() function
+                                                       // must execute for it either way, otherwise it would cause bugs if it went out of the player's trace.
+                                                       // This also makes sure that an object can only pe picked up if in range, but does not get dropped if
+                                                       // it goes out of range while slinging it around.
+                                                       if(vlen(self.origin - e.origin) <= autocvar_g_grab_range)
+                                                       {
+                                                               switch(e.grab)
+                                                               {
+                                                                       case 0: // can't grab
+                                                                               break;
+                                                                       case 1: // owner can grab
+                                                                               if(e.owner == self || e.realowner == self)
+                                                                                       pick = TRUE;
+                                                                               break;
+                                                                       case 2: // owner and team mates can grab
+                                                                               if(SAME_TEAM(e.owner, self) || SAME_TEAM(e.realowner, self) || e.team == self.team)
+                                                                                       pick = TRUE;
+                                                                               break;
+                                                                       case 3: // anyone can grab
+                                                                               pick = TRUE;
+                                                                               break;
+                                                                       default:
+                                                                               break;
+                                                               }
+                                                       }
+                                               }
+                                               // Find e and pick
+                                               if(e && pick)
                                                        if(Drag_IsDraggable(e))
                                                        {
                                                                if(ischeat)
index e763d662df93bb27b206b77965f497126c81d306,d803602ad6ccd6c229e5b61ffa20f4dfc976b6ae..a839145009af42ce7e604300e1d43084cd8c9548
@@@ -167,7 -167,7 +167,7 @@@ void PutObserverInServer (void
        MUTATOR_CALLHOOK(MakePlayerObserver);
  
        Portal_ClearAll(self);
-       
        if(self.alivetime)
        {
                if(!warmup_stage)
        }
  
        if(self.vehicle)
-               vehicles_exit(VHEF_RELESE);         
+               vehicles_exit(VHEF_RELESE);
  
        WaypointSprite_PlayerDead();
  
-       if not(g_ca)  // don't reset teams when moving a ca player to the spectators
+       if (!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)
        accuracy_resend(self);
  
        self.spectatortime = time;
-       
        self.classname = "observer";
        self.iscreature = FALSE;
        self.teleportable = TELEPORT_SIMPLE;
@@@ -297,7 -297,13 +297,13 @@@ void FixPlayermodel(
  
                n = tokenize_console(defaultmodel);
                if(n > 0)
+               {
                        defaultmodel = argv(floor(n * self.model_randomizer));
+                       // However, do NOT randomize if the player-selected model is in the list.
+                       for (i = 0; i < n; ++i)
+                               if ((argv(i) == self.playermodel && defaultskin == stof(self.playerskin)) || argv(i) == strcat(self.playermodel, ":", self.playerskin))
+                                       defaultmodel = argv(i);
+               }
  
                i = strstrofs(defaultmodel, ":", 0);
                if(i >= 0)
@@@ -417,11 -423,11 +423,11 @@@ void PutClientInServer (void
                self.effects |= EF_TELEPORT_BIT | EF_RESTARTANIM_BIT;
                self.air_finished = time + 12;
                self.dmg = 2;
 -              if(autocvar_g_balance_nex_charge)
 +              if(WEP_CVAR(nex, charge))
                {
 -                      if(autocvar_g_balance_nex_secondary_chargepool)
 +                      if(WEP_CVAR_SEC(nex, chargepool))
                                self.nex_chargepool_ammo = 1;
 -                      self.nex_charge = autocvar_g_balance_nex_charge_start;
 +                      self.nex_charge = WEP_CVAR(nex, charge_start);
                }
  
                if(warmup_stage)
                        self.ammo_fuel = warmup_start_ammo_fuel;
                        self.health = warmup_start_health;
                        self.armorvalue = warmup_start_armorvalue;
-                       self.weapons = warmup_start_weapons;
+                       self.weapons = WARMUP_START_WEAPONS;
                }
                else
                {
  
                //stuffcmd(self, "chase_active 0");
                //stuffcmd(self, "set viewsize $tmpviewsize \n");
-               
                target_voicescript_clear(self);
  
                // reset fields the weapons may use
                for (j = WEP_FIRST; j <= WEP_LAST; ++j)
                {
 -                      weapon_action(j, WR_RESETPLAYER);
 +                      WEP_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"));
 +                              self.(weapon_load[j]) = e.reloading_ammo;
                }
  
                oldself = self;
@@@ -620,27 -626,26 +626,27 @@@ 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(gauntlet_shotorigin[0]));
 -      WriteInt24_t(MSG_ENTITY, compressShotOrigin(gauntlet_shotorigin[1]));
 -      WriteInt24_t(MSG_ENTITY, compressShotOrigin(gauntlet_shotorigin[2]));
 -      WriteInt24_t(MSG_ENTITY, compressShotOrigin(gauntlet_shotorigin[3]));
 +      WriteInt24_t(MSG_ENTITY, compressShotOrigin(arc_shotorigin[0]));
 +      WriteInt24_t(MSG_ENTITY, compressShotOrigin(arc_shotorigin[1]));
 +      WriteInt24_t(MSG_ENTITY, compressShotOrigin(arc_shotorigin[2]));
 +      WriteInt24_t(MSG_ENTITY, compressShotOrigin(arc_shotorigin[3]));
 +
        if(sv_foginterval && world.fog != "")
                WriteString(MSG_ENTITY, world.fog);
        else
                WriteString(MSG_ENTITY, "");
        WriteByte(MSG_ENTITY, self.count * 255.0); // g_balance_armor_blockpercent
 -      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_rifle_secondary); // client has to know if it should zoom or not
 +      WriteCoord(MSG_ENTITY, self.bouncefactor); // g_balance_mortar_bouncefactor // WEAPONTODO
 +      WriteCoord(MSG_ENTITY, self.bouncestop); // g_balance_mortar_bouncestop
 +      WriteCoord(MSG_ENTITY, self.ebouncefactor); // g_balance_mortar_bouncefactor
 +      WriteCoord(MSG_ENTITY, self.ebouncestop); // g_balance_mortar_bouncestop
 +      WriteByte(MSG_ENTITY, WEP_CVAR(nex, secondary)); // client has to know if it should zoom or not // WEAPONTODO
 +      WriteByte(MSG_ENTITY, WEP_CVAR(rifle, secondary)); // client has to know if it should zoom or not // WEAPONTODO
        WriteByte(MSG_ENTITY, serverflags); // client has to know if it should zoom or not
 -      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
 +      WriteByte(MSG_ENTITY, WEP_CVAR(minelayer, limit)); // minelayer max mines // WEAPONTODO
 +      WriteByte(MSG_ENTITY, WEP_CVAR_SEC(hagar, load_max)); // hagar max loadable rockets // WEAPONTODO
        WriteCoord(MSG_ENTITY, autocvar_g_trueaim_minrange);
 -      WriteByte(MSG_ENTITY, autocvar_g_balance_porto_secondary);
 +      WriteByte(MSG_ENTITY, WEP_CVAR(porto, secondary)); // WEAPONTODO
        return TRUE;
  }
  
@@@ -652,14 -657,14 +658,14 @@@ void ClientInit_CheckUpdate(
                self.count = autocvar_g_balance_armor_blockpercent;
                self.SendFlags |= 1;
        }
 -      if(self.bouncefactor != autocvar_g_balance_grenadelauncher_bouncefactor)
 +      if(self.bouncefactor != autocvar_g_balance_mortar_bouncefactor) // WEAPONTODO
        {
 -              self.bouncefactor = autocvar_g_balance_grenadelauncher_bouncefactor;
 +              self.bouncefactor = autocvar_g_balance_mortar_bouncefactor;
                self.SendFlags |= 1;
        }
 -      if(self.bouncestop != autocvar_g_balance_grenadelauncher_bouncestop)
 +      if(self.bouncestop != autocvar_g_balance_mortar_bouncestop)
        {
 -              self.bouncestop = autocvar_g_balance_grenadelauncher_bouncestop;
 +              self.bouncestop = autocvar_g_balance_mortar_bouncestop;
                self.SendFlags |= 1;
        }
        if(self.ebouncefactor != autocvar_g_balance_electro_secondary_bouncefactor)
@@@ -761,7 -766,7 +767,7 @@@ void ClientKill_Now(
            if(!self.killindicator_teamchange)
            {
              self.vehicle_health = -1;
-             Damage(self, self, self, 1 , DEATH_KILL, self.origin, '0 0 0');           
+             Damage(self, self, self, 1 , DEATH_KILL, self.origin, '0 0 0');
            }
        }
  
@@@ -929,7 -934,7 +935,7 @@@ void ClientKill (void
        if(gameover) return;
        if(self.player_blocked) return;
        if(self.freezetag_frozen) return;
-       
        ClientKill_TeamChange(0);
  }
  
@@@ -979,7 -984,7 +985,7 @@@ float PlayerInIDList(entity p, string i
        string s;
  
        // NOTE: we do NOT check crypto_keyfp here, an unsigned ID is fine too for this
-       if not(p.crypto_idfp)
+       if (!p.crypto_idfp)
                return 0;
  
        // this function allows abbreviated player IDs too!
@@@ -1188,7 -1193,13 +1194,7 @@@ void ClientConnect (void
        if(!sv_foginterval && world.fog != "")
                stuffcmd(self, strcat("\nfog ", world.fog, "\nr_fog_exp2 0\nr_drawfog 1\n"));
  
 -      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);
 -              fputs(self.hitplotfh, strcat("#name ", self.netname, "\n"));
 -      }
 -      else
 -              self.hitplotfh = -1;
 +      W_HitPlotOpen(self);
  
        if(g_race || g_cts) {
                string rr;
@@@ -1238,7 -1249,7 +1244,7 @@@ void ClientDisconnect (void
        if(self.vehicle)
            vehicles_exit(VHEF_RELESE);
  
-       if not(IS_CLIENT(self))
+       if (!IS_CLIENT(self))
        {
                print("Warning: ClientDisconnect without ClientConnect\n");
                return;
  
        CheatShutdownClient();
  
 -      if(self.hitplotfh >= 0)
 -      {
 -              fclose(self.hitplotfh);
 -              self.hitplotfh = -1;
 -      }
 +      W_HitPlotClose(self);
  
        anticheat_report();
        anticheat_shutdown();
  
        if(autocvar_sv_eventlog)
                GameLogEcho(strcat(":part:", ftos(self.playerid)));
-               
        Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_QUIT_DISCONNECT, self.netname);
  
        MUTATOR_CALLHOOK(ClientDisconnect);
@@@ -1415,7 -1430,7 +1421,7 @@@ void player_powerups (void
        Fire_ApplyDamage(self);
        Fire_ApplyEffect(self);
  
-       if not(g_minstagib)
+       if (!g_minstagib)
        {
                if (self.items & IT_STRENGTH)
                {
                        self.superweapons_finished = 0;
                }
        }
-       
        if(autocvar_g_nodepthtestplayers)
                self.effects = self.effects | EF_NODEPTHTEST;
  
@@@ -1598,7 -1613,7 +1604,7 @@@ void player_regen (void
                        self.event_damage(self, self, 1, DEATH_ROT, self.origin, '0 0 0');
        }
  
-       if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
+       if (!(self.items & IT_UNLIMITED_WEAPON_AMMO))
                self.ammo_fuel = CalcRotRegen(self.ammo_fuel, minf, autocvar_g_balance_fuel_regen, autocvar_g_balance_fuel_regenlinear, regen_mod * frametime * (time > self.pauseregen_finished) * ((self.items & IT_FUEL_REGEN) != 0), maxf, autocvar_g_balance_fuel_rot, autocvar_g_balance_fuel_rotlinear, rot_mod * frametime * (time > self.pauserotfuel_finished), limitf);
  }
  
@@@ -1715,7 -1730,7 +1721,7 @@@ void SpectateCopy(entity spectatee) 
        setorigin(self, spectatee.origin);
        setsize(self, spectatee.mins, spectatee.maxs);
        SetZoomState(spectatee.zoomstate);
-     
      anticheat_spectatecopy(spectatee);
        self.hud = spectatee.hud;
        if(spectatee.vehicle)
          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);            
+         //    WriteEntity(MSG_ONE, self);
          //makevectors(spectatee.v_angle);
-         //setorigin(self, spectatee.origin - v_forward * 400 + v_up * 300);*/    
+         //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 not(IS_PLAYER(self.enemy))
+       if (!IS_PLAYER(self.enemy))
                return 0;
  
        SpectateCopy(self.enemy);
@@@ -1805,13 -1820,13 +1811,13 @@@ 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");
                        other = find(other, classname, "player");
                }
        }
-       
        return other;
  }
  
@@@ -1846,7 -1861,7 +1852,7 @@@ float SpectatePrev(
  {
        // NOTE: chain order is from the highest to the lower entnum (unlike find)
        other = findchain(classname, "player");
-       if not(other) // no player
+       if (!other) // no player
                return FALSE;
  
        entity first = other;
                do { other = other.chain; }
                while(other && other.team != self.team);
  
-               if not(other)
+               if (!other)
                {
                        other = first;
                        while(other.team != self.team)
@@@ -2030,7 -2045,7 +2036,7 @@@ void PrintWelcomeMessage(
        {
                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)
+               else if(self.motd_actived_time == -2 || IS_PLAYER(self))
                {
                        // instanctly hide MOTD
                        self.motd_actived_time = 0;
@@@ -2120,7 -2135,7 +2126,7 @@@ void SpectatorThink(
  
  void PlayerUseKey()
  {
-       if not(IS_PLAYER(self))
+       if (!IS_PLAYER(self))
                return;
  
        if(self.vehicle)
          vehicles_exit(VHEF_NORMAL);
          return;
        }
-       
        // a use key was pressed; call handlers
        MUTATOR_CALLHOOK(PlayerUseKey);
  }
@@@ -2253,17 -2268,17 +2259,17 @@@ void PlayerPreThink (void
  
                if(frametime)
                {
 -                      if(self.weapon == WEP_NEX && autocvar_g_balance_nex_charge)
 +                      if(self.weapon == WEP_NEX && WEP_CVAR(nex, charge))
                        {
 -                              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);
 +                              self.weaponentity_glowmod_x = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_red_half * min(1, self.nex_charge / WEP_CVAR(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 / WEP_CVAR(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 / WEP_CVAR(nex, charge_animlimit));
  
 -                              if(self.nex_charge > autocvar_g_balance_nex_charge_animlimit)
 +                              if(self.nex_charge > WEP_CVAR(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);
 +                                      self.weaponentity_glowmod_x = self.weaponentity_glowmod_x + autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_red_full * (self.nex_charge - WEP_CVAR(nex, charge_animlimit)) / (1 - WEP_CVAR(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 - WEP_CVAR(nex, charge_animlimit)) / (1 - WEP_CVAR(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 - WEP_CVAR(nex, charge_animlimit)) / (1 - WEP_CVAR(nex, charge_animlimit));
                                }
                        }
                        else
                                if(frametime)
                                        player_anim();
                                button_pressed = (self.BUTTON_ATCK || self.BUTTON_JUMP || self.BUTTON_ATCK2 || self.BUTTON_HOOK || self.BUTTON_USE);
-                               
                                if (self.deadflag == DEAD_DYING)
                                {
-                                       if(self.respawn_flags & RESPAWN_FORCE)
+                                       if((self.respawn_flags & RESPAWN_FORCE) && !autocvar_g_respawn_delay_max)
                                                self.deadflag = DEAD_RESPAWNING;
                                        else if(!button_pressed)
                                                self.deadflag = DEAD_DEAD;
                                {
                                        if(button_pressed)
                                                self.deadflag = DEAD_RESPAWNABLE;
+                                       else if(time >= self.respawn_time_max && (self.respawn_flags & RESPAWN_FORCE))
+                                               self.deadflag = DEAD_RESPAWNING;
                                }
                                else if (self.deadflag == DEAD_RESPAWNABLE)
                                {
                                        if(time > self.respawn_time)
                                        {
                                                self.respawn_time = time + 1; // only retry once a second
+                                               self.respawn_time_max = self.respawn_time;
                                                respawn();
                                        }
                                }
  
                                if(self.respawn_flags & RESPAWN_SILENT)
                                        self.stat_respawn_time = 0;
+                               else if((self.respawn_flags & RESPAWN_FORCE) && autocvar_g_respawn_delay_max)
+                                       self.stat_respawn_time = self.respawn_time_max;
                                else
                                        self.stat_respawn_time = self.respawn_time;
                        }
                player_regen();
  
                // rot nex charge to the charge limit
 -              if(autocvar_g_balance_nex_charge_rot_rate && self.nex_charge > autocvar_g_balance_nex_charge_limit && self.nex_charge_rottime < time)
 -                      self.nex_charge = bound(autocvar_g_balance_nex_charge_limit, self.nex_charge - autocvar_g_balance_nex_charge_rot_rate * frametime / W_TICSPERFRAME, 1);
 +              if(WEP_CVAR(nex, charge_rot_rate) && self.nex_charge > WEP_CVAR(nex, charge_limit) && self.nex_charge_rottime < time)
 +                      self.nex_charge = bound(WEP_CVAR(nex, charge_limit), self.nex_charge - WEP_CVAR(nex, charge_rot_rate) * frametime / W_TICSPERFRAME, 1);
  
                if(frametime)
                        player_anim();
-               
                // 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(!zoomstate_set)
 -              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));
 +              SetZoomState(self.BUTTON_ZOOM || self.BUTTON_ZOOMSCRIPT || (self.BUTTON_ATCK2 && self.weapon == WEP_NEX) || (self.BUTTON_ATCK2 && self.weapon == WEP_RIFLE && WEP_CVAR(rifle, secondary) == 0)); // WEAPONTODO
  
        float oldspectatee_status;
        oldspectatee_status = self.spectatee_status;
@@@ -2558,7 -2578,7 +2569,7 @@@ void PlayerPostThink (void
                        return;         // intermission or finale
                GetPressedKeys();
        }
-       
  #ifdef TETRIS
        }
  #endif
        //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));
+               WaypointSprite_UpdateHealth(self.waypointsprite_attachedforcarrier, '1 0 0' * healtharmor_maxdamage(self.health, self.armorvalue, autocvar_g_balance_armor_blockpercent, DEATH_WEAPON));
  
        playerdemo_write();
  
        if((g_cts || g_race) && self.cvar_cl_allow_uidtracking == 1 && self.cvar_cl_allow_uid2name == 1)
        {
-               if not(self.stored_netname)
+               if (!self.stored_netname)
                        self.stored_netname = strzone(uid2name(self.crypto_idfp));
                if(self.stored_netname != self.netname)
                {
index 46241be975e55717995de503fe3dbe11c25f96b0,a4376bd418a101096d5fdf7d2e68c76070796578..148eafa84875877e72a5fcae8163f2ff2d041f58
@@@ -52,13 -52,13 +52,13 @@@ void ImpulseCommands (void
  
        if (timeout_status == TIMEOUT_ACTIVE) //don't allow any impulses while the game is paused
                return;
-     
      if(self.vehicle)
          if(self.vehicle.deadflag == DEAD_NO)
              if(self.vehicle.vehicles_impusle)
                  if(self.vehicle.vehicles_impusle(imp))
                      return;
-     
        if(CheatImpulse(imp))
        {
        }
                        switch(imp)
                        {
                                case 10:
 -                                      W_NextWeapon (0);
 +                                      W_NextWeapon(0);
                                        break;
                                case 11:
                                        W_LastWeapon();
                                        break;
                                case 12:
 -                                      W_PreviousWeapon (0);
 +                                      W_PreviousWeapon(0);
                                        break;
                                case 13:
 -                                      W_SwitchWeapon (w_getbestweapon(self));
 +                                      W_SwitchWeapon(w_getbestweapon(self));
                                        break;
                                case 14:
                                        W_NextWeaponOnImpulse(0);
                                        break;
                                case 15:
 -                                      W_NextWeapon (2);
 +                                      W_NextWeapon(2);
                                        break;
                                case 16:
 -                                      W_PreviousWeapon (2);
 +                                      W_PreviousWeapon(2);
                                        break;
                                case 17:
                                        W_ThrowWeapon(W_CalculateProjectileVelocity(self.velocity, v_forward * 750, FALSE), '0 0 0', TRUE);
                                        break;
                                case 18:
 -                                      W_NextWeapon (1);
 +                                      W_NextWeapon(1);
                                        break;
                                case 19:
 -                                      W_PreviousWeapon (1);
 +                                      W_PreviousWeapon(1);
                                        break;
                                case 20:
 -                                      W_TriggerReload ();
 +                                      WEP_ACTION(self.weapon, WR_RELOAD);
                                        break;
                        }
                }
                        case 33:
                                if(self.deadflag == DEAD_NO && teamplay)
                                {
-                                       if not(MUTATOR_CALLHOOK(HelpMePing))
+                                       if (!MUTATOR_CALLHOOK(HelpMePing))
                                        {
                                                wp = WaypointSprite_Attach("helpme", TRUE, RADARICON_HELPME, '1 0.5 0');
                                                if(!wp)
                                case 104:
                                        e = navigation_findnearestwaypoint(self, FALSE);
                                        if (e)
-                                       if not(e.wpflags & WAYPOINTFLAG_GENERATED)
+                                       if (!(e.wpflags & WAYPOINTFLAG_GENERATED))
                                        {
                                                bprint(strcat("Waypoint removed at ",vtos(e.origin),"\n"));
                                                waypoint_remove(e);
                                                {
                                                        print("cannot reach me: ", etos(e), " ", vtos(e.origin), "\n");
                                                        e.colormod_x = 8;
-                                                       if not(e.effects & EF_NODEPTHTEST) // not already reported before
+                                                       if(!(e.effects & EF_NODEPTHTEST)) // not already reported before
                                                                ++m;
                                                        e.effects |= EF_NODEPTHTEST | EF_RED;
                                                        ++i;
index f29ca1c663f0c60231b4ec0667d775ae60d18270,edad6d63f845881338547c06bc59d2a4285a0ce7..12cc888fee7b383d119dd6185151d8f69a6a8f33
@@@ -24,11 -24,11 +24,11 @@@ void PlayerJump (void
        player_multijump = doublejump;
        if(MUTATOR_CALLHOOK(PlayerJump))
                return;
-               
        doublejump = player_multijump;
  
        float mjumpheight;
-       
        if (autocvar_sv_doublejump)
        {
                tracebox(self.origin + '0 0 0.01', self.mins, self.maxs, self.origin - '0 0 0.01', MOVE_NORMAL, self);
        self.flags &= ~FL_JUMPRELEASED;
  
        animdecide_setaction(self, ANIMACTION_JUMP, TRUE);
-       
        if(autocvar_g_jump_grunt)
                PlayerSound(playersound_jump, CH_PLAYER, VOICETYPE_PLAYERSOUND);
  
@@@ -517,9 -517,9 +517,9 @@@ void PM_Accelerate(vector wishdir, floa
        }
        else
                vel_perpend = vel_perpend * max(0, 1 - frametime * wishspeed * sidefric);
-       
        vel_xy = vel_straight * wishdir + vel_perpend;
-       
        if(speedclamp >= 0)
        {
                float vel_xy_preclamp;
@@@ -633,7 -633,7 +633,7 @@@ void SV_PlayerPhysics(
        string c;
  
        WarpZone_PlayerPhysics_FixVAngle();
-       
        maxspd_mod = 1;
        if(self.ballcarried)
                if(g_nexball)
                        return;
                bot_think();
        }
-       
        self.items &= ~IT_USING_JETPACK;
  
        if(IS_PLAYER(self))
        if(self.conveyor.state)
                self.velocity -= self.conveyor.movedir;
  
-       if not(IS_PLAYER(self))
+       if (!IS_PLAYER(self))
        {
                maxspd_mod = autocvar_sv_spectator_speed_multiplier;
                if(!self.spectatorspeed)
  
                if(self.waterlevel < WATERLEVEL_SWIMMING)
                if(time >= self.ladder_time)
-               if not(self.hook)
+               if (!self.hook)
                {
                        self.nextstep = time + 0.3 + random() * 0.1;
                        trace_dphitq3surfaceflags = 0;
                        tracebox(self.origin, self.mins, self.maxs, self.origin - '0 0 1', MOVE_NOMONSTERS, self);
-                       if not(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOSTEPS)
+                       if (!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOSTEPS))
                        {
                                if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_METALSTEPS)
                                        GlobalSound(globalsound_metalfall, CH_PLAYER, VOICETYPE_PLAYERSOUND);
                if (f > 0 && wishvel != '0 0 0')
                {
                        self.velocity = self.velocity + wishvel * f * frametime;
-                       if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
+                       if (!(self.items & IT_UNLIMITED_WEAPON_AMMO))
                                self.ammo_fuel -= autocvar_g_jetpack_fuel * frametime * fvel * f;
                        self.flags &= ~FL_ONGROUND;
                        self.items |= IT_USING_JETPACK;
                }
        }
  
 +      // WEAPONTODO
        float xyspeed;
        xyspeed = vlen('1 0 0' * self.velocity_x + '0 1 0' * self.velocity_y);
 -      if(self.weapon == WEP_NEX && autocvar_g_balance_nex_charge && autocvar_g_balance_nex_charge_velocity_rate && xyspeed > autocvar_g_balance_nex_charge_minspeed)
 +      if(self.weapon == WEP_NEX && WEP_CVAR(nex, charge) && WEP_CVAR(nex, charge_velocity_rate) && xyspeed > WEP_CVAR(nex, charge_minspeed))
        {
                // add a maximum of charge_velocity_rate when going fast (f = 1), gradually increasing from minspeed (f = 0) to maxspeed
 -              xyspeed = min(xyspeed, autocvar_g_balance_nex_charge_maxspeed);
 -              f = (xyspeed - autocvar_g_balance_nex_charge_minspeed) / (autocvar_g_balance_nex_charge_maxspeed - autocvar_g_balance_nex_charge_minspeed);
 +              xyspeed = min(xyspeed, WEP_CVAR(nex, charge_maxspeed));
 +              f = (xyspeed - WEP_CVAR(nex, charge_minspeed)) / (WEP_CVAR(nex, charge_maxspeed) - WEP_CVAR(nex, charge_minspeed));
                // add the extra charge
 -              self.nex_charge = min(1, self.nex_charge + autocvar_g_balance_nex_charge_velocity_rate * f * frametime);
 +              self.nex_charge = min(1, self.nex_charge + WEP_CVAR(nex, charge_velocity_rate) * f * frametime);
        }
  :end
        if(self.flags & FL_ONGROUND)
index 2aae32abb053484b3e37302e53ff29eecd0d77c6,eb3e81fbb280a7d226e65f2554b22df8c5eab99d..e7256766607d87988296dbae02556508435423b7
@@@ -1,3 -1,6 +1,3 @@@
 -.entity accuracy;
 -.float accuracy_frags[WEP_MAXCOUNT];
 -
  float weaponstats_buffer;
  
  void WeaponStats_Init()
@@@ -273,7 -276,7 +273,7 @@@ void PlayerCorpseDamage (entity inflict
        // damage resistance (ignore most of the damage from a bullet or similar)
        damage = max(damage - 5, 1);
  
-       v = healtharmor_applydamage(self.armorvalue, autocvar_g_balance_armor_blockpercent, damage);
+       v = healtharmor_applydamage(self.armorvalue, autocvar_g_balance_armor_blockpercent, deathtype, damage);
        take = v_x;
        save = v_y;
  
@@@ -350,7 -353,10 +350,10 @@@ void PlayerDamage (entity inflictor, en
                ear1 += v_right * -10;
                ear2 += v_right * +10;
                d = inflictor.origin - self.origin;
-               f = (d * v_right) / vlen(d); // this is cos of angle of d and v_right!
+               if (d)
+                       f = (d * v_right) / vlen(d); // this is cos of angle of d and v_right!
+               else
+                       f = 0;  // Assum ecenter.
                force = v_right * vlen(force);
                Violence_GibSplash_At(ear1, force * -1, 2, bound(0, damage, 25) / 2 * (0.5 - 0.5 * f), self, attacker);
                Violence_GibSplash_At(ear2, force,      2, bound(0, damage, 25) / 2 * (0.5 + 0.5 * f), self, attacker);
                Violence_GibSplash_At(hitloc, force, 2, bound(0, damage, 200) / 16, self, attacker);
  
  
-       v = healtharmor_applydamage(self.armorvalue, autocvar_g_balance_armor_blockpercent, damage);
+       v = healtharmor_applydamage(self.armorvalue, autocvar_g_balance_armor_blockpercent, deathtype, damage);
        take = v_x;
        save = v_y;
  
                frag_deathtype = deathtype;
                MUTATOR_CALLHOOK(PlayerDies);
  
 -              weapon_action(self.weapon, WR_PLAYERDEATH);
 +              WEP_ACTION(self.weapon, WR_PLAYERDEATH);
  
                RemoveGrapplingHook(self);
  
                        self.respawn_time = ceil((time + sdelay) / waves) * waves;
                else
                        self.respawn_time = time + sdelay;
+               if(autocvar_g_respawn_delay_max > sdelay)
+                       self.respawn_time_max = time + autocvar_g_respawn_delay_max;
+               else
+                       self.respawn_time_max = self.respawn_time;
                if((sdelay + waves >= 5.0) && (self.respawn_time - time > 1.75))
                        self.respawn_countdown = 10; // first number to count down from is 10
                else
                // reset fields the weapons may use just in case
                for (j = WEP_FIRST; j <= WEP_LAST; ++j)
                {
 -                      weapon_action(j, WR_RESETPLAYER);
 +                      WEP_ACTION(j, WR_RESETPLAYER);
                        ATTACK_FINISHED_FOR(self, j) = 0;
                }
        }
@@@ -691,7 -701,7 +698,7 @@@ float Say(entity source, float teamsay
  
        msgin = formatmessage(msgin);
  
-       if not(IS_PLAYER(source))
+       if (!IS_PLAYER(source))
                colorstr = "^0"; // black for spectators
        else if(teamplay)
                colorstr = Team_ColorCode(source.team);
        }
  
        if(!privatesay)
-       if not(IS_PLAYER(source))
+       if (!IS_PLAYER(source))
        {
-               if not(intermission_running)
+               if (!intermission_running)
                        if(teamsay || (autocvar_g_chat_nospectators == 1) || (autocvar_g_chat_nospectators == 2 && !(warmup_stage || gameover)))
                                teamsay = -1; // spectators
        }
                {
                        sprint(source, sourcemsgstr);
                        sprint(privatesay, msgstr);
-                       if not(autocvar_g_chat_tellprivacy) { dedicated_print(msgstr); } // send to server console too if "tellprivacy" is disabled
+                       if (!autocvar_g_chat_tellprivacy) { dedicated_print(msgstr); } // send to server console too if "tellprivacy" is disabled
                        if(cmsgstr != "")
                                centerprint(privatesay, cmsgstr);
                }
                {
                        sprint(source, sourcemsgstr);
                        dedicated_print(msgstr); // send to server console too
-                       FOR_EACH_REALCLIENT(head) if not(IS_PLAYER(head))
+                       FOR_EACH_REALCLIENT(head) if (!IS_PLAYER(head))
                                if(head != source)
                                        sprint(head, msgstr);
                }
@@@ -1008,7 -1018,7 +1015,7 @@@ void PrecachePlayerSounds(string f
        }
        fclose(fh);
  
-       if not(allvoicesamples)
+       if (!allvoicesamples)
        {
  #define _VOICEMSG(m) allvoicesamples = strcat(allvoicesamples, " ", #m);
                ALLVOICEMSGS
diff --combined qcsrc/server/defs.qh
index b7e0515b96c603aa2e2045220a8a39c47461530e,72f4457d61d9fe99dff84bc1c2e728b2dcacab62..0ebc93756bc0c2b82e3d5bd8da5f5f2bf8adbd6e
@@@ -55,7 -55,7 +55,7 @@@ float team1_score, team2_score, team3_s
  float maxclients;
  
  // flag set on worldspawn so that the code knows if it is dedicated or not
- float server_is_dedicated; 
+ float server_is_dedicated;
  
  // Fields
  
@@@ -73,7 -73,8 +73,8 @@@
  //.float      style;
  //.float      skill;
  .float        sounds;
- .float  platmovetype;
+ .string  platmovetype;
+ .float platmovetype_start, platmovetype_end;
  
  .string killtarget;
  
  .float play_time;
  .float respawn_flags;
  .float respawn_time;
+ .float respawn_time_max;
  .float death_time;
  .float fade_time;
  .float fade_rate;
@@@ -181,9 -183,8 +183,9 @@@ void setanim(entity e, vector anim, flo
  .float switchingweapon; // weapon currently being switched to (is copied from switchweapon once switch is possible)
  .string weaponname; // name of .weapon
  
 +// WEAPONTODO
  .float autoswitch;
 -float weapon_action(float wpn, float wrequest);
 +//float WEP_ACTION(float wpn, float wrequest);
  float client_hasweapon(entity cl, float wpn, float andammo, float complain);
  void w_clear();
  void w_ready();
  .float weapon_nextthink;
  .void() weapon_think;
  
 -//float       PLAYER_WEAPONSELECTION_DELAY = );
 -const float   PLAYER_WEAPONSELECTION_SPEED = 18;
 -const vector  PLAYER_WEAPONSELECTION_RANGE = '0 20 -40';
  
  // weapon states (self.weaponentity.state)
  const float WS_CLEAR                  = 0; // no weapon selected
@@@ -468,10 -472,11 +470,11 @@@ void target_voicescript_clear(entity pl
  .string target2;
  .string target3;
  .string target4;
+ .string curvetarget;
  .float target_random;
  .float trigger_reverse;
  
- // Nexball 
+ // Nexball
  .entity ballcarried; // Also used for keepaway
  .float metertime;
  float g_nexball_meter_period;
@@@ -508,11 -513,12 +511,11 @@@ float servertime, serverprevtime, serve
  .float stat_shotorg; // networked stat for trueaim HUD
  
  string matchid;
 -.float hitplotfh;
  
  .float last_pickup;
  
- .float hit_time; 
- .float typehit_time; 
+ .float hit_time;
+ .float typehit_time;
  
  .float stat_leadlimit;
  
@@@ -555,6 -561,9 +558,6 @@@ string deathmessage
  
  .float just_joined;
  
 -.float cvar_cl_accuracy_data_share;
 -.float cvar_cl_accuracy_data_receive;
 -
  .float cvar_cl_weaponimpulsemode;
  .float selectweapon; // last selected weapon of the player
  
index 142bd7a8b8c2246a2493f2091996ab9f4f3cb643,d67e79cd4d3396e45b74e9747291036680fc968d..0bf71059e6029ae10d9e94b1ed0ba861842cd609
@@@ -70,7 -70,7 +70,7 @@@ void LaunchDebris (string debrisname, v
  void func_breakable_colormod()
  {
        float h;
-       if not(self.spawnflags & 2)
+       if (!(self.spawnflags & 2))
                return;
        h = self.health / self.max_health;
        if(h < 0.25)
@@@ -79,6 -79,8 +79,8 @@@
                self.colormod = '1 0 0' + '0 1 0' * (2 * h - 0.5);
        else
                self.colormod = '1 1 1';
+               
+       CSQCMODEL_AUTOUPDATE();
  }
  
  void func_breakable_look_destroyed()
@@@ -140,12 -142,16 +142,16 @@@ void func_breakable_destroyed(
  {
        func_breakable_look_destroyed();
        func_breakable_behave_destroyed();
+       
+       CSQCMODEL_AUTOUPDATE();
  }
  
  void func_breakable_restore()
  {
        func_breakable_look_restore();
        func_breakable_behave_restore();
+       
+       CSQCMODEL_AUTOUPDATE();
  }
  
  vector debrisforce; // global, set before calling this
@@@ -167,7 -173,7 +173,7 @@@ void func_breakable_destroy() 
                sound (self, CH_TRIGGER, self.noise, VOL_BASE, ATTEN_NORM);
  
        if(self.dmg)
 -              RadiusDamage(self, activator, self.dmg, self.dmg_edge, self.dmg_radius, self, self.dmg_force, DEATH_HURTTRIGGER, world);
 +              RadiusDamage(self, activator, self.dmg, self.dmg_edge, self.dmg_radius, self, world, self.dmg_force, DEATH_HURTTRIGGER, world);
  
        if(self.cnt)
                pointparticles(self.cnt, self.absmin * 0.5 + self.absmax * 0.5, '0 0 0', self.count);
@@@ -217,6 -223,8 +223,8 @@@ void func_breakable_reset(
                func_breakable_behave_destroyed();
        else
                func_breakable_behave_restore();
+               
+       CSQCMODEL_AUTOUPDATE();
  }
  
  // destructible walls that can be used to trigger target_objective_decrease
@@@ -268,6 -276,8 +276,8 @@@ void spawnfunc_func_breakable() 
  
        self.reset = func_breakable_reset;
        func_breakable_reset();
+       
+       CSQCMODEL_AUTOINIT();
  }
  
  // for use in maps with a "model" key set
diff --combined qcsrc/server/g_damage.qc
index b2ca5e9207027c403fdbabb5ea232b4fa59315e0,195829b40d00c701f9e95d494b19178caeb1a815..7b63c3866016c2dd1faf904d7e78b14f3d3c01a8
@@@ -128,7 -128,7 +128,7 @@@ void GiveFrags (entity attacker, entit
                        }
  
                        if(warmup_stage)
-                               GiveFrags_randomweapons.weapons = warmup_start_weapons;
+                               GiveFrags_randomweapons.weapons = WARMUP_START_WEAPONS;
                        else
                                GiveFrags_randomweapons.weapons = start_weapons;
  
                }
  
                // after a frag, choose another random weapon set
-               if not(attacker.weapons & WepSet_FromWeapon(attacker.weapon))
+               if (!(attacker.weapons & WepSet_FromWeapon(attacker.weapon)))
                        W_SwitchWeapon_Force(attacker, w_getbestweapon(attacker));
        }
  
@@@ -225,7 -225,7 +225,7 @@@ void Obituary_SpecialDeath
        if(DEATH_ISSPECIAL(deathtype))
        {
                entity deathent = deathtypes[(deathtype - DT_FIRST)];
-               if not(deathent) { backtrace("Obituary_SpecialDeath: Could not find deathtype entity!\n"); return; }
+               if (!deathent) { backtrace("Obituary_SpecialDeath: Could not find deathtype entity!\n"); return; }
  
                if(murder)
                {
@@@ -287,7 -287,7 +287,7 @@@ float Obituary_WeaponDeath
        if(death_weapon)
        {
                w_deathtype = deathtype;
 -              float death_message = weapon_action(death_weapon, ((murder) ? WR_KILLMESSAGE : WR_SUICIDEMESSAGE));
 +              float death_message = WEP_ACTION(death_weapon, ((murder) ? WR_KILLMESSAGE : WR_SUICIDEMESSAGE));
                w_deathtype = FALSE;
  
                if(death_message)
  void Obituary(entity attacker, entity inflictor, entity targ, float deathtype)
  {
        // Sanity check
-       if not(IS_PLAYER(targ)) { backtrace("Obituary called on non-player?!\n"); return; }
+       if (!IS_PLAYER(targ)) { backtrace("Obituary called on non-player?!\n"); return; }
  
        // Declarations
        float notif_firstblood = FALSE;
                )
        );
        #endif
-       
        // =======
        // SUICIDE
        // =======
                                                Obituary_SpecialDeath(targ, FALSE, deathtype, targ.netname, deathlocation, "", targ.killcount, 0, 0);
                                                break;
                                        }
-                                       
                                        default:
                                        {
                                                Obituary_SpecialDeath(targ, FALSE, deathtype, targ.netname, deathlocation, "", targ.killcount, 0, 0);
                                }
                        }
                }
-               else if not(Obituary_WeaponDeath(targ, FALSE, deathtype, targ.netname, deathlocation, "", targ.killcount, 0))
+               else if (!Obituary_WeaponDeath(targ, FALSE, deathtype, targ.netname, deathlocation, "", targ.killcount, 0))
                {
                        backtrace("SUICIDE: what the hell happened here?\n");
                        return;
                        GiveFrags(attacker, targ, -1, deathtype);
  
                        attacker.killcount = 0;
-                       
                        Send_Notification(NOTIF_ONE, attacker, MSG_CENTER, CENTER_DEATH_TEAMKILL_FRAG, targ.netname);
                        Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_DEATH_TEAMKILL_FRAGGED, attacker.netname);
                        Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(targ.team, INFO_DEATH_TEAMKILL_), targ.netname, attacker.netname, deathlocation, targ.killcount);
                                );
                        }
  
-                       if not(Obituary_WeaponDeath(targ, TRUE, deathtype, targ.netname, attacker.netname, deathlocation, targ.killcount, kill_count_to_attacker))
+                       if (!Obituary_WeaponDeath(targ, TRUE, deathtype, targ.netname, attacker.netname, deathlocation, targ.killcount, kill_count_to_attacker))
                                Obituary_SpecialDeath(targ, TRUE, deathtype, targ.netname, attacker.netname, deathlocation, targ.killcount, kill_count_to_attacker, 0);
                }
        }
                                        0);
                                break;
                        }
-                       
                        default:
                        {
                                Obituary_SpecialDeath(targ, FALSE, deathtype, targ.netname, deathlocation, "", targ.killcount, 0, 0);
@@@ -558,7 -558,7 +558,7 @@@ void Damage (entity targ, entity inflic
  {
        float mirrordamage;
        float mirrorforce;
-       float complainteamdamage = 0; 
+       float complainteamdamage = 0;
        entity attacker_save;
        mirrordamage = 0;
        mirrorforce = 0;
  
        if(deathtype == DEATH_KILL || deathtype == DEATH_TEAMCHANGE || deathtype == DEATH_AUTOTEAMCHANGE)
        {
+               // exit the vehicle before killing (fixes a crash)
+               if(IS_PLAYER(targ) && targ.vehicle)
+                       vehicles_exit(VHEF_RELESE);
                // These are ALWAYS lethal
                // No damage modification here
                // Instead, prepare the victim for his death...
  
                                                        if(autocvar_g_mirrordamage_virtual)
                                                        {
-                                                               vector v  = healtharmor_applydamage(attacker.armorvalue, autocvar_g_balance_armor_blockpercent, mirrordamage);
+                                                               vector v  = healtharmor_applydamage(attacker.armorvalue, autocvar_g_balance_armor_blockpercent, deathtype, mirrordamage);
                                                                attacker.dmg_take += v_x;
                                                                attacker.dmg_save += v_y;
                                                                attacker.dmg_inflictor = inflictor;
  
                                                        if(autocvar_g_friendlyfire_virtual)
                                                        {
-                                                               vector v = healtharmor_applydamage(targ.armorvalue, autocvar_g_balance_armor_blockpercent, damage);
+                                                               vector v = healtharmor_applydamage(targ.armorvalue, autocvar_g_balance_armor_blockpercent, deathtype, damage);
                                                                targ.dmg_take += v_x;
                                                                targ.dmg_save += v_y;
                                                                targ.dmg_inflictor = inflictor;
                        }
                }
  
-               if not(DEATH_ISSPECIAL(deathtype))
+               if (!DEATH_ISSPECIAL(deathtype))
                {
                        damage *= g_weapondamagefactor;
                        mirrordamage *= g_weapondamagefactor;
                        force = force * g_weaponforcefactor;
                        mirrorforce *= g_weaponforcefactor;
                }
-               
                // should this be changed at all? If so, in what way?
                frag_attacker = attacker;
                frag_target = targ;
                damage = frag_damage;
                mirrordamage = frag_mirrordamage;
                force = frag_force;
-               
-               if not(g_minstagib)
+               if (!g_minstagib)
                {
                        // apply strength multiplier
                        if (attacker.items & IT_STRENGTH)
                                                damage_goodhits += 1;
                                                damage_gooddamage += damage;
  
-                                               if not(DEATH_ISSPECIAL(deathtype))
+                                               if (!DEATH_ISSPECIAL(deathtype))
                                                {
                                                        if(IS_PLAYER(targ)) // don't do this for vehicles
                                                        if(IsFlying(victim))
  }
  
  float RadiusDamage_running;
 -float RadiusDamage (entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity ignore, float forceintensity, float deathtype, entity directhitentity)
 +float RadiusDamageForSource (entity inflictor, vector inflictororigin, vector inflictorvelocity, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float inflictorselfdamage, float forceintensity, float deathtype, entity directhitentity)
        // Returns total damage applies to creatures
  {
        entity  targ;
 -      vector  blastorigin;
        vector  force;
        float   total_damage_to_creatures;
        entity  next;
        tfloordmg = autocvar_g_throughfloor_damage;
        tfloorforce = autocvar_g_throughfloor_force;
  
 -      blastorigin = (inflictor.origin + (inflictor.mins + inflictor.maxs) * 0.5);
        total_damage_to_creatures = 0;
  
        if(deathtype != (WEP_HOOK | HITTYPE_SECONDARY | HITTYPE_BOUNCE)) // only send gravity bomb damage once
                if(DEATH_WEAPONOF(deathtype) != WEP_TUBA) // do not send tuba damage (bandwidth hog)
                {
 -                      force = inflictor.velocity;
 +                      force = inflictorvelocity;
                        if(vlen(force) == 0)
                                force = '0 0 -1';
                        else
                                force = normalize(force);
                        if(forceintensity >= 0)
 -                              Damage_DamageInfo(blastorigin, coredamage, edgedamage, rad, forceintensity * force, deathtype, 0, attacker);
 +                              Damage_DamageInfo(inflictororigin, coredamage, edgedamage, rad, forceintensity * force, deathtype, 0, attacker);
                        else
 -                              Damage_DamageInfo(blastorigin, coredamage, edgedamage, -rad, (-forceintensity) * force, deathtype, 0, attacker);
 +                              Damage_DamageInfo(inflictororigin, coredamage, edgedamage, -rad, (-forceintensity) * force, deathtype, 0, attacker);
                }
  
        stat_damagedone = 0;
  
 -      targ = WarpZone_FindRadius (blastorigin, rad + MAX_DAMAGEEXTRARADIUS, FALSE);
 +      targ = WarpZone_FindRadius (inflictororigin, rad + MAX_DAMAGEEXTRARADIUS, FALSE);
        while (targ)
        {
                next = targ.chain;
 -              if (targ != inflictor)
 -                      if (ignore != targ) if(targ.takedamage)
 +              if ((targ != inflictor) || inflictorselfdamage)
 +              if (((cantbe != targ) && !mustbe) || (mustbe == targ))
 +              if (targ.takedamage)
 +              {
 +                      vector nearest;
 +                      vector diff;
 +                      float power;
 +
 +                      // LordHavoc: measure distance to nearest point on target (not origin)
 +                      // (this guarentees 100% damage on a touch impact)
 +                      nearest = targ.WarpZone_findradius_nearest;
 +                      diff = targ.WarpZone_findradius_dist;
 +                      // round up a little on the damage to ensure full damage on impacts
 +                      // and turn the distance into a fraction of the radius
 +                      power = 1 - ((vlen (diff) - bound(MIN_DAMAGEEXTRARADIUS, targ.damageextraradius, MAX_DAMAGEEXTRARADIUS)) / rad);
 +                      //bprint(" ");
 +                      //bprint(ftos(power));
 +                      //if (targ == attacker)
 +                      //      print(ftos(power), "\n");
 +                      if (power > 0)
                        {
 -                              vector nearest;
 -                              vector diff;
 -                              float power;
 -
 -                              // LordHavoc: measure distance to nearest point on target (not origin)
 -                              // (this guarentees 100% damage on a touch impact)
 -                              nearest = targ.WarpZone_findradius_nearest;
 -                              diff = targ.WarpZone_findradius_dist;
 -                              // round up a little on the damage to ensure full damage on impacts
 -                              // and turn the distance into a fraction of the radius
 -                              power = 1 - ((vlen (diff) - bound(MIN_DAMAGEEXTRARADIUS, targ.damageextraradius, MAX_DAMAGEEXTRARADIUS)) / rad);
 -                              //bprint(" ");
 -                              //bprint(ftos(power));
 -                              //if (targ == attacker)
 -                              //      print(ftos(power), "\n");
 -                              if (power > 0)
 +                              float finaldmg;
 +                              if (power > 1)
 +                                      power = 1;
 +                              finaldmg = coredamage * power + edgedamage * (1 - power);
 +                              if (finaldmg > 0)
                                {
 -                                      float finaldmg;
 -                                      if (power > 1)
 -                                              power = 1;
 -                                      finaldmg = coredamage * power + edgedamage * (1 - power);
 -                                      if (finaldmg > 0)
 -                                      {
 -                                              float a;
 -                                              float c;
 -                                              vector hitloc;
 -                                              vector myblastorigin;
 -                                              vector center;
 -
 -                                              myblastorigin = WarpZone_TransformOrigin(targ, blastorigin);
 -
 -                                              // if it's a player, use the view origin as reference
 -                                              center = CENTER_OR_VIEWOFS(targ);
 +                                      float a;
 +                                      float c;
 +                                      vector hitloc;
 +                                      vector myblastorigin;
 +                                      vector center;
  
 -                                              force = normalize(center - myblastorigin);
 -                                              force = force * (finaldmg / coredamage) * forceintensity;
 -                                              hitloc = nearest;
 +                                      myblastorigin = WarpZone_TransformOrigin(targ, inflictororigin);
  
 -                                              if(targ != directhitentity)
 -                                              {
 -                                                      float hits;
 -                                                      float total;
 -                                                      float hitratio;
 -                                                      float mininv_f, mininv_d;
 +                                      // if it's a player, use the view origin as reference
 +                                      center = CENTER_OR_VIEWOFS(targ);
  
 -                                                      // test line of sight to multiple positions on box,
 -                                                      // and do damage if any of them hit
 -                                                      hits = 0;
 +                                      force = normalize(center - myblastorigin);
 +                                      force = force * (finaldmg / coredamage) * forceintensity;
 +                                      hitloc = nearest;
  
 -                                                      // we know: max stddev of hitratio = 1 / (2 * sqrt(n))
 -                                                      // so for a given max stddev:
 -                                                      // n = (1 / (2 * max stddev of hitratio))^2
 +                                      if(targ != directhitentity)
 +                                      {
 +                                              float hits;
 +                                              float total;
 +                                              float hitratio;
 +                                              float mininv_f, mininv_d;
  
 -                                                      mininv_d = (finaldmg * (1-tfloordmg)) / autocvar_g_throughfloor_damage_max_stddev;
 -                                                      mininv_f = (vlen(force) * (1-tfloorforce)) / autocvar_g_throughfloor_force_max_stddev;
 +                                              // test line of sight to multiple positions on box,
 +                                              // and do damage if any of them hit
 +                                              hits = 0;
  
 -                                                      if(autocvar_g_throughfloor_debug)
 -                                                              print(sprintf("THROUGHFLOOR: D=%f F=%f max(dD)=1/%f max(dF)=1/%f", finaldmg, vlen(force), mininv_d, mininv_f));
 +                                              // we know: max stddev of hitratio = 1 / (2 * sqrt(n))
 +                                              // so for a given max stddev:
 +                                              // n = (1 / (2 * max stddev of hitratio))^2
  
 -                                                      total = 0.25 * pow(max(mininv_f, mininv_d), 2);
 +                                              mininv_d = (finaldmg * (1-tfloordmg)) / autocvar_g_throughfloor_damage_max_stddev;
 +                                              mininv_f = (vlen(force) * (1-tfloorforce)) / autocvar_g_throughfloor_force_max_stddev;
  
 -                                                      if(autocvar_g_throughfloor_debug)
 -                                                              print(sprintf(" steps=%f", total));
 +                                              if(autocvar_g_throughfloor_debug)
 +                                                      print(sprintf("THROUGHFLOOR: D=%f F=%f max(dD)=1/%f max(dF)=1/%f", finaldmg, vlen(force), mininv_d, mininv_f));
  
 -                                                      if (IS_PLAYER(targ))
 -                                                              total = ceil(bound(autocvar_g_throughfloor_min_steps_player, total, autocvar_g_throughfloor_max_steps_player));
 -                                                      else
 -                                                              total = ceil(bound(autocvar_g_throughfloor_min_steps_other, total, autocvar_g_throughfloor_max_steps_other));
 +                                              total = 0.25 * pow(max(mininv_f, mininv_d), 2);
  
 -                                                      if(autocvar_g_throughfloor_debug)
 -                                                              print(sprintf(" steps=%f dD=%f dF=%f", total, finaldmg * (1-tfloordmg) / (2 * sqrt(total)), vlen(force) * (1-tfloorforce) / (2 * sqrt(total))));
 +                                              if(autocvar_g_throughfloor_debug)
 +                                                      print(sprintf(" steps=%f", total));
  
 -                                                      for(c = 0; c < total; ++c)
 -                                                      {
 -                                                              //traceline(targ.WarpZone_findradius_findorigin, nearest, MOVE_NOMONSTERS, inflictor);
 -                                                              WarpZone_TraceLine(blastorigin, WarpZone_UnTransformOrigin(targ, nearest), MOVE_NOMONSTERS, inflictor);
 -                                                              if (trace_fraction == 1 || trace_ent == targ)
 -                                                              {
 -                                                                      ++hits;
 -                                                                      if (hits > 1)
 -                                                                              hitloc = hitloc + nearest;
 -                                                                      else
 -                                                                              hitloc = nearest;
 -                                                              }
 -                                                              nearest_x = targ.origin_x + targ.mins_x + random() * targ.size_x;
 -                                                              nearest_y = targ.origin_y + targ.mins_y + random() * targ.size_y;
 -                                                              nearest_z = targ.origin_z + targ.mins_z + random() * targ.size_z;
 -                                                      }
 -
 -                                                      nearest = hitloc * (1 / max(1, hits));
 -                                                      hitratio = (hits / total);
 -                                                      a = bound(0, tfloordmg + (1-tfloordmg) * hitratio, 1);
 -                                                      finaldmg = finaldmg * a;
 -                                                      a = bound(0, tfloorforce + (1-tfloorforce) * hitratio, 1);
 -                                                      force = force * a;
 +                                              if (IS_PLAYER(targ))
 +                                                      total = ceil(bound(autocvar_g_throughfloor_min_steps_player, total, autocvar_g_throughfloor_max_steps_player));
 +                                              else
 +                                                      total = ceil(bound(autocvar_g_throughfloor_min_steps_other, total, autocvar_g_throughfloor_max_steps_other));
  
 -                                                      if(autocvar_g_throughfloor_debug)
 -                                                              print(sprintf(" D=%f F=%f\n", finaldmg, vlen(force)));
 -                                              }
 +                                              if(autocvar_g_throughfloor_debug)
 +                                                      print(sprintf(" steps=%f dD=%f dF=%f", total, finaldmg * (1-tfloordmg) / (2 * sqrt(total)), vlen(force) * (1-tfloorforce) / (2 * sqrt(total))));
  
 -                                              // laser force adjustments :P
 -                                              if(DEATH_WEAPONOF(deathtype) == WEP_LASER)
 +                                              for(c = 0; c < total; ++c)
                                                {
 -                                                      if (targ == attacker)
 -                                                      {
 -                                                              vector vel;
 -
 -                                                              float force_zscale;
 -                                                              float force_velocitybiasramp;
 -                                                              float force_velocitybias;
 -
 -                                                              force_velocitybiasramp = autocvar_sv_maxspeed;
 -                                                              if(deathtype & HITTYPE_SECONDARY)
 -                                                              {
 -                                                                      force_zscale = autocvar_g_balance_laser_secondary_force_zscale;
 -                                                                      force_velocitybias = autocvar_g_balance_laser_secondary_force_velocitybias;
 -                                                              }
 -                                                              else
 -                                                              {
 -                                                                      force_zscale = autocvar_g_balance_laser_primary_force_zscale;
 -                                                                      force_velocitybias = autocvar_g_balance_laser_primary_force_velocitybias;
 -                                                              }
 -
 -                                                              vel = targ.velocity;
 -                                                              vel_z = 0;
 -                                                              vel = normalize(vel) * bound(0, vlen(vel) / force_velocitybiasramp, 1) * force_velocitybias;
 -                                                              force =
 -                                                                      vlen(force)
 -                                                                      *
 -                                                                      normalize(normalize(force) + vel);
 -
 -                                                              force_z *= force_zscale;
 -                                                      }
 -                                                      else
 +                                                      //traceline(targ.WarpZone_findradius_findorigin, nearest, MOVE_NOMONSTERS, inflictor);
 +                                                      WarpZone_TraceLine(inflictororigin, WarpZone_UnTransformOrigin(targ, nearest), MOVE_NOMONSTERS, inflictor);
 +                                                      if (trace_fraction == 1 || trace_ent == targ)
                                                        {
 -                                                              if(deathtype & HITTYPE_SECONDARY)
 -                                                              {
 -                                                                      force *= autocvar_g_balance_laser_secondary_force_other_scale;
 -                                                              }
 +                                                              ++hits;
 +                                                              if (hits > 1)
 +                                                                      hitloc = hitloc + nearest;
                                                                else
 -                                                              {
 -                                                                      force *= autocvar_g_balance_laser_primary_force_other_scale;
 -                                                              }
 +                                                                      hitloc = nearest;
                                                        }
 +                                                      nearest_x = targ.origin_x + targ.mins_x + random() * targ.size_x;
 +                                                      nearest_y = targ.origin_y + targ.mins_y + random() * targ.size_y;
 +                                                      nearest_z = targ.origin_z + targ.mins_z + random() * targ.size_z;
                                                }
  
 -                                              //if (targ == attacker)
 -                                              //{
 -                                              //      print("hits ", ftos(hits), " / ", ftos(total));
 -                                              //      print(" finaldmg ", ftos(finaldmg), " force ", vtos(force));
 -                                              //      print(" (", ftos(a), ")\n");
 -                                              //}
 -                                              if(finaldmg || vlen(force))
 -                                              {
 -                                                      if(targ.iscreature)
 -                                                      {
 -                                                              total_damage_to_creatures += finaldmg;
 +                                              nearest = hitloc * (1 / max(1, hits));
 +                                              hitratio = (hits / total);
 +                                              a = bound(0, tfloordmg + (1-tfloordmg) * hitratio, 1);
 +                                              finaldmg = finaldmg * a;
 +                                              a = bound(0, tfloorforce + (1-tfloorforce) * hitratio, 1);
 +                                              force = force * a;
  
 -                                                              if(accuracy_isgooddamage(attacker, targ))
 -                                                                      stat_damagedone += finaldmg;
 -                                                      }
 +                                              if(autocvar_g_throughfloor_debug)
 +                                                      print(sprintf(" D=%f F=%f\n", finaldmg, vlen(force)));
 +                                      }
  
 -                                                      if(targ == directhitentity || DEATH_ISSPECIAL(deathtype))
 -                                                              Damage (targ, inflictor, attacker, finaldmg, deathtype, nearest, force);
 -                                                      else
 -                                                              Damage (targ, inflictor, attacker, finaldmg, deathtype | HITTYPE_SPLASH, nearest, force);
 +                                      //if (targ == attacker)
 +                                      //{
 +                                      //      print("hits ", ftos(hits), " / ", ftos(total));
 +                                      //      print(" finaldmg ", ftos(finaldmg), " force ", vtos(force));
 +                                      //      print(" (", ftos(a), ")\n");
 +                                      //}
 +                                      if(finaldmg || vlen(force))
 +                                      {
 +                                              if(targ.iscreature)
 +                                              {
 +                                                      total_damage_to_creatures += finaldmg;
 +
 +                                                      if(accuracy_isgooddamage(attacker, targ))
 +                                                              stat_damagedone += finaldmg;
                                                }
 +
 +                                              if(targ == directhitentity || DEATH_ISSPECIAL(deathtype))
 +                                                      Damage (targ, inflictor, attacker, finaldmg, deathtype, nearest, force);
 +                                              else
 +                                                      Damage (targ, inflictor, attacker, finaldmg, deathtype | HITTYPE_SPLASH, nearest, force);
                                        }
                                }
                        }
 +              }
                targ = next;
        }
  
        return total_damage_to_creatures;
  }
  
 +float RadiusDamage (entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float forceintensity, float deathtype, entity directhitentity)
 +{
 +      return RadiusDamageForSource (inflictor, (inflictor.origin + (inflictor.mins + inflictor.maxs) * 0.5), inflictor.velocity, attacker, coredamage, edgedamage, rad, cantbe, mustbe, FALSE, forceintensity, deathtype, directhitentity);
 +}
 +
  .float fire_damagepersec;
  .float fire_endtime;
  .float fire_deathtype;
@@@ -1052,7 -1098,7 +1056,7 @@@ float Fire_AddDamage(entity e, entity o
                if(maxtime > mintime || maxdps > mindps)
                {
                        // Constraints:
-                       
                        // damage we have right now
                        mindamage = mindps * mintime;
  
@@@ -1141,7 -1187,7 +1145,7 @@@ void Fire_ApplyDamage(entity e
        float t, d, hi, ty;
        entity o;
  
-       if not(Fire_IsBurning(e))
+       if (!Fire_IsBurning(e))
                return;
  
        for(t = 0, o = e.owner; o.owner && t < 16; o = o.owner, ++t);
        }
        e.fire_hitsound = TRUE;
  
-       if not(IS_INDEPENDENT_PLAYER(e))
+       if (!IS_INDEPENDENT_PLAYER(e))
        FOR_EACH_PLAYER(other) if(e != other)
        {
                if(IS_PLAYER(other))
                if(other.deadflag == DEAD_NO)
-               if not(IS_INDEPENDENT_PLAYER(other))
+               if (!IS_INDEPENDENT_PLAYER(other))
                if(boxesoverlap(e.absmin, e.absmax, other.absmin, other.absmax))
                {
                        t = autocvar_g_balance_firetransfer_time * (e.fire_endtime - time);
diff --combined qcsrc/server/g_hook.qc
index db8c30fe4c976911d09ed61af076d60310c2e3bf,0df6ba0aee59c4cc5a070ce9f20bdc6da263d50c..c2768cf6ae777a95b235bdef1d2f0255ad926b4d
@@@ -274,12 -274,12 +274,12 @@@ void GrapplingHook_Damage (entity infli
  {
        if(self.health <= 0)
                return;
-               
        if (!W_CheckProjectileDamage(inflictor.realowner, self.realowner, deathtype, -1)) // no exceptions
                return; // g_balance_projectiledamage says to halt
-                       
        self.health = self.health - damage;
-               
        if (self.health <= 0)
        {
                if(attacker != self.realowner)
@@@ -383,7 -383,7 +383,7 @@@ void GrapplingHookFrame(
                // offhand hook controls
                if(self.BUTTON_HOOK)
                {
-                       if not(self.hook || (self.hook_state & HOOK_WAITING_FOR_RELEASE))
+                       if (!(self.hook || (self.hook_state & HOOK_WAITING_FOR_RELEASE)))
                        {
                                self.hook_state |= HOOK_FIRING;
                                self.hook_state |= HOOK_WAITING_FOR_RELEASE;
@@@ -475,7 -475,7 +475,7 @@@ void GrappleHookInit(
        }
        else
        {
 -              weapon_action(WEP_HOOK, WR_PRECACHE);
 +              WEP_ACTION(WEP_HOOK, WR_INIT);
                hook_shotorigin[0] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_HOOK), FALSE, FALSE, 1);
                hook_shotorigin[1] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_HOOK), FALSE, FALSE, 2);
                hook_shotorigin[2] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_HOOK), FALSE, FALSE, 3);
diff --combined qcsrc/server/g_world.qc
index f8b62d337844e648c2bf898049937844028b72c7,42c2d7a8e4e74cad37e0a1cacc88f0b74361fd6e..d2a2273891fb8fdc01d666f066ea9dfe22152ff5
@@@ -253,7 -253,6 +253,6 @@@ void cvar_changes_init(
  
                // mapinfo
                BADCVAR("fraglimit");
-               BADCVAR("g_arena");
                BADCVAR("g_assault");
                BADCVAR("g_ca");
                BADCVAR("g_ca_teams");
  
                // does nothing visible
                BADCVAR("captureleadlimit_override");
-               BADCVAR("g_arena_point_leadlimit");
                BADCVAR("g_balance_kill_delay");
                BADCVAR("g_ca_point_leadlimit");
                BADCVAR("g_ctf_captimerecord_always");
                BADCVAR("sv_fraginfo");
                BADCVAR("sv_timeout");
                BADPREFIX("sv_timeout_");
-               BADCVAR("welcome_message_time");
                BADPREFIX("crypto_");
                BADPREFIX("g_chat_");
                BADPREFIX("g_ctf_captimerecord_");
                BADCVAR("g_nix");
                BADCVAR("g_grappling_hook");
                BADCVAR("g_jetpack");
-               
  #undef BADPREFIX
  #undef BADCVAR
  
@@@ -653,8 -650,8 +650,8 @@@ void spawnfunc_worldspawn (void
        InitGameplayMode();
        readlevelcvars();
        GrappleHookInit();
 +      ArcInit();
        ElectroInit();
 -      LaserInit();
  
        player_count = 0;
        bot_waypoints_for_items = autocvar_g_waypoints_for_items;
@@@ -1049,6 -1046,8 +1046,8 @@@ float() MaplistMethod_Iterate = // usua
  {
        float pass, i;
  
+       dprint("Trying MaplistMethod_Iterate\n");
        for(pass = 1; pass <= 2; ++pass)
        {
                for(i = 1; i < Map_Count; ++i)
  
  float() MaplistMethod_Repeat = // fallback method
  {
+       dprint("Trying MaplistMethod_Repeat\n");
        if(Map_Check(Map_Current, 2))
                return Map_Current;
        return -2;
@@@ -1073,6 -1074,8 +1074,8 @@@ float() MaplistMethod_Random = // rando
  {
        float i, imax;
  
+       dprint("Trying MaplistMethod_Random\n");
        imax = 42;
  
        for(i = 0; i <= imax; ++i)
@@@ -1091,6 -1094,8 +1094,8 @@@ float(float exponent) MaplistMethod_Shu
  {
        float i, j, imax, insertpos;
  
+       dprint("Trying MaplistMethod_Shuffle\n");
        imax = 42;
  
        for(i = 0; i <= imax; ++i)
  void Maplist_Init()
  {
        Map_Count = tokenizebyseparator(autocvar_g_maplist, " ");
-       if(Map_Count == 0)
+       float i;
+       for (i = 0; i < Map_Count; ++i)
+               if (Map_Check(i, 2))
+                       break;
+       if (i == Map_Count)
        {
-               bprint( "Maplist is empty!  Resetting it to default map list.\n" );
-               cvar_set("g_maplist", MapInfo_ListAllAllowedMaps(MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags()));
+               bprint( "Maplist contains no usable maps!  Resetting it to default map list.\n" );
+               cvar_set("g_maplist", MapInfo_ListAllAllowedMaps(MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags() | MAPINFO_FLAG_NOAUTOMAPLIST));
                if(autocvar_g_maplist_shuffle)
                        ShuffleMaplist();
                localcmd("\nmenu_cmd sync\n");
@@@ -1231,31 -1240,12 +1240,12 @@@ void GotoNextMap(float reinit
                return;
        alreadychangedlevel = TRUE;
  
-       {
-               string nextMap;
-               float allowReset;
-               for(allowReset = 1; allowReset >= 0; --allowReset)
-               {
-                       nextMap = GetNextMap();
-                       if(nextMap != "")
-                               break;
+       string nextMap;
  
-                       if(allowReset)
-                       {
-                               bprint( "Maplist contains no single playable map!  Resetting it to default map list.\n" );
-                               cvar_set("g_maplist", MapInfo_ListAllAllowedMaps(MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags()));
-                               if(autocvar_g_maplist_shuffle)
-                                       ShuffleMaplist();
-                               localcmd("\nmenu_cmd sync\n");
-                       }
-                       else
-                       {
-                               error("Everything is broken - not even the default map list works. Please report this to the developers.");
-                       }
-               }
-               Map_Goto(reinit);
-       }
+       nextMap = GetNextMap();
+       if(nextMap == "")
+               error("Everything is broken - cannot find a next map. Please report this to the developers.");
+       Map_Goto(reinit);
  }
  
  
@@@ -1409,7 -1399,7 +1399,7 @@@ void DumpStats(float final
                {
                        s = strcat(":player:see-labels:", GetPlayerScoreString(other, 0), ":");
                        s = strcat(s, ftos(rint(time - other.jointime)), ":");
-                       if(IS_PLAYER(other) || g_arena || other.caplayer == 1 || g_lms)
+                       if(IS_PLAYER(other) || other.caplayer == 1 || g_lms)
                                s = strcat(s, ftos(other.team), ":");
                        else
                                s = strcat(s, "spectator:");
@@@ -1522,7 -1512,7 +1512,7 @@@ void NextLevel(
                PlayerStats_AddGlobalInfo(e);
        PlayerStats_Shutdown();
        WeaponStats_Shutdown();
-       
        Kill_Notification(NOTIF_ALL, world, MSG_CENTER, 0); // kill all centerprints now
  
        if(autocvar_sv_eventlog)
@@@ -1863,7 -1853,7 +1853,7 @@@ float WinningCondition_Scores(float lim
        if(WinningConditionHelper_zeroisworst)
                leadlimit = 0; // not supported in this mode
  
-       if(g_dm || g_tdm || g_arena || g_ca || (g_race && !g_race_qualifying) || g_nexball)
+       if(g_dm || g_tdm || g_ca || (g_race && !g_race_qualifying) || g_nexball)
        // these modes always score in increments of 1, thus this makes sense
        {
                if(leaderfrags != WinningConditionHelper_topscore)
@@@ -2246,7 -2236,7 +2236,7 @@@ string MapVote_Suggest(string m
        if(mapvote_initialized)
                return "Can't suggest - voting is already in progress!";
        m = MapInfo_FixName(m);
-       if not(m)
+       if (!m)
                return "The map you suggested is not available on this server.";
        if(!autocvar_g_maplist_votable_suggestions_override_mostrecent)
                if(Map_IsRecent(m))
index 0fe7a04a9bfbeda7ee76fffca53af0d5ab9344d6,e7e771dc6ed03a26ff89f050aa1499ff2fc835ad..33d43cbc23876c9990834e1391c2c72ec0381033
@@@ -96,7 -96,7 +96,7 @@@ const string STR_OBSERVER = "observer"
  #define FOR_EACH_REALCLIENT(v) FOR_EACH_CLIENT(v) if(IS_REAL_CLIENT(v))
  
  #define FOR_EACH_PLAYER(v) FOR_EACH_CLIENT(v) if(IS_PLAYER(v))
- #define FOR_EACH_SPEC(v) FOR_EACH_CLIENT(v) if not(IS_PLAYER(v)) // Samual: shouldn't this be IS_SPEC(v)? and rather create a separate macro to include observers too
+ #define FOR_EACH_SPEC(v) FOR_EACH_CLIENT(v) if (!IS_PLAYER(v)) // Samual: shouldn't this be IS_SPEC(v)? and rather create a separate macro to include observers too
  #define FOR_EACH_REALPLAYER(v) FOR_EACH_REALCLIENT(v) if(IS_PLAYER(v))
  
  #define CENTER_OR_VIEWOFS(ent) (ent.origin + (IS_PLAYER(ent) ? ent.view_ofs : ((ent.mins + ent.maxs) * 0.5)))
@@@ -458,6 -458,7 +458,6 @@@ void GetCvars_handleFloatOnce(string th
                        stuffcmd(self, strcat("cl_cmd sendcvar ", name, "\n"));
        }
  }
 -float w_getbestweapon(entity e);
  string W_FixWeaponOrder_ForceComplete_AndBuildImpulseList(string wo)
  {
        string o;
@@@ -614,6 -615,7 +614,7 @@@ float start_armorvalue
  WepSet warmup_start_weapons;
  WepSet warmup_start_weapons_default;
  WepSet warmup_start_weapons_defaultmask;
+ #define WARMUP_START_WEAPONS ((g_warmup_allguns == 1) ? (warmup_start_weapons & (weaponsInMap | start_weapons)) : warmup_start_weapons)
  float warmup_start_ammo_shells;
  float warmup_start_ammo_nails;
  float warmup_start_ammo_rockets;
@@@ -641,21 -643,21 +642,21 @@@ float want_weapon(string cvarprefix, en
                        d = FALSE;
        }
        else if (g_cts)
 -              d = (i == WEP_SHOTGUN);
 +              d = (i == WEP_SHOTGUN); // todo: how to handle shotgun in CTS mode? we're removing it.. so.... 
        else if (g_nexball)
                d = 0; // weapon is set a few lines later
        else
-               d = (i == WEP_LASER);
-               
+               d = (i == WEP_LASER || i == WEP_SHOTGUN);
        if(g_grappling_hook) // if possible, redirect off-hand hook to on-hand hook
                d |= (i == WEP_HOOK);
        if(weaponinfo.spawnflags & WEP_FLAG_MUTATORBLOCKED) // never default mutator blocked guns
                d = 0;
  
        var float t = cvar(strcat(cvarprefix, weaponinfo.netname));
-       
        //print(strcat("want_weapon: ", weaponinfo.netname, " - d: ", ftos(d), ", t: ", ftos(t), ". \n"));
-       
        // bit order in t:
        // 1: want or not
        // 2: is default?
@@@ -711,7 -713,7 +712,7 @@@ void readplayerstartcvars(
                for (j = WEP_FIRST; j <= WEP_LAST; ++j)
                {
                        e = get_weaponinfo(j);
-                       if not(e.spawnflags & WEP_FLAG_MUTATORBLOCKED)
+                       if (!(e.spawnflags & WEP_FLAG_MUTATORBLOCKED))
                                g_weaponarena_weapons |= WepSet_FromWeapon(j);
                }
        }
                for (j = WEP_FIRST; j <= WEP_LAST; ++j)
                {
                        e = get_weaponinfo(j);
-                       if not(e.spawnflags & WEP_FLAG_MUTATORBLOCKED)
+                       if (!(e.spawnflags & WEP_FLAG_MUTATORBLOCKED))
                                if (e.spawnflags & WEP_FLAG_NORMAL)
                                        g_weaponarena_weapons |= WepSet_FromWeapon(j);
                }
  
        if(!cvar("g_use_ammunition"))
                start_items |= IT_UNLIMITED_AMMO;
-       
        if(start_items & IT_UNLIMITED_WEAPON_AMMO)
        {
                start_ammo_rockets = 999;
                        for (i = WEP_FIRST; i <= WEP_LAST; ++i)
                        {
                                e = get_weaponinfo(i);
-                               float w = want_weapon("g_start_weapon_", e, cvar("g_warmup_allguns"));
+                               float w = want_weapon("g_start_weapon_", e, g_warmup_allguns);
                                if(w & 1)
                                        warmup_start_weapons |= WepSet_FromWeapon(i);
                                if(w & 2)
                warmup_start_ammo_fuel = max(warmup_start_ammo_fuel, cvar("g_balance_fuel_rotstable"));
        }
  
+       WepSet precache_weapons = start_weapons;
+       if (g_warmup_allguns != 1)
+               precache_weapons |= warmup_start_weapons;
        for (i = WEP_FIRST; i <= WEP_LAST; ++i)
        {
                e = get_weaponinfo(i);
-               if((start_weapons | warmup_start_weapons) & WepSet_FromWeapon(i))
+               if(precache_weapons & WepSet_FromWeapon(i))
 -                      weapon_action(i, WR_PRECACHE);
 +                      WEP_ACTION(i, WR_INIT);
        }
  
        start_ammo_shells = max(0, start_ammo_shells);
@@@ -902,7 -907,7 +906,7 @@@ void readlevelcvars(void
        // load mutators
        #define CHECK_MUTATOR_ADD(mut_cvar,mut_name,dependence) \
                { if(cvar(mut_cvar) && dependence) { MUTATOR_ADD(mut_name); } }
-               
        CHECK_MUTATOR_ADD("g_dodging", mutator_dodging, 1);
        CHECK_MUTATOR_ADD("g_spawn_near_teammate", mutator_spawn_near_teammate, 1);
        CHECK_MUTATOR_ADD("g_physical_items", mutator_physical_items, 1);
        CHECK_MUTATOR_ADD("g_nades", mutator_nades, 1);
        CHECK_MUTATOR_ADD("g_sandbox", sandbox, 1);
        CHECK_MUTATOR_ADD("g_campcheck", mutator_campcheck, 1);
-       
        #undef CHECK_MUTATOR_ADD
-       
        if(cvar("sv_allow_fullbright"))
                serverflags |= SERVERFLAG_ALLOW_FULLBRIGHT;
  
      g_bugrigs_speed_ref = cvar("g_bugrigs_speed_ref");
      g_bugrigs_speed_pow = cvar("g_bugrigs_speed_pow");
      g_bugrigs_steer = cvar("g_bugrigs_steer");
-       
        g_minstagib = cvar("g_minstagib");
  
        sv_clones = cvar("sv_clones");
        g_warmup_allguns = cvar("g_warmup_allguns");
        g_warmup_allow_timeout = cvar("g_warmup_allow_timeout");
  
-       if ((g_race && g_race_qualifying == 2) || g_arena || g_assault || cvar("g_campaign"))
+       if ((g_race && g_race_qualifying == 2) || g_assault || cvar("g_campaign"))
                warmup_stage = 0; // these modes cannot work together, sorry
  
        g_pickup_respawntime_weapon = cvar("g_pickup_respawntime_weapon");
      if(!g_weapon_stay)
          g_weapon_stay = cvar("g_weapon_stay");
  
-       if not(warmup_stage)
+       if (!warmup_stage)
                game_starttime = time + cvar("g_start_delay");
  
        readplayerstartcvars();
@@@ -1384,6 -1389,18 +1388,6 @@@ void precache(
          precache_sound ("weapons/hook_impact.wav"); // hook
      }
  
 -    if(autocvar_sv_precacheweapons)
 -    {
 -        //precache weapon models/sounds
 -        float wep;
 -        wep = WEP_FIRST;
 -        while (wep <= WEP_LAST)
 -        {
 -            weapon_action(wep, WR_PRECACHE);
 -            wep = wep + 1;
 -        }
 -    }
 -
      precache_model("models/elaser.mdl");
      precache_model("models/laser.mdl");
      precache_model("models/ebomb.mdl");
@@@ -1628,7 -1645,7 +1632,7 @@@ void adaptor_think2use(
  
  void adaptor_think2use_hittype_splash() // for timed projectile detonation
  {
-       if not(self.flags & FL_ONGROUND) // if onground, we ARE touching something, but HITTYPE_SPLASH is to be networked if the damage causing projectile is not touching ANYTHING
+       if(!(self.flags & FL_ONGROUND)) // if onground, we ARE touching something, but HITTYPE_SPLASH is to be networked if the damage causing projectile is not touching ANYTHING
                self.projectiledeathtype |= HITTYPE_SPLASH;
        adaptor_think2use();
  }
@@@ -1801,7 -1818,7 +1805,7 @@@ string uid2name(string myuid) 
                        db_put(ServerProgsDB, strcat("uid2name", myuid), "");
                }
        }
-       
        if(s == "")
                s = "^1Unregistered Player";
        return s;
@@@ -2319,7 -2336,7 +2323,7 @@@ void shockwave_spawn(string m, vector o
  
  float randombit(float bits)
  {
-       if not(bits & (bits-1)) // this ONLY holds for powers of two!
+       if(!(bits & (bits-1))) // this ONLY holds for powers of two!
                return bits;
  
        float n, f, b, r;
@@@ -2387,7 -2404,7 +2391,7 @@@ float ExponentialFalloff(float mindist
  #else
  string cvar_string_normal(string n)
  {
-       if not(cvar_type(n) & 1)
+       if (!(cvar_type(n) & 1))
                backtrace(strcat("Attempt to access undefined cvar: ", n));
        return builtin_cvar_string(n);
  }
index 731927a771d61e474438d700d4534bd50989d743,2d2c857e90dbff166c673e53f05488bb6970e878..fc9e45b96e8f011edd8d997f4335ff9b011e212c
@@@ -107,7 -107,7 +107,7 @@@ void GiveBall(entity plyr, entity ball
        {
                WaypointSprite_Kill(ball.waypointsprite_attachedforcarrier);
        }
-       
        //setattachment(ball, plyr, "");
        setorigin(ball, plyr.origin + plyr.view_ofs);
  
                ball.think = DropOwner;
                ball.nextthink = time + autocvar_g_nexball_basketball_delay_hold;
        }
-       
        ownr = self;
-       self = plyr;    
+       self = plyr;
        self.weaponentity.weapons = self.weapons;
        self.weaponentity.switchweapon = self.weapon;
        self.weapons = WEPSET_PORTO;
 -      weapon_action(WEP_PORTO, WR_RESETPLAYER);
 +      WEP_ACTION(WEP_PORTO, WR_RESETPLAYER);
        self.switchweapon = WEP_PORTO;
        W_SwitchWeapon(WEP_PORTO);
        self = ownr;
@@@ -248,7 -248,7 +248,7 @@@ void football_touch(void
                        self.nextthink = time + autocvar_g_nexball_delay_idle;
                return;
        }
-       if not(IS_PLAYER(other))
+       if (!IS_PLAYER(other))
                return;
        if(other.health < 1)
                return;
@@@ -529,7 -529,7 +529,7 @@@ void spawnfunc_nexball_basketball(void
  {
        nexball_mode |= NBM_BASKETBALL;
        self.classname = "nexball_basketball";
-       if not(balls & BALL_BASKET)
+       if (!(balls & BALL_BASKET))
        {
                /*
                CVTOV(g_nexball_basketball_effects_default);
@@@ -655,13 -655,13 +655,13 @@@ void W_Nexball_Think(
        //dprint("W_Nexball_Think\n");
        //vector new_dir = steerlib_arrive(self.enemy.origin, 2500);
        vector new_dir = normalize(self.enemy.origin + '0 0 50' - self.origin);
-       vector old_dir = normalize(self.velocity);       
-       float _speed = vlen(self.velocity);     
+       vector old_dir = normalize(self.velocity);
+       float _speed = vlen(self.velocity);
        vector new_vel = normalize(old_dir + (new_dir * autocvar_g_nexball_safepass_turnrate)) * _speed;
        //vector new_vel = (new_dir * autocvar_g_nexball_safepass_turnrate
-       
        self.velocity = new_vel;
-       
        self.nextthink = time;
  }
  
@@@ -671,7 -671,7 +671,7 @@@ void W_Nexball_Touch(void
        attacker = self.owner;
        //self.think = func_null;
        //self.enemy = world;
-       
        PROJECTILE_TOUCH;
        if(attacker.team != other.team || autocvar_g_nexball_basketball_teamsteal)
                if((ball = other.ballcarried) && (IS_PLAYER(attacker)))
@@@ -725,9 -725,9 +725,9 @@@ void W_Nexball_Attack(float t
                        mul = 2 - mul;
                mul = mi + (ma - mi) * mul; // range from the minimal power to the maximal power
        }
-       
        DropBall(ball, w_shotorg, W_CalculateProjectileVelocity(self.velocity, w_shotdir * autocvar_g_balance_nexball_primary_speed * mul, FALSE));
-       
  
        //TODO: use the speed_up cvar too ??
  }
@@@ -743,10 -743,10 +743,10 @@@ void W_Nexball_Attack2(void
                _ball.nextthink = time;
                return;
        }
-       
        if(!autocvar_g_nexball_tackling)
                return;
-       
        entity missile;
        if(!(balls & BALL_BASKET))
                return;
@@@ -782,8 -782,8 +782,8 @@@ float ball_customize(
                self.scale = 1;
                self.customizeentityforclient = func_null;
                return TRUE;
-       }               
-       
+       }
        if(other == self.owner)
        {
                self.scale = autocvar_g_nexball_viewmodel_scale;
                        self.effects |= EF_FLAME;
                else
                        self.effects &= ~EF_FLAME;
-       }       
+       }
        else
        {
                self.effects &= ~EF_FLAME;
                self.scale = 1;
        }
-               
        return TRUE;
  }
  
@@@ -833,7 -833,7 +833,7 @@@ float w_nexball_weapon(float req
                        weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_nexball_primary_animtime, w_ready);
                }
        }
 -      else if(req == WR_PRECACHE)
 +      else if(req == WR_INIT)
        {
                precache_model("models/weapons/g_porto.md3");
                precache_model("models/weapons/v_porto.md3");
        }
        else if(req == WR_SETUP)
        {
 -              weapon_setup(WEP_PORTO);
 +              //weapon_setup(WEP_PORTO);
        }
        // No need to check WR_CHECKAMMO* or WR_AIM, it should always return TRUE
        return TRUE;
@@@ -875,18 -875,18 +875,18 @@@ MUTATOR_HOOKFUNCTION(nexball_PlayerPreT
  {
        makevectors(self.v_angle);
        if(nexball_mode & NBM_BASKETBALL)
-       {               
+       {
                if(self.ballcarried)
                {
                        // 'view ball'
-                       self.ballcarried.velocity = self.velocity;                      
+                       self.ballcarried.velocity = self.velocity;
                        self.ballcarried.customizeentityforclient = ball_customize;
-                       
-                       setorigin(self.ballcarried, self.origin + self.view_ofs + 
-                                         v_forward * autocvar_g_nexball_viewmodel_offset_x + 
-                                         v_right * autocvar_g_nexball_viewmodel_offset_y + 
-                                         v_up * autocvar_g_nexball_viewmodel_offset_z);        
-                                         
+                       setorigin(self.ballcarried, self.origin + self.view_ofs +
+                                         v_forward * autocvar_g_nexball_viewmodel_offset_x +
+                                         v_right * autocvar_g_nexball_viewmodel_offset_y +
+                                         v_up * autocvar_g_nexball_viewmodel_offset_z);
                        // 'safe passing'
                        if(autocvar_g_nexball_safepass_maxdist)
                        {
                                        //centerprint(self, sprintf("Lost lock on %s", self.ballcarried.enemy.netname));
                                        self.ballcarried.enemy = world;
                                }
-                                       
-                               
                                //tracebox(self.origin + self.view_ofs, '-2 -2 -2', '2 2 2', self.origin + self.view_ofs + v_forward * autocvar_g_nexball_safepass_maxdist);
                                crosshair_trace(self);
-                               if( trace_ent && 
+                               if( trace_ent &&
                                        IS_CLIENT(trace_ent) &&
                                        trace_ent.deadflag == DEAD_NO &&
                                        trace_ent.team == self.team &&
                                        vlen(trace_ent.origin - self.origin) <= autocvar_g_nexball_safepass_maxdist )
                                {
-                                       
                                        //if(self.ballcarried.enemy != trace_ent)
                                        //      centerprint(self, sprintf("Locked to %s", trace_ent.netname));
                                        self.ballcarried.enemy = trace_ent;
                                        self.ballcarried.wait = time + autocvar_g_nexball_safepass_holdtime;
-                                       
-                                       
                                }
                        }
                }
                else
-               {                       
+               {
                        if(self.weaponentity.weapons)
                        {
                                self.weapons = self.weaponentity.weapons;
 -                              weapon_action(WEP_PORTO, WR_RESETPLAYER);
 +                              WEP_ACTION(WEP_PORTO, WR_RESETPLAYER);
                                self.switchweapon = self.weaponentity.switchweapon;
                                W_SwitchWeapon(self.switchweapon);
-                               
                self.weaponentity.weapons = '0 0 0';
                        }
                }
-               
        }
-       
        nexball_setstatus();
-       
        return FALSE;
  }
  
  MUTATOR_HOOKFUNCTION(nexball_PlayerSpawn)
- {     
+ {
        self.weaponentity.weapons = '0 0 0';
-       
        if(nexball_mode & NBM_BASKETBALL)
                self.weapons |= WEPSET_PORTO;
        else
  MUTATOR_HOOKFUNCTION(nexball_SetStartItems)
  {
        start_items |= IT_UNLIMITED_SUPERWEAPONS; // FIXME BAD BAD BAD BAD HACK, NEXBALL SHOULDN'T ABUSE PORTO'S WEAPON SLOT
-       
        return FALSE;
  }
  
index b845e38ae4ecfcd7e7f9982be78c06088c774196,ac6e158ed4c824c2b8f41fb9d5422211c413ea14..9c27e4df05e9556a8a158e83af1b60373e79c51a
@@@ -1,9 -1,9 +1,9 @@@
- void spawnfunc_item_minst_cells (void) 
+ void spawnfunc_item_minst_cells (void)
  {
-       if not(g_minstagib) { remove(self); return; }
-       if not(self.ammo_cells)
+       if (!g_minstagib) { remove(self); return; }
+       if (!self.ammo_cells)
                self.ammo_cells = autocvar_g_minstagib_ammo_drop;
-               
        StartItem ("models/items/a_cells.md3",
                           "misc/itempickup.wav", 45, 0,
                           "MinstaNex Ammo", IT_CELLS, 0, 0, generic_pickupevalfunc, 100);
@@@ -28,7 -28,7 +28,7 @@@ void minstagib_stop_countdown(entity e
  }
  void minstagib_ammocheck()
  {
-       if not(IS_PLAYER(self))
+       if (!IS_PLAYER(self))
                return; // not a player
        if (time < self.minstagib_nextthink)
                return;
@@@ -105,7 -105,7 +105,7 @@@ MUTATOR_HOOKFUNCTION(minstagib_MatchEnd
        entity head;
        FOR_EACH_PLAYER(head)
                minstagib_stop_countdown(head);
-               
        return FALSE;
  }
  
@@@ -113,7 -113,7 +113,7 @@@ MUTATOR_HOOKFUNCTION(minstagib_BotShoul
  {
        if(checkentity.items & IT_STRENGTH)
                return TRUE;
-               
        return FALSE;
  }
  
@@@ -137,7 -137,7 +137,7 @@@ MUTATOR_HOOKFUNCTION(minstagib_PlayerPr
  
  MUTATOR_HOOKFUNCTION(minstagib_PlayerPowerups)
  {
-       if not(self.effects & EF_FULLBRIGHT)
+       if (!(self.effects & EF_FULLBRIGHT))
                self.effects |= EF_FULLBRIGHT;
  
        if (self.items & IT_STRENGTH)
@@@ -188,7 -188,7 +188,7 @@@ MUTATOR_HOOKFUNCTION(minstagib_PlayerPh
  {
        if(self.items & IT_INVINCIBLE)
                self.stat_sv_maxspeed = self.stat_sv_maxspeed * autocvar_g_minstagib_speed_highspeed;
-               
        return FALSE;
  }
  
@@@ -196,7 -196,7 +196,7 @@@ MUTATOR_HOOKFUNCTION(minstagib_SplitHea
  {
        damage_save = 0;
        damage_take = frag_damage;
-       
        return FALSE;
  }
  
@@@ -212,7 -212,7 +212,7 @@@ MUTATOR_HOOKFUNCTION(minstagib_PlayerDa
  {
        if(autocvar_g_friendlyfire == 0 && SAME_TEAM(frag_target, frag_attacker) && IS_PLAYER(frag_target) && IS_PLAYER(frag_attacker))
                frag_damage = 0;
-               
        if(IS_PLAYER(frag_target))
        {
                if ((frag_deathtype == DEATH_FALL)  ||
                {
                        frag_damage = 0;
                }
-               
                if(IS_PLAYER(frag_attacker))
                if(DEATH_ISWEAPON(frag_deathtype, WEP_MINSTANEX))
                if(frag_target.armorvalue)
                        frag_target.hitsound += 1;
                        frag_attacker.hitsound += 1; // TODO change this to a future specific hitsound for armor hit
                }
-               
                if(IS_PLAYER(frag_attacker))
                if (DEATH_ISWEAPON(frag_deathtype, WEP_LASER))
                {
                        }
                }
        }
-       
        if(IS_PLAYER(frag_attacker))
        if(frag_mirrordamage > 0)
        {
                }
                frag_mirrordamage = 0;
        }
-       
        if(frag_target.items & IT_STRENGTH)
                yoda = 1;
-               
        return FALSE;
  }
  
  MUTATOR_HOOKFUNCTION(minstagib_SetStartItems)
  {
        start_ammo_cells = cvar("g_minstagib_ammo_start");
-       
        start_health = 100;
        start_armorvalue = 0;
        start_weapons = WEPSET_MINSTANEX;
        warmup_start_weapons = WEPSET_MINSTANEX;
        start_items |= IT_UNLIMITED_SUPERWEAPONS;
-               
        return FALSE;
  }
  
@@@ -286,14 -286,14 +286,14 @@@ MUTATOR_HOOKFUNCTION(minstagib_FilterIt
  {
        if(self.classname == "item_cells")
                return TRUE; // no normal cells?
-               
        if(self.weapon == WEP_MINSTANEX && self.classname == "droppedweapon")
        {
                self.ammo_cells = autocvar_g_minstagib_ammo_drop;
                return FALSE;
        }
-       
 -      if(self.weapon == WEP_ROCKET_LAUNCHER || self.weapon == WEP_NEX)
 +      if(self.weapon == WEP_DEVASTATOR || self.weapon == WEP_NEX)
        {
                entity e = spawn();
                setorigin(e, self.origin);
                self = oldself;
                return TRUE;
        }
-               
        if(self.flags & FL_POWERUP)
                return FALSE;
-               
        if(self.ammo_cells > autocvar_g_minstagib_ammo_drop && self.classname != "item_minst_cells")
                self.ammo_cells = autocvar_g_minstagib_ammo_drop;
-               
        if(self.ammo_cells && !self.weapon)
                return FALSE;
-               
        return TRUE;
  }
  
  MUTATOR_HOOKFUNCTION(minstagib_CustomizeWaypoint)
  {
        entity e = WaypointSprite_getviewentity(other);
-       
        // if you have the invisibility powerup, sprites ALWAYS are restricted to your team
        // but only apply this to real players, not to spectators
        if((self.owner.flags & FL_CLIENT) && (self.owner.items & IT_STRENGTH) && (e == other))
        if(DIFF_TEAM(self.owner, e))
                return TRUE;
-       
        return FALSE;
  }
  
@@@ -359,37 -359,37 +359,37 @@@ MUTATOR_HOOKFUNCTION(minstagib_ItemTouc
  
                return MUT_ITEMTOUCH_CONTINUE;
        }
-       
        if(self.max_health)
        {
                other.armorvalue = bound(other.armorvalue, 999, other.armorvalue + autocvar_g_minstagib_extralives);
                Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_EXTRALIVES);
                return MUT_ITEMTOUCH_PICKUP;
        }
-               
        return MUT_ITEMTOUCH_CONTINUE;
  }
  
  MUTATOR_HOOKFUNCTION(minstagib_OnEntityPreSpawn)
  {
-       if not(autocvar_g_powerups) { return FALSE; }
-       if not(self.classname == "item_strength" || self.classname == "item_invincible" || self.classname == "item_health_mega")
+       if (!autocvar_g_powerups) { return FALSE; }
+       if (!(self.classname == "item_strength" || self.classname == "item_invincible" || self.classname == "item_health_mega"))
                return FALSE;
-       
        entity e = spawn();
-       
        if(random() < 0.3)
                e.think = spawnfunc_item_strength;
        else if(random() < 0.6)
                e.think = minstagib_health_mega;
        else
                e.think = spawnfunc_item_invincible;
-               
        e.nextthink = time + 0.1;
        e.spawnflags = self.spawnflags;
        e.noalign = self.noalign;
        setorigin(e, self.origin);
-       
        return TRUE;
  }
  
@@@ -405,6 -405,12 +405,12 @@@ MUTATOR_HOOKFUNCTION(minstagib_BuildMut
        return FALSE;
  }
  
+ MUTATOR_HOOKFUNCTION(minstagib_SetModname)
+ {
+       modname = "MinstaGib";
+       return TRUE;
+ }
  MUTATOR_DEFINITION(mutator_minstagib)
  {
        MUTATOR_HOOK(MatchEnd, minstagib_MatchEnd, CBC_ORDER_ANY);
        MUTATOR_HOOK(OnEntityPreSpawn, minstagib_OnEntityPreSpawn, CBC_ORDER_ANY);
        MUTATOR_HOOK(BuildMutatorsString, minstagib_BuildMutatorsString, CBC_ORDER_ANY);
        MUTATOR_HOOK(BuildMutatorsPrettyString, minstagib_BuildMutatorsPrettyString, CBC_ORDER_ANY);
+       MUTATOR_HOOK(SetModname, minstagib_SetModname, CBC_ORDER_ANY);
  
        return FALSE;
  }
index c1a2c39f7187fe05ac1ce34c3f6891fc98c2d777,5ab6df75dc720e2d6b385ed665d1cf0ccf9fcfc3..2e6f7ea3046e089575c1167c300bc519a5f934f7
@@@ -4,13 -4,13 +4,13 @@@ void nade_timer_think(
        self.nextthink = time;
        if(!self.owner || wasfreed(self.owner))
                remove(self);
-       
  }
  
  void nade_burn_spawn(entity _nade)
  {
        float p;
-       
        switch(_nade.realowner.team)
        {
                case NUM_TEAM_1: p = PROJECTILE_NADE_RED_BURN; break;
@@@ -19,7 -19,7 +19,7 @@@
                case NUM_TEAM_4: p = PROJECTILE_NADE_PINK_BURN; break;
                default:                 p = PROJECTILE_NADE_BURN; break;
        }
-       
        CSQCProjectile(_nade, TRUE, p, TRUE);
  }
  
@@@ -35,9 -35,9 +35,9 @@@ void nade_spawn(entity _nade
        timer.think = nade_timer_think;
        timer.nextthink = time;
        timer.wait = _nade.wait;
-       timer.owner = _nade;    
+       timer.owner = _nade;
        timer.skin = 10;
-       
        switch(_nade.realowner.team)
        {
                case NUM_TEAM_1: p = PROJECTILE_NADE_RED; break;
                case NUM_TEAM_4: p = PROJECTILE_NADE_PINK; break;
                default:                 p = PROJECTILE_NADE; break;
        }
-       
        CSQCProjectile(_nade, TRUE, p, TRUE);
-       
  }
  
  void nade_boom()
  {
        string expef;
-       
        switch(self.realowner.team)
        {
                case NUM_TEAM_1: expef = "nade_red_explode"; break;
                case NUM_TEAM_4: expef = "nade_pink_explode"; break;
                default:                 expef = "nade_explode"; break;
        }
-       
        sound(self, CH_SHOTS_SINGLE, "misc/null.wav", VOL_BASE, ATTEN_NORM);
        sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM);
        pointparticles(particleeffectnum(expef), self.origin + '0 0 1', '0 0 0', 1);
-       
        Damage_DamageInfo(self.origin, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage, autocvar_g_nades_nade_radius, '1 1 1' * autocvar_g_nades_nade_force, self.projectiledeathtype, 0, self);
  
        self.takedamage = DAMAGE_NO;
        RadiusDamage(self, self.realowner, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage,
 -                               autocvar_g_nades_nade_radius, self, autocvar_g_nades_nade_force, self.projectiledeathtype, self.enemy);
 +                               autocvar_g_nades_nade_radius, self, world, autocvar_g_nades_nade_force, self.projectiledeathtype, self.enemy);
  
        remove(self);
  }
@@@ -115,13 -115,13 +115,13 @@@ void nade_damage(entity inflictor, enti
  
        if(DEATH_ISWEAPON(deathtype, WEP_SHOTGUN) && !(deathtype & HITTYPE_SECONDARY))
                damage = self.max_health * 1.1;
-               
        if(DEATH_ISWEAPON(deathtype, WEP_SHOTGUN) && (deathtype & HITTYPE_SECONDARY))
        {
                damage = self.max_health * 0.1;
                force *= 15;
        }
-       
        self.velocity += force;
  
        if(!damage || (self.flags & FL_ONGROUND && IS_PLAYER(attacker)))
@@@ -147,16 -147,16 +147,16 @@@ void toss_nade(entity e, vector _veloci
  {
        entity _nade = e.nade;
        e.nade = world;
-       
        remove(e.fake_nade);
        e.fake_nade = world;
-       
        makevectors(e.v_angle);
-       
        W_SetupShot(e, FALSE, FALSE, "", CH_WEAPON_A, 0);
-       
        Kill_Notification(NOTIF_ONE_ONLY, e, MSG_CENTER_CPID, CPID_NADES);
-       
        //setorigin(_nade, CENTER_OR_VIEWOFS(e) + (v_right * 10) * -1);
        setorigin(_nade, w_shotorg + (v_right * 25) * -1);
        setmodel(_nade, "models/weapons/v_ok_grenade.md3");
        PROJECTILE_MAKETRIGGER(_nade);
        setsize(_nade, '-16 -16 -16', '16 16 16');
        _nade.movetype = MOVETYPE_BOUNCE;
-       
        tracebox(_nade.origin, _nade.mins, _nade.maxs, _nade.origin, FALSE, _nade);
        if (trace_startsolid)
                setorigin(_nade, e.origin);
-       
        if(e.crouch)
                _nade.velocity = '0 0 -10';
        else if(autocvar_g_nades_nade_newton_style == 1)
@@@ -207,10 -207,10 +207,10 @@@ void nade_prime(
  {
        if(self.nade)
                remove(self.nade);
-               
        if(self.fake_nade)
                remove(self.fake_nade);
-       
        self.nade = spawn();
        setmodel(self.nade, "null");
        setattachment(self.nade, self, "bip01 l hand");
@@@ -240,22 -240,22 +240,22 @@@ float CanThrowNade(
  {
        if(self.vehicle)
                return FALSE;
-               
        if(gameover)
                return FALSE;
-               
        if(self.deadflag != DEAD_NO)
                return FALSE;
-       
-       if not(autocvar_g_nades)
+       if (!autocvar_g_nades)
                return FALSE; // allow turning them off mid match
-               
        if(forbidWeaponUse())
                return FALSE;
-               
-       if not(IS_PLAYER(self))
+       if (!IS_PLAYER(self))
                return FALSE;
-               
        return TRUE;
  }
  
@@@ -263,7 -263,7 +263,7 @@@ void nades_CheckThrow(
  {
        if(!CanThrowNade())
                return;
-               
        if(!self.nade)
        {
                if(self.nade_refire < time)
@@@ -290,18 -290,18 +290,18 @@@ MUTATOR_HOOKFUNCTION(nades_VehicleEnter
  {
        if(other.nade)
                toss_nade(other, '0 0 100', max(other.nade.wait, time + 0.05));
-       
        return FALSE;
  }
  
  MUTATOR_HOOKFUNCTION(nades_PlayerPreThink)
  {
        float key_pressed = ((g_grappling_hook || client_hasweapon(self, WEP_HOOK, FALSE, FALSE) || (weaponsInMap & WEPSET_HOOK)) ? self.button16 : self.BUTTON_HOOK);
-       
        if(self.nade)
                if(self.nade.wait - 0.1 <= time)
                        toss_nade(self, '0 0 0', time + 0.05);
-                       
        if(CanThrowNade())
        if(self.nade_refire < time)
        {
                                makevectors(self.v_angle);
                                float _force = time - self.nade.lifetime;
                                _force /= autocvar_g_nades_nade_lifetime;
-                               _force = autocvar_g_nades_nade_minforce + (_force * (autocvar_g_nades_nade_maxforce - autocvar_g_nades_nade_minforce));                         
+                               _force = autocvar_g_nades_nade_minforce + (_force * (autocvar_g_nades_nade_maxforce - autocvar_g_nades_nade_minforce));
                                toss_nade(self, (v_forward * 0.7 + v_up * 0.2 + v_right * 0.1) * _force, 0);
                        }
                }
@@@ -340,7 -340,7 +340,7 @@@ MUTATOR_HOOKFUNCTION(nades_PlayerDies
  {
        if(self.nade)
                toss_nade(self, '0 0 100', max(self.nade.wait, time + 0.05));
-               
        return FALSE;
  }
  
@@@ -351,7 -351,7 +351,7 @@@ MUTATOR_HOOKFUNCTION(nades_RemovePlayer
  
        if(self.fake_nade)
                remove(self.fake_nade);
-               
        return FALSE;
  }
  
@@@ -377,11 -377,11 +377,11 @@@ MUTATOR_DEFINITION(mutator_nades
        MUTATOR_HOOK(ClientDisconnect, nades_RemovePlayer, CBC_ORDER_ANY);
        MUTATOR_HOOK(BuildMutatorsString, nades_BuildMutatorsString, CBC_ORDER_ANY);
        MUTATOR_HOOK(BuildMutatorsPrettyString, nades_BuildMutatorsPrettyString, CBC_ORDER_ANY);
-       
        MUTATOR_ONADD
        {
                precache_model("models/ok_nade_counter/ok_nade_counter.md3");
-               
                precache_model("models/weapons/h_ok_grenade.iqm");
                precache_model("models/weapons/v_ok_grenade.md3");
                precache_sound("weapons/rocket_impact.wav");
index 28d7e5431c707e114f01373ddb73649d41d90d32,dc12b05209eccc70baa32187ab62b033eb8fb961..70357067e466c6ee429e133f06347c0917a8395a
@@@ -1,5 -1,5 +1,5 @@@
  float g_nix_with_laser;
 -
 +// WEAPONTODO
  float nix_weapon;
  float nix_weapon_ammo;
  float nix_nextchange;
@@@ -26,7 -26,7 +26,7 @@@ float NIX_CanChooseWeapon(float wpn
                        return FALSE;
                if(e.spawnflags & WEP_FLAG_MUTATORBLOCKED)
                        return FALSE;
-               if not(e.spawnflags & WEP_FLAG_NORMAL)
+               if (!(e.spawnflags & WEP_FLAG_NORMAL))
                        return FALSE;
        }
        return TRUE;
@@@ -60,7 -60,7 +60,7 @@@ void NIX_GiveCurrentWeapon(
                        nix_nextchange = time; // start the first round now!
                else
                        nix_nextchange = time + autocvar_g_balance_nix_roundtime;
 -              //weapon_action(nix_weapon, WR_PRECACHE); // forget it, too slow
 +              //WEP_ACTION(nix_weapon, WR_INIT); // forget it, too slow
        }
  
        if(nix_nextchange != self.nix_lastchange_id) // this shall only be called once per round!
                else
                        Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_NIX_NEWWEAPON, nix_weapon);
  
 -              weapon_action(nix_weapon, WR_RESETPLAYER);
 +              WEP_ACTION(nix_weapon, WR_RESETPLAYER);
  
                // all weapons must be fully loaded when we spawn
                entity e;
                e = get_weaponinfo(nix_weapon);
                if(e.spawnflags & WEP_FLAG_RELOADABLE) // prevent accessing undefined cvars
 -                      self.(weapon_load[nix_weapon]) = cvar(strcat("g_balance_", e.netname, "_reload_ammo"));
 +                      self.(weapon_load[nix_weapon]) = e.reloading_ammo;
  
                // nex too
 -              if(autocvar_g_balance_nex_charge)
 +              if(WEP_CVAR(nex, charge))
                {
 -                      if(autocvar_g_balance_nex_secondary_chargepool)
 +                      if(WEP_CVAR_SEC(nex, chargepool))
                                self.nex_chargepool_ammo = 1;
 -                      self.nex_charge = autocvar_g_balance_nex_charge_start;
 +                      self.nex_charge = WEP_CVAR(nex, charge_start);
                }
        }
        if(self.nix_lastinfotime != dt)
@@@ -152,7 -152,7 +152,7 @@@ void NIX_precache(
        float i;
        for (i = WEP_FIRST; i <= WEP_LAST; ++i)
                if (NIX_CanChooseWeapon(i))
 -                      weapon_action(i, WR_PRECACHE);
 +                      WEP_ACTION(i, WR_INIT);
  }
  
  MUTATOR_HOOKFUNCTION(nix_ForbidThrowCurrentWeapon)
index 7ea1db00fb023789fa0333623553d95d30760448,fabf13639cf89d6ccf4ba810a099d303a74d0ff7..9e3023b7215496e3bce03026982b74b8f58d1df5
@@@ -12,22 -12,22 +12,22 @@@ void PlayerTouchExplode(entity p1, enti
        entity e;
        e = spawn();
        setorigin(e, org);
 -      RadiusDamage(e, world, autocvar_g_touchexplode_damage, autocvar_g_touchexplode_edgedamage, autocvar_g_touchexplode_radius, world, autocvar_g_touchexplode_force, DEATH_TOUCHEXPLODE, world);
 +      RadiusDamage(e, world, autocvar_g_touchexplode_damage, autocvar_g_touchexplode_edgedamage, autocvar_g_touchexplode_radius, world, world, autocvar_g_touchexplode_force, DEATH_TOUCHEXPLODE, world);
        remove(e);
  }
  
  MUTATOR_HOOKFUNCTION(touchexplode_PlayerThink)
  {
        if(time > self.touchexplode_time)
-       if not(gameover)
+       if (!gameover)
        if(IS_PLAYER(self))
        if(self.deadflag == DEAD_NO)
-       if not(IS_INDEPENDENT_PLAYER(self))
+       if (!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 (!IS_INDEPENDENT_PLAYER(other))
                if(boxesoverlap(self.absmin, self.absmax, other.absmin, other.absmax))
                {
                        PlayerTouchExplode(self, other);
diff --combined qcsrc/server/progs.src
index cd01a857adfe5f477a611d180bf4a5b5490a4b57,f29324a478a8e622e4b72b81d995681a01d511b4..1a505f5fed26a64768b022e58542af24d298ece1
@@@ -11,11 -11,14 +11,11 @@@ sys-post.q
  ../warpzonelib/common.qh
  ../warpzonelib/util_server.qh
  ../warpzonelib/server.qh
 -
  ../common/constants.qh
  ../common/teams.qh
  ../common/util.qh
  ../common/test.qh
  ../common/counting.qh
 -../common/items.qh
 -../common/explosion_equation.qh
  ../common/urllib.qh
  ../common/command/markup.qh
  ../common/command/rpn.qh
  ../common/net_notice.qh
  ../common/animdecide.qh
  
 +../common/weapons/config.qh
 +../common/weapons/weapons.qh // TODO
 +weapons/accuracy.qh
 +weapons/common.qh
 +weapons/csqcprojectile.qh // TODO
 +weapons/hitplot.qh
 +weapons/selection.qh
 +weapons/spawning.qh
 +weapons/throwing.qh
 +weapons/tracing.qh
 +weapons/weaponsystem.qh
 +
 +t_items.qh
 +
  autocvars.qh
  constants.qh
  defs.qh               // Should rename this, it has fields and globals
@@@ -48,7 -37,6 +48,6 @@@
  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
@@@ -75,7 -63,8 +74,7 @@@ command/getreplies.q
  command/cmd.qh
  command/sv_cmd.qh
  
 -accuracy.qh
 -csqcprojectile.qh
 +
  ../common/csqcmodel_settings.qh
  ../csqcmodellib/common.qh
  ../csqcmodellib/sv_model.qh
@@@ -87,7 -76,9 +86,7 @@@ playerstats.q
  
  portals.qh
  
 -g_hook.qh
 -w_electro.qh
 -w_laser.qh
 +g_hook.qh // TODO
  
  scores.qh
  
@@@ -148,19 -139,13 +147,19 @@@ g_models.q
  item_key.qc
  secret.qc
  
 -cl_weaponsystem.qc
 -w_common.qc
 -
 -w_all.qc
 +weapons/accuracy.qc
 +weapons/common.qc
 +weapons/csqcprojectile.qc // TODO
 +weapons/hitplot.qc
 +weapons/selection.qc
 +weapons/spawning.qc
 +weapons/throwing.qc
 +weapons/tracing.qc
 +weapons/weaponsystem.qc
 +../common/weapons/config.qc
 +../common/weapons/weapons.qc // TODO
  
  t_items.qc
 -cl_weapons.qc
  cl_impulse.qc
  
  ent_cs.qc
@@@ -223,7 -208,12 +222,7 @@@ target_spawn.q
  func_breakable.qc
  target_music.qc
  
 -../common/items.qc
 -
 -
 -accuracy.qc
  ../csqcmodellib/sv_model.qc
 -csqcprojectile.qc
  
  playerdemo.qc
  
@@@ -233,9 -223,10 +232,8 @@@ playerstats.q
  
  round_handler.qc
  
 -../common/explosion_equation.qc
 -
  mutators/base.qc
  mutators/gamemode_assault.qc
- mutators/gamemode_arena.qc
  mutators/gamemode_ca.qc
  mutators/gamemode_ctf.qc
  mutators/gamemode_domination.qc
@@@ -276,5 -267,3 +274,3 @@@ mutators/mutator_campcheck.q
  ../common/test.qc
  ../common/util.qc
  ../common/notifications.qc
- ../common/if-this-file-errors-scroll-up-and-fix-the-warnings.fteqccfail
diff --combined qcsrc/server/t_items.qc
index 69223cc020b80411e9c3fad67e12fcd0dac8fd9d,1db8f6cd7630fcf7913d3fd229696986f8aa5e7d..493ca337dc4822c6bb9d5a1a2b0519db2a359d96
@@@ -1,36 -1,64 +1,36 @@@
 -#define ISF_LOCATION 2
 -#define ISF_MODEL    4
 -#define ISF_STATUS   8
 -    #define ITS_STAYWEP   1
 -    #define ITS_ANIMATE1  2
 -    #define ITS_ANIMATE2  4
 -    #define ITS_AVAILABLE 8
 -    #define ITS_ALLOWFB   16
 -    #define ITS_ALLOWSI   32
 -    #define ITS_POWERUP   64
 -#define ISF_COLORMAP 16
 -#define ISF_DROP 32
 -#define ISF_ANGLES 64
 -
 -.float ItemStatus;
 -
  #ifdef CSQC
 -
 -var float  autocvar_cl_animate_items = 1;
 -var float  autocvar_cl_ghost_items = 0.45;
 -var vector autocvar_cl_ghost_items_color = '-1 -1 -1';
 -var float  autocvar_cl_fullbright_items = 0;
 -var vector autocvar_cl_weapon_stay_color = '2 0.5 0.5';
 -var float  autocvar_cl_weapon_stay_alpha = 0.75;
 -var float  autocvar_cl_simple_items = 0;
 -var string autocvr_cl_simpleitems_postfix = "_simple";
 -.float  spawntime;
 -.float  gravity;
 -.vector colormod;
  void ItemDraw()
- {    
+ {
      if(self.gravity)
-     {        
+     {
          Movetype_Physics_MatchServer(autocvar_cl_projectiles_sloppy);
-         if(self.move_flags & FL_ONGROUND) 
+         if(self.move_flags & FL_ONGROUND)
          { // For some reason move_avelocity gets set to '0 0 0' here ...
              self.oldorigin = self.origin;
              self.gravity = 0;
  
-             if(autocvar_cl_animate_items)   
-             { // ... so reset it if animations are requested. 
+             if(autocvar_cl_animate_items)
+             { // ... so reset it if animations are requested.
                  if(self.ItemStatus & ITS_ANIMATE1)
                      self.move_avelocity = '0 180 0';
-                 
                  if(self.ItemStatus & ITS_ANIMATE2)
                      self.move_avelocity = '0 -90 0';
              }
          }
      }
      else if (autocvar_cl_animate_items)
-     {        
+     {
          if(self.ItemStatus & ITS_ANIMATE1)
          {
              self.angles += self.move_avelocity * frametime;
-             setorigin(self, '0 0 10' + self.oldorigin + '0 0 8' * sin(time * 2));        
-         }    
-         
+             setorigin(self, '0 0 10' + self.oldorigin + '0 0 8' * sin(time * 2));
+         }
          if(self.ItemStatus & ITS_ANIMATE2)
          {
              self.angles += self.move_avelocity * frametime;
-             setorigin(self, '0 0 8' + self.oldorigin + '0 0 4' * sin(time * 3));        
+             setorigin(self, '0 0 8' + self.oldorigin + '0 0 4' * sin(time * 3));
          }
      }
  }
@@@ -38,9 -66,9 +38,9 @@@
  void ItemDrawSimple()
  {
      if(self.gravity)
-     {        
-         Movetype_Physics_MatchServer(autocvar_cl_projectiles_sloppy);    
-         
+     {
+         Movetype_Physics_MatchServer(autocvar_cl_projectiles_sloppy);
          if(self.move_flags & FL_ONGROUND)
              self.gravity = 0;
      }
@@@ -58,19 -86,19 +58,19 @@@ void ItemRead(float _IsNew
          setorigin(self, self.origin);
          self.oldorigin = self.origin;
      }
-     
-     if(sf & ISF_ANGLES) 
+     if(sf & ISF_ANGLES)
      {
          self.angles_x = ReadCoord();
          self.angles_y = ReadCoord();
-         self.angles_z = ReadCoord();        
+         self.angles_z = ReadCoord();
          self.move_angles = self.angles;
      }
-     
      if(sf & ISF_STATUS) // need to read/write status frist so model can handle simple, fb etc.
      {
-         self.ItemStatus = ReadByte();    
-         
+         self.ItemStatus = ReadByte();
          if(self.ItemStatus & ITS_AVAILABLE)
          {
              self.alpha = 1;
              }
              else
                  self.alpha = -1;
-         }    
-         
+         }
          if(autocvar_cl_fullbright_items)
              if(self.ItemStatus & ITS_ALLOWFB)
                  self.effects |= EF_FULLBRIGHT;
-             
          if(self.ItemStatus & ITS_STAYWEP)
          {
              self.colormod = self.glowmod = autocvar_cl_weapon_stay_color;
              self.alpha = autocvar_cl_weapon_stay_alpha;
-             
          }
-         
          if(self.ItemStatus & ITS_POWERUP)
          {
              if(self.ItemStatus & ITS_AVAILABLE)
                   self.effects &= ~(EF_ADDITIVE | EF_FULLBRIGHT);
          }
      }
-     
      if(sf & ISF_MODEL)
      {
          self.drawmask  = MASK_NORMAL;
          self.movetype  = MOVETYPE_NOCLIP;
          self.draw       = ItemDraw;
-         
          if(self.mdl)
              strunzone(self.mdl);
-         
          self.mdl = "";
          string _fn = ReadString();
-         
          if(autocvar_cl_simple_items && (self.ItemStatus & ITS_ALLOWSI))
          {
              string _fn2 = substring(_fn, 0 , strlen(_fn) -4);
              self.draw = ItemDrawSimple;
-                     
-             
-             
              if(fexists(sprintf("%s%s.md3", _fn2, autocvr_cl_simpleitems_postfix)))
                  self.mdl = strzone(sprintf("%s%s.md3", _fn2, autocvr_cl_simpleitems_postfix));
              else if(fexists(sprintf("%s%s.dpm", _fn2, autocvr_cl_simpleitems_postfix)))
                  dprint("Simple item requested for ", _fn, " but no model exsist for it\n");
              }
          }
-         
-         if(self.draw != ItemDrawSimple)        
-             self.mdl = strzone(_fn);                
-         
-         
+         if(self.draw != ItemDrawSimple)
+             self.mdl = strzone(_fn);
          if(self.mdl == "")
              dprint("^1WARNING!^7 self.mdl is unset for item ", self.classname, " tell tZork aboute this!\n");
-         
          precache_model(self.mdl);
          setmodel(self, self.mdl);
      }
-     
      if(sf & ISF_COLORMAP)
          self.colormap = ReadShort();
-     
      if(sf & ISF_DROP)
      {
          self.gravity = 1;
          self.move_velocity_z = ReadCoord();
          self.velocity = self.move_velocity;
          self.move_origin = self.oldorigin;
-         
          if(!self.move_time)
          {
              self.move_time = time;
          else
              self.move_time = max(self.move_time, time);
      }
-         
      if(autocvar_cl_animate_items)
-     {        
+     {
          if(self.ItemStatus & ITS_ANIMATE1)
              self.move_avelocity = '0 180 0';
-                 
          if(self.ItemStatus & ITS_ANIMATE2)
              self.move_avelocity = '0 -90 0';
      }
  #endif
  
  #ifdef SVQC
 -float autocvar_sv_simple_items;
  float ItemSend(entity to, float sf)
  {
      if(self.gravity)
          sf |= ISF_DROP;
      else
          sf &= ~ISF_DROP;
-       
-       WriteByte(MSG_ENTITY, ENT_CLIENT_ITEM); 
+       WriteByte(MSG_ENTITY, ENT_CLIENT_ITEM);
        WriteByte(MSG_ENTITY, sf);
  
        //WriteByte(MSG_ENTITY, self.cnt);
          WriteCoord(MSG_ENTITY, self.origin_y);
          WriteCoord(MSG_ENTITY, self.origin_z);
      }
-     
      if(sf & ISF_ANGLES)
      {
          WriteCoord(MSG_ENTITY, self.angles_x);
  
      if(sf & ISF_MODEL)
      {
-         
          if(self.mdl == "")
              dprint("^1WARNING!^7 self.mdl is unset for item ", self.classname, "exspect a crash just aboute now\n");
-         
          WriteString(MSG_ENTITY, self.mdl);
      }
-         
-         
      if(sf & ISF_COLORMAP)
          WriteShort(MSG_ENTITY, self.colormap);
  
          WriteCoord(MSG_ENTITY, self.velocity_y);
          WriteCoord(MSG_ENTITY, self.velocity_z);
      }
-         
      return TRUE;
  }
  
+ void ItemUpdate(entity item)
+ {
+       item.SendFlags |= ISF_LOCATION;
+ }
  
  float have_pickup_item(void)
  {
        return TRUE;
  }
  
 -#define ITEM_RESPAWN_TICKS 10
 -
 -#define ITEM_RESPAWNTIME(i)         ((i).respawntime + crandom() * (i).respawntimejitter)
 -      // range: respawntime - respawntimejitter .. respawntime + respawntimejitter
 -#define ITEM_RESPAWNTIME_INITIAL(i) (ITEM_RESPAWN_TICKS + random() * ((i).respawntime + (i).respawntimejitter - ITEM_RESPAWN_TICKS))
 -      // range: 10 .. respawntime + respawntimejitter
 -
  floatfield Item_CounterField(float it)
  {
        switch(it)
@@@ -304,6 -344,8 +308,6 @@@ string Item_CounterFieldName(float it
  #endif
  }
  
 -.float max_armorvalue;
 -.float pickup_anyway;
  /*
  float Item_Customize()
  {
  */
  
  void Item_Show (entity e, float mode)
- {    
+ {
        e.effects &= ~(EF_ADDITIVE | EF_STARDUST | EF_FULLBRIGHT | EF_NODEPTHTEST);
        e.ItemStatus &= ~ITS_STAYWEP;
        if (mode > 0)
                e.spawnshieldtime = 1;
                e.ItemStatus &= ~ITS_AVAILABLE;
        }
-       
        if (e.items & IT_STRENGTH || e.items & IT_INVINCIBLE)
-           e.ItemStatus |= ITS_POWERUP;                
-       
+           e.ItemStatus |= ITS_POWERUP;
        if (autocvar_g_nodepthtestitems)
                e.effects |= EF_NODEPTHTEST;
-               
-     
      if (autocvar_g_fullbrightitems)
                e.ItemStatus |= ITS_ALLOWFB;
-       
        if (autocvar_sv_simple_items)
          e.ItemStatus |= ITS_ALLOWSI;
  
@@@ -495,6 -537,10 +499,6 @@@ void Item_ScheduleInitialRespawn(entit
        Item_ScheduleRespawnIn(e, game_starttime - time + ITEM_RESPAWNTIME_INITIAL(e));
  }
  
 -const float ITEM_MODE_NONE = 0;
 -const float ITEM_MODE_HEALTH = 1;
 -const float ITEM_MODE_ARMOR = 2;
 -const float ITEM_MODE_FUEL = 3;
  float Item_GiveAmmoTo(entity item, entity player, .float ammofield, float ammomax, float mode)
  {
        if (!item.ammofield)
@@@ -555,7 -601,7 +559,7 @@@ float Item_GiveTo(entity item, entity p
        if (player.switchweapon == w_getbestweapon(player))
                _switchweapon = TRUE;
  
-       if not(player.weapons & WepSet_FromWeapon(player.switchweapon))
+       if (!(player.weapons & WepSet_FromWeapon(player.switchweapon)))
                _switchweapon = TRUE;
  
        pickedup |= Item_GiveAmmoTo(item, player, ammo_fuel, g_pickup_fuel_max, ITEM_MODE_FUEL);
        }
  
  :skip
-       
        // always eat teamed entities
        if(item.team)
                pickedup = TRUE;
  void Item_Touch (void)
  {
        entity e, head;
-       
        // remove the item if it's currnetly in a NODROP brush or hits a NOIMPACT surface (such as sky)
        if(self.classname == "droppedweapon")
        {
                }
        }
  
-       if not(IS_PLAYER(other))
+       if (!IS_PLAYER(other))
                return;
        if (other.deadflag)
                return;
  
        if (self.classname == "droppedweapon")
                remove (self);
-       else if not(self.spawnshieldtime)
+       else if (!self.spawnshieldtime)
                return;
        else
        {
@@@ -823,7 -869,7 +827,7 @@@ float commodity_pickupevalfunc(entity p
        {
                wi = get_weaponinfo(i);
  
-               if not(player.weapons & WepSet_FromWeapon(i))
+               if (!(player.weapons & WepSet_FromWeapon(i)))
                        continue;
  
                if(wi.items & IT_SHELLS)
@@@ -877,22 -923,23 +881,22 @@@ void Item_Damage(entity inflictor, enti
                RemoveItem();
  }
  
 -.float is_item;
  void StartItem (string itemmodel, string pickupsound, float defaultrespawntime, float defaultrespawntimejitter, string itemname, float itemid, float weaponid, float itemflags, float(entity player, entity item) pickupevalfunc, float pickupbasevalue)
  {
        startitem_failed = FALSE;
  
        if(self.model == "")
                self.model = itemmodel;
-       
        if(self.model == "")
      {
          error(strcat("^1Tried to spawn ", itemname, " with no model!\n"));
          return;
      }
-         
        if(self.item_pickupsound == "")
                self.item_pickupsound = pickupsound;
-       
        if(!self.respawntime) // both need to be set
        {
                self.respawntime = defaultrespawntime;
  
        if(weaponid)
                self.weapons = WepSet_FromWeapon(weaponid);
-       
        self.flags = FL_ITEM | itemflags;
  
        if(MUTATOR_CALLHOOK(FilterItem)) // error means we do not want the item
                        remove (self);
                        return;
                }
-               
                if(self.angles != '0 0 0')
              self.SendFlags |= ISF_ANGLES;
  
        self.netname = itemname;
        self.touch = Item_Touch;
        setmodel(self, "null"); // precision set below
-       //self.effects |= EF_LOWPRECISION; 
-       
+       //self.effects |= EF_LOWPRECISION;
        if((itemflags & FL_POWERUP) || self.health || self.armorvalue)
      {
          self.pos1 = '-16 -16 0';
          self.pos2 = '16 16 32';
      }
      setsize (self, self.pos1, self.pos2);
-     
-     if(itemflags & FL_POWERUP) 
+     if(itemflags & FL_POWERUP)
          self.ItemStatus |= ITS_ANIMATE1;
-       
        if(self.armorvalue || self.health)
          self.ItemStatus |= ITS_ANIMATE2;
-       
        if(itemflags & FL_WEAPON)
        {
                if (self.classname != "droppedweapon") // if dropped, colormap is already set up nicely
              self.colormap = 1024; // color shirt=0 pants=0 grey
          else
              self.gravity = 1;
-             
                self.ItemStatus |= ITS_ANIMATE1;
                self.ItemStatus |= ISF_COLORMAP;
        }
        {
                if(!self.cnt)
                        self.cnt = 1; // item probability weight
-                       
                self.effects |= EF_NODRAW; // marker for item team search
                InitializeEntity(self, Item_FindTeam, INITPRIO_FINDTARGET);
        }
        else
                Item_Reset();
-         
      Net_LinkEntity(self, FALSE, 0, ItemSend);
  
        // call this hook after everything else has been done
                return;
        }
  }
 -
 -float weaponswapping;
 -float internalteam;
 -
 -void weapon_defaultspawnfunc(float wpn)
 -{
 -      entity e;
 -      float t;
 -      var .float ammofield;
 -      string s;
 -      entity oldself;
 -      float i, j;
 -      float f;
 -
 -      if(self.classname != "droppedweapon" && self.classname != "replacedweapon")
 -      {
 -              e = get_weaponinfo(wpn);
 -
 -              if(e.spawnflags & WEP_FLAG_MUTATORBLOCKED)
 -              {
 -                      objerror("Attempted to spawn a mutator-blocked weapon rejected");
 -                      startitem_failed = TRUE;
 -                      return;
 -              }
 -
 -              s = W_Apply_Weaponreplace(e.netname);
 -              ret_string = s;
 -              other = e;
 -              MUTATOR_CALLHOOK(SetWeaponreplace);
 -              s = ret_string;
 -              if(s == "")
 -              {
 -                      remove(self);
 -                      startitem_failed = TRUE;
 -                      return;
 -              }
 -              t = tokenize_console(s);
 -              if(t >= 2)
 -              {
 -                      self.team = --internalteam;
 -                      oldself = self;
 -                      for(i = 1; i < t; ++i)
 -                      {
 -                              s = argv(i);
 -                              for(j = WEP_FIRST; j <= WEP_LAST; ++j)
 -                              {
 -                                      e = get_weaponinfo(j);
 -                                      if(e.netname == s)
 -                                      {
 -                                              self = spawn();
 -                                              copyentity(oldself, self);
 -                                              self.classname = "replacedweapon";
 -                                              weapon_defaultspawnfunc(j);
 -                                              break;
 -                                      }
 -                              }
 -                              if(j > WEP_LAST)
 -                              {
 -                                      print("The weapon replace list for ", oldself.classname, " contains an unknown weapon ", s, ". Skipped.\n");
 -                              }
 -                      }
 -                      self = oldself;
 -              }
 -              if(t >= 1) // always the case!
 -              {
 -                      s = argv(0);
 -                      wpn = 0;
 -                      for(j = WEP_FIRST; j <= WEP_LAST; ++j)
 -                      {
 -                              e = get_weaponinfo(j);
 -                              if(e.netname == s)
 -                              {
 -                                      wpn = j;
 -                                      break;
 -                              }
 -                      }
 -                      if(j > WEP_LAST)
 -                      {
 -                              print("The weapon replace list for ", self.classname, " contains an unknown weapon ", s, ". Skipped.\n");
 -                      }
 -              }
 -              if(wpn == 0)
 -              {
 -                      remove(self);
 -                      startitem_failed = TRUE;
 -                      return;
 -              }
 -      }
 -
 -      e = get_weaponinfo(wpn);
 -
 -      if(!self.respawntime)
 -      {
 -              if(e.weapons & WEPSET_SUPERWEAPONS)
 -              {
 -                      self.respawntime = g_pickup_respawntime_superweapon;
 -                      self.respawntimejitter = g_pickup_respawntimejitter_superweapon;
 -              }
 -              else
 -              {
 -                      self.respawntime = g_pickup_respawntime_weapon;
 -                      self.respawntimejitter = g_pickup_respawntimejitter_weapon;
 -              }
 -      }
 -
 -      if(e.weapons & WEPSET_SUPERWEAPONS)
 -              if(!self.superweapons_finished)
 -                      self.superweapons_finished = autocvar_g_balance_superweapons_time;
 -
 -      if(e.items)
 -      {
 -              for(i = 0, j = 1; i < 24; ++i, j *= 2)
 -              {
 -                      if(e.items & j)
 -                      {
 -                              ammofield = Item_CounterField(j);
 -                              if(!self.ammofield)
 -                                      self.ammofield = cvar(strcat("g_pickup_", Item_CounterFieldName(j), "_weapon"));
 -                      }
 -              }
 -      }
 -
 -      // pickup anyway
 -      if(g_pickup_weapons_anyway)
 -              self.pickup_anyway = TRUE;
 -
 -      f = FL_WEAPON;
 -
 -      // no weapon-stay on superweapons
 -      if(e.weapons & WEPSET_SUPERWEAPONS)
 -              f |= FL_NO_WEAPON_STAY;
 -
 -      // weapon stay isn't supported for teamed weapons
 -      if(self.team)
 -              f |= FL_NO_WEAPON_STAY;
 -
 -      StartItem(e.model, "weapons/weaponpickup.wav", self.respawntime, self.respawntimejitter, e.message, 0, e.weapon, f, weapon_pickupevalfunc, e.bot_pickupbasevalue);
 -      if (self.modelindex) // don't precache if self was removed
 -              weapon_action(e.weapon, WR_PRECACHE);
 -}
 -
 -void spawnfunc_weapon_shotgun (void);
 -void spawnfunc_weapon_uzi (void) {
 -      if(autocvar_sv_q3acompat_machineshotgunswap)
 -      if(self.classname != "droppedweapon")
 -      {
 -              weapon_defaultspawnfunc(WEP_SHOTGUN);
 -              return;
 -      }
 -      weapon_defaultspawnfunc(WEP_UZI);
 -}
 -
 -void spawnfunc_weapon_shotgun (void) {
 -      if(autocvar_sv_q3acompat_machineshotgunswap)
 -      if(self.classname != "droppedweapon")
 -      {
 -              weapon_defaultspawnfunc(WEP_UZI);
 -              return;
 -      }
 -      weapon_defaultspawnfunc(WEP_SHOTGUN);
 -}
 -
 -void spawnfunc_weapon_nex (void)
 -{
 -      weapon_defaultspawnfunc(WEP_NEX);
 -}
 -
 -void spawnfunc_weapon_minstanex (void)
 -{
 -      weapon_defaultspawnfunc(WEP_MINSTANEX);
 -}
 -
 -void spawnfunc_weapon_rocketlauncher (void)
 -{
 -      weapon_defaultspawnfunc(WEP_ROCKET_LAUNCHER);
 -}
 -
  void spawnfunc_item_rockets (void) {
        if(!self.ammo_rockets)
                self.ammo_rockets = g_pickup_rockets;
@@@ -1252,6 -1476,7 +1256,6 @@@ void spawnfunc_item_invincible (void) 
  // compatibility:
  void spawnfunc_item_quad (void) {self.classname = "item_strength";spawnfunc_item_strength();}
  
 -float GiveItems(entity e, float beginarg, float endarg);
  void target_items_use (void)
  {
        if(activator.classname == "droppedweapon")
                return;
        }
  
-       if not(IS_PLAYER(activator))
+       if (!IS_PLAYER(activator))
                return;
        if(activator.deadflag != DEAD_NO)
                return;
@@@ -1322,7 -1547,7 +1326,7 @@@ void spawnfunc_target_items (void
                                        {
                                                self.weapons |= WepSet_FromWeapon(j);
                                                if(self.spawnflags == 0 || self.spawnflags == 2)
 -                                                      weapon_action(e.weapon, WR_PRECACHE);
 +                                                      WEP_ACTION(e.weapon, WR_INIT);
                                                break;
                                        }
                                }
                        e = get_weaponinfo(j);
                        if(argv(i) == e.netname)
                        {
 -                              weapon_action(e.weapon, WR_PRECACHE);
 +                              WEP_ACTION(e.weapon, WR_INIT);
                                break;
                        }
                }
@@@ -1434,6 -1659,13 +1438,6 @@@ void spawnfunc_item_jetpack(void
        StartItem ("models/items/g_jetpack.md3", "misc/itempickup.wav", g_pickup_respawntime_powerup, g_pickup_respawntimejitter_powerup, "Jet pack", IT_JETPACK, 0, FL_POWERUP, commodity_pickupevalfunc, BOT_PICKUP_RATING_LOW);
  }
  
 -
 -#define OP_SET 0
 -#define OP_MIN 1
 -#define OP_MAX 2
 -#define OP_PLUS 3
 -#define OP_MINUS 4
 -
  float GiveWeapon(entity e, float wpn, float op, float val)
  {
        WepSet v0, v1;
@@@ -1543,6 -1775,14 +1547,6 @@@ void GiveRot(entity e, float v0, float 
        else if(v0 > v1)
                e.regenfield = max(e.regenfield, time + regentime);
  }
 -
 -#define PREGIVE_WEAPONS(e) WepSet save_weapons; save_weapons = e.weapons
 -#define PREGIVE(e,f) float save_##f; save_##f = (e).f
 -#define POSTGIVE_WEAPON(e,b,snd_incr,snd_decr) GiveSound((e), !!(save_weapons & WepSet_FromWeapon(b)), !!(e.weapons & WepSet_FromWeapon(b)), 0, snd_incr, snd_decr)
 -#define POSTGIVE_BIT(e,f,b,snd_incr,snd_decr) GiveSound((e), save_##f & (b), (e).f & (b), 0, snd_incr, snd_decr)
 -#define POSTGIVE_VALUE(e,f,t,snd_incr,snd_decr) GiveSound((e), save_##f, (e).f, t, snd_incr, snd_decr)
 -#define POSTGIVE_VALUE_ROT(e,f,t,rotfield,rottime,regenfield,regentime,snd_incr,snd_decr) GiveRot((e), save_##f, (e).f, rotfield, rottime, regenfield, regentime); GiveSound((e), save_##f, (e).f, t, snd_incr, snd_decr)
 -
  float GiveItems(entity e, float beginarg, float endarg)
  {
        float got, i, j, val, op;
        e.strength_finished = max(0, e.strength_finished - time);
        e.invincible_finished = max(0, e.invincible_finished - time);
        e.superweapons_finished = max(0, e.superweapons_finished - time);
-       
        PREGIVE(e, items);
        PREGIVE_WEAPONS(e);
        PREGIVE(e, strength_finished);
                                {
                                        wi = get_weaponinfo(j);
                                        if(wi.weapon)
-                                               if not(wi.spawnflags & WEP_FLAG_MUTATORBLOCKED)
+                                               if (!(wi.spawnflags & WEP_FLAG_MUTATORBLOCKED))
                                                        got += GiveWeapon(e, j, op, val);
                                }
                        case "allammo":
                if(wi.weapon)
                {
                        POSTGIVE_WEAPON(e, j, "weapons/weaponpickup.wav", string_null);
-                       if not(save_weapons & WepSet_FromWeapon(j))
+                       if (!(save_weapons & WepSet_FromWeapon(j)))
                                if(e.weapons & WepSet_FromWeapon(j))
 -                                      weapon_action(wi.weapon, WR_PRECACHE);
 +                                      WEP_ACTION(wi.weapon, WR_INIT);
                }
        }
        POSTGIVE_VALUE(e, strength_finished, 1, "misc/powerup.wav", "misc/poweroff.wav");
        else
                e.superweapons_finished += time;
  
-       if not(e.weapons & WepSet_FromWeapon(e.switchweapon))
+       if (!(e.weapons & WepSet_FromWeapon(e.switchweapon)))
                _switchweapon = TRUE;
        if(_switchweapon)
                W_SwitchWeapon_Force(e, w_getbestweapon(e));
diff --combined qcsrc/server/t_quake3.qc
index aeb07a560e66bd88d11b55276fc25530aaf4e161,bb1128bd60e8c532c217de9d8f9d99f9c0404d27..d55c8cbd636878105d0a4cfffc4fe4d40d8f9049
@@@ -14,8 -14,8 +14,8 @@@ 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
@@@ -72,11 -72,11 +72,11 @@@ void target_give_init(
        entity targ;
        for (targ = world; (targ = find(targ, targetname, self.target)); ) {
                if (targ.classname == "weapon_rocketlauncher") {
 -                      self.ammo_rockets += targ.count * autocvar_g_balance_rocketlauncher_ammo;
 +                      self.ammo_rockets += targ.count * WEP_CVAR(devastator, ammo);
                        self.netname = "rocketlauncher";
                }
                else if (targ.classname == "weapon_plasmagun") {
 -                      self.ammo_rockets += targ.count * autocvar_g_balance_hagar_primary_ammo;
 +                      self.ammo_rockets += targ.count * WEP_CVAR_PRI(hagar, ammo); // WEAPONTODO
                        if(self.netname == "")
                                self.netname = "hagar";
                        else
@@@ -90,7 -90,7 +90,7 @@@
                                self.netname = strcat(self.netname, " crylink");
                }
                else if (targ.classname == "weapon_grenadelauncher") {
 -                      self.ammo_rockets += targ.count * autocvar_g_balance_grenadelauncher_primary_ammo;
 +                      self.ammo_rockets += targ.count * autocvar_g_balance_mortar_primary_ammo; // WEAPONTODO
                        if(self.netname == "")
                                self.netname = "grenadelauncher";
                        else
@@@ -142,7 -142,7 +142,7 @@@ float DoesQ3ARemoveThisEntity(
                        return 1;
  
        if(self.notta)
-               if not(!teamplay || g_tdm || g_ctf)
+               if (!(!teamplay || g_tdm || g_ctf))
                        return 1;
  
        if(self.notsingle)
                gametypename = "ffa";
                if(teamplay)
                        gametypename = "team";
-               if(g_arena)
-                       gametypename = "tournament";
                if(g_ctf)
                        gametypename = "ctf";
                if(maxclients == 1)
index a62bf9f6a276ede0d8ba8899a5419d1b70d673ec,b4ad709b4d0b547278fd74c4f20fff29a0d64b62..831ed49cb9cfef8888a6919874b8118897611458
@@@ -1,49 -1,49 +1,49 @@@
  #define cvar_base "g_turrets_unit_"
  .float clientframe;
  void turrets_setframe(float _frame, float client_only)
- {        
+ {
      if((client_only ? self.clientframe : self.frame ) != _frame)
      {
          self.SendFlags |= TNSF_ANIM;
          self.anim_start_time = time;
      }
-     
       if(client_only)
          self.clientframe = _frame;
      else
          self.frame = _frame;
-    
  }
  
  float turret_send(entity to, float sf)
  {
-       
-       WriteByte(MSG_ENTITY, ENT_CLIENT_TURRET);    
+       WriteByte(MSG_ENTITY, ENT_CLIENT_TURRET);
        WriteByte(MSG_ENTITY, sf);
        if(sf & TNSF_SETUP)
        {
            WriteByte(MSG_ENTITY, self.turret_type);
-           
            WriteCoord(MSG_ENTITY, self.origin_x);
            WriteCoord(MSG_ENTITY, self.origin_y);
            WriteCoord(MSG_ENTITY, self.origin_z);
-           
            WriteAngle(MSG_ENTITY, self.angles_x);
            WriteAngle(MSG_ENTITY, self.angles_y);
      }
-     
      if(sf & TNSF_ANG)
      {
          WriteShort(MSG_ENTITY, rint(self.tur_head.angles_x));
          WriteShort(MSG_ENTITY, rint(self.tur_head.angles_y));
      }
-     
      if(sf & TNSF_AVEL)
-     {        
+     {
          WriteShort(MSG_ENTITY, rint(self.tur_head.avelocity_x));
          WriteShort(MSG_ENTITY, rint(self.tur_head.avelocity_y));
      }
-     
      if(sf & TNSF_MOVE)
      {
          WriteShort(MSG_ENTITY, rint(self.origin_x));
  
          WriteShort(MSG_ENTITY, rint(self.velocity_x));
          WriteShort(MSG_ENTITY, rint(self.velocity_y));
-         WriteShort(MSG_ENTITY, rint(self.velocity_z));        
-         
-         WriteShort(MSG_ENTITY, rint(self.angles_y));        
+         WriteShort(MSG_ENTITY, rint(self.velocity_z));
+         WriteShort(MSG_ENTITY, rint(self.angles_y));
      }
-     
      if(sf & TNSF_ANIM)
      {
          WriteCoord(MSG_ENTITY, self.anim_start_time);
          WriteByte(MSG_ENTITY, self.frame);
      }
-     
      if(sf & TNSF_STATUS)
      {
          WriteByte(MSG_ENTITY, self.team);
-         
          if(self.health <= 0)
              WriteByte(MSG_ENTITY, 0);
          else
              WriteByte(MSG_ENTITY, ceil((self.health / self.tur_health) * 255));
      }
-     
        return TRUE;
  }
  
@@@ -83,13 -83,13 +83,13 @@@ void load_unit_settings(entity ent, str
      if (ent == world)
          return;
  
-     if not (ent.turret_scale_damage)    ent.turret_scale_damage  = 1;
-     if not (ent.turret_scale_range)     ent.turret_scale_range   = 1;
-     if not (ent.turret_scale_refire)    ent.turret_scale_refire  = 1;
-     if not (ent.turret_scale_ammo)      ent.turret_scale_ammo    = 1;
-     if not (ent.turret_scale_aim)       ent.turret_scale_aim     = 1;
-     if not (ent.turret_scale_health)    ent.turret_scale_health  = 1;
-     if not (ent.turret_scale_respawn)   ent.turret_scale_respawn = 1;
+     if (!ent.turret_scale_damage)    ent.turret_scale_damage  = 1;
+     if (!ent.turret_scale_range)     ent.turret_scale_range   = 1;
+     if (!ent.turret_scale_refire)    ent.turret_scale_refire  = 1;
+     if (!ent.turret_scale_ammo)      ent.turret_scale_ammo    = 1;
+     if (!ent.turret_scale_aim)       ent.turret_scale_aim     = 1;
+     if (!ent.turret_scale_health)    ent.turret_scale_health  = 1;
+     if (!ent.turret_scale_respawn)   ent.turret_scale_respawn = 1;
  
      sbase = strcat(cvar_base,unitname);
      if (is_reload)
  
  void turret_projectile_explode()
  {
-     
      self.takedamage = DAMAGE_NO;
-     self.event_damage = func_null;    
+     self.event_damage = func_null;
  #ifdef TURRET_DEBUG
      float d;
 -    d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, self, self.owner.shot_force, self.totalfrags, world);
 +    d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, self, world, self.owner.shot_force, self.totalfrags, world);
      self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d;
      self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
  #else
 -    RadiusDamage (self, self.realowner, self.owner.shot_dmg, 0, self.owner.shot_radius, self, self.owner.shot_force, self.totalfrags, world);
 +    RadiusDamage (self, self.realowner, self.owner.shot_dmg, 0, self.owner.shot_radius, self, world, self.owner.shot_force, self.totalfrags, world);
  #endif
      remove(self);
  }
@@@ -183,12 -183,12 +183,12 @@@ entity turret_projectile(string _snd, f
      proj.owner           = self;
      proj.realowner       = self;
      proj.bot_dodge       = TRUE;
-     proj.bot_dodgerating = self.shot_dmg;    
+     proj.bot_dodgerating = self.shot_dmg;
      proj.think           = turret_projectile_explode;
      proj.touch           = turret_projectile_touch;
-     proj.nextthink       = time + 9;    
+     proj.nextthink       = time + 9;
      proj.movetype        = MOVETYPE_FLYMISSILE;
-     proj.velocity        = normalize(self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;    
+     proj.velocity        = normalize(self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
      proj.flags           = FL_PROJECTILE;
      proj.enemy           = self.enemy;
      proj.totalfrags      = _death;
          proj.flags |= FL_NOTARGET;
  
      CSQCProjectile(proj, _cli_anim, _proj_type, _cull);
-     
      return proj;
  }
  
@@@ -241,8 -241,8 +241,8 @@@ void turret_do_updates(entity t_turret
      }
      else*/
          tracebox(self.tur_shotorg, '-1 -1 -1','1 1 1', self.tur_shotorg + (self.tur_shotdir_updated * self.tur_dist_aimpos), MOVE_NORMAL,self);
-       
-       self.tur_dist_impact_to_aimpos = vlen(trace_endpos - self.tur_aimpos) - (vlen(self.enemy.maxs - self.enemy.mins) * 0.5);                
+       self.tur_dist_impact_to_aimpos = vlen(trace_endpos - self.tur_aimpos) - (vlen(self.enemy.maxs - self.enemy.mins) * 0.5);
        self.tur_impactent             = trace_ent;
        self.tur_impacttime            = vlen(self.tur_shotorg - trace_endpos) / self.shot_speed;
  
@@@ -328,11 -328,11 +328,11 @@@ void turret_stdproc_track(
      vector v1, v2;
      v1 = self.tur_head.angles;
      v2 = self.tur_head.avelocity;
-     
      if (self.track_flags == TFL_TRACK_NO)
          return;
  
-     if not (self.active)
+     if (!self.active)
          target_angle = self.idle_aim - ('1 0 0' * self.aim_maxpitch);
      else if (self.enemy == world)
      {
      }
      else
      {
-         target_angle = vectoangles(normalize(self.tur_aimpos - self.tur_shotorg)); 
+         target_angle = vectoangles(normalize(self.tur_aimpos - self.tur_shotorg));
      }
-     
      self.tur_head.angles_x = anglemods(self.tur_head.angles_x);
      self.tur_head.angles_y = anglemods(self.tur_head.angles_y);
  
      // Find the diffrence between where we currently aim and where we want to aim
      //move_angle = target_angle - (self.angles + self.tur_head.angles);
      //move_angle = shortangle_vxy(move_angle,(self.angles + self.tur_head.angles));
-     
-     move_angle = AnglesTransform_ToAngles(AnglesTransform_LeftDivide(AnglesTransform_FromAngles(self.angles), AnglesTransform_FromAngles(target_angle))) - self.tur_head.angles; 
+     move_angle = AnglesTransform_ToAngles(AnglesTransform_LeftDivide(AnglesTransform_FromAngles(self.angles), AnglesTransform_FromAngles(target_angle))) - self.tur_head.angles;
      move_angle = shortangle_vxy(move_angle, self.tur_head.angles);
  
      switch(self.track_type)
                  if(self.tur_head.angles_y  < -self.aim_maxrot)
                      self.tur_head.angles_y = self.aim_maxrot;
              }
-             
              // CSQC
              self.SendFlags  |= TNSF_ANG;
-             
              return;
  
          case TFL_TRACKTYPE_FLUIDINERTIA:
          {
              self.tur_head.avelocity_x = 0;
              self.tur_head.angles_x = self.aim_maxpitch;
-             
              self.SendFlags  |= TNSF_ANG;
          }
-         
          if((self.tur_head.angles_x + self.tur_head.avelocity_x * self.ticrate) < -self.aim_maxpitch)
          {
              self.tur_head.avelocity_x = 0;
              self.tur_head.angles_x = -self.aim_maxpitch;
-                         
              self.SendFlags  |= TNSF_ANG;
          }
      }
          {
              self.tur_head.avelocity_y = 0;
              self.tur_head.angles_y = self.aim_maxrot;
-             
              self.SendFlags  |= TNSF_ANG;
          }
  
          {
              self.tur_head.avelocity_y = 0;
              self.tur_head.angles_y = -self.aim_maxrot;
-             
              self.SendFlags  |= TNSF_ANG;
          }
      }
-         
      self.SendFlags  |= TNSF_AVEL;
-     
      // Force a angle update every 10'th frame
      self.turret_framecounter += 1;
      if(self.turret_framecounter >= 10)
-     {        
+     {
          self.SendFlags |= TNSF_ANG;
          self.turret_framecounter = 0;
-     }            
+     }
  }
  
  
  float turret_stdproc_firecheck()
  {
      // This one just dont care =)
-     if (self.firecheck_flags & TFL_FIRECHECK_NO) 
+     if (self.firecheck_flags & TFL_FIRECHECK_NO)
          return 1;
  
      if (self.enemy == world)
      if (self.shoot_flags & TFL_SHOOT_VOLLYALWAYS)
          if (self.volly_counter != self.shot_volly)
                        if(self.ammo >= self.shot_dmg)
-                               return 1;               
+                               return 1;
  
      // Lack of zombies makes shooting dead things unnecessary :P
      if (self.firecheck_flags & TFL_FIRECHECK_DEAD)
      if (self.firecheck_flags & TFL_FIRECHECK_OTHER_AMMO)
          if (self.enemy.ammo >= self.enemy.ammo_max)
              return 0;
-       
        // Target of opertunity?
        if(turret_validate_target(self, self.tur_impactent, self.target_validate_flags) > 0)
        {
                self.enemy = self.tur_impactent;
                return 1;
-       }                               
+       }
  
      if (self.firecheck_flags & TFL_FIRECHECK_DISTANCES)
      {
          // To close?
          if (self.tur_dist_aimpos < self.target_range_min)
-                       if(turret_validate_target(self, self.tur_impactent, self.target_validate_flags) > 0)                    
+                       if(turret_validate_target(self, self.tur_impactent, self.target_validate_flags) > 0)
                                return 1; // Target of opertunity?
-                       else 
-                               return 0;                               
+                       else
+                               return 0;
      }
  
      // Try to avoid FF?
  float turret_validate_target(entity e_turret, entity e_target, float validate_flags)
  {
      vector v_tmp;
-         
      //if(!validate_flags & TFL_TARGETSELECT_NOBUILTIN)
      //    return -0.5;
  
      if(e_target.owner == e_turret)
          return -0.5;
  
-     if not(checkpvs(e_target.origin, e_turret))
-         return -1;        
+     if (!checkpvs(e_target.origin, e_turret))
+         return -1;
  
-     if not (e_target)
+     if (!e_target)
          return -2;
  
        if(g_onslaught)
          return -5;
  
      // Cant touch this
-     if(e_target.vehicle_flags & VHF_ISVEHICLE)    
+     if(e_target.vehicle_flags & VHF_ISVEHICLE)
      {
          if (e_target.vehicle_health <= 0)
              return -6;
      // player
      if (IS_CLIENT(e_target))
      {
-         if not (validate_flags & TFL_TARGETSELECT_PLAYERS)
+         if (!(validate_flags & TFL_TARGETSELECT_PLAYERS))
              return -7;
  
          if (e_target.deadflag != DEAD_NO)
  
      // Missile
      if (e_target.flags & FL_PROJECTILE)
-         if not (validate_flags & TFL_TARGETSELECT_MISSILES)
+         if (!(validate_flags & TFL_TARGETSELECT_MISSILES))
              return -10;
  
      if (validate_flags & TFL_TARGETSELECT_MISSILESONLY)
-         if not (e_target.flags & FL_PROJECTILE)
+         if (!(e_target.flags & FL_PROJECTILE))
              return -10.5;
  
      // Team check
@@@ -729,7 -729,7 +729,7 @@@ entity turret_select_target(
      e = findradius(self.origin, self.target_range);
  
      // Nothing to aim at?
-     if (!e) 
+     if (!e)
                return world;
  
      while (e)
@@@ -759,7 -759,7 +759,7 @@@ void turret_think(
      entity e;
  
      self.nextthink = time + self.ticrate;
-     
      // ONS uses somewhat backwards linking.
      if (teamplay)
      {
  #endif
  
      // Handle ammo
-     if not (self.spawnflags & TSF_NO_AMMO_REGEN)
+     if (!(self.spawnflags & TSF_NO_AMMO_REGEN))
      if (self.ammo < self.ammo_max)
          self.ammo = min(self.ammo + self.ammo_recharge, self.ammo_max);
-                       
      // Inactive turrets needs to run the think loop,
      // So they can handle animation and wake up if need be.
-     if not (self.active)
+     if (!self.active)
      {
          turret_stdproc_track();
          return;
          // This one is doing something.. oddball. assume its handles what needs to be handled.
  
          // Predict?
-         if not(self.aim_flags & TFL_AIM_NO)
+         if (!(self.aim_flags & TFL_AIM_NO))
              self.tur_aimpos = turret_stdproc_aim_generic();
  
          // Turn & pitch?
-         if not(self.track_flags & TFL_TRACK_NO)
+         if (!(self.track_flags & TFL_TRACK_NO))
              turret_stdproc_track();
  
          turret_do_updates(self);
              if(self.volly_counter != self.shot_volly)
              {
                  // Predict or whatnot
-                 if not(self.aim_flags & TFL_AIM_NO)
+                 if (!(self.aim_flags & TFL_AIM_NO))
                      self.tur_aimpos = turret_stdproc_aim_generic();
  
                  // Turn & pitch
-                 if not(self.track_flags & TFL_TRACK_NO)
+                 if (!(self.track_flags & TFL_TRACK_NO))
                      turret_stdproc_track();
  
                  turret_do_updates(self);
          if (self.enemy == world)
          {
              // Turn & pitch
-             if not(self.track_flags & TFL_TRACK_NO)
+             if (!(self.track_flags & TFL_TRACK_NO))
                  turret_stdproc_track();
  
              // do any per-turret stuff
              self.lip = time + autocvar_g_turrets_aimidle_delay; // Keep track of the last time we had a target.
  
          // Predict?
-         if not(self.aim_flags & TFL_AIM_NO)
+         if (!(self.aim_flags & TFL_AIM_NO))
              self.tur_aimpos = turret_stdproc_aim_generic();
  
          // Turn & pitch?
-         if not(self.track_flags & TFL_TRACK_NO)
+         if (!(self.track_flags & TFL_TRACK_NO))
              turret_stdproc_track();
  
          turret_do_updates(self);
@@@ -1021,24 -1021,24 +1021,24 @@@ float turret_stdproc_init (string cvar_
      // Are turrets allowed?
      if (autocvar_g_turrets == 0)
          return 0;
-     
      if(_turret_type < 1 || _turret_type > TID_LAST)
      {
          dprint("Invalid / Unkown turret type\"", ftos(_turret_type), "\", aborting!\n");
          return 0;
-     }    
+     }
      self.turret_type = _turret_type;
-     
      e = find(world, classname, "turret_manager");
-     if not (e)
+     if (!e)
      {
          e = spawn();
          e.classname = "turret_manager";
          e.think = turrets_manager_think;
          e.nextthink = time + 2;
      }
-     
-     if not (self.spawnflags & TSF_SUSPENDED)
+     if (!(self.spawnflags & TSF_SUSPENDED))
          builtin_droptofloor(); // why can't we use regular droptofloor here?
  
      // Terrainbase spawnflag. This puts a enlongated model
      load_unit_settings(self, self.cvar_basename, 0);
  
      self.effects = EF_NODRAW;
-     
      // Handle turret teams.
-     if not (teamplay)
+     if (!teamplay)
                self.team = MAX_SHOT_DISTANCE; // Group all turrets into the same team, so they dont kill eachother.
        else if(g_onslaught && self.targetname)
        {
      * if it hits a glitch in my logic :P so try to set as mutch
      * as possible beforehand.
      */
-     if not(self.ticrate)
-     {        
+     if (!self.ticrate)
+     {
          if (self.turrcaps_flags & TFL_TURRCAPS_SUPPORT)
              self.ticrate = 0.2;     // Support units generaly dont need to have a high speed ai-loop
          else
              self.ticrate = 0.1;     // 10 fps for normal turrets
      }
-     
      self.ticrate = bound(sys_frametime, self.ticrate, 60);  // keep it sane
  
  // General stuff
      if (self.netname == "")
          self.netname = self.classname;
  
-     if not (self.respawntime)
+     if (!self.respawntime)
          self.respawntime = 60;
      self.respawntime = max(-1, self.respawntime);
  
-     if not (self.health)
+     if (!self.health)
          self.health = 1000;
      self.tur_health = max(1, self.health);
  
-     if not (self.turrcaps_flags)
+     if (!self.turrcaps_flags)
          self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL;
  
-     if not (self.damage_flags)
+     if (!self.damage_flags)
          self.damage_flags = TFL_DMG_YES | TFL_DMG_RETALIATE | TFL_DMG_AIMSHAKE;
  
  // Shot stuff.
-     if not (self.shot_refire)
+     if (!self.shot_refire)
          self.shot_refire = 1;
      self.shot_refire = bound(0.01, self.shot_refire, 9999);
  
-     if not (self.shot_dmg)
+     if (!self.shot_dmg)
          self.shot_dmg  = self.shot_refire * 50;
      self.shot_dmg = max(1, self.shot_dmg);
  
-     if not (self.shot_radius)
+     if (!self.shot_radius)
          self.shot_radius = self.shot_dmg * 0.5;
      self.shot_radius = max(1, self.shot_radius);
  
-     if not (self.shot_speed)
+     if (!self.shot_speed)
          self.shot_speed = 2500;
      self.shot_speed = max(1, self.shot_speed);
  
-     if not (self.shot_spread)
+     if (!self.shot_spread)
          self.shot_spread = 0.0125;
      self.shot_spread = bound(0.0001, self.shot_spread, 500);
  
-     if not (self.shot_force)
+     if (!self.shot_force)
          self.shot_force = self.shot_dmg * 0.5 + self.shot_radius * 0.5;
      self.shot_force = bound(0.001, self.shot_force, 5000);
  
-     if not (self.shot_volly)
+     if (!self.shot_volly)
          self.shot_volly = 1;
      self.shot_volly = bound(1, self.shot_volly, floor(self.ammo_max / self.shot_dmg));
  
-     if not (self.shot_volly_refire)
+     if (!self.shot_volly_refire)
          self.shot_volly_refire = self.shot_refire * self.shot_volly;
      self.shot_volly_refire = bound(self.shot_refire, self.shot_volly_refire, 60);
  
-     if not (self.firecheck_flags)
+     if (!self.firecheck_flags)
          self.firecheck_flags = TFL_FIRECHECK_DEAD | TFL_FIRECHECK_DISTANCES |
                                 TFL_FIRECHECK_LOS | TFL_FIRECHECK_AIMDIST | TFL_FIRECHECK_TEAMCECK |
                                 TFL_FIRECHECK_OWM_AMMO | TFL_FIRECHECK_REFIRE;
  
  // Range stuff.
-     if not (self.target_range)
+     if (!self.target_range)
          self.target_range = self.shot_speed * 0.5;
      self.target_range = bound(0, self.target_range, MAX_SHOT_DISTANCE);
  
-     if not (self.target_range_min)
+     if (!self.target_range_min)
          self.target_range_min = self.shot_radius * 2;
      self.target_range_min = bound(0, self.target_range_min, MAX_SHOT_DISTANCE);
  
-     if not (self.target_range_optimal)
+     if (!self.target_range_optimal)
          self.target_range_optimal = self.target_range * 0.5;
      self.target_range_optimal = bound(0, self.target_range_optimal, MAX_SHOT_DISTANCE);
  
  
  // Aim stuff.
-     if not (self.aim_maxrot)
+     if (!self.aim_maxrot)
          self.aim_maxrot = 90;
      self.aim_maxrot = bound(0, self.aim_maxrot, 360);
  
-     if not (self.aim_maxpitch)
+     if (!self.aim_maxpitch)
          self.aim_maxpitch = 20;
      self.aim_maxpitch = bound(0, self.aim_maxpitch, 90);
  
-     if not (self.aim_speed)
+     if (!self.aim_speed)
          self.aim_speed = 36;
      self.aim_speed  = bound(0.1, self.aim_speed, 1000);
  
-     if not (self.aim_firetolerance_dist)
+     if (!self.aim_firetolerance_dist)
          self.aim_firetolerance_dist  = 5 + (self.shot_radius * 2);
      self.aim_firetolerance_dist = bound(0.1, self.aim_firetolerance_dist, MAX_SHOT_DISTANCE);
  
-     if not (self.aim_flags)
+     if (!self.aim_flags)
      {
          self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
          if(self.turrcaps_flags & TFL_TURRCAPS_RADIUSDMG)
              self.aim_flags |= TFL_AIM_GROUNDGROUND;
      }
  
-     if not (self.track_type)
+     if (!self.track_type)
          self.track_type = TFL_TRACKTYPE_STEPMOTOR;
  
      if (self.track_type != TFL_TRACKTYPE_STEPMOTOR)
          // Fluid / Ineria mode. Looks mutch nicer.
          // Can reduce aim preformance alot, needs a bit diffrent aimspeed
  
-         if not (self.aim_speed)
+         if (!self.aim_speed)
              self.aim_speed = 180;
          self.aim_speed = bound(0.1, self.aim_speed, 1000);
  
-         if not (self.track_accel_pitch)
+         if (!self.track_accel_pitch)
              self.track_accel_pitch = 0.5;
  
-         if not (self.track_accel_rot)
+         if (!self.track_accel_rot)
              self.track_accel_rot   = 0.5;
  
-         if not (self.track_blendrate)
+         if (!self.track_blendrate)
              self.track_blendrate   = 0.35;
      }
  
  
  
  // Target selection stuff.
-     if not (self.target_select_rangebias)
+     if (!self.target_select_rangebias)
          self.target_select_rangebias = 1;
      self.target_select_rangebias = bound(-10, self.target_select_rangebias, 10);
  
-     if not (self.target_select_samebias)
+     if (!self.target_select_samebias)
          self.target_select_samebias = 1;
      self.target_select_samebias = bound(-10, self.target_select_samebias, 10);
  
-     if not (self.target_select_anglebias)
+     if (!self.target_select_anglebias)
          self.target_select_anglebias = 1;
      self.target_select_anglebias = bound(-10, self.target_select_anglebias, 10);
  
-     if not (self.target_select_missilebias)
+     if (!self.target_select_missilebias)
          self.target_select_missilebias = -10;
  
      self.target_select_missilebias = bound(-10, self.target_select_missilebias, 10);
      self.target_select_playerbias = bound(-10, self.target_select_playerbias, 10);
  
-     if not (self.target_select_flags)
+     if (!self.target_select_flags)
      {
              self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_TEAMCHECK
                                       | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_ANGLELIMITS;
      self.target_validate_flags = self.target_select_flags;
  
  // Ammo stuff
-     if not (self.ammo_max)
+     if (!self.ammo_max)
          self.ammo_max = self.shot_dmg * 10;
      self.ammo_max = max(self.shot_dmg, self.ammo_max);
  
-     if not (self.ammo)
+     if (!self.ammo)
          self.ammo = self.shot_dmg * 5;
      self.ammo = bound(0,self.ammo, self.ammo_max);
  
-     if not (self.ammo_recharge)
+     if (!self.ammo_recharge)
          self.ammo_recharge = self.shot_dmg * 0.5;
      self.ammo_recharge = max(0 ,self.ammo_recharge);
  
      // Convert the recharge from X per sec to X per ticrate
      self.ammo_recharge = self.ammo_recharge * self.ticrate;
  
-     if not (self.ammo_flags)
+     if (!self.ammo_flags)
          self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE;
  
  // Damage stuff
      if(self.spawnflags & TSL_NO_RESPAWN)
-         if not (self.damage_flags & TFL_DMG_DEATH_NORESPAWN)
+         if (!(self.damage_flags & TFL_DMG_DEATH_NORESPAWN))
              self.damage_flags |= TFL_DMG_DEATH_NORESPAWN;
  
  // Offsets & origins
      if (!self.tur_shotorg)   self.tur_shotorg = '50 0 50';
-     
      if (!self.health)
          self.health = 150;
  
      self.tur_head.movetype   = MOVETYPE_NOCLIP;
  
      // Defend mode?
-     if not (self.tur_defend)
+     if (!self.tur_defend)
      if (self.target != "")
      {
          self.tur_defend = find(world, targetname, self.target);
      self.turret_firecheckfunc   = turret_stdproc_firecheck;
      self.turret_firefunc        = turret_stdproc_fire;
      self.event_damage           = turret_stdproc_damage;
-     
      if (self.turrcaps_flags & TFL_TURRCAPS_SUPPORT)
          self.turret_score_target    = turret_stdproc_targetscore_support;
      else
          activator = ee;
          self.use();
      }
-     
        turret_link();
-       turret_stdproc_respawn();           
+       turret_stdproc_respawn();
      turret_tag_fire_update();
-     
      return 1;
  }
  
index 5f83a304f7187a7ddb40340aea2720ad07152cce,8a01a9752a9f8f4b0cc1d1aad6d7c33a4a29986f..3c9e55863f7698d423ede49d0664115bc7fd660c
@@@ -7,14 -7,14 +7,14 @@@ void turret_flac_projectile_think_explo
      if(self.enemy != world)
      if(vlen(self.origin - self.enemy.origin) < self.owner.shot_radius * 3)
          setorigin(self,self.enemy.origin + randomvec() * self.owner.shot_radius);
-             
  #ifdef TURRET_DEBUG
      float d;
 -    d = RadiusDamage (self, self.owner, self.owner.shot_dmg, self.owner.shot_dmg, self.owner.shot_radius, self, self.owner.shot_force, self.totalfrags, world);
 +    d = RadiusDamage (self, self.owner, self.owner.shot_dmg, self.owner.shot_dmg, self.owner.shot_radius, self, world, self.owner.shot_force, self.totalfrags, world);
      self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d;
      self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
  #else
 -    RadiusDamage (self, self.realowner, self.owner.shot_dmg, self.owner.shot_dmg, self.owner.shot_radius, self, self.owner.shot_force, self.totalfrags, world);
 +    RadiusDamage (self, self.realowner, self.owner.shot_dmg, self.owner.shot_dmg, self.owner.shot_radius, self, world, self.owner.shot_force, self.totalfrags, world);
  #endif
      remove(self);
  }
@@@ -24,28 -24,28 +24,28 @@@ void turret_flac_attack(
      entity proj;
  
      turret_tag_fire_update();
-     
-     proj = turret_projectile("weapons/hagar_fire.wav", 5, 0, DEATH_TURRET_FLAC, PROJECTILE_HAGAR, TRUE, TRUE);    
+     proj = turret_projectile("weapons/hagar_fire.wav", 5, 0, DEATH_TURRET_FLAC, PROJECTILE_HAGAR, TRUE, TRUE);
      pointparticles(particleeffectnum("laser_muzzleflash"), self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
      proj.think      = turret_flac_projectile_think_explode;
      proj.nextthink  = time + self.tur_impacttime + (random() * 0.01 - random() * 0.01);
      proj.missile_flags = MIF_SPLASH | MIF_PROXY;
-     
      self.tur_head.frame = self.tur_head.frame + 1;
-     if (self.tur_head.frame >= 4) 
+     if (self.tur_head.frame >= 4)
          self.tur_head.frame = 0;
  
  }
  
  void turret_flac_dinit()
  {
-     if (self.netname == "")      
+     if (self.netname == "")
          self.netname  = "FLAC Cannon";
  
      self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_FASTPROJ | TFL_TURRCAPS_MISSILEKILL;
      self.ammo_flags     = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
      self.aim_flags      = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
-     
      if (turret_stdproc_init("flac_std", "models/turrets/base.md3", "models/turrets/flac.md3", TID_FLAC) == 0)
      {
          remove(self);
@@@ -55,7 -55,7 +55,7 @@@
  
      self.damage_flags |= TFL_DMG_HEADSHAKE;
      self.target_select_flags |= TFL_TARGETSELECT_NOTURRETS | TFL_TARGETSELECT_MISSILESONLY;
-     
      // Our fire routine
      self.turret_firefunc  = turret_flac_attack;
  
index 8137a9dbcb884f2e20fd471cdd2fac08e8b2bce0,46c46d7f8f04068e7dba48f4b5f1e59320388385..04d9e186ef3b266ab601da93b7910a5e794037d4
@@@ -5,7 -5,7 +5,7 @@@ void turret_machinegun_attack()
  //.float bulletcounter;
  void turret_machinegun_attack()
  {
-     fireBallisticBullet (self.tur_shotorg, self.tur_shotdir_updated,self.shot_spread, self.shot_speed, 5, self.shot_dmg, self.shot_force, DEATH_TURRET_MACHINEGUN, 0, 1, WEP_CVAR(uzi, bulletconstant)); // WEAPONTODO
 -    fireBallisticBullet (self.tur_shotorg, self.tur_shotdir_updated,self.shot_spread, self.shot_speed, 5, self.shot_dmg, self.shot_force, DEATH_TURRET_MACHINEGUN, 0, autocvar_g_balance_uzi_bulletconstant);
++    fireBallisticBullet (self.tur_shotorg, self.tur_shotdir_updated,self.shot_spread, self.shot_speed, 5, self.shot_dmg, self.shot_force, DEATH_TURRET_MACHINEGUN, 0, WEP_CVAR(uzi, bulletconstant)); // WEAPONTODO
      endFireBallisticBullet();
  
      UziFlash();
@@@ -20,9 -20,8 +20,8 @@@ void turret_machinegun_std_init(
      self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
      self.turrcaps_flags = TFL_TURRCAPS_PLAYERKILL;
      self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
-     
-       if not (autocvar_g_antilag_bullets)
-               self.turrcaps_flags |= TFL_TURRCAPS_HITSCAN;
+     self.turrcaps_flags |= TFL_TURRCAPS_HITSCAN;
  
      if (turret_stdproc_init("machinegun_std", "models/turrets/base.md3", "models/turrets/machinegun.md3", TID_MACHINEGUN) == 0)
      {
index 30a4c60ebc9dd95e823b82ede89bf6836605074f,1ce59dd278bfb4e3bc2c5d84a9584bde94b212b2..2da91aad05c207fe9481455877461f9ec868329d
@@@ -29,12 -29,12 +29,12 @@@ void walker_meele_do_dmg(
  {
      vector where;
      entity e;
-     
      makevectors(self.angles);
      where = self.origin + v_forward * 128;
  
      e = findradius(where,32);
-     while (e) 
+     while (e)
      {
          if (turret_validate_target(self, e, self.target_validate_flags))
              if (e != self && e.owner != self)
@@@ -51,8 -51,7 +51,8 @@@ void walker_setnoanim(
  }
  void walker_rocket_explode()
  {
 -    RadiusDamage (self, self.owner, autocvar_g_turrets_unit_walker_std_rocket_dmg, 0, autocvar_g_turrets_unit_walker_std_rocket_radius, self, autocvar_g_turrets_unit_walker_std_rocket_force, DEATH_TURRET_WALK_ROCKET, world);
 +    RadiusDamage (self, self.owner, autocvar_g_turrets_unit_walker_std_rocket_dmg, 0, autocvar_g_turrets_unit_walker_std_rocket_radius, self, world, autocvar_g_turrets_unit_walker_std_rocket_force, DEATH_TURRET_WALK_ROCKET, world);
 +
      remove (self);
  }
  
@@@ -60,7 -59,7 +60,7 @@@ void walker_rocket_damage (entity infli
  {
      self.health = self.health - damage;
      self.velocity = self.velocity + vforce;
-     
      if (self.health <= 0)
          W_PrepareExplosionByDamage(self.owner, walker_rocket_explode);
  }
@@@ -179,7 -178,7 +179,7 @@@ void walker_rocket_loop(
  void walker_fire_rocket(vector org)
  {
      entity rocket;
-  
      fixedmakevectors(self.angles);
  
      te_explosion (org);
      rocket.tur_shotorg        = randomvec() * 512;
      rocket.cnt                = time + 1;
      rocket.enemy              = self.enemy;
-     
      if (random() < 0.01)
          rocket.think          = walker_rocket_loop;
      else
      rocket.solid              = SOLID_BBOX;
      rocket.tur_health         = time + 9;
      rocket.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_HEAT;
-     
      CSQCProjectile(rocket, FALSE, PROJECTILE_ROCKET, FALSE); // no culling, has fly sound
  }
  
@@@ -249,7 -248,7 +249,7 @@@ void walker_move_to(vector _target, flo
      if(self.enemy)
      {
          self.enemy_last_loc = _target;
-         self.enemy_last_time = time;        
+         self.enemy_last_time = time;
      }
  }
  
@@@ -288,12 -287,12 +288,12 @@@ void walker_move_path(
      walker_move_to(self.moveto, 0);
  
  #else
-     if (vlen(self.origin - self.pathcurrent.origin) < 64)    
+     if (vlen(self.origin - self.pathcurrent.origin) < 64)
          self.pathcurrent = self.pathcurrent.enemy;
-     
      if(!self.pathcurrent)
          return;
-     
      self.moveto = self.pathcurrent.origin;
      self.steerto = steerlib_attract2(self.moveto, 0.5, 500, 0.95);
      walker_move_to(self.moveto, 0);
@@@ -317,35 -316,35 +317,35 @@@ void walker_postthink(
              {
                  if(vlen(self.origin - self.enemy_last_loc) < 128 || time - self.enemy_last_time > 10)
                      self.enemy_last_time = 0;
-                 else                
+                 else
                      walker_move_to(self.enemy_last_loc, 0);
              }
              else
-             {        
+             {
                  if(self.animflag != ANIM_NO)
-                 {                    
+                 {
                      traceline(self.origin + '0 0 64', self.origin + '0 0 64' + v_forward * 128, MOVE_NORMAL, self);
-                     
                      if(trace_fraction != 1.0)
                          self.tur_head.idletime = -1337;
                      else
                      {
-                         traceline(trace_endpos, trace_endpos - '0 0 256', MOVE_NORMAL, self);            
+                         traceline(trace_endpos, trace_endpos - '0 0 256', MOVE_NORMAL, self);
                          if(trace_fraction == 1.0)
                              self.tur_head.idletime = -1337;
                      }
-                     
                      if(self.tur_head.idletime == -1337)
                      {
-                         self.moveto = self.origin + randomvec() * 256;        
+                         self.moveto = self.origin + randomvec() * 256;
                          self.tur_head.idletime = 0;
                      }
  
                      self.moveto = self.moveto * 0.9 + ((self.origin + v_forward * 500) + randomvec() * 400) * 0.1;
-                     self.moveto_z = self.origin_z + 64;            
+                     self.moveto_z = self.origin_z + 64;
                      walker_move_to(self.moveto, 0);
-                 }         
-                 
+                 }
                  if(self.idletime < time)
                  {
                      if(random() < 0.5 || !(self.spawnflags & TSL_ROAM))
                      {
                          self.animflag = ANIM_WALK;
                          self.idletime = time + 4 + random() * 2;
-                         self.moveto = self.origin + randomvec() * 256;        
+                         self.moveto = self.origin + randomvec() * 256;
                          self.tur_head.moveto = self.moveto;
                          self.tur_head.idletime = 0;
                      }
                  }
-             }            
+             }
          }
      }
      else
          if (self.tur_dist_enemy < autocvar_g_turrets_unit_walker_std_meele_range && self.animflag != ANIM_MEELE)
          {
              vector wish_angle;
-             
-             wish_angle = angleofs(self, self.enemy);    
+             wish_angle = angleofs(self, self.enemy);
              if (self.animflag != ANIM_SWIM)
              if (fabs(wish_angle_y) < 15)
              {
              }
          }
          else if (self.tur_head.attack_finished_single < time)
-         {            
+         {
              if(self.tur_head.shot_volly)
              {
                  self.animflag = ANIM_NO;
-                 
                  self.tur_head.shot_volly = self.tur_head.shot_volly -1;
                  if(self.tur_head.shot_volly == 0)
                      self.tur_head.attack_finished_single = time + autocvar_g_turrets_unit_walker_std_rocket_refire;
                  else
                      self.tur_head.attack_finished_single = time + 0.2;
-                 
                  if(self.tur_head.shot_volly > 1)
                      walker_fire_rocket(gettaginfo(self, gettagindex(self, "tag_rocket01")));
                  else
              }
              else
              {
-                 if (self.tur_dist_enemy > autocvar_g_turrets_unit_walker_std_rockets_range_min)        
+                 if (self.tur_dist_enemy > autocvar_g_turrets_unit_walker_std_rockets_range_min)
                  if (self.tur_dist_enemy < autocvar_g_turrets_unit_walker_std_rockets_range)
                      self.tur_head.shot_volly = 4;
              }
          }
          else
-         {            
+         {
              if (self.animflag != ANIM_MEELE)
                  walker_move_to(self.enemy.origin, self.tur_dist_enemy);
          }
  
          real_angle = vectoangles(self.steerto) - self.angles;
          vz         = self.velocity_z;
-             
          switch (self.animflag)
          {
              case ANIM_NO:
              case ANIM_PAIN:
                  if(self.frame != ANIM_PAIN)
                      defer(0.25, walker_setnoanim);
-                 
                  break;
  
              case ANIM_MEELE:
              case ANIM_SWIM:
                  turny = autocvar_g_turrets_unit_walker_turn_swim;
                  turnx = autocvar_g_turrets_unit_walker_turn_swim;
-                 
                  self.angles_x += bound(-10, shortangle_f(real_angle_x, self.angles_x), 10);
                  movelib_move_simple(v_forward, autocvar_g_turrets_unit_walker_speed_swim, 0.3);
                  vz = self.velocity_z + sin(time * 4) * 8;
                  movelib_move_simple(v_forward ,autocvar_g_turrets_unit_walker_speed_roam, 0.5);
                  break;
          }
-             
          if(turny)
-         {        
+         {
              turny = bound( turny * -1, shortangle_f(real_angle_y, self.angles_y), turny );
              self.angles_y += turny;
          }
  
          if(turnx)
-         {        
+         {
              turnx = bound( turnx * -1, shortangle_f(real_angle_x, self.angles_x), turnx );
              self.angles_x += turnx;
          }
  
-         self.velocity_z = vz;        
+         self.velocity_z = vz;
      }
  
-     
      if(self.origin != self.oldorigin)
          self.SendFlags |= TNSF_MOVE;
-     
      self.oldorigin = self.origin;
      turrets_setframe(self.animflag, FALSE);
  }
  void walker_attack()
  {
      sound (self, CH_WEAPON_A, "weapons/uzi_fire.wav", VOL_BASE, ATTEN_NORM);
-     fireBallisticBullet (self.tur_shotorg, self.tur_shotdir_updated, self.shot_spread, self.shot_speed, 5, self.shot_dmg, self.shot_force, DEATH_TURRET_WALK_GUN, 0, 1, WEP_CVAR(uzi, bulletconstant)); // WEAPONTODO
 -    fireBallisticBullet (self.tur_shotorg, self.tur_shotdir_updated, self.shot_spread, self.shot_speed, 5, self.shot_dmg, self.shot_force, DEATH_TURRET_WALK_GUN, 0, autocvar_g_balance_uzi_bulletconstant);
++    fireBallisticBullet (self.tur_shotorg, self.tur_shotdir_updated, self.shot_spread, self.shot_speed, 5, self.shot_dmg, self.shot_force, DEATH_TURRET_WALK_GUN, 0, WEP_CVAR(uzi, bulletconstant)); // WEAPONTODO
      endFireBallisticBullet();
      pointparticles(particleeffectnum("laser_muzzleflash"), self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
  }
@@@ -529,10 -528,10 +529,10 @@@ void walker_respawnhook(
      // Respawn is called & first spawn to, to set team. need to make sure we do not move the initial spawn.
      if(self.movetype != MOVETYPE_WALK)
                return;
-               
      setorigin(self, self.pos1);
      self.angles = self.pos2;
-     
      if (self.target != "")
      {
          e = find(world, targetname, self.target);
@@@ -575,10 -574,7 +575,7 @@@ void turret_walker_dinit(
      self.turrcaps_flags = TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MOVE ;
      self.aim_flags = TFL_AIM_LEAD;
  
-     if (autocvar_g_antilag_bullets)
-         self.turrcaps_flags |= TFL_TURRCAPS_HITSCAN;
-     else
-         self.aim_flags      |= TFL_AIM_SHOTTIMECOMPENSATE;
+     self.turrcaps_flags |= TFL_TURRCAPS_HITSCAN;
  
  
      self.turret_respawnhook = walker_respawnhook;
      self.damagedbycontents = TRUE;
      self.movetype   = MOVETYPE_WALK;
      self.solid      = SOLID_SLIDEBOX;
-     self.takedamage = DAMAGE_AIM;    
+     self.takedamage = DAMAGE_AIM;
      setorigin(self, self.origin);
      tracebox(self.origin + '0 0 128', self.mins, self.maxs, self.origin - '0 0 10000', MOVE_NORMAL, self);
      setorigin(self, trace_endpos + '0 0 4');
index 36a0a8e764715e8396156d3fdcd03d9243d88edd,bc5f03d8ae52f53d01bcdf33f51f6243974b98bd..986397c8965fd8b4bc23a810a7bd70f7dbf0cbc8
@@@ -97,12 -97,12 +97,12 @@@ float bumb_gunner_frame(
        self = vehic;
  
  
-       
-       
        vehic.solid = SOLID_NOT;
        //setorigin(gunner, vehic.origin);
        gunner.velocity = vehic.velocity;
-       
        float _in, _out;
        vehic.angles_x *= -1;
        makevectors(vehic.angles);
        {
                _in = autocvar_g_vehicle_bumblebee_cannon_turnlimit_out;
                _out = autocvar_g_vehicle_bumblebee_cannon_turnlimit_in;
-               setorigin(gunner, vehic.origin + v_up * -16 + v_forward * -16 + v_right * -128);                
+               setorigin(gunner, vehic.origin + v_up * -16 + v_forward * -16 + v_right * -128);
        }
-       
        crosshair_trace(gunner);
        vector _ct = trace_endpos;
        vector ad;
@@@ -225,7 -225,7 +225,7 @@@ void bumb_gunner_exit(float _exitflag
                WriteAngle(MSG_ONE, self.vehicle.angles_y);
                WriteAngle(MSG_ONE, 0);
        }
-       
        CSQCVehicleSetup(self, HUD_NORMAL);
        setsize(self, PL_MIN, PL_MAX);
  
  
        if(self == self.vehicle.owner.gunner1)
        {
-               self.vehicle.owner.gunner1 = world;             
+               self.vehicle.owner.gunner1 = world;
        }
        else if(self == self.vehicle.owner.gunner2)
        {
-               self.vehicle.owner.gunner2 = world;     
+               self.vehicle.owner.gunner2 = world;
                v_right *= -1;
-       }       
+       }
        else
                dprint("^1self != gunner1 or gunner2, this is a BIG PROBLEM, tell tZork this happend.\n");
-               
        vector spot = self.vehicle.owner.origin + + v_up * 128 + v_right * 300;
        spot = vehicles_findgoodexit(spot);
        //setorigin(self , spot);
@@@ -327,7 -327,7 +327,7 @@@ float bumb_gunner_enter(
        _gun.vehicle_hudmodel.viewmodelforclient = other;
  
        CSQCVehicleSetup(other, other.hud);
-       
      vh_player = other;
      vh_vehicle = _gun;
      MUTATOR_CALLHOOK(VehicleEnter);
  
  float vehicles_valid_pilot()
  {
-       if not(IS_PLAYER(other))
+       if (!IS_PLAYER(other))
                return FALSE;
  
        if(other.deadflag != DEAD_NO)
        if(other.vehicle != world)
                return FALSE;
  
-       if not(IS_REAL_CLIENT(other))
+       if (!IS_REAL_CLIENT(other))
                if(!autocvar_g_vehicles_allow_bots)
                        return FALSE;
  
@@@ -442,9 -442,9 +442,9 @@@ float bumb_pilot_frame(
  
        // Pitch
        ftmp = 0;
-       if(pilot.movement_x > 0 && vang_x < autocvar_g_vehicle_bumblebee_pitchlimit) 
+       if(pilot.movement_x > 0 && vang_x < autocvar_g_vehicle_bumblebee_pitchlimit)
                ftmp = 4;
-       else if(pilot.movement_x < 0 && vang_x > -autocvar_g_vehicle_bumblebee_pitchlimit) 
+       else if(pilot.movement_x < 0 && vang_x > -autocvar_g_vehicle_bumblebee_pitchlimit)
                ftmp = -8;
  
        newvel_x = bound(-autocvar_g_vehicle_bumblebee_pitchlimit, newvel_x , autocvar_g_vehicle_bumblebee_pitchlimit);
  
        vehic.velocity  += newvel * frametime;
        pilot.velocity = pilot.movement  = vehic.velocity;
-       
  
        if(autocvar_g_vehicle_bumblebee_healgun_locktime)
-       {               
+       {
                if(vehic.tur_head.lock_time < time || vehic.tur_head.enemy.deadflag)
                        vehic.tur_head.enemy = world;
  
                                }
                        }
                        else
-                       {            
+                       {
                                vehic.tur_head.enemy = trace_ent;
                                vehic.tur_head.lock_time = time + autocvar_g_vehicle_bumblebee_healgun_locktime;
                        }
                }
-                       
                if(vehic.tur_head.enemy)
                {
-                       trace_endpos = real_origin(vehic.tur_head.enemy);                       
-                       UpdateAuxiliaryXhair(pilot, trace_endpos, '0 0.75 0', 0);               
+                       trace_endpos = real_origin(vehic.tur_head.enemy);
+                       UpdateAuxiliaryXhair(pilot, trace_endpos, '0 0.75 0', 0);
                }
        }
-       
        vang = vehicle_aimturret(vehic, trace_endpos, self.gun3, "fire",
                                          autocvar_g_vehicle_bumblebee_raygun_pitchlimit_down * -1,  autocvar_g_vehicle_bumblebee_raygun_pitchlimit_up,
                                          autocvar_g_vehicle_bumblebee_raygun_turnlimit_sides * -1,  autocvar_g_vehicle_bumblebee_raygun_turnlimit_sides,  autocvar_g_vehicle_bumblebee_raygun_turnspeed);
        {
                vehic.gun3.enemy.realowner = pilot;
                vehic.gun3.enemy.effects &= ~EF_NODRAW;
-               
                vehic.gun3.enemy.hook_start = gettaginfo(vehic.gun3, gettagindex(vehic.gun3, "fire"));
                vehic.gun3.enemy.SendFlags |= BRG_START;
-               
                traceline(vehic.gun3.enemy.hook_start, vehic.gun3.enemy.hook_start + v_forward * autocvar_g_vehicle_bumblebee_raygun_range, MOVE_NORMAL, vehic);
-               
                if(trace_ent)
                {
                        if(autocvar_g_vehicle_bumblebee_raygun)
                                        }
                        }
                }
-               
                vehic.gun3.enemy.hook_end = trace_endpos;
                setorigin(vehic.gun3.enemy, trace_endpos);
                vehic.gun3.enemy.SendFlags |= BRG_END;
-               
                vehic.wait = time + 1;
        }
        else
                vehic.gun3.enemy = world;
        }
        */
-       
        VEHICLE_UPDATE_PLAYER(pilot, health, bumblebee);
        VEHICLE_UPDATE_PLAYER(pilot, energy, bumblebee);
  
  
        if(vehic.vehicle_flags & VHF_HASSHIELD)
                VEHICLE_UPDATE_PLAYER(pilot, shield, bumblebee);
-               
        vehic.angles_x *= -1;
        makevectors(vehic.angles);
        vehic.angles_x *= -1;
  void bumb_think()
  {
        self.movetype = MOVETYPE_TOSS;
-               
                //self.velocity = self.velocity * 0.5;
        self.angles_z *= 0.8;
        self.angles_x *= 0.8;
-       
        self.nextthink = time + 0.05;
-       
        if(!self.owner)
        {
-               entity oldself = self;          
+               entity oldself = self;
                if(self.gunner1)
                {
                        self = self.gunner1;
                        other = oldother;
                        return;
                }
-               
                if(self.gunner2)
                {
                        self = self.gunner2;
                        self.touch();
                        other = oldother;
                        return;
-               }               
+               }
        }
-       
  }
  
  void bumb_enter()
@@@ -672,19 -672,19 +672,19 @@@ void bumb_exit(float eject
        self.touch = vehicles_touch;
        self.think = bumb_think;
        self.nextthink = time;
-       
        if(!self.owner)
                return;
-       
        fixedmakevectors(self.angles);
        vector spot;
-       if(vlen(self.velocity) > autocvar_g_vehicle_bumblebee_speed_forward * 0.5)              
+       if(vlen(self.velocity) > autocvar_g_vehicle_bumblebee_speed_forward * 0.5)
                spot = self.origin + v_up * 128 + v_forward * 200;
        else
                spot = self.origin + v_up * 128 - v_forward * 200;
-       
        spot = vehicles_findgoodexit(spot);
-       
        // Hide beam
        if(self.gun3.enemy || !wasfreed(self.gun3.enemy)) {
                self.gun3.enemy.effects |= EF_NODRAW;
        self.owner.velocity = 0.75 * self.vehicle.velocity + normalize(spot - self.vehicle.origin) * 200;
        self.owner.velocity_z += 10;
        setorigin(self.owner, spot);
-       
        antilag_clear(self.owner);
      self.owner = world;
  }
@@@ -702,16 -702,16 +702,16 @@@ void bumb_blowup(
  {
        RadiusDamage(self, self.enemy, autocvar_g_vehicle_bumblebee_blowup_coredamage,
                                 autocvar_g_vehicle_bumblebee_blowup_edgedamage,
 -                               autocvar_g_vehicle_bumblebee_blowup_radius, self,
 +                               autocvar_g_vehicle_bumblebee_blowup_radius, self, world,
                                 autocvar_g_vehicle_bumblebee_blowup_forceintensity,
                                 DEATH_VH_BUMB_DEATH, world);
  
        sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM);
        pointparticles(particleeffectnum("explosion_large"), randomvec() * 80 + (self.origin + '0 0 100'), '0 0 0', 1);
-       
        if(self.owner.deadflag == DEAD_DYING)
                self.owner.deadflag = DEAD_DEAD;
-       
        remove(self);
  }
  
@@@ -732,11 -732,11 +732,11 @@@ void bumb_diethink(
  void bumb_die()
  {
        entity oldself = self;
-       
        // Hide beam
        if(self.gun3.enemy || !wasfreed(self.gun3.enemy))
                self.gun3.enemy.effects |= EF_NODRAW;
-       
        if(self.gunner1)
        {
                self = self.gunner1;
                _body.touch = bumb_blowup;
        else
                _body.touch = func_null;
-               
        _body.think = bumb_diethink;
        _body.nextthink = time;
        _body.wait = time + 2 + (random() * 8);
        _body.owner = self;
        _body.enemy = self.enemy;
-       
        pointparticles(particleeffectnum("explosion_medium"), findbetterlocation(self.origin, 16), '0 0 0', 1);
-       
        self.health                     = 0;
        self.event_damage       = func_null;
        self.solid                      = SOLID_CORPSE;
        self.nextthink          = 0;
  
        setorigin(self, self.pos1);
 -
  }
  
  void bumb_impact()
  {
      if(autocvar_g_vehicle_bumblebee_bouncepain_x)
-         vehilces_impact(autocvar_g_vehicle_bumblebee_bouncepain_x, 
-                                               autocvar_g_vehicle_bumblebee_bouncepain_y, 
+         vehilces_impact(autocvar_g_vehicle_bumblebee_bouncepain_x,
+                                               autocvar_g_vehicle_bumblebee_bouncepain_y,
                                                autocvar_g_vehicle_bumblebee_bouncepain_z);
  }
  
@@@ -860,14 -861,14 +860,14 @@@ void bumb_spawn(float _f
                setorigin(self.gun2.vehicle_viewport, '-85 0 50');
  
                self.scale = 1.5;
-               
                // Raygun beam
                if(self.gun3.enemy == world)
-               {                       
+               {
                        self.gun3.enemy = spawn();
                        Net_LinkEntity(self.gun3.enemy, TRUE, 0, bumble_raygun_send);
-                       self.gun3.enemy.SendFlags = BRG_SETUP;                  
-                       self.gun3.enemy.cnt = autocvar_g_vehicle_bumblebee_raygun;                      
+                       self.gun3.enemy.SendFlags = BRG_SETUP;
+                       self.gun3.enemy.cnt = autocvar_g_vehicle_bumblebee_raygun;
                        self.gun3.enemy.effects = EF_NODRAW | EF_LOWPRECISION;
                }
        }
        self.movetype           = MOVETYPE_TOSS;
        self.vehicle_impact = bumb_impact;
        self.damageforcescale = 0.025;
-       
        setorigin(self, self.origin + '0 0 25');
  }
  
@@@ -912,7 -913,7 +912,7 @@@ void spawnfunc_vehicle_bumblebee(
        if(autocvar_g_vehicle_bumblebee_health_regen)
                self.vehicle_flags |= VHF_HEALTHREGEN;
  
-       if not(vehicle_initialize(
+       if(!vehicle_initialize(
                           "Bumblebee", "models/vehicles/bumblebee_body.dpm",
                           "", "models/vehicles/spiderbot_cockpit.dpm", "", "", "tag_viewport",
                           HUD_BUMBLEBEE, BUMB_MIN, BUMB_MAX, FALSE,
@@@ -970,7 -971,7 +970,7 @@@ void bumble_raygun_draw(
  
        _len = vlen(self.origin - self.move_origin);
        _dir = normalize(self.move_origin - self.origin);
-       
        if(self.total_damages < time)
        {
                boxparticles(self.traileffect, self, self.origin, self.origin + _dir * -64, _dir * -_len , _dir * -_len, 1, PARTICLES_USEALPHA);
@@@ -1009,19 -1010,19 +1009,19 @@@ void bumble_raygun_read(float bIsNew
                self.cnt  = ReadByte();
                self.team = ReadByte();
                self.cnt  = ReadByte();
-               
                if(self.cnt)
                        self.colormod = '1 0 0';
                else
                        self.colormod = '0 1 0';
  
                self.traileffect = particleeffectnum("healray_muzzleflash");
-               self.lip = particleeffectnum("healray_impact");         
+               self.lip = particleeffectnum("healray_impact");
  
                self.draw = bumble_raygun_draw;
        }
-       
-       
        if(sf & BRG_START)
        {
                self.origin_x = ReadCoord();
index 6ed9a326a7e135f1917f2642e4898438c8524db0,ff54539027eaa8cebb27d1f45caa6101a11e6046..70d660c42a13d28f0d45eafe6a0517ecdc6a69bd
@@@ -150,7 -150,7 +150,7 @@@ void racer_rocket_groundhugger(
          return;
      }
  
-     if not (self.realowner.vehicle)
+     if (!self.realowner.vehicle)
      {
          UpdateCSQCProjectile(self);
          return;
@@@ -198,7 -198,7 +198,7 @@@ void racer_rocket_tracker(
          return;
      }
  
-     if not (self.realowner.vehicle)
+     if (!self.realowner.vehicle)
      {
          UpdateCSQCProjectile(self);
          return;
@@@ -492,7 -492,7 +492,7 @@@ void racer_exit(float eject
      self.movetype   = MOVETYPE_BOUNCE;
      sound (self.tur_head, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_VEHICLEENGINE, ATTEN_NORM);
  
-     if not (self.owner)
+     if (!self.owner)
          return;
  
        makevectors(self.angles);
@@@ -540,7 -540,7 +540,7 @@@ void racer_blowup(
  
      RadiusDamage (self, self.enemy, autocvar_g_vehicle_racer_blowup_coredamage,
                                        autocvar_g_vehicle_racer_blowup_edgedamage,
 -                                      autocvar_g_vehicle_racer_blowup_radius, world,
 +                                      autocvar_g_vehicle_racer_blowup_radius, world, world,
                                        autocvar_g_vehicle_racer_blowup_forceintensity,
                                        DEATH_VH_WAKI_DEATH, world);
  
@@@ -637,8 -637,8 +637,8 @@@ void spawnfunc_vehicle_racer(
      {
          remove(self);
          return;
-     }        
-     
+     }
      self.vehicle_flags |= VHF_DMGSHAKE;
      self.vehicle_flags |= VHF_DMGROLL;
  
      if(autocvar_g_vehicle_racer_health_regen)
          self.vehicle_flags |= VHF_HEALTHREGEN;
  
-     if not (vehicle_initialize(
+     if(!vehicle_initialize(
               "Wakizashi",
               "models/vehicles/wakizashi.dpm",
               "null", // we need this so tur_head is networked and usable for sounds
               racer_frame,
               racer_enter, racer_exit,
               racer_die,   racer_think,
-              TRUE, 
+              TRUE,
               autocvar_g_vehicle_racer_health,
               autocvar_g_vehicle_racer_shield))
      {
index 1b002c210fee9f9eccf620e9063f5503abce5c32,58a640e9cf8672afe3d0861b7c572f4ad4617bd9..50dc32bc688ccf4e0306186b6105d9288c188879
@@@ -92,7 -92,7 +92,7 @@@ void raptor_bomblet_boom(
  {
      RadiusDamage (self, self.realowner, autocvar_g_vehicle_raptor_bomblet_damage,
                                      autocvar_g_vehicle_raptor_bomblet_edgedamage,
 -                                    autocvar_g_vehicle_raptor_bomblet_radius, world,
 +                                    autocvar_g_vehicle_raptor_bomblet_radius, world, world,
                                      autocvar_g_vehicle_raptor_bomblet_force, DEATH_VH_RAPT_BOMB, world);
      remove(self);
  }
@@@ -208,15 -208,15 +208,15 @@@ void raptor_enter(
  
      if(self.owner.flagcarried)
         setorigin(self.owner.flagcarried, '-20 0 96');
-     
      CSQCVehicleSetup(self.owner, 0);
  }
  
  void raptor_land()
- {    
+ {
      float hgt;
-         
-     hgt = raptor_altitude(512);    
+     hgt = raptor_altitude(512);
      self.velocity = (self.velocity * 0.9) + ('0 0 -1800' * (hgt / 256) * sys_frametime);
      self.angles_x *= 0.95;
      self.angles_z *= 0.95;
@@@ -249,9 -249,9 +249,9 @@@ void raptor_exit(float eject
          self.nextthink  = time;
      }
  
-     if not (self.owner)
+     if (!self.owner)
          return;
-       
        makevectors(self.angles);
        if(eject)
        {
            self.owner.oldvelocity = self.owner.velocity;
            setorigin(self.owner , spot);
        }
-       
-       antilag_clear(self.owner);      
+       antilag_clear(self.owner);
      self.owner = world;
  }
  
  float raptor_takeoff()
  {
      entity player, raptor;
-     
      player = self;
      raptor = self.vehicle;
      self   = raptor;
      if(self.sound_nexttime < time)
-     {        
+     {
          self.sound_nexttime = time + 7.955812; //soundlength("vehicles/raptor_fly.wav");
          sound (self, CH_TRIGGER_SINGLE, "vehicles/raptor_speed.wav", VOL_VEHICLEENGINE, ATTEN_NORM);
-     }   
+     }
  
      // Takeoff sequense
      if(raptor.frame < 25)
@@@ -359,7 -359,7 +359,7 @@@ void raptor_flare_think(
              _missile.enemy = self;
          _missile = _missile.chain;
      }
-     
      if(self.tur_impacttime < time)
          remove(self);
  }
@@@ -369,7 -369,7 +369,7 @@@ float raptor_frame(
      entity player, raptor;
      float ftmp = 0;
      vector df;
-     
        if(intermission_running)
                return 1;
  
      vehicles_painframe();
      /*
      ftmp = vlen(self.velocity);
-     if(ftmp > autocvar_g_vehicle_raptor_speed_forward) 
+     if(ftmp > autocvar_g_vehicle_raptor_speed_forward)
          ftmp = 1;
-     else  
+     else
          ftmp = ftmp / autocvar_g_vehicle_raptor_speed_forward;
      */
-         
      if(self.sound_nexttime < time)
-     {        
-         self.sound_nexttime = time + 7.955812; 
+     {
+         self.sound_nexttime = time + 7.955812;
          //sound (self.tur_head, CH_TRIGGER_SINGLE, "vehicles/raptor_fly.wav", 1 - ftmp,   ATTEN_NORM );
-         sound (self, CH_TRIGGER_SINGLE, "vehicles/raptor_speed.wav", 1, ATTEN_NORM);        
+         sound (self, CH_TRIGGER_SINGLE, "vehicles/raptor_speed.wav", 1, ATTEN_NORM);
          self.wait = ftmp;
-     }        
+     }
      /*
      else if(fabs(ftmp - self.wait) > 0.2)
      {
          sound (self.tur_head, CH_TRIGGER_SINGLE, "", 1 - ftmp,   ATTEN_NORM );
-         sound (self, CH_TRIGGER_SINGLE, "", ftmp, ATTEN_NORM);        
+         sound (self, CH_TRIGGER_SINGLE, "", ftmp, ATTEN_NORM);
          self.wait = ftmp;
      }
      */
-     
      if(raptor.deadflag != DEAD_NO)
      {
          self = player;
      {
          if(raptor.gun1.lock_time < time || raptor.gun1.enemy.deadflag)
              raptor.gun1.enemy = world;
-     
          if(trace_ent)
          if(trace_ent.movetype)
          if(trace_ent.takedamage)
                  }
              }
              else
-             {            
+             {
                  raptor.gun1.enemy = trace_ent;
                  raptor.gun1.lock_time = time + 0.5;
              }
          }
-             
          if(raptor.gun1.enemy)
          {
              float i, distance, impact_time;
              vector _vel = raptor.gun1.enemy.velocity;
              if(raptor.gun1.enemy.movetype == MOVETYPE_WALK)
                  _vel_z *= 0.1;
-             
              if(autocvar_g_vehicle_raptor_cannon_predicttarget)
              {
                  ad = vf;
                      impact_time = distance / autocvar_g_vehicle_raptor_cannon_speed;
                      ad = vf + _vel * impact_time;
                  }
-                 trace_endpos = ad;                        
+                 trace_endpos = ad;
              }
              else
-                 trace_endpos = vf;                        
+                 trace_endpos = vf;
          }
      }
      else if(autocvar_g_vehicle_raptor_cannon_locktarget == 1)
      }
  
  
-     vehicle_aimturret(raptor, trace_endpos, raptor.gun1, "fire1", 
-                           autocvar_g_vehicle_raptor_cannon_pitchlimit_down * -1,  autocvar_g_vehicle_raptor_cannon_pitchlimit_up, 
+     vehicle_aimturret(raptor, trace_endpos, raptor.gun1, "fire1",
+                           autocvar_g_vehicle_raptor_cannon_pitchlimit_down * -1,  autocvar_g_vehicle_raptor_cannon_pitchlimit_up,
                            autocvar_g_vehicle_raptor_cannon_turnlimit * -1,  autocvar_g_vehicle_raptor_cannon_turnlimit,  autocvar_g_vehicle_raptor_cannon_turnspeed);
  
-     vehicle_aimturret(raptor, trace_endpos, raptor.gun2, "fire1", 
-                           autocvar_g_vehicle_raptor_cannon_pitchlimit_down * -1,  autocvar_g_vehicle_raptor_cannon_pitchlimit_up, 
+     vehicle_aimturret(raptor, trace_endpos, raptor.gun2, "fire1",
+                           autocvar_g_vehicle_raptor_cannon_pitchlimit_down * -1,  autocvar_g_vehicle_raptor_cannon_pitchlimit_up,
                            autocvar_g_vehicle_raptor_cannon_turnlimit * -1,  autocvar_g_vehicle_raptor_cannon_turnlimit,  autocvar_g_vehicle_raptor_cannon_turnspeed);
  
      /*
      traceline(ad, ad + v_forward * MAX_SHOT_DISTANCE, MOVE_NORMAL, raptor);
      UpdateAuxiliaryXhair(player, trace_endpos, '0 1 0', 0);
      */
-     
      if(player.BUTTON_ATCK)
      if(raptor.attack_finished_single <= time)
      if(raptor.vehicle_energy > autocvar_g_vehicle_raptor_cannon_cost)
              raptor_bombdrop();
              raptor.delay = time + autocvar_g_vehicle_raptor_bombs_refire;
              raptor.lip   = time;
-         }        
+         }
      }
      else
      {
          {
              float i;
              entity _flare;
-             
              for(i = 0; i < 3; ++i)
              {
              _flare = spawn();
-             setmodel(_flare, "models/runematch/rune.mdl"); 
+             setmodel(_flare, "models/runematch/rune.mdl");
              _flare.effects = EF_LOWPRECISION | EF_FLAME;
              _flare.scale = 0.5;
              setorigin(_flare, self.origin - '0 0 16');
              raptor.lip   = time;
          }
      }
-     
      raptor.bomb1.alpha = raptor.bomb2.alpha = (time - raptor.lip) / (raptor.delay - raptor.lip);
      player.vehicle_reload2 = bound(0, raptor.bomb1.alpha * 100, 100);
  
  
              _missile = _missile.chain;
          }
-         
          if(_incomming)
              sound(self, CH_PAIN_SINGLE, "vehicles/missile_alarm.wav", VOL_BASE, ATTEN_NONE);
-         
          self.bomb1.cnt = time + 1;
      }
-     
  
      VEHICLE_UPDATE_PLAYER(player, health, raptor);
      VEHICLE_UPDATE_PLAYER(player, energy, raptor);
          VEHICLE_UPDATE_PLAYER(player, shield, raptor);
  
      player.BUTTON_ATCK = player.BUTTON_ATCK2 = player.BUTTON_CROUCH = 0;
-     
      self = player;
      return 1;
  }
@@@ -690,8 -690,7 +690,8 @@@ void raptor_blowup(
  {
      self.deadflag    = DEAD_DEAD;
      self.vehicle_exit(VHEF_NORMAL);
 -    RadiusDamage (self, self.enemy, 250, 15, 250, world, 250, DEATH_VH_RAPT_DEATH, world);
 +
 +    RadiusDamage (self, self.enemy, 250, 15, 250, world, world, 250, DEATH_VH_RAPT_DEATH, world);
  
      self.alpha          = -1;
      self.movetype       = MOVETYPE_NONE;
@@@ -709,7 -708,7 +709,7 @@@ void raptor_diethink(
  {
        if(time >= self.wait)
                self.think = raptor_blowup;
-     
      if(random() < 0.1)
      {
          sound (self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM);
@@@ -729,7 -728,7 +729,7 @@@ void raptor_die(
      self.think        = raptor_diethink;
      self.nextthink    = time;
      self.wait                   = time + 5 + (random() * 5);
-     
      pointparticles(particleeffectnum("explosion_medium"), findbetterlocation (self.origin, 16), '0 0 0', 1);
  
      self.velocity_z += 600;
@@@ -761,12 -760,12 +761,12 @@@ float raptor_impulse(float _imp
      switch(_imp)
      {
          case 10:
-         case 15:        
+         case 15:
          case 18:
              self.vehicle.vehicle_weapon2mode += 1;
              if(self.vehicle.vehicle_weapon2mode > RSM_LAST)
                  self.vehicle.vehicle_weapon2mode = RSM_FIRST;
-             
              CSQCVehicleSetup(self, 0);
              return TRUE;
          case 12:
              self.vehicle.vehicle_weapon2mode -= 1;
              if(self.vehicle.vehicle_weapon2mode < RSM_FIRST)
                  self.vehicle.vehicle_weapon2mode = RSM_LAST;
-             
              CSQCVehicleSetup(self, 0);
              return TRUE;
  
-         /*                    
+         /*
          case 17: // toss gun, could be used to exit?
              break;
          case 20: // Manual minigun reload?
              break;
          */
-     }    
+     }
      return FALSE;
  }
  
@@@ -798,9 -797,9 +798,9 @@@ void raptor_spawn(float _f
  
          //FIXME: Camera is in a bad place in HUD model.
          //setorigin(self.vehicle_viewport, '25 0 5');
-         
          self.vehicles_impusle   = raptor_impulse;
-         
          self.frame = 0;
  
          self.bomb1 = spawn();
  
      setsize(self, RAPTOR_MIN, RAPTOR_MAX );
      self.delay = time;
-         
      self.bouncefactor = autocvar_g_vehicle_raptor_bouncefactor;
-     self.bouncestop = autocvar_g_vehicle_raptor_bouncestop;    
-     self.vehicle_impact = raptor_impact;    
+     self.bouncestop = autocvar_g_vehicle_raptor_bouncestop;
+     self.vehicle_impact = raptor_impact;
      self.damageforcescale = 0.25;
  }
  
@@@ -886,11 -885,11 +886,11 @@@ void spawnfunc_vehicle_raptor(
      {
          remove(self);
          return;
-     }        
-     
+     }
      self.vehicle_flags |= VHF_DMGSHAKE;
      self.vehicle_flags |= VHF_DMGROLL;
-    
      if(autocvar_g_vehicle_raptor_shield)
          self.vehicle_flags |= VHF_HASSHIELD;
  
      //precache_model ("models/vehicles/clusterbomb.md3");
      precache_model ("models/vehicles/clusterbomb_folded.md3");
      precache_model ("models/vehicles/raptor_body.dpm");
-     
      precache_sound ("vehicles/raptor_fly.wav");
      precache_sound ("vehicles/raptor_speed.wav");
      precache_sound ("vehicles/missile_alarm.wav");
-     
-     if not (vehicle_initialize(
+     if(!vehicle_initialize(
               "Raptor",
               "models/vehicles/raptor.dpm",
               "",
               raptor_frame,
               raptor_enter, raptor_exit,
               raptor_die,   raptor_think,
-              FALSE, 
+              FALSE,
               autocvar_g_vehicle_raptor_health,
               autocvar_g_vehicle_raptor_shield))
      {
          remove(self);
          return;
      }
-     
-     
  }
  #endif // SVQC
index 8b247995fccb82746785a73687dd797f38e646bd,bdbcb828870829577254ea87fe569ad792acd51a..e268f7f8309df477d9f0ffcb7da597a09c64af94
@@@ -99,7 -99,7 +99,7 @@@ void spiderbot_rocket_guided(
  
      self.nextthink  = time;
  
-     if not (self.realowner.vehicle)
+     if (!self.realowner.vehicle)
          self.think = spiderbot_rocket_unguided;
  
      crosshair_trace(self.realowner);
@@@ -117,7 -117,7 +117,7 @@@ void spiderbot_guide_release(
  {
      entity rkt;
      rkt = findchainentity(realowner, self.owner);
-     if not (rkt)
+     if (!rkt)
          return;
  
      crosshair_trace(self.owner);
      }
  }
  
- float spiberbot_calcartillery_flighttime;  
+ float spiberbot_calcartillery_flighttime;
  vector spiberbot_calcartillery(vector org, vector tgt, float ht)
  {
        float grav, sdist, zdist, vs, vz, jumpheight;
        vector sdir;
-       
        grav  = autocvar_sv_gravity;
        zdist = tgt_z - org_z;
        sdist = vlen(tgt - org - zdist * '0 0 1');
@@@ -213,7 -213,7 +213,7 @@@ void spiderbot_rocket_do(
      entity rocket = world;
  
      if (self.wait != -10)
-     {        
+     {
          if (self.owner.BUTTON_ATCK2 && self.vehicle_weapon2mode == SBRM_GUIDE)
          {
              if (self.wait == 1)
              self.wait = 0;
          }
      }
-     
      if(self.gun2.cnt > time)
          return;
  
          self.tur_head.frame = 1;
          self.wait = 0;
      }
-         
      if (self.wait != -10)
-         if not (self.owner.BUTTON_ATCK2)
+         if (!self.owner.BUTTON_ATCK2)
              return;
  
  
      v = gettaginfo(self.tur_head,gettagindex(self.tur_head,"tag_fire"));
-     
      switch(self.vehicle_weapon2mode)
      {
          case SBRM_VOLLY:
              rocket.nextthink  = time;
              rocket.think      = spiderbot_rocket_guided;
  
-                 
          break;
          case SBRM_ARTILLERY:
              rocket = vehicles_projectile("spiderbot_rocket_launch", "weapons/rocket_fire.wav",
                                     v, normalize(v_forward) * autocvar_g_vehicle_spiderbot_rocket_speed,
                                     autocvar_g_vehicle_spiderbot_rocket_damage, autocvar_g_vehicle_spiderbot_rocket_radius, autocvar_g_vehicle_spiderbot_rocket_force, 1,
                                     DEATH_VH_SPID_ROCKET, PROJECTILE_SPIDERROCKET, autocvar_g_vehicle_spiderbot_rocket_health, FALSE, TRUE, self.owner);
-             
              crosshair_trace(self.owner);
-             
              rocket.pos1       = trace_endpos + randomvec() * (0.75 * autocvar_g_vehicle_spiderbot_rocket_radius);
              rocket.pos1_z       = trace_endpos_z;
-             
-             traceline(v, v + '0 0 1' * MAX_SHOT_DISTANCE, MOVE_WORLDONLY, self);             
+             traceline(v, v + '0 0 1' * MAX_SHOT_DISTANCE, MOVE_WORLDONLY, self);
              float h1 = 0.75 * vlen(v - trace_endpos);
-             
              //v = trace_endpos;
-             traceline(v , rocket.pos1 + '0 0 1' * MAX_SHOT_DISTANCE, MOVE_WORLDONLY, self); 
+             traceline(v , rocket.pos1 + '0 0 1' * MAX_SHOT_DISTANCE, MOVE_WORLDONLY, self);
              float h2 = 0.75 * vlen(rocket.pos1 - v);
-             
              rocket.velocity  = spiberbot_calcartillery(v, rocket.pos1, ((h1 < h2) ? h1 : h2));
-             rocket.movetype  = MOVETYPE_TOSS;            
+             rocket.movetype  = MOVETYPE_TOSS;
              rocket.gravity   = 1;
-             //rocket.think     = spiderbot_rocket_artillery;   
+             //rocket.think     = spiderbot_rocket_artillery;
          break;
      }
      rocket.classname  = "spiderbot_rocket";
-     
      rocket.cnt = time + autocvar_g_vehicle_spiderbot_rocket_lifetime;
-     
      self.tur_head.frame += 1;
      if (self.tur_head.frame == 9)
          self.attack_finished_single = autocvar_g_vehicle_spiderbot_rocket_reload;
@@@ -329,17 -329,17 +329,17 @@@ float spiderbot_frame(
  
        if(intermission_running)
                return 1;
-               
      player = self;
      spider = self.vehicle;
      self   = spider;
  
      vehicles_painframe();
-     
      player.BUTTON_ZOOM      = 0;
      player.BUTTON_CROUCH    = 0;
      player.switchweapon     = 0;
-     
  
  #if 1 // 0 to enable per-gun impact aux crosshairs
      // Avarage gun impact point's -> aux cross
      ad = AnglesTransform_ToAngles(AnglesTransform_LeftDivide(AnglesTransform_FromAngles(spider.angles), AnglesTransform_FromAngles(ad))) - spider.tur_head.angles;
      ad = AnglesTransform_Normalize(ad, TRUE);
      //UpdateAuxiliaryXhair(player, trace_endpos, ('1 0 0' * player.vehicle_reload2) + ('0 1 0' * (1 - player.vehicle_reload2)), 2);
-     
      // Rotate head
-     ftmp = autocvar_g_vehicle_spiderbot_head_turnspeed * sys_frametime;    
+     ftmp = autocvar_g_vehicle_spiderbot_head_turnspeed * sys_frametime;
      ad_y = bound(-ftmp, ad_y, ftmp);
      spider.tur_head.angles_y = bound(autocvar_g_vehicle_spiderbot_head_turnlimit * -1, spider.tur_head.angles_y + ad_y, autocvar_g_vehicle_spiderbot_head_turnlimit);
  
  
      //fixedmakevectors(spider.angles);
      makevectors(spider.angles + '-2 0 0' * spider.angles_x);
-     
      movelib_groundalign4point(autocvar_g_vehicle_spiderbot_springlength, autocvar_g_vehicle_spiderbot_springup, autocvar_g_vehicle_spiderbot_springblend, autocvar_g_vehicle_spiderbot_tiltlimit);
  
      if(spider.flags & FL_ONGROUND)
          if(spider.frame == 4 && self.tur_head.wait != 0)
          {
              sound (self, CH_TRIGGER_SINGLE, "vehicles/spiderbot_land.wav", VOL_VEHICLEENGINE, ATTEN_NORM);
-             spider.frame = 5;            
+             spider.frame = 5;
          }
-         
          if(player.BUTTON_JUMP && self.tur_head.wait < time)
-         {        
+         {
              sound (self, CH_TRIGGER_SINGLE, "vehicles/spiderbot_jump.wav", VOL_VEHICLEENGINE, ATTEN_NORM);
              //dprint("spiderbot_jump:", ftos(soundlength("vehicles/spiderbot_jump.wav")), "\n");
              self.delay = 0;
              if(vlen(player.movement) == 0)
              {
                  if(self.sound_nexttime < time || self.delay != 3)
-                 {                        
+                 {
                      self.delay = 3;
                      self.sound_nexttime = time + 6.486500; //soundlength("vehicles/spiderbot_idle.wav");
                      //dprint("spiderbot_idle:", ftos(soundlength("vehicles/spiderbot_idle.wav")), "\n");
                      sound (self, CH_TRIGGER_SINGLE, "vehicles/spiderbot_idle.wav", VOL_VEHICLEENGINE, ATTEN_NORM);
-                 }                
+                 }
                  movelib_beak_simple(autocvar_g_vehicle_spiderbot_speed_stop);
                  spider.frame = 5;
              }
                      ftmp = autocvar_g_vehicle_spiderbot_turnspeed_strafe * sys_frametime;
                  else
                      ftmp = autocvar_g_vehicle_spiderbot_turnspeed * sys_frametime;
-                 
-                 ftmp = bound(-ftmp, spider.tur_head.angles_y, ftmp);                
+                 ftmp = bound(-ftmp, spider.tur_head.angles_y, ftmp);
                  spider.angles_y = anglemods(spider.angles_y + ftmp);
                  spider.tur_head.angles_y -= ftmp;
  
                      movelib_move_simple(normalize(v_forward * player.movement_x),autocvar_g_vehicle_spiderbot_speed_walk,autocvar_g_vehicle_spiderbot_movement_inertia);
  
                      if(self.sound_nexttime < time || self.delay != 1)
-                     {                        
+                     {
                          self.delay = 1;
                          self.sound_nexttime = time + 6.486500; //soundlength("vehicles/spiderbot_walk.wav");
                          sound (self, CH_TRIGGER_SINGLE, "vehicles/spiderbot_walk.wav", VOL_VEHICLEENGINE, ATTEN_NORM);
                      }
                      movelib_move_simple(normalize(v_right * player.movement_y),autocvar_g_vehicle_spiderbot_speed_strafe,autocvar_g_vehicle_spiderbot_movement_inertia);
                      if(self.sound_nexttime < time || self.delay != 2)
-                     {                        
+                     {
                          self.delay = 2;
                          self.sound_nexttime = time + 6.486500; //soundlength("vehicles/spiderbot_strafe.wav");
                          sound (self, CH_TRIGGER_SINGLE, "vehicles/spiderbot_strafe.wav", VOL_VEHICLEENGINE, ATTEN_NORM);
              v_forward = normalize(v_forward);
              v += v_forward * 50;
  
- //void fireBallisticBullet(vector start, vector dir, float spread, float pSpeed, float lifetime, float damage, float force, float dtype, float tracereffects, float gravityfactor, float bulletconstant)
+ //void fireBallisticBullet(vector start, vector dir, float spread, float pSpeed, float lifetime, float damage, float force, float dtype, float tracereffects, float bulletconstant)
  
              fireBallisticBullet(v, v_forward, autocvar_g_vehicle_spiderbot_minigun_spread, autocvar_g_vehicle_spiderbot_minigun_speed,
-                                 5, autocvar_g_vehicle_spiderbot_minigun_damage, autocvar_g_vehicle_spiderbot_minigun_force, DEATH_VH_SPID_MINIGUN, 0, 1, autocvar_g_vehicle_spiderbot_minigun_bulletconstant);
+                                 5, autocvar_g_vehicle_spiderbot_minigun_damage, autocvar_g_vehicle_spiderbot_minigun_force, DEATH_VH_SPID_MINIGUN, 0, autocvar_g_vehicle_spiderbot_minigun_bulletconstant);
  
              endFireBallisticBullet();
  
          vehicles_regen(spider.cnt, vehicle_ammo1, autocvar_g_vehicle_spiderbot_minigun_ammo_max,
                                             autocvar_g_vehicle_spiderbot_minigun_ammo_regen_pause,
                                             autocvar_g_vehicle_spiderbot_minigun_ammo_regen, frametime, FALSE);
-         
  
      spiderbot_rocket_do();
  
          VEHICLE_UPDATE_PLAYER(player, shield, spiderbot);
  
      self = player;
-     return 1;    
+     return 1;
  }
  void spiderbot_think()
  {
@@@ -574,8 -574,8 +574,8 @@@ void spiderbot_enter(
  
      if(self.owner.flagcarried)
      {
-         setattachment(self.owner.flagcarried, self.tur_head, ""); 
-         setorigin(self.owner.flagcarried, '-20 0 120'); 
+         setattachment(self.owner.flagcarried, self.tur_head, "");
+         setorigin(self.owner.flagcarried, '-20 0 120');
      }
  }
  
@@@ -583,7 -583,7 +583,7 @@@ void spiderbot_exit(float eject
  {
      entity e;
      vector spot;
-     
      e = findchain(classname,"spiderbot_rocket");
      while(e)
      {
      self.nextthink  = time;
      self.frame      = 5;
      self.movetype   = MOVETYPE_WALK;
-     
-     if not (self.owner)
+     if (!self.owner)
          return;
  
        makevectors(self.angles);
            self.owner.oldvelocity = self.owner.velocity;
            setorigin(self.owner , spot);
        }
-       
        antilag_clear(self.owner);
      self.owner = world;
  }
  void spider_impact()
  {
      if(autocvar_g_vehicle_spiderbot_bouncepain_x)
-         vehilces_impact(autocvar_g_vehicle_spiderbot_bouncepain_x, autocvar_g_vehicle_spiderbot_bouncepain_y, autocvar_g_vehicle_spiderbot_bouncepain_z);    
+         vehilces_impact(autocvar_g_vehicle_spiderbot_bouncepain_x, autocvar_g_vehicle_spiderbot_bouncepain_y, autocvar_g_vehicle_spiderbot_bouncepain_z);
  }
  
  void spiderbot_headfade()
@@@ -672,7 -672,7 +672,7 @@@ void spiderbot_blowup(
          self.nextthink = time + 0.1;
          return;
      }
-     
      entity h, g1, g2, b;
      b = spawn();
      h = spawn();
      SUB_SetFade(g1, time, min(autocvar_g_vehicle_spiderbot_respawntime, 10));
      SUB_SetFade(g2, time, min(autocvar_g_vehicle_spiderbot_respawntime, 10));
  
 -    RadiusDamage (self, self.enemy, 250, 15, 250, world, 250, DEATH_VH_SPID_DEATH, world);
 +    RadiusDamage (self, self.enemy, 250, 15, 250, world, world, 250, DEATH_VH_SPID_DEATH, world);
  
      self.alpha = self.tur_head.alpha = self.gun1.alpha = self.gun2.alpha = -1;
      self.movetype   = MOVETYPE_NONE;
@@@ -755,12 -755,12 +755,12 @@@ float spiderbot_impulse(float _imp
      switch(_imp)
      {
          case 10:
-         case 15:        
+         case 15:
          case 18:
              self.vehicle.vehicle_weapon2mode += 1;
              if(self.vehicle.vehicle_weapon2mode > SBRM_LAST)
                  self.vehicle.vehicle_weapon2mode = SBRM_FIRST;
-             
              //centerprint(self, strcat("Rocket mode is ", ftos(self.vehicle.vehicle_weapon2mode)));
              CSQCVehicleSetup(self, 0);
              return TRUE;
              self.vehicle.vehicle_weapon2mode -= 1;
              if(self.vehicle.vehicle_weapon2mode < SBRM_FIRST)
                  self.vehicle.vehicle_weapon2mode = SBRM_LAST;
-             
              //centerprint(self, strcat("Rocket mode is ", ftos(self.vehicle.vehicle_weapon2mode)));
              CSQCVehicleSetup(self, 0);
              return TRUE;
  
-         /*                    
+         /*
          case 17: // toss gun, could be used to exit?
              break;
          case 20: // Manual minigun reload?
              break;
          */
-     }    
+     }
      return FALSE;
  }
  
  void spiderbot_spawn(float _f)
  {
      if(!self.gun1)
-     {        
+     {
          self.vehicles_impusle   = spiderbot_impulse;
          self.gun1               = spawn();
-         self.gun2               = spawn();    
+         self.gun2               = spawn();
          setmodel(self.gun1, "models/vehicles/spiderbot_barrels.dpm");
          setmodel(self.gun2, "models/vehicles/spiderbot_barrels.dpm");
          setattachment(self.gun1, self.tur_head, "tag_hardpoint01");
      self.movetype           = MOVETYPE_WALK;
      self.solid              = SOLID_SLIDEBOX;
      self.alpha              = self.tur_head.alpha = self.gun1.alpha = self.gun2.alpha = 1;
-     self.tur_head.angles    = '0 0 0';    
+     self.tur_head.angles    = '0 0 0';
  
      setorigin(self, self.pos1 + '0 0 128');
      self.angles = self.pos2;
@@@ -823,12 -823,12 +823,12 @@@ void spawnfunc_vehicle_spiderbot(
      {
          remove(self);
          return;
-     }        
+     }
  
      self.vehicle_flags |= VHF_DMGSHAKE;
      //self.vehicle_flags |= VHF_DMGROLL;
      //self.vehicle_flags |= VHF_DMGHEADROLL;
-     
      precache_model ( "models/vhshield.md3");
      precache_model ( "models/vehicles/spiderbot.dpm");
      precache_model ( "models/vehicles/spiderbot_top.dpm");
  
      precache_sound ( "weapons/uzi_fire.wav" );
      precache_sound ( "weapons/rocket_impact.wav");
-     
      precache_sound ( "vehicles/spiderbot_die.wav");
      precache_sound ( "vehicles/spiderbot_idle.wav");
      precache_sound ( "vehicles/spiderbot_jump.wav");
  
      if(autocvar_g_vehicle_spiderbot_health_regen)
          self.vehicle_flags |= VHF_HEALTHREGEN;
-         
-     if not (vehicle_initialize(
+     if(!vehicle_initialize(
               "Spiderbot",
               "models/vehicles/spiderbot.dpm",
               "models/vehicles/spiderbot_top.dpm",
               spiderbot_frame,
               spiderbot_enter, spiderbot_exit,
               spiderbot_die,   spiderbot_think,
-              FALSE, 
+              FALSE,
               autocvar_g_vehicle_spiderbot_health,
               autocvar_g_vehicle_spiderbot_shield))
      {
index f669899bf34b61660a8661ffbec6771ec49b8a7a,1e5537a259934cd2faab7750716d1b9d57ea22de..829c0ce89f21c247f22073ecb26e3e2ed772ed6c
@@@ -46,7 -46,7 +46,7 @@@ float SendAuxiliaryXhair(entity to, flo
  
  void UpdateAuxiliaryXhair(entity own, vector loc, vector clr, float axh_id)
  {
-     if not(IS_REAL_CLIENT(own))
+     if (!IS_REAL_CLIENT(own))
          return;
  
      entity axh;
@@@ -101,15 -101,15 +101,15 @@@ void SendAuxiliaryXhair2(entity own, ve
  **/
  void CSQCVehicleSetup(entity own, float vehicle_id)
  {
-     if not(IS_REAL_CLIENT(own))
+     if (!IS_REAL_CLIENT(own))
          return;
-       
        msg_entity = own;
  
        WriteByte(MSG_ONE, SVC_TEMPENTITY);
        WriteByte(MSG_ONE, TE_CSQC_VEHICLESETUP);
        if(vehicle_id != 0)
-           WriteByte(MSG_ONE, vehicle_id);        
+           WriteByte(MSG_ONE, vehicle_id);
        else
          WriteByte(MSG_ONE, 1 + own.vehicle.vehicle_weapon2mode + HUD_VEHICLE_LAST);
  }
@@@ -275,7 -275,7 +275,7 @@@ void vehicles_locktarget(float incr, fl
          if(trace_ent.deadflag != DEAD_NO)
              trace_ent = world;
  
-         if not (trace_ent.vehicle_flags & VHF_ISVEHICLE ||
+         if(!trace_ent.vehicle_flags & VHF_ISVEHICLE ||
                                trace_ent.turrcaps_flags & TFL_TURRCAPS_ISTURRET ||
                                trace_ent.takedamage == DAMAGE_TARGETDRONE)
              trace_ent = world;
@@@ -397,7 -397,7 +397,7 @@@ void vehicles_projectile_explode(
        PROJECTILE_TOUCH;
  
        self.event_damage = func_null;
 -    RadiusDamage (self, self.realowner, self.shot_dmg, 0, self.shot_radius, self, self.shot_force, self.totalfrags, other);
 +    RadiusDamage (self, self.realowner, self.shot_dmg, 0, self.shot_radius, self, world, self.shot_force, self.totalfrags, other);
  
      remove (self);
  }
@@@ -492,10 -492,10 +492,10 @@@ void vehicles_spawn(
      setorigin(self, self.pos1 + '0 0 0');
      // Show it
      pointparticles(particleeffectnum("teleport"), self.origin + '0 0 64', '0 0 0', 1);
-     
      if(self.vehicle_controller)
          self.team = self.vehicle_controller.team;
-        
      vehicles_reset_colors();
      self.vehicle_spawn(VHSF_NORMAL);
  }
@@@ -539,7 -539,7 +539,7 @@@ void vehicles_touch(
  {
        if(MUTATOR_CALLHOOK(VehicleTouch))
                return;
-       
      // Vehicle currently in use
      if(self.owner)
      {
          return;
      }
  
-     if not(IS_PLAYER(other))
+     if (!IS_PLAYER(other))
          return;
  
      if(other.deadflag != DEAD_NO)
@@@ -574,8 -574,8 +574,8 @@@ var float autocvar_g_vehicles_allow_bot
  void vehicles_enter()
  {
     // Remove this when bots know how to use vehicles
-    
-     if (IS_BOT_CLIENT(other))    
+     if (IS_BOT_CLIENT(other))
          if (autocvar_g_vehicles_allow_bots)
              dprint("Bot enters vehicle\n"); // This is where we need to disconnect (some, all?) normal bot AI and hand over to vehicle's _aiframe()
          else
  
      self.team                 = self.owner.team;
      self.flags               -= FL_NOTARGET;
-     
      if (IS_REAL_CLIENT(other))
      {
          msg_entity = other;
          WriteByte (MSG_ONE, SVC_SETVIEWPORT);
          WriteEntity(MSG_ONE, self.vehicle_viewport);
-                 
          WriteByte (MSG_ONE, SVC_SETVIEWANGLES);
          if(self.tur_head)
          {
      vehicles_clearrturn();
  
      CSQCVehicleSetup(self.owner, self.hud);
-     
      vh_player = other;
      vh_vehicle = self;
      MUTATOR_CALLHOOK(VehicleEnter);
@@@ -735,31 -735,31 +735,31 @@@ void vehicles_exit(float eject
      entity _vehicle;
      entity _player;
      entity _oldself = self;
-     
      if(vehicles_exit_running)
      {
          dprint("^1vehicles_exit allready running! this is not good..\n");
          return;
      }
-     
      vehicles_exit_running = TRUE;
      if(IS_CLIENT(self))
      {
          _vehicle = self.vehicle;
-             
          if (_vehicle.vehicle_flags & VHF_PLAYERSLOT)
          {
              _vehicle.vehicle_exit(eject);
              self = _oldself;
              vehicles_exit_running = FALSE;
-             return;            
+             return;
          }
      }
      else
          _vehicle = self;
-     
      _player = _vehicle.owner;
-     
      self = _vehicle;
  
      if (_player)
              WriteAngle(MSG_ONE, _vehicle.angles_y);
              WriteAngle(MSG_ONE, 0);
          }
-         
          setsize(_player, PL_MIN,PL_MAX);
  
          _player.takedamage     = DAMAGE_AIM;
          CSQCVehicleSetup(_player, HUD_NORMAL);
      }
      _vehicle.flags |= FL_NOTARGET;
-     
      if(_vehicle.deadflag == DEAD_NO)
          _vehicle.avelocity          = '0 0 0';
-     
      _vehicle.tur_head.nodrawtoclient             = world;
-     
      if(!teamplay)
          _vehicle.team = 0;
  
      _vehicle = vh_vehicle;
  
      _vehicle.team = _vehicle.tur_head.team;
-         
      sound (_vehicle, CH_TRIGGER_SINGLE, "misc/null.wav", 1, ATTEN_NORM);
-     _vehicle.vehicle_hudmodel.viewmodelforclient = _vehicle;  
+     _vehicle.vehicle_hudmodel.viewmodelforclient = _vehicle;
      _vehicle.phase = time + 1;
-     
      _vehicle.vehicle_exit(eject);
-     
      vehicles_setreturn();
-     vehicles_reset_colors();        
+     vehicles_reset_colors();
      _vehicle.owner = world;
      self = _oldself;
-     
      vehicles_exit_running = FALSE;
  }
  
@@@ -832,7 -832,7 +832,7 @@@ void vehicles_regen(float timer, .floa
      {
          if(_healthscale)
              regen = regen * (self.vehicle_health / self.tur_health);
-             
          self.regen_field = min(self.regen_field + regen * delta_time, field_max);
  
          if(self.owner)
@@@ -880,24 -880,24 +880,24 @@@ void vehicles_painframe(
  void vehicles_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
  {
      self.dmg_time = time;
-     
      if(DEATH_ISWEAPON(deathtype, WEP_NEX))
          damage *= autocvar_g_vehicles_nex_damagerate;
-         
      if(DEATH_ISWEAPON(deathtype, WEP_UZI))
          damage *= autocvar_g_vehicles_uzi_damagerate;
-         
      if(DEATH_ISWEAPON(deathtype, WEP_RIFLE))
          damage *= autocvar_g_vehicles_rifle_damagerate;
-         
      if(DEATH_ISWEAPON(deathtype, WEP_MINSTANEX))
          damage *= autocvar_g_vehicles_minstanex_damagerate;
  
      if(DEATH_ISWEAPON(deathtype, WEP_SEEKER))
          damage *= autocvar_g_vehicles_tag_damagerate;
-     
      self.enemy = attacker;
-     
      if((self.vehicle_flags & VHF_HASSHIELD) && (self.vehicle_shield > 0))
      {
          if (wasfreed(self.vehicle_shieldent) || self.vehicle_shieldent == world)
          if(sound_allowed(MSG_BROADCAST, attacker))
              spamsound (self, CH_PAIN, "onslaught/ons_hit2.wav", VOL_BASE, ATTEN_NORM);  // FIXME: PLACEHOLDER
      }
-     
        if(self.damageforcescale < 1 && self.damageforcescale > 0)
                self.velocity += force * self.damageforcescale;
        else
@@@ -1133,7 -1133,7 +1133,7 @@@ void vehicle_use(
          self.active = ACTIVE_NOT;
      else
          self.active = ACTIVE_ACTIVE;
-     
      if(self.active == ACTIVE_ACTIVE && self.deadflag == DEAD_NO)
      {
          dprint("^3Eat shit yall!\n");
      }
      else if(self.active == ACTIVE_NOT && self.deadflag != DEAD_NO)
      {
-         
      }
  }
  
- float vehicle_addplayerslot(    entity _owner, 
-                                 entity _slot, 
-                                 float _hud, 
+ float vehicle_addplayerslot(    entity _owner,
+                                 entity _slot,
+                                 float _hud,
                                  string _hud_model,
-                                 float() _framefunc, 
+                                 float() _framefunc,
                                  void(float) _exitfunc)
  {
-     if not (_owner.vehicle_flags & VHF_MULTISLOT)
+     if (!(_owner.vehicle_flags & VHF_MULTISLOT))
          _owner.vehicle_flags |= VHF_MULTISLOT;
  
      _slot.PlayerPhysplug = _framefunc;
      _slot.vehicle_hudmodel = spawn();
      _slot.vehicle_hudmodel.viewmodelforclient = _slot;
      _slot.vehicle_viewport.effects = (EF_ADDITIVE | EF_DOUBLESIDED | EF_FULLBRIGHT | EF_NODEPTHTEST | EF_NOGUNBOB | EF_NOSHADOW | EF_LOWPRECISION | EF_SELECTABLE | EF_TELEPORT_BIT);
-     
      setmodel(_slot.vehicle_hudmodel, _hud_model);
      setmodel(_slot.vehicle_viewport, "null");
-     
      setattachment(_slot.vehicle_hudmodel, _slot, "");
      setattachment(_slot.vehicle_viewport, _slot.vehicle_hudmodel, "");
-     
      return TRUE;
  }
  
@@@ -1198,7 -1198,7 +1198,7 @@@ float vehicle_initialize(string  net_na
  {
        if(!autocvar_g_vehicles)
                return FALSE;
-       
      if(self.targetname)
      {
          self.vehicle_controller = find(world, target, self.targetname);
          }
          else
          {
-             self.team = self.vehicle_controller.team;        
+             self.team = self.vehicle_controller.team;
              self.use = vehicle_use;
-             
              if(teamplay)
              {
                  if(self.vehicle_controller.team == 0)
                      self.active = ACTIVE_NOT;
                  else
-                     self.active = ACTIVE_ACTIVE;                
+                     self.active = ACTIVE_ACTIVE;
              }
          }
      }
-     
      precache_sound("onslaught/ons_hit2.wav");
      precache_sound("onslaught/electricity_explode.wav");
  
      }
  
      setsize(self, min_s, max_s);
-     if not (nodrop)
+     if (!nodrop)
      {
          setorigin(self, self.origin);
          tracebox(self.origin + '0 0 100', min_s, max_s, self.origin - '0 0 10000', MOVE_WORLDONLY, self);
          setorigin(self, trace_endpos);
      }
-     
      self.pos1 = self.origin;
      self.pos2 = self.angles;
      self.tur_head.team = self.team;
-       
        if(MUTATOR_CALLHOOK(VehicleSpawn))
                return FALSE;
  
      return TRUE;
  }
  
- vector vehicle_aimturret(entity _vehic, vector _target, entity _turrret, string _tagname, 
-                          float _pichlimit_min, float _pichlimit_max, 
+ vector vehicle_aimturret(entity _vehic, vector _target, entity _turrret, string _tagname,
+                          float _pichlimit_min, float _pichlimit_max,
                           float _rotlimit_min, float _rotlimit_max, float _aimspeed)
  {
      vector vtmp, vtag;
      ftmp = _aimspeed * frametime;
      vtmp_y = bound(-ftmp, vtmp_y, ftmp);
      vtmp_x = bound(-ftmp, vtmp_x, ftmp);
-     _turrret.angles_y = bound(_rotlimit_min, _turrret.angles_y + vtmp_y, _rotlimit_max);    
+     _turrret.angles_y = bound(_rotlimit_min, _turrret.angles_y + vtmp_y, _rotlimit_max);
      _turrret.angles_x = bound(_pichlimit_min, _turrret.angles_x + vtmp_x, _pichlimit_max);
      return vtag;
  }
@@@ -1370,23 -1370,23 +1370,23 @@@ entity vehicle_tossgib(entity _template
        _gib.movetype = MOVETYPE_TOSS;
        _gib.solid = SOLID_CORPSE;
        _gib.colormod = '-0.5 -0.5 -0.5';
-       _gib.effects = EF_LOWPRECISION; 
+       _gib.effects = EF_LOWPRECISION;
        _gib.avelocity = _rot;
-       
        if(_burn)
                _gib.effects |= EF_FLAME;
-       
        if(_explode)
        {
-               _gib.think = vehicles_gib_explode; 
+               _gib.think = vehicles_gib_explode;
                _gib.nextthink = time + random() * _explode;
                _gib.touch = vehicles_gib_explode;
        }
        else
        {
                _gib.cnt = time + _maxtime;
-               _gib.think = vehicles_gib_think; 
-               _gib.nextthink = time + _maxtime - 1;           
+               _gib.think = vehicles_gib_think;
+               _gib.nextthink = time + _maxtime - 1;
                _gib.alpha = 1;
        }
        return _gib;
index 084a9d0e4d7b121878f851bb06ecda17cf9d1795,0000000000000000000000000000000000000000..00605ce6b966850b90cc5a8b870f2ab99af45524
mode 100644,000000..100644
--- /dev/null
@@@ -1,120 -1,0 +1,120 @@@
-               if not(self.owner.cvar_cl_accuracy_data_share && autocvar_sv_accuracy_data_share)
 +float accuracy_byte(float n, float d)
 +{
 +      //print(sprintf("accuracy: %d / %d\n", n, d));
 +      if(n <= 0)
 +              return 0;
 +      if(n > d)
 +              return 255;
 +      return 1 + rint(n * 100.0 / d);
 +}
 +
 +float accuracy_send(entity to, float sf)
 +{
 +      float w, f;
 +      entity a;
 +      WriteByte(MSG_ENTITY, ENT_CLIENT_ACCURACY);
 +
 +      a = self.owner;
 +      if(IS_SPEC(a))
 +              a = a.enemy;
 +      a = a.accuracy;
 +
 +      if(to != a.owner)
++              if (!(self.owner.cvar_cl_accuracy_data_share && autocvar_sv_accuracy_data_share))
 +                      sf = 0;
 +      // note: zero sendflags can never be sent... so we can use that to say that we send no accuracy!
 +      WriteInt24_t(MSG_ENTITY, sf);
 +      if(sf == 0)
 +              return TRUE;
 +      // note: we know that client and server agree about SendFlags...
 +      for(w = 0, f = 1; w <= WEP_LAST - WEP_FIRST; ++w)
 +      {
 +              if(sf & f)
 +                      WriteByte(MSG_ENTITY, accuracy_byte(self.(accuracy_hit[w]), self.(accuracy_fired[w])));
 +              if(f == 0x800000)
 +                      f = 1;
 +              else
 +                      f *= 2;
 +      }
 +      return TRUE;
 +}
 +
 +// init/free
 +void accuracy_init(entity e)
 +{
 +      e.accuracy = spawn();
 +      e.accuracy.owner = e;
 +      e.accuracy.classname = "accuracy";
 +      e.accuracy.drawonlytoclient = e;
 +      Net_LinkEntity(e.accuracy, FALSE, 0, accuracy_send);
 +}
 +
 +void accuracy_free(entity e)
 +{
 +      remove(e.accuracy);
 +}
 +
 +// force a resend of a player's accuracy stats
 +void accuracy_resend(entity e)
 +{
 +      e.accuracy.SendFlags = 0xFFFFFF;
 +}
 +
 +// update accuracy stats
 +.float hit_time;
 +.float fired_time;
 +
 +void accuracy_add(entity e, float w, float fired, float hit)
 +{
 +      entity a;
 +      float b;
 +      if(IS_INDEPENDENT_PLAYER(e))
 +              return;
 +      a = e.accuracy;
 +      if(!a || !(hit || fired))
 +              return;
 +      w -= WEP_FIRST;
 +      b = accuracy_byte(a.(accuracy_hit[w]), a.(accuracy_fired[w]));
 +      if(hit)
 +              a.(accuracy_hit[w]) += hit;
 +      if(fired)
 +              a.(accuracy_fired[w]) += fired;
 +
 +    if(hit && a.hit_time != time) // only run this once per frame
 +    {
 +        a.(accuracy_cnt_hit[w]) += 1;
 +        a.hit_time = time;
 +    }
 +
 +    if(fired && a.fired_time != time) // only run this once per frame
 +    {
 +        a.(accuracy_cnt_fired[w]) += 1;
 +        a.fired_time = time;
 +    }
 +
 +      if(b == accuracy_byte(a.(accuracy_hit[w]), a.(accuracy_fired[w])))
 +              return;
 +      w = pow(2, mod(w, 24));
 +      a.SendFlags |= w;
 +      FOR_EACH_CLIENT(a)
 +              if(IS_SPEC(a))
 +                      if(a.enemy == e)
 +                              a.SendFlags |= w;
 +}
 +
 +float accuracy_isgooddamage(entity attacker, entity targ)
 +{
 +      if(!warmup_stage)
 +      if(IS_CLIENT(targ))
 +      if(targ.deadflag == DEAD_NO)
 +      if(DIFF_TEAM(attacker, targ))
 +              return TRUE;
 +      return FALSE;
 +}
 +
 +float accuracy_canbegooddamage(entity attacker)
 +{
 +      if(!warmup_stage)
 +              return TRUE;
 +      return FALSE;
 +}
index 3554f1ff67235142f837507183b772c41c841c09,0000000000000000000000000000000000000000..4d208ebda808341f778f242ba0135d7255bd29d9
mode 100644,000000..100644
--- /dev/null
@@@ -1,106 -1,0 +1,116 @@@
-       
 +.float csqcprojectile_type;
 +
 +float CSQCProjectile_SendEntity(entity to, float sf)
 +{
 +      float ft, fr;
 +
 +      // note: flag 0x08 = no trail please (teleport bit)
 +      sf = sf & 0x0F;
 +
 +      if(self.csqcprojectile_clientanimate)
 +              sf |= 0x80; // client animated, not interpolated
 +
 +      if(self.flags & FL_ONGROUND)
 +              sf |= 0x40;
 +
 +      ft = fr = 0;
 +      if(self.fade_time != 0 || self.fade_rate != 0)
 +      {
 +              ft = (self.fade_time - time) / sys_frametime;
 +              fr = (1 / self.fade_rate) / sys_frametime;
 +              if(ft <= 255 && fr <= 255 && fr >= 1)
 +                      sf |= 0x20;
 +      }
 +
 +      if(self.gravity != 0)
 +              sf |= 0x10;
 +
 +      WriteByte(MSG_ENTITY, ENT_CLIENT_PROJECTILE);
 +      WriteByte(MSG_ENTITY, sf);
 +
 +      if(sf & 1)
 +      {
 +              WriteCoord(MSG_ENTITY, self.origin_x);
 +              WriteCoord(MSG_ENTITY, self.origin_y);
 +              WriteCoord(MSG_ENTITY, self.origin_z);
 +
 +              if(sf & 0x80)
 +              {
 +                      WriteCoord(MSG_ENTITY, self.velocity_x);
 +                      WriteCoord(MSG_ENTITY, self.velocity_y);
 +                      WriteCoord(MSG_ENTITY, self.velocity_z);
 +                      if(sf & 0x10)
 +                              WriteCoord(MSG_ENTITY, self.gravity);
 +              }
 +
 +              if(sf & 0x20)
 +              {
 +                      WriteByte(MSG_ENTITY, ft);
 +                      WriteByte(MSG_ENTITY, fr);
 +              }
 +      }
 +
 +      if(sf & 2)
 +              WriteByte(MSG_ENTITY, self.csqcprojectile_type); // TODO maybe put this into sf?
-       
++
 +      return 1;
 +}
 +
 +.vector csqcprojectile_oldorigin;
 +void CSQCProjectile_Check(entity e)
 +{
 +      if(e.csqcprojectile_clientanimate)
 +      if(e.flags & FL_ONGROUND)
 +      if(e.origin != e.csqcprojectile_oldorigin)
 +              UpdateCSQCProjectile(e);
 +      e.csqcprojectile_oldorigin = e.origin;
 +}
 +
 +void CSQCProjectile(entity e, float clientanimate, float type, float docull)
 +{
 +      Net_LinkEntity(e, docull, 0, CSQCProjectile_SendEntity);
-       
++
 +      e.csqcprojectile_clientanimate = clientanimate;
++
 +      if(e.movetype == MOVETYPE_TOSS || e.movetype == MOVETYPE_BOUNCE)
 +      {
 +              if(e.gravity == 0)
 +                      e.gravity = 1;
 +      }
 +      else
 +              e.gravity = 0;
 +
 +      if(!sound_allowed(MSG_BROADCAST, e))
 +              type |= 0x80;
 +      e.csqcprojectile_type = type;
 +}
 +
++// FIXME HACK
++float ItemSend(entity to, float sf);
++void ItemUpdate(entity item);
++// END HACK
 +void UpdateCSQCProjectile(entity e)
 +{
 +      if(e.SendEntity == CSQCProjectile_SendEntity)
 +      {
 +              // send new origin data
 +              e.SendFlags |= 0x01;
 +      }
++// FIXME HACK
++      else if(e.SendEntity == ItemSend)
++      {
++              ItemUpdate(e);
++      }
++// END HACK
 +}
 +
 +void UpdateCSQCProjectileAfterTeleport(entity e)
 +{
 +      if(e.SendEntity == CSQCProjectile_SendEntity)
 +      {
 +              // send new origin data
 +              e.SendFlags |= 0x01;
 +              // mark as teleported
 +              e.SendFlags |= 0x08;
 +      }
 +}
index 6fcab0dc7782fbe26a8fea326b0b903931c41370,0000000000000000000000000000000000000000..b70988945564923fcf2b0519a85dec069506a6b1
mode 100644,000000..100644
--- /dev/null
@@@ -1,717 -1,0 +1,697 @@@
-               FOR_EACH_REALCLIENT(msg_entity) if(msg_entity != self) if(!msg_entity.railgunhit) if not(IS_SPEC(msg_entity) && msg_entity.enemy == self) // we use realclient, so spectators can hear the whoosh too
 +// this function calculates w_shotorg and w_shotdir based on the weapon model
 +// offset, trueaim and antilag, and won't put w_shotorg inside a wall.
 +// make sure you call makevectors first (FIXME?)
 +void W_SetupShot_Dir_ProjectileSize_Range(entity ent, vector s_forward, vector mi, vector ma, float antilag, float recoil, string snd, float chan, float maxdamage, float range)
 +{
 +      float nudge = 1; // added to traceline target and subtracted from result
 +      float oldsolid;
 +      vector vecs, dv;
 +      oldsolid = ent.dphitcontentsmask;
 +      if(ent.weapon == WEP_RIFLE)
 +              ent.dphitcontentsmask = DPCONTENTS_BODY | DPCONTENTS_CORPSE;
 +      else
 +              ent.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
 +      if(antilag)
 +              WarpZone_traceline_antilag(world, ent.origin + ent.view_ofs, ent.origin + ent.view_ofs + s_forward * range, MOVE_NORMAL, ent, ANTILAG_LATENCY(ent));
 +              // passing world, because we do NOT want it to touch dphitcontentsmask
 +      else
 +              WarpZone_TraceLine(ent.origin + ent.view_ofs, ent.origin + ent.view_ofs + s_forward * range, MOVE_NOMONSTERS, ent);
 +      ent.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
 +
 +      vector vf, vr, vu;
 +      vf = v_forward;
 +      vr = v_right;
 +      vu = v_up;
 +      w_shotend = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos); // warpzone support
 +      v_forward = vf;
 +      v_right = vr;
 +      v_up = vu;
 +
 +      // un-adjust trueaim if shotend is too close
 +      if(vlen(w_shotend - (ent.origin + ent.view_ofs)) < autocvar_g_trueaim_minrange)
 +              w_shotend = ent.origin + ent.view_ofs + s_forward * autocvar_g_trueaim_minrange;
 +
 +      // track max damage
 +      if(accuracy_canbegooddamage(ent))
 +              accuracy_add(ent, ent.weapon, maxdamage, 0);
 +
 +      W_HitPlotAnalysis(ent, v_forward, v_right, v_up);
 +
 +      if(ent.weaponentity.movedir_x > 0)
 +              vecs = ent.weaponentity.movedir;
 +      else
 +              vecs = '0 0 0';
 +
 +      dv = v_right * -vecs_y + v_up * vecs_z;
 +      w_shotorg = ent.origin + ent.view_ofs + dv;
 +
 +      // now move the shotorg forward as much as requested if possible
 +      if(antilag)
 +      {
 +              if(ent.antilag_debug)
 +                      tracebox_antilag(ent, w_shotorg, mi, ma, w_shotorg + v_forward * (vecs_x + nudge), MOVE_NORMAL, ent, ent.antilag_debug);
 +              else
 +                      tracebox_antilag(ent, w_shotorg, mi, ma, w_shotorg + v_forward * (vecs_x + nudge), MOVE_NORMAL, ent, ANTILAG_LATENCY(ent));
 +      }
 +      else
 +              tracebox(w_shotorg, mi, ma, w_shotorg + v_forward * (vecs_x + nudge), MOVE_NORMAL, ent);
 +      w_shotorg = trace_endpos - v_forward * nudge;
 +      // calculate the shotdir from the chosen shotorg
 +      w_shotdir = normalize(w_shotend - w_shotorg);
 +
 +      if (antilag)
 +      if (!ent.cvar_cl_noantilag)
 +      {
 +              if (autocvar_g_antilag == 1) // switch to "ghost" if not hitting original
 +              {
 +                      traceline(w_shotorg, w_shotorg + w_shotdir * range, MOVE_NORMAL, ent);
 +                      if (!trace_ent.takedamage)
 +                      {
 +                              traceline_antilag_force (ent, w_shotorg, w_shotorg + w_shotdir * range, MOVE_NORMAL, ent, ANTILAG_LATENCY(ent));
 +                              if (trace_ent.takedamage && IS_PLAYER(trace_ent))
 +                              {
 +                                      entity e;
 +                                      e = trace_ent;
 +                                      traceline(w_shotorg, e.origin, MOVE_NORMAL, ent);
 +                                      if(trace_ent == e)
 +                                              w_shotdir = normalize(trace_ent.origin - w_shotorg);
 +                              }
 +                      }
 +              }
 +              else if(autocvar_g_antilag == 3) // client side hitscan
 +              {
 +                      // this part MUST use prydon cursor
 +                      if (ent.cursor_trace_ent)                 // client was aiming at someone
 +                      if (ent.cursor_trace_ent != ent)         // just to make sure
 +                      if (ent.cursor_trace_ent.takedamage)      // and that person is killable
 +                      if (IS_PLAYER(ent.cursor_trace_ent)) // and actually a player
 +                      {
 +                              // verify that the shot would miss without antilag
 +                              // (avoids an issue where guns would always shoot at their origin)
 +                              traceline(w_shotorg, w_shotorg + w_shotdir * range, MOVE_NORMAL, ent);
 +                              if (!trace_ent.takedamage)
 +                              {
 +                                      // verify that the shot would hit if altered
 +                                      traceline(w_shotorg, ent.cursor_trace_ent.origin, MOVE_NORMAL, ent);
 +                                      if (trace_ent == ent.cursor_trace_ent)
 +                                              w_shotdir = normalize(ent.cursor_trace_ent.origin - w_shotorg);
 +                                      else
 +                                              print("antilag fail\n");
 +                              }
 +                      }
 +              }
 +      }
 +
 +      ent.dphitcontentsmask = oldsolid; // restore solid type (generally SOLID_SLIDEBOX)
 +
 +      if (!autocvar_g_norecoil)
 +              ent.punchangle_x = recoil * -1;
 +
 +      if (snd != "")
 +      {
 +              sound (ent, chan, snd, VOL_BASE, ATTN_NORM);
 +              W_PlayStrengthSound(ent);
 +      }
 +
 +      // nudge w_shotend so a trace to w_shotend hits
 +      w_shotend = w_shotend + normalize(w_shotend - w_shotorg) * nudge;
 +}
 +
 +vector W_CalculateProjectileVelocity(vector pvelocity, vector mvelocity, float forceAbsolute)
 +{
 +      vector mdirection;
 +      float mspeed;
 +      vector outvelocity;
 +
 +      mvelocity = mvelocity * g_weaponspeedfactor;
 +
 +      mdirection = normalize(mvelocity);
 +      mspeed = vlen(mvelocity);
 +
 +      outvelocity = get_shotvelocity(pvelocity, mdirection, mspeed, (forceAbsolute ? 0 : autocvar_g_projectiles_newton_style), autocvar_g_projectiles_newton_style_2_minfactor, autocvar_g_projectiles_newton_style_2_maxfactor);
 +
 +      return outvelocity;
 +}
 +
 +#if 0
 +float mspercallsum;
 +float mspercallsstyle;
 +float mspercallcount;
 +#endif
 +void W_SetupProjectileVelocityEx(entity missile, vector dir, vector upDir, float pSpeed, float pUpSpeed, float pZSpeed, float spread, float forceAbsolute)
 +{
 +      if(missile.owner == world)
 +              error("Unowned missile");
 +
 +      dir = dir + upDir * (pUpSpeed / pSpeed);
 +      dir_z += pZSpeed / pSpeed;
 +      pSpeed *= vlen(dir);
 +      dir = normalize(dir);
 +
 +#if 0
 +      if(autocvar_g_projectiles_spread_style != mspercallsstyle)
 +      {
 +              mspercallsum = mspercallcount = 0;
 +              mspercallsstyle = autocvar_g_projectiles_spread_style;
 +      }
 +      mspercallsum -= gettime(GETTIME_HIRES);
 +#endif
 +      dir = W_CalculateSpread(dir, spread, g_weaponspreadfactor, autocvar_g_projectiles_spread_style);
 +#if 0
 +      mspercallsum += gettime(GETTIME_HIRES);
 +      mspercallcount += 1;
 +      print("avg: ", ftos(mspercallcount / mspercallsum), " per sec\n");
 +#endif
 +
 +      missile.velocity = W_CalculateProjectileVelocity(missile.owner.velocity, pSpeed * dir, forceAbsolute);
 +}
 +
 +void W_SetupProjectileVelocity(entity missile, float pSpeed, float spread) // WEAPONTODO
 +{
 +      W_SetupProjectileVelocityEx(missile, w_shotdir, v_up, pSpeed, 0, 0, spread, FALSE);
 +}
 +
 +
 +// ====================
 +//  Ballistics Tracing
 +// ====================
 +
 +void FireRailgunBullet (vector start, vector end, float bdamage, float bforce, float mindist, float maxdist, float halflifedist, float forcehalflifedist, float deathtype)
 +{
 +      vector hitloc, force, endpoint, dir;
 +      entity ent, endent;
 +      float endq3surfaceflags;
 +      float totaldmg;
 +      entity o;
 +
 +      float length;
 +      vector beampos;
 +      string snd;
 +      entity pseudoprojectile;
 +      float f, ffs;
 +
 +      pseudoprojectile = world;
 +
 +      railgun_start = start;
 +      railgun_end = end;
 +
 +      dir = normalize(end - start);
 +      length = vlen(end - start);
 +      force = dir * bforce;
 +
 +      // go a little bit into the wall because we need to hit this wall later
 +      end = end + dir;
 +
 +      totaldmg = 0;
 +
 +      // trace multiple times until we hit a wall, each obstacle will be made
 +      // non-solid so we can hit the next, while doing this we spawn effects and
 +      // note down which entities were hit so we can damage them later
 +      o = self;
 +      while (1)
 +      {
 +              if(self.antilag_debug)
 +                      WarpZone_traceline_antilag (self, start, end, FALSE, o, self.antilag_debug);
 +              else
 +                      WarpZone_traceline_antilag (self, start, end, FALSE, o, ANTILAG_LATENCY(self));
 +              if(o && WarpZone_trace_firstzone)
 +              {
 +                      o = world;
 +                      continue;
 +              }
 +
 +              if(trace_ent.solid == SOLID_BSP || trace_ent.solid == SOLID_SLIDEBOX)
 +                      Damage_DamageInfo(trace_endpos, bdamage, 0, 0, force, deathtype, trace_ent.species, self);
 +
 +              // if it is world we can't hurt it so stop now
 +              if (trace_ent == world || trace_fraction == 1)
 +                      break;
 +
 +              // make the entity non-solid so we can hit the next one
 +              trace_ent.railgunhit = TRUE;
 +              trace_ent.railgunhitloc = end;
 +              trace_ent.railgunhitsolidbackup = trace_ent.solid;
 +              trace_ent.railgundistance = vlen(WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos) - start);
 +              trace_ent.railgunforce = WarpZone_TransformVelocity(WarpZone_trace_transform, force);
 +
 +              // stop if this is a wall
 +              if (trace_ent.solid == SOLID_BSP)
 +                      break;
 +
 +              // make the entity non-solid
 +              trace_ent.solid = SOLID_NOT;
 +      }
 +
 +      endpoint = trace_endpos;
 +      endent = trace_ent;
 +      endq3surfaceflags = trace_dphitq3surfaceflags;
 +
 +      // find all the entities the railgun hit and restore their solid state
 +      ent = findfloat(world, railgunhit, TRUE);
 +      while (ent)
 +      {
 +              // restore their solid type
 +              ent.solid = ent.railgunhitsolidbackup;
 +              ent = findfloat(ent, railgunhit, TRUE);
 +      }
 +
 +      // spawn a temporary explosion entity for RadiusDamage calls
 +      //explosion = spawn();
 +
 +      // Find all non-hit players the beam passed close by
 +      if(deathtype == WEP_MINSTANEX || deathtype == WEP_NEX)
 +      {
-                       self.last_yoda = time; 
++              FOR_EACH_REALCLIENT(msg_entity)
++              if(msg_entity != self)
++              if(!msg_entity.railgunhit)
++              if(!(IS_SPEC(msg_entity) && msg_entity.enemy == self)) // we use realclient, so spectators can hear the whoosh too
 +              {
 +                      // nearest point on the beam
 +                      beampos = start + dir * bound(0, (msg_entity.origin - start) * dir, length);
 +
 +                      f = bound(0, 1 - vlen(beampos - msg_entity.origin) / 512, 1);
 +                      if(f <= 0)
 +                              continue;
 +
 +                      snd = strcat("weapons/nexwhoosh", ftos(floor(random() * 3) + 1), ".wav");
 +
 +                      if(!pseudoprojectile)
 +                              pseudoprojectile = spawn(); // we need this so the sound uses the "entchannel4" volume
 +                      soundtoat(MSG_ONE, pseudoprojectile, beampos, CH_SHOTS, snd, VOL_BASE * f, ATTEN_NONE);
 +              }
 +
 +              if(pseudoprojectile)
 +                      remove(pseudoprojectile);
 +      }
 +
 +      // find all the entities the railgun hit and hurt them
 +      ent = findfloat(world, railgunhit, TRUE);
 +      while (ent)
 +      {
 +              // get the details we need to call the damage function
 +              hitloc = ent.railgunhitloc;
 +
 +              f = ExponentialFalloff(mindist, maxdist, halflifedist, ent.railgundistance);
 +              ffs = ExponentialFalloff(mindist, maxdist, forcehalflifedist, ent.railgundistance);
 +
 +              if(accuracy_isgooddamage(self.realowner, ent))
 +                      totaldmg += bdamage * f;
 +
 +              // apply the damage
 +              if (ent.takedamage)
 +                      Damage (ent, self, self, bdamage * f, deathtype, hitloc, ent.railgunforce * ffs);
 +
 +              // create a small explosion to throw gibs around (if applicable)
 +              //setorigin (explosion, hitloc);
 +              //RadiusDamage (explosion, self, 10, 0, 50, world, world, 300, deathtype);
 +
 +              ent.railgunhitloc = '0 0 0';
 +              ent.railgunhitsolidbackup = SOLID_NOT;
 +              ent.railgunhit = FALSE;
 +              ent.railgundistance = 0;
 +
 +              // advance to the next entity
 +              ent = findfloat(ent, railgunhit, TRUE);
 +      }
 +
 +      // calculate hits and fired shots for hitscan
 +      accuracy_add(self, self.weapon, 0, min(bdamage, totaldmg));
 +
 +      trace_endpos = endpoint;
 +      trace_ent = endent;
 +      trace_dphitq3surfaceflags = endq3surfaceflags;
 +}
 +
 +void W_BallisticBullet_Hit (void)
 +{
 +      float f, q, g;
 +
 +      f = pow(bound(0, vlen(self.velocity) / vlen(self.oldvelocity), 1), 2); // energy multiplier
 +      q = 1 + self.dmg_edge / self.dmg;
 +
 +      if(other.solid == SOLID_BSP || other.solid == SOLID_SLIDEBOX)
 +              Damage_DamageInfo(self.origin, self.dmg * f, 0, 0, max(1, self.dmg_force) * normalize(self.velocity) * f, self.projectiledeathtype, other.species, self);
 +
 +      if(other && other != self.enemy)
 +      {
 +              endzcurveparticles();
 +
 +              yoda = 0;
 +              railgun_start = self.origin - 2 * frametime * self.velocity;
 +              railgun_end = self.origin + 2 * frametime * self.velocity;
 +              g = accuracy_isgooddamage(self.realowner, other);
 +              Damage(other, self, self.realowner, self.dmg * f, self.projectiledeathtype, self.origin, self.dmg_force * normalize(self.velocity) * f);
 +
 +              /*if(yoda && (time > (self.last_yoda + 5)))
 +              {
 +                      Send_Notification(NOTIF_ONE, self.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_YODA);
-       // special case for zero density and zero bullet constant: 
++                      self.last_yoda = time;
 +              }*/
 +
 +              // calculate hits for ballistic weapons
 +              if(g)
 +              {
 +                      // do not exceed 100%
 +                      q = min(self.dmg * q, self.dmg_total + f * self.dmg) - self.dmg_total;
 +                      self.dmg_total += f * self.dmg;
 +                      accuracy_add(self.realowner, self.realowner.weapon, 0, q);
 +              }
 +      }
 +
 +      self.enemy = other; // don't hit the same player twice with the same bullet
 +}
 +
 +void W_BallisticBullet_LeaveSolid_think()
 +{
 +      setorigin(self, self.W_BallisticBullet_LeaveSolid_origin);
 +      self.velocity = self.W_BallisticBullet_LeaveSolid_velocity;
 +
 +      self.think = self.W_BallisticBullet_LeaveSolid_think_save;
 +      self.nextthink = max(time, self.W_BallisticBullet_LeaveSolid_nextthink_save);
 +      self.W_BallisticBullet_LeaveSolid_think_save = func_null;
 +
 +      self.flags &= ~FL_ONGROUND;
 +
 +      if(self.enemy.solid == SOLID_BSP)
 +      {
 +              float f;
 +              f = pow(bound(0, vlen(self.velocity) / vlen(self.oldvelocity), 1), 2); // energy multiplier
 +              Damage_DamageInfo(self.origin, 0, 0, 0, max(1, self.dmg_force) * normalize(self.velocity) * -f, self.projectiledeathtype, 0, self);
 +      }
 +
 +      UpdateCSQCProjectile(self);
 +}
 +
 +float W_BallisticBullet_LeaveSolid(float eff)
 +{
 +      // move the entity along its velocity until it's out of solid, then let it resume
 +      vector vel = self.velocity;
 +      float dt, dst, velfactor, v0, vs;
 +      float maxdist;
 +      float E0_m, Es_m;
 +      float constant = self.dmg_radius * (other.ballistics_density ? other.ballistics_density : 1);
 +
 +      // outside the world? forget it
 +      if(self.origin_x > world.maxs_x || self.origin_y > world.maxs_y || self.origin_z > world.maxs_z || self.origin_x < world.mins_x || self.origin_y < world.mins_y || self.origin_z < world.mins_z)
 +              return 0;
 +
-       if not(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NONSOLID)
-       if not(trace_dphitcontents & DPCONTENTS_OPAQUE)
++      // special case for zero density and zero bullet constant:
 +
 +      if(self.dmg_radius == 0)
 +      {
 +              if(other.ballistics_density < 0)
 +                      constant = 0; // infinite travel distance
 +              else
 +                      return 0; // no penetration
 +      }
 +      else
 +      {
 +              if(other.ballistics_density < 0)
 +                      constant = 0; // infinite travel distance
 +              else if(other.ballistics_density == 0)
 +                      constant = self.dmg_radius;
 +              else
 +                      constant = self.dmg_radius * other.ballistics_density;
 +      }
 +
 +      // E(s) = E0 - constant * s, constant = area of bullet circle * material constant / mass
 +      v0 = vlen(vel);
 +
 +      E0_m = 0.5 * v0 * v0;
 +
 +      if(constant)
 +      {
 +              maxdist = E0_m / constant;
 +              // maxdist = 0.5 * v0 * v0 / constant
 +              // dprint("max dist = ", ftos(maxdist), "\n");
 +
 +              if(maxdist <= autocvar_g_ballistics_mindistance)
 +                      return 0;
 +      }
 +      else
 +      {
 +              maxdist = vlen(other.maxs - other.mins) + 1; // any distance, as long as we leave the entity
 +      }
 +
 +      traceline_inverted (self.origin, self.origin + normalize(vel) * maxdist, MOVE_NORMAL, self, TRUE);
 +      if(trace_fraction == 1) // 1: we never got out of solid
 +              return 0;
 +
 +      self.W_BallisticBullet_LeaveSolid_origin = trace_endpos;
 +
 +      dst = max(autocvar_g_ballistics_mindistance, vlen(trace_endpos - self.origin));
 +      // E(s) = E0 - constant * s, constant = area of bullet circle * material constant / mass
 +      Es_m = E0_m - constant * dst;
 +      if(Es_m <= 0)
 +      {
 +              // roundoff errors got us
 +              return 0;
 +      }
 +      vs = sqrt(2 * Es_m);
 +      velfactor = vs / v0;
 +
 +      dt = dst / (0.5 * (v0 + vs));
 +      // this is not correct, but the differential equations have no analytic
 +      // solution - and these times are very small anyway
 +      //print("dt = ", ftos(dt), "\n");
 +
 +      self.W_BallisticBullet_LeaveSolid_think_save = self.think;
 +      self.W_BallisticBullet_LeaveSolid_nextthink_save = self.nextthink;
 +      self.think = W_BallisticBullet_LeaveSolid_think;
 +      self.nextthink = time + dt;
 +
 +      vel = vel * velfactor;
 +
 +      self.velocity = '0 0 0';
 +      self.flags |= FL_ONGROUND; // prevent moving
 +      self.W_BallisticBullet_LeaveSolid_velocity = vel;
 +
 +      if(eff >= 0)
 +              if(vlen(trace_endpos - self.origin) > 4)
 +              {
 +                      endzcurveparticles();
 +                      trailparticles(self, eff, self.origin, trace_endpos);
 +              }
 +
 +      return 1;
 +}
 +
 +void W_BallisticBullet_Touch (void)
 +{
 +      //float density;
 +
 +      if(self.think == W_BallisticBullet_LeaveSolid_think) // skip this!
 +              return;
 +
 +      PROJECTILE_TOUCH;
 +      W_BallisticBullet_Hit ();
 +
 +      if(self.dmg_radius < 0) // these NEVER penetrate solid
 +      {
 +              remove(self);
 +              return;
 +      }
 +
 +      // if we hit "weapclip", bail out
 +      //
 +      // rationale of this check:
 +      //
 +      // any shader that is solid, nodraw AND trans is meant to clip weapon
 +      // shots and players, but has no other effect!
 +      //
 +      // if it is not trans, it is caulk and should not have this side effect
 +      //
 +      // matching shaders:
 +      //   common/weapclip (intended)
 +      //   common/noimpact (is supposed to eat projectiles, but is erased farther above)
 +      if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NODRAW)
- void fireBallisticBullet(vector start, vector dir, float spread, float pSpeed, float lifetime, float damage, float force, float dtype, float tracereffects, float gravityfactor, float bulletconstant)
++      if (!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NONSOLID))
++      if (!(trace_dphitcontents & DPCONTENTS_OPAQUE))
 +      {
 +              remove(self);
 +              return;
 +      }
 +
 +      // go through solid!
 +      if(!W_BallisticBullet_LeaveSolid(-1))
 +      {
 +              remove(self);
 +              return;
 +      }
 +
 +      self.projectiledeathtype |= HITTYPE_BOUNCE;
 +}
 +
 +void endFireBallisticBullet() // WEAPONTODO
 +{
 +      endzcurveparticles();
 +}
 +
 +void fireBallisticBullet_trace_callback(vector start, vector hit, vector end)
 +{
 +      if(vlen(trace_endpos - fireBallisticBullet_trace_callback_ent.origin) > 16)
 +              zcurveparticles_from_tracetoss(fireBallisticBullet_trace_callback_eff, fireBallisticBullet_trace_callback_ent.origin, trace_endpos, fireBallisticBullet_trace_callback_ent.velocity);
 +      WarpZone_trace_forent = world;
 +      self.owner = world;
 +}
 +
-       float antilagging;
-       antilagging = (autocvar_g_antilag_bullets && (pSpeed >= autocvar_g_antilag_bullets));
++void fireBallisticBullet(vector start, vector dir, float spread, float pSpeed, float lifetime, float damage, float force, float dtype, float tracereffects, float bulletconstant)
 +{
 +      float lag, dt, savetime; //, density;
 +      entity pl, oldself;
-       if(gravityfactor > 0)
-       {
-               proj.movetype = MOVETYPE_TOSS;
-               proj.gravity = gravityfactor;
-       }
-       else
-               proj.movetype = MOVETYPE_FLY;
 +
 +      entity proj;
 +      proj = spawn();
 +      proj.classname = "bullet";
 +      proj.owner = proj.realowner = self;
 +      PROJECTILE_MAKETRIGGER(proj);
-       W_SetupProjectileVelocityEx(proj, dir, v_up, pSpeed, 0, 0, spread, antilagging);
++      proj.movetype = MOVETYPE_FLY;
 +      proj.think = SUB_Remove;
 +      proj.nextthink = time + lifetime; // min(pLifetime, vlen(world.maxs - world.mins) / pSpeed);
-       if(antilagging)
-       {
-               float eff;
-               if(tracereffects & EF_RED)
-                       eff = particleeffectnum("tr_rifle");
-               else if(tracereffects & EF_BLUE)
-                       eff = particleeffectnum("tr_rifle_weak");
-               else
-                       eff = particleeffectnum("tr_bullet");
-               // NOTE: this may severely throw off weapon balance
-               lag = ANTILAG_LATENCY(self);
-               if(lag < 0.001)
-                       lag = 0;
-               if not(IS_REAL_CLIENT(self))
-                       lag = 0;
-               if(autocvar_g_antilag == 0 || self.cvar_cl_noantilag)
-                       lag = 0; // only do hitscan, but no antilag
++      W_SetupProjectileVelocityEx(proj, dir, v_up, pSpeed, 0, 0, spread, TRUE);
 +      proj.angles = vectoangles(proj.velocity);
 +      if(bulletconstant > 0)
 +              proj.dmg_radius = autocvar_g_ballistics_materialconstant / bulletconstant;
 +      else if(bulletconstant == 0)
 +              proj.dmg_radius = 0;
 +      else
 +              proj.dmg_radius = -1;
 +      // so: bulletconstant = bullet mass / area of bullet circle
 +      setorigin(proj, start);
 +      proj.flags = FL_PROJECTILE;
 +
 +      proj.touch = W_BallisticBullet_Touch;
 +      proj.dmg = damage;
 +      proj.dmg_force = force;
 +      proj.projectiledeathtype = dtype;
 +
 +      proj.oldvelocity = proj.velocity;
 +
 +      other = proj; MUTATOR_CALLHOOK(EditProjectile);
 +
-               if(lag)
-                       FOR_EACH_PLAYER(pl)
-                               if(pl != self)
-                                       antilag_takeback(pl, time - lag);
-               oldself = self;
-               self = proj;
++      float eff;
 +
-               savetime = frametime;
-               frametime = 0.05;
++      if(tracereffects & EF_RED)
++              eff = particleeffectnum("tr_rifle");
++      else if(tracereffects & EF_BLUE)
++              eff = particleeffectnum("tr_rifle_weak");
++      else
++              eff = particleeffectnum("tr_bullet");
 +
-               for(;;)
-               {
-                       // DP tracetoss is stupid and always traces in 0.05s
-                       // ticks. This makes it trace in 0.05*0.125s ticks
-                       // instead.
-                       vector v0;
-                       float g0;
-                       v0 = self.velocity;
-                       g0 = self.gravity;
-                       self.velocity = self.velocity * 0.125;
-                       self.gravity *= 0.125 * 0.125;
-                       trace_fraction = 0;
-                       fireBallisticBullet_trace_callback_ent = self;
-                       fireBallisticBullet_trace_callback_eff = eff;
-                       WarpZone_TraceToss_ThroughZone(self, self.owner, world, fireBallisticBullet_trace_callback);
-                       self.velocity = v0;
-                       self.gravity = g0;
-                       if(trace_fraction == 1)
-                               break;
-                               // won't hit anything anytime soon (DP's
-                               // tracetoss does 200 tics of, here,
-                               // 0.05*0.125s, that is, 1.25 seconds
++      // NOTE: this may severely throw off weapon balance
++      lag = ANTILAG_LATENCY(self);
++      if(lag < 0.001)
++              lag = 0;
++      if (!IS_REAL_CLIENT(self))
++              lag = 0;
++      if(autocvar_g_antilag == 0 || self.cvar_cl_noantilag)
++              lag = 0; // only do hitscan, but no antilag
 +
-                       other = trace_ent;
-                       dt = WarpZone_tracetoss_time * 0.125; // this is only approximate!
-                       setorigin(self, trace_endpos);
-                       self.velocity = WarpZone_tracetoss_velocity * (1 / 0.125);
++      if(lag)
++              FOR_EACH_PLAYER(pl)
++                      if(pl != self)
++                              antilag_takeback(pl, time - lag);
 +
-                       if(!SUB_OwnerCheck())
-                       {
-                               if(SUB_NoImpactCheck())
-                                       break;
++      oldself = self;
++      self = proj;
 +
-                               // hit the player
-                               W_BallisticBullet_Hit();
-                       }
++      savetime = frametime;
++      frametime = 0.05;
 +
-                       if(proj.dmg_radius < 0) // these NEVER penetrate solid
-                               break;
++      for(;;)
++      {
++              // DP tracetoss is stupid and always traces in 0.05s
++              // ticks. This makes it trace in 0.05*0.125s ticks
++              // instead.
++              vector v0;
++              v0 = self.velocity;
++              self.velocity = self.velocity * 0.125;
++              trace_fraction = 0;
++              fireBallisticBullet_trace_callback_ent = self;
++              fireBallisticBullet_trace_callback_eff = eff;
++              WarpZone_TraceToss_ThroughZone(self, self.owner, world, fireBallisticBullet_trace_callback);
++              self.velocity = v0;
++
++              if(trace_fraction == 1)
++                      break;
++                      // won't hit anything anytime soon (DP's
++                      // tracetoss does 200 tics of, here,
++                      // 0.05*0.125s, that is, 1.25 seconds
 +
-                       // if we hit "weapclip", bail out
-                       //
-                       // rationale of this check:
-                       //
-                       // any shader that is solid, nodraw AND trans is meant to clip weapon
-                       // shots and players, but has no other effect!
-                       //
-                       // if it is not trans, it is caulk and should not have this side effect
-                       //
-                       // matching shaders:
-                       //   common/weapclip (intended)
-                       //   common/noimpact (is supposed to eat projectiles, but is erased farther above)
-                       if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NODRAW)
-                       if not(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NONSOLID)
-                       if not(trace_dphitcontents & DPCONTENTS_OPAQUE)
++              other = trace_ent;
++              dt = WarpZone_tracetoss_time * 0.125; // this is only approximate!
++              setorigin(self, trace_endpos);
++              self.velocity = WarpZone_tracetoss_velocity * (1 / 0.125);
 +
-                       // go through solid!
-                       if(!W_BallisticBullet_LeaveSolid((other && (other.solid != SOLID_BSP)) ? eff : -1))
-                               break;
++              if(!SUB_OwnerCheck())
++              {
++                      if(SUB_NoImpactCheck())
 +                              break;
 +
-                       W_BallisticBullet_LeaveSolid_think();
++                      // hit the player
++                      W_BallisticBullet_Hit();
++              }
 +
-                       self.projectiledeathtype |= HITTYPE_BOUNCE;
-               }
-               frametime = savetime;
-               self = oldself;
++              if(proj.dmg_radius < 0) // these NEVER penetrate solid
++                      break;
 +
-               if(lag)
-                       FOR_EACH_PLAYER(pl)
-                               if(pl != self)
-                                       antilag_restore(pl);
++              // if we hit "weapclip", bail out
++              //
++              // rationale of this check:
++              //
++              // any shader that is solid, nodraw AND trans is meant to clip weapon
++              // shots and players, but has no other effect!
++              //
++              // if it is not trans, it is caulk and should not have this side effect
++              //
++              // matching shaders:
++              //   common/weapclip (intended)
++              //   common/noimpact (is supposed to eat projectiles, but is erased farther above)
++              if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NODRAW)
++              if (!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NONSOLID))
++              if (!(trace_dphitcontents & DPCONTENTS_OPAQUE))
++                      break;
 +
-               remove(proj);
++              // go through solid!
++              if(!W_BallisticBullet_LeaveSolid((other && (other.solid != SOLID_BSP)) ? eff : -1))
++                      break;
 +
-               return;
++              W_BallisticBullet_LeaveSolid_think();
 +
-       if(tracereffects & EF_RED)
-               CSQCProjectile(proj, TRUE, PROJECTILE_BULLET_GLOWING_TRACER, TRUE);
-       else if(tracereffects & EF_BLUE)
-               CSQCProjectile(proj, TRUE, PROJECTILE_BULLET_GLOWING, TRUE);
-       else
-               CSQCProjectile(proj, TRUE, PROJECTILE_BULLET, TRUE);
++              self.projectiledeathtype |= HITTYPE_BOUNCE;
 +      }
++      frametime = savetime;
++      self = oldself;
 +
-               if not (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
-                       Damage_DamageInfo(trace_endpos, damage, 0, 0, dir * max(1, force), dtype, trace_ent.species, self);                    
++      if(lag)
++              FOR_EACH_PLAYER(pl)
++                      if(pl != self)
++                              antilag_restore(pl);
++
++      remove(proj);
++
++      return;
 +}
 +
 +void fireBullet (vector start, vector dir, float spread, float damage, float force, float dtype, float tracer)
 +{
 +      vector  end;
 +
 +      dir = normalize(dir + randomvec() * spread);
 +      end = start + dir * MAX_SHOT_DISTANCE;
 +      if(self.antilag_debug)
 +              traceline_antilag (self, start, end, FALSE, self, self.antilag_debug);
 +      else
 +              traceline_antilag (self, start, end, FALSE, self, ANTILAG_LATENCY(self));
 +
 +      end = trace_endpos;
 +
 +      if (pointcontents (trace_endpos) != CONTENT_SKY)
 +      {
++              if (!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT))
++                      Damage_DamageInfo(trace_endpos, damage, 0, 0, dir * max(1, force), dtype, trace_ent.species, self);
 +
 +              Damage (trace_ent, self, self, damage, dtype, trace_endpos, dir * force);
 +      }
 +      trace_endpos = end;
 +}
index 2586c2ee49a2c23dcdcae491efdb8911fb7f9511,0000000000000000000000000000000000000000..ddf1424439d14e77008ff60580819bd73ecec595
mode 100644,000000..100644
--- /dev/null
@@@ -1,943 -1,0 +1,943 @@@
-       
 +/*
 +===========================================================================
 +
 +  CLIENT WEAPONSYSTEM CODE
 +  Bring back W_Weaponframe
 +
 +===========================================================================
 +*/
 +
 +.float weapon_frametime;
 +
 +float W_WeaponRateFactor()
 +{
 +      float t;
 +      t = 1.0 / g_weaponratefactor;
 +
 +      return t;
 +}
 +
 +// VorteX: static frame globals
 +const float WFRAME_DONTCHANGE = -1;
 +const float WFRAME_FIRE1 = 0;
 +const float WFRAME_FIRE2 = 1;
 +const float WFRAME_IDLE = 2;
 +const float WFRAME_RELOAD = 3;
 +.float wframe;
 +
 +void(float fr, float t, void() func) weapon_thinkf;
 +
 +float CL_Weaponentity_CustomizeEntityForClient()
 +{
 +      self.viewmodelforclient = self.owner;
 +      if(IS_SPEC(other))
 +              if(other.enemy == self.owner)
 +                      self.viewmodelforclient = other;
 +      return TRUE;
 +}
 +
 +/*
 + * supported formats:
 + *
 + * 1. simple animated model, muzzle flash handling on h_ model:
 + *    h_tuba.dpm, h_tuba.dpm.framegroups - invisible model controlling the animation
 + *      tags:
 + *        shot = muzzle end (shot origin, also used for muzzle flashes)
 + *        shell = casings ejection point (must be on the right hand side of the gun)
 + *        weapon = attachment for v_tuba.md3
 + *    v_tuba.md3 - first and third person model
 + *    g_tuba.md3 - pickup model
 + *
 + * 2. simple animated model, muzzle flash handling on v_ model:
 + *    h_tuba.dpm, h_tuba.dpm.framegroups - invisible model controlling the animation
 + *      tags:
 + *        weapon = attachment for v_tuba.md3
 + *    v_tuba.md3 - first and third person model
 + *      tags:
 + *        shot = muzzle end (shot origin, also used for muzzle flashes)
 + *        shell = casings ejection point (must be on the right hand side of the gun)
 + *    g_tuba.md3 - pickup model
 + *
 + * 3. fully animated model, muzzle flash handling on h_ model:
 + *    h_tuba.dpm, h_tuba.dpm.framegroups - animated first person model
 + *      tags:
 + *        shot = muzzle end (shot origin, also used for muzzle flashes)
 + *        shell = casings ejection point (must be on the right hand side of the gun)
 + *        handle = corresponding to the origin of v_tuba.md3 (used for muzzle flashes)
 + *    v_tuba.md3 - third person model
 + *    g_tuba.md3 - pickup model
 + *
 + * 4. fully animated model, muzzle flash handling on v_ model:
 + *    h_tuba.dpm, h_tuba.dpm.framegroups - animated first person model
 + *      tags:
 + *        shot = muzzle end (shot origin)
 + *        shell = casings ejection point (must be on the right hand side of the gun)
 + *    v_tuba.md3 - third person model
 + *      tags:
 + *        shot = muzzle end (for muzzle flashes)
 + *    g_tuba.md3 - pickup model
 + */
 +
 +// writes:
 +//   self.origin, self.angles
 +//   self.weaponentity
 +//   self.movedir, self.view_ofs
 +//   attachment stuff
 +//   anim stuff
 +// to free:
 +//   call again with ""
 +//   remove the ent
 +void CL_WeaponEntity_SetModel(string name)
 +{
 +      float v_shot_idx;
 +      if (name != "")
 +      {
 +              // if there is a child entity, hide it until we're sure we use it
 +              if (self.weaponentity)
 +                      self.weaponentity.model = "";
 +              setmodel(self, strcat("models/weapons/v_", name, ".md3")); // precision set below
 +              v_shot_idx = gettagindex(self, "shot"); // used later
 +              if(!v_shot_idx)
 +                      v_shot_idx = gettagindex(self, "tag_shot");
 +
 +              setmodel(self, strcat("models/weapons/h_", name, ".iqm")); // precision set below
 +              // preset some defaults that work great for renamed zym files (which don't need an animinfo)
 +              self.anim_fire1  = animfixfps(self, '0 1 0.01', '0 0 0');
 +              self.anim_fire2  = animfixfps(self, '1 1 0.01', '0 0 0');
 +              self.anim_idle   = animfixfps(self, '2 1 0.01', '0 0 0');
 +              self.anim_reload = animfixfps(self, '3 1 0.01', '0 0 0');
 +
 +              // if we have a "weapon" tag, let's attach the v_ model to it ("invisible hand" style model)
 +              // if we don't, this is a "real" animated model
 +              if(gettagindex(self, "weapon"))
 +              {
 +                      if (!self.weaponentity)
 +                              self.weaponentity = spawn();
 +                      setmodel(self.weaponentity, strcat("models/weapons/v_", name, ".md3")); // precision does not matter
 +                      setattachment(self.weaponentity, self, "weapon");
 +              }
 +              else if(gettagindex(self, "tag_weapon"))
 +              {
 +                      if (!self.weaponentity)
 +                              self.weaponentity = spawn();
 +                      setmodel(self.weaponentity, strcat("models/weapons/v_", name, ".md3")); // precision does not matter
 +                      setattachment(self.weaponentity, self, "tag_weapon");
 +              }
 +              else
 +              {
 +                      if(self.weaponentity)
 +                              remove(self.weaponentity);
 +                      self.weaponentity = world;
 +              }
 +
 +              setorigin(self,'0 0 0');
 +              self.angles = '0 0 0';
 +              self.frame = 0;
 +              self.viewmodelforclient = world;
 +
 +              float idx;
 +
 +              if(v_shot_idx) // v_ model attached to invisible h_ model
 +              {
 +                      self.movedir = gettaginfo(self.weaponentity, v_shot_idx);
 +              }
 +              else
 +              {
 +                      idx = gettagindex(self, "shot");
 +                      if(!idx)
 +                              idx = gettagindex(self, "tag_shot");
 +                      if(idx)
 +                              self.movedir = gettaginfo(self, idx);
 +                      else
 +                      {
 +                              print("WARNING: weapon model ", self.model, " does not support the 'shot' tag, will display shots TOTALLY wrong\n");
 +                              self.movedir = '0 0 0';
 +                      }
 +              }
 +
 +              if(self.weaponentity) // v_ model attached to invisible h_ model
 +              {
 +                      idx = gettagindex(self.weaponentity, "shell");
 +                      if(!idx)
 +                              idx = gettagindex(self.weaponentity, "tag_shell");
 +                      if(idx)
 +                              self.spawnorigin = gettaginfo(self.weaponentity, idx);
 +              }
 +              else
 +                      idx = 0;
 +              if(!idx)
 +              {
 +                      idx = gettagindex(self, "shell");
 +                      if(!idx)
 +                              idx = gettagindex(self, "tag_shell");
 +                      if(idx)
 +                              self.spawnorigin = gettaginfo(self, idx);
 +                      else
 +                      {
 +                              print("WARNING: weapon model ", self.model, " does not support the 'shell' tag, will display casings wrong\n");
 +                              self.spawnorigin = self.movedir;
 +                      }
 +              }
 +
 +              if(v_shot_idx)
 +              {
 +                      self.oldorigin = '0 0 0'; // use regular attachment
 +              }
 +              else
 +              {
 +                      if(self.weaponentity)
 +                      {
 +                              idx = gettagindex(self, "weapon");
 +                              if(!idx)
 +                                      idx = gettagindex(self, "tag_weapon");
 +                      }
 +                      else
 +                      {
 +                              idx = gettagindex(self, "handle");
 +                              if(!idx)
 +                                      idx = gettagindex(self, "tag_handle");
 +                      }
 +                      if(idx)
 +                      {
 +                              self.oldorigin = self.movedir - gettaginfo(self, idx);
 +                      }
 +                      else
 +                      {
 +                              print("WARNING: weapon model ", self.model, " does not support the 'handle' tag and neither does the v_ model support the 'shot' tag, will display muzzle flashes TOTALLY wrong\n");
 +                              self.oldorigin = '0 0 0'; // there is no way to recover from this
 +                      }
 +              }
 +
 +              self.viewmodelforclient = self.owner;
 +      }
 +      else
 +      {
 +              self.model = "";
 +              if(self.weaponentity)
 +                      remove(self.weaponentity);
 +              self.weaponentity = world;
 +              self.movedir = '0 0 0';
 +              self.spawnorigin = '0 0 0';
 +              self.oldorigin = '0 0 0';
 +              self.anim_fire1  = '0 1 0.01';
 +              self.anim_fire2  = '0 1 0.01';
 +              self.anim_idle   = '0 1 0.01';
 +              self.anim_reload = '0 1 0.01';
 +      }
 +
 +      self.view_ofs = '0 0 0';
 +
 +      if(self.movedir_x >= 0)
 +      {
 +              vector v0;
 +              v0 = self.movedir;
 +              self.movedir = shotorg_adjust(v0, FALSE, FALSE);
 +              self.view_ofs = shotorg_adjust(v0, FALSE, TRUE) - v0;
 +      }
 +      self.owner.stat_shotorg = compressShotOrigin(self.movedir);
 +      self.movedir = decompressShotOrigin(self.owner.stat_shotorg); // make them match perfectly
 +
 +      self.spawnorigin += self.view_ofs; // offset the casings origin by the same amount
 +
 +      // check if an instant weapon switch occurred
 +      setorigin(self, self.view_ofs);
 +      // reset animstate now
 +      self.wframe = WFRAME_IDLE;
 +      setanim(self, self.anim_idle, TRUE, FALSE, TRUE);
 +}
 +
 +vector CL_Weapon_GetShotOrg(float wpn)
 +{
 +      entity wi, oldself;
 +      vector ret;
 +      wi = get_weaponinfo(wpn);
 +      oldself = self;
 +      self = spawn();
 +      CL_WeaponEntity_SetModel(wi.mdl);
 +      ret = self.movedir;
 +      CL_WeaponEntity_SetModel("");
 +      remove(self);
 +      self = oldself;
 +      return ret;
 +}
 +
 +void CL_Weaponentity_Think()
 +{
 +      float tb;
 +      self.nextthink = time;
 +      if (intermission_running)
 +              self.frame = self.anim_idle_x;
 +      if (self.owner.weaponentity != self)
 +      {
 +              if (self.weaponentity)
 +                      remove(self.weaponentity);
 +              remove(self);
 +              return;
 +      }
 +      if (self.owner.deadflag != DEAD_NO)
 +      {
 +              self.model = "";
 +              if (self.weaponentity)
 +                      self.weaponentity.model = "";
 +              return;
 +      }
 +      if (self.weaponname != self.owner.weaponname || self.dmg != self.owner.modelindex || self.deadflag != self.owner.deadflag)
 +      {
 +              self.weaponname = self.owner.weaponname;
 +              self.dmg = self.owner.modelindex;
 +              self.deadflag = self.owner.deadflag;
 +
 +              CL_WeaponEntity_SetModel(self.owner.weaponname);
 +      }
 +
 +      tb = (self.effects & (EF_TELEPORT_BIT | EF_RESTARTANIM_BIT));
 +      self.effects = self.owner.effects & EFMASK_CHEAP;
 +      self.effects &= ~EF_LOWPRECISION;
 +      self.effects &= ~EF_FULLBRIGHT; // can mask team color, so get rid of it
 +      self.effects &= ~EF_TELEPORT_BIT;
 +      self.effects &= ~EF_RESTARTANIM_BIT;
 +      self.effects |= tb;
 +
 +      if(self.owner.alpha == default_player_alpha)
 +              self.alpha = default_weapon_alpha;
 +      else if(self.owner.alpha != 0)
 +              self.alpha = self.owner.alpha;
 +      else
 +              self.alpha = 1;
 +
 +      self.glowmod = self.owner.weaponentity_glowmod;
 +      self.colormap = self.owner.colormap;
 +      if (self.weaponentity)
 +      {
 +              self.weaponentity.effects = self.effects;
 +              self.weaponentity.alpha = self.alpha;
 +              self.weaponentity.colormap = self.colormap;
 +              self.weaponentity.glowmod = self.glowmod;
 +      }
 +
 +      self.angles = '0 0 0';
-       if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
++
 +      float f = (self.owner.weapon_nextthink - time);
 +      if (self.state == WS_RAISE && !intermission_running)
 +      {
 +              entity newwep = get_weaponinfo(self.owner.switchweapon);
 +              f = f * g_weaponratefactor / max(f, newwep.switchdelay_raise);
 +              //print(sprintf("CL_Weaponentity_Think(): cvar: %s, value: %f, nextthink: %f\n", sprintf("g_balance_%s_switchdelay_raise", newwep.netname), cvar(sprintf("g_balance_%s_switchdelay_raise", newwep.netname)), (self.owner.weapon_nextthink - time)));
 +              self.angles_x = -90 * f * f;
 +      }
 +      else if (self.state == WS_DROP && !intermission_running)
 +      {
 +              entity oldwep = get_weaponinfo(self.owner.weapon);
 +              f = 1 - f * g_weaponratefactor / max(f, oldwep.switchdelay_drop);
 +              //print(sprintf("CL_Weaponentity_Think(): cvar: %s, value: %f, nextthink: %f\n", sprintf("g_balance_%s_switchdelay_drop", oldwep.netname), cvar(sprintf("g_balance_%s_switchdelay_drop", oldwep.netname)), (self.owner.weapon_nextthink - time)));
 +              self.angles_x = -90 * f * f;
 +      }
 +      else if (self.state == WS_CLEAR)
 +      {
 +              f = 1;
 +              self.angles_x = -90 * f * f;
 +      }
 +}
 +
 +void CL_ExteriorWeaponentity_Think()
 +{
 +      float tag_found;
 +      self.nextthink = time;
 +      if (self.owner.exteriorweaponentity != self)
 +      {
 +              remove(self);
 +              return;
 +      }
 +      if (self.owner.deadflag != DEAD_NO)
 +      {
 +              self.model = "";
 +              return;
 +      }
 +      if (self.weaponname != self.owner.weaponname || self.dmg != self.owner.modelindex || self.deadflag != self.owner.deadflag)
 +      {
 +              self.weaponname = self.owner.weaponname;
 +              self.dmg = self.owner.modelindex;
 +              self.deadflag = self.owner.deadflag;
 +              if (self.owner.weaponname != "")
 +                      setmodel(self, strcat("models/weapons/v_", self.owner.weaponname, ".md3")); // precision set below
 +              else
 +                      self.model = "";
 +
 +              if((tag_found = gettagindex(self.owner, "tag_weapon")))
 +              {
 +                      self.tag_index = tag_found;
 +                      self.tag_entity = self.owner;
 +              }
 +              else
 +                      setattachment(self, self.owner, "bip01 r hand");
 +      }
 +      self.effects = self.owner.effects;
 +      self.effects |= EF_LOWPRECISION;
 +      self.effects = self.effects & EFMASK_CHEAP; // eat performance
 +      if(self.owner.alpha == default_player_alpha)
 +              self.alpha = default_weapon_alpha;
 +      else if(self.owner.alpha != 0)
 +              self.alpha = self.owner.alpha;
 +      else
 +              self.alpha = 1;
 +
 +      self.glowmod = self.owner.weaponentity_glowmod;
 +      self.colormap = self.owner.colormap;
 +
 +      CSQCMODEL_AUTOUPDATE();
 +}
 +
 +// spawning weaponentity for client
 +void CL_SpawnWeaponentity()
 +{
 +      self.weaponentity = spawn();
 +      self.weaponentity.classname = "weaponentity";
 +      self.weaponentity.solid = SOLID_NOT;
 +      self.weaponentity.owner = self;
 +      setmodel(self.weaponentity, ""); // precision set when changed
 +      setorigin(self.weaponentity, '0 0 0');
 +      self.weaponentity.angles = '0 0 0';
 +      self.weaponentity.viewmodelforclient = self;
 +      self.weaponentity.flags = 0;
 +      self.weaponentity.think = CL_Weaponentity_Think;
 +      self.weaponentity.customizeentityforclient = CL_Weaponentity_CustomizeEntityForClient;
 +      self.weaponentity.nextthink = time;
 +
 +      self.exteriorweaponentity = spawn();
 +      self.exteriorweaponentity.classname = "exteriorweaponentity";
 +      self.exteriorweaponentity.solid = SOLID_NOT;
 +      self.exteriorweaponentity.exteriorweaponentity = self.exteriorweaponentity;
 +      self.exteriorweaponentity.owner = self;
 +      setorigin(self.exteriorweaponentity, '0 0 0');
 +      self.exteriorweaponentity.angles = '0 0 0';
 +      self.exteriorweaponentity.think = CL_ExteriorWeaponentity_Think;
 +      self.exteriorweaponentity.nextthink = time;
 +
 +      {
 +              entity oldself = self;
 +              self = self.exteriorweaponentity;
 +              CSQCMODEL_AUTOINIT();
 +              self = oldself;
 +      }
 +}
 +
 +// Weapon subs
 +void w_clear()
 +{
 +      if (self.weapon != -1)
 +      {
 +              self.weapon = 0;
 +              self.switchingweapon = 0;
 +      }
 +      if (self.weaponentity)
 +      {
 +              self.weaponentity.state = WS_CLEAR;
 +              self.weaponentity.effects = 0;
 +      }
 +}
 +
 +void w_ready()
 +{
 +      if (self.weaponentity)
 +              self.weaponentity.state = WS_READY;
 +      weapon_thinkf(WFRAME_IDLE, 1000000, w_ready);
 +}
 +
 +.float prevdryfire;
 +.float prevwarntime;
 +float weapon_prepareattack_checkammo(float secondary)
 +{
-               
++      if (!(self.items & IT_UNLIMITED_WEAPON_AMMO))
 +      if (!WEP_ACTION(self.weapon, WR_CHECKAMMO1 + secondary))
 +      {
 +              // always keep the Mine Layer if we placed mines, so that we can detonate them
 +              entity mine;
 +              if(self.weapon == WEP_MINE_LAYER)
 +              for(mine = world; (mine = find(mine, classname, "mine")); ) if(mine.owner == self)
 +                      return FALSE;
 +
 +              if(self.weapon == self.switchweapon && time - self.prevdryfire > 1) // only play once BEFORE starting to switch weapons
 +              {
 +                      sound (self, CH_WEAPON_A, "weapons/dryfire.wav", VOL_BASE, ATTEN_NORM);
 +                      self.prevdryfire = time;
 +              }
 +
 +              if(WEP_ACTION(self.weapon, WR_CHECKAMMO2 - secondary)) // check if the other firing mode has enough ammo
 +              {
 +                      if(time - self.prevwarntime > 1)
 +                      {
 +                              Send_Notification(
 +                                      NOTIF_ONE,
 +                                      self,
 +                                      MSG_MULTI,
 +                                      ITEM_WEAPON_PRIMORSEC,
 +                                      self.weapon,
 +                                      secondary,
 +                                      (1 - secondary)
 +                              );
 +                      }
 +                      self.prevwarntime = time;
 +              }
 +              else // this weapon is totally unable to fire, switch to another one
 +              {
 +                      W_SwitchToOtherWeapon(self);
 +              }
-       if not(e.spawnflags & WEP_FLAG_RELOADABLE)
++
 +              return FALSE;
 +      }
 +      return TRUE;
 +}
 +.float race_penalty;
 +float weapon_prepareattack_check(float secondary, float attacktime)
 +{
 +      if(!weapon_prepareattack_checkammo(secondary))
 +              return FALSE;
 +
 +      //if sv_ready_restart_after_countdown is set, don't allow the player to shoot
 +      //if all players readied up and the countdown is running
 +      if(time < game_starttime || time < self.race_penalty) {
 +              return FALSE;
 +      }
 +
 +      if (timeout_status == TIMEOUT_ACTIVE) //don't allow the player to shoot while game is paused
 +              return FALSE;
 +
 +      // do not even think about shooting if switching
 +      if(self.switchweapon != self.weapon)
 +              return FALSE;
 +
 +      if(attacktime >= 0)
 +      {
 +              // don't fire if previous attack is not finished
 +              if (ATTACK_FINISHED(self) > time + self.weapon_frametime * 0.5)
 +                      return FALSE;
 +              // don't fire while changing weapon
 +              if (self.weaponentity.state != WS_READY)
 +                      return FALSE;
 +      }
 +
 +      return TRUE;
 +}
 +float weapon_prepareattack_do(float secondary, float attacktime)
 +{
 +      self.weaponentity.state = WS_INUSE;
 +
 +      self.spawnshieldtime = min(self.spawnshieldtime, time); // kill spawn shield when you fire
 +
 +      // if the weapon hasn't been firing continuously, reset the timer
 +      if(attacktime >= 0)
 +      {
 +              if (ATTACK_FINISHED(self) < time - self.weapon_frametime * 1.5)
 +              {
 +                      ATTACK_FINISHED(self) = time;
 +                      //dprint("resetting attack finished to ", ftos(time), "\n");
 +              }
 +              ATTACK_FINISHED(self) = ATTACK_FINISHED(self) + attacktime * W_WeaponRateFactor();
 +      }
 +      self.bulletcounter += 1;
 +      //dprint("attack finished ", ftos(ATTACK_FINISHED(self)), "\n");
 +      return TRUE;
 +}
 +float weapon_prepareattack(float secondary, float attacktime)
 +{
 +      if(weapon_prepareattack_check(secondary, attacktime))
 +      {
 +              weapon_prepareattack_do(secondary, attacktime);
 +              return TRUE;
 +      }
 +      else
 +              return FALSE;
 +}
 +
 +void weapon_thinkf(float fr, float t, void() func)
 +{
 +      vector a;
 +      vector of, or, ou;
 +      float restartanim;
 +
 +      if(fr == WFRAME_DONTCHANGE)
 +      {
 +              fr = self.weaponentity.wframe;
 +              restartanim = FALSE;
 +      }
 +      else if (fr == WFRAME_IDLE)
 +              restartanim = FALSE;
 +      else
 +              restartanim = TRUE;
 +
 +      of = v_forward;
 +      or = v_right;
 +      ou = v_up;
 +
 +      if (self.weaponentity)
 +      {
 +              self.weaponentity.wframe = fr;
 +              a = '0 0 0';
 +              if (fr == WFRAME_IDLE)
 +                      a = self.weaponentity.anim_idle;
 +              else if (fr == WFRAME_FIRE1)
 +                      a = self.weaponentity.anim_fire1;
 +              else if (fr == WFRAME_FIRE2)
 +                      a = self.weaponentity.anim_fire2;
 +              else // if (fr == WFRAME_RELOAD)
 +                      a = self.weaponentity.anim_reload;
 +              a_z *= g_weaponratefactor;
 +              setanim(self.weaponentity, a, restartanim == FALSE, restartanim, restartanim);
 +      }
 +
 +      v_forward = of;
 +      v_right = or;
 +      v_up = ou;
 +
 +      if(self.weapon_think == w_ready && func != w_ready && self.weaponentity.state == WS_RAISE)
 +      {
 +              backtrace("Tried to override initial weapon think function - should this really happen?");
 +      }
 +
 +      t *= W_WeaponRateFactor();
 +
 +      // VorteX: haste can be added here
 +      if (self.weapon_think == w_ready)
 +      {
 +              self.weapon_nextthink = time;
 +              //dprint("started firing at ", ftos(time), "\n");
 +      }
 +      if (self.weapon_nextthink < time - self.weapon_frametime * 1.5 || self.weapon_nextthink > time + self.weapon_frametime * 1.5)
 +      {
 +              self.weapon_nextthink = time;
 +              //dprint("reset weapon animation timer at ", ftos(time), "\n");
 +      }
 +      self.weapon_nextthink = self.weapon_nextthink + t;
 +      self.weapon_think = func;
 +      //dprint("next ", ftos(self.weapon_nextthink), "\n");
 +
 +      if((fr == WFRAME_FIRE1 || fr == WFRAME_FIRE2) && t)
 +      {
 +              if(self.weapon == WEP_SHOTGUN && fr == WFRAME_FIRE2)
 +                      animdecide_setaction(self, ANIMACTION_MELEE, restartanim);
 +              else
 +                      animdecide_setaction(self, ANIMACTION_SHOOT, restartanim);
 +      }
 +      else
 +      {
 +              if(self.anim_upper_action == ANIMACTION_SHOOT || self.anim_upper_action == ANIMACTION_MELEE)
 +                      self.anim_upper_action = 0;
 +      }
 +}
 +
 +float forbidWeaponUse()
 +{
 +      if(time < game_starttime && !autocvar_sv_ready_restart_after_countdown)
 +              return 1;
 +      if(round_handler_IsActive() && !round_handler_IsRoundStarted())
 +              return 1;
 +      if(self.player_blocked)
 +              return 1;
 +      if(self.freezetag_frozen)
 +              return 1;
 +      return 0;
 +}
 +
 +void W_WeaponFrame()
 +{
 +      vector fo, ri, up;
 +
 +      if (frametime)
 +              self.weapon_frametime = frametime;
 +
 +      if (!self.weaponentity || self.health < 1)
 +              return; // Dead player can't use weapons and injure impulse commands
 +
 +      if(forbidWeaponUse())
 +      if(self.weaponentity.state != WS_CLEAR)
 +      {
 +              w_ready();
 +              return;
 +      }
 +
 +      if(!self.switchweapon)
 +      {
 +              self.weapon = 0;
 +              self.switchingweapon = 0;
 +              self.weaponentity.state = WS_CLEAR;
 +              self.weaponname = "";
 +              self.items &= ~IT_AMMO;
 +              return;
 +      }
 +
 +      makevectors(self.v_angle);
 +      fo = v_forward; // save them in case the weapon think functions change it
 +      ri = v_right;
 +      up = v_up;
 +
 +      // Change weapon
 +      if (self.weapon != self.switchweapon)
 +      {
 +              if (self.weaponentity.state == WS_CLEAR)
 +              {
 +                      // end switching!
 +                      self.switchingweapon = self.switchweapon;
 +                      entity newwep = get_weaponinfo(self.switchweapon);
 +
 +                      self.items &= ~IT_AMMO;
 +                      self.items = self.items | (newwep.items & IT_AMMO);
 +
 +                      // the two weapon entities will notice this has changed and update their models
 +                      self.weapon = self.switchweapon;
 +                      self.weaponname = newwep.mdl;
 +                      self.bulletcounter = 0; // WEAPONTODO
 +                      WEP_ACTION(self.switchweapon, WR_SETUP);
 +                      self.weaponentity.state = WS_RAISE;
 +
 +                      // set our clip load to the load of the weapon we switched to, if it's reloadable
 +                      if(newwep.spawnflags & WEP_FLAG_RELOADABLE && newwep.reloading_ammo) // prevent accessing undefined cvars
 +                      {
 +                              self.clip_load = self.(weapon_load[self.switchweapon]);
 +                              self.clip_size = newwep.reloading_ammo;
 +                      }
 +                      else
 +                              self.clip_load = self.clip_size = 0;
 +
 +                      // VorteX: add player model weapon select frame here
 +                      // setcustomframe(PlayerWeaponRaise);
 +                      weapon_thinkf(WFRAME_IDLE, newwep.switchdelay_raise, w_ready);
 +                      //print(sprintf("W_WeaponFrame(): cvar: %s, value: %f\n", sprintf("g_balance_%s_switchdelay_raise", newwep.netname), cvar(sprintf("g_balance_%s_switchdelay_raise", newwep.netname))));
 +              }
 +              else if (self.weaponentity.state == WS_DROP)
 +              {
 +                      // in dropping phase we can switch at any time
 +                      self.switchingweapon = self.switchweapon;
 +              }
 +              else if (self.weaponentity.state == WS_READY)
 +              {
 +                      // start switching!
 +                      self.switchingweapon = self.switchweapon;
 +
 +                      entity oldwep = get_weaponinfo(self.weapon);
 +                      
 +#ifndef INDEPENDENT_ATTACK_FINISHED
 +                      if(ATTACK_FINISHED(self) <= time + self.weapon_frametime * 0.5)
 +                      {
 +#endif
 +                      sound (self, CH_WEAPON_SINGLE, "weapons/weapon_switch.wav", VOL_BASE, ATTN_NORM);
 +                      self.weaponentity.state = WS_DROP;
 +                      // set up weapon switch think in the future, and start drop anim
 +                      weapon_thinkf(WFRAME_DONTCHANGE, oldwep.switchdelay_drop, w_clear);
 +                      //print(sprintf("W_WeaponFrame(): cvar: %s, value: %f\n", sprintf("g_balance_%s_switchdelay_drop", oldwep.netname), cvar(sprintf("g_balance_%s_switchdelay_drop", oldwep.netname))));
 +#ifndef INDEPENDENT_ATTACK_FINISHED
 +                      }
 +#endif
 +              }
 +      }
 +
 +      // LordHavoc: network timing test code
 +      //if (self.button0)
 +      //      print(ftos(frametime), " ", ftos(time), " >= ", ftos(ATTACK_FINISHED(self)), " >= ", ftos(self.weapon_nextthink), "\n");
 +
 +      float w;
 +      w = self.weapon;
 +
 +      // call the think code which may fire the weapon
 +      // and do so multiple times to resolve framerate dependency issues if the
 +      // server framerate is very low and the weapon fire rate very high
 +      float c;
 +      c = 0;
 +      while (c < W_TICSPERFRAME)
 +      {
 +              c = c + 1;
 +              if(w && !(self.weapons & WepSet_FromWeapon(w)))
 +              {
 +                      if(self.weapon == self.switchweapon)
 +                              W_SwitchWeapon_Force(self, w_getbestweapon(self));
 +                      w = 0;
 +              }
 +
 +              v_forward = fo;
 +              v_right = ri;
 +              v_up = up;
 +
 +              if(w)
 +                      WEP_ACTION(self.weapon, WR_THINK);
 +              else
 +                      WEP_ACTION(self.weapon, WR_GONETHINK);
 +
 +              if (time + self.weapon_frametime * 0.5 >= self.weapon_nextthink)
 +              {
 +                      if(self.weapon_think)
 +                      {
 +                              v_forward = fo;
 +                              v_right = ri;
 +                              v_up = up;
 +                              self.weapon_think();
 +                      }
 +                      else
 +                              bprint("\{1}^1ERROR: undefined weapon think function for ", self.netname, "\n");
 +              }
 +      }
 +
 +#if 0
 +      if (self.items & IT_CELLS)
 +              self.currentammo = self.ammo_cells;
 +      else if (self.items & IT_ROCKETS)
 +              self.currentammo = self.ammo_rockets;
 +      else if (self.items & IT_NAILS)
 +              self.currentammo = self.ammo_nails;
 +      else if (self.items & IT_SHELLS)
 +              self.currentammo = self.ammo_shells;
 +      else
 +              self.currentammo = 1;
 +#endif
 +}
 +
 +void W_AttachToShotorg(entity flash, vector offset)
 +{
 +      entity xflash;
 +      flash.owner = self;
 +      flash.angles_z = random() * 360;
 +
 +      if(gettagindex(self.weaponentity, "shot"))
 +              setattachment(flash, self.weaponentity, "shot");
 +      else
 +              setattachment(flash, self.weaponentity, "tag_shot");
 +      setorigin(flash, offset);
 +
 +      xflash = spawn();
 +      copyentity(flash, xflash);
 +
 +      flash.viewmodelforclient = self;
 +
 +      if(self.weaponentity.oldorigin_x > 0)
 +      {
 +              setattachment(xflash, self.exteriorweaponentity, "");
 +              setorigin(xflash, self.weaponentity.oldorigin + offset);
 +      }
 +      else
 +      {
 +              if(gettagindex(self.exteriorweaponentity, "shot"))
 +                      setattachment(xflash, self.exteriorweaponentity, "shot");
 +              else
 +                      setattachment(xflash, self.exteriorweaponentity, "tag_shot");
 +              setorigin(xflash, offset);
 +      }
 +}
 +
 +void W_DecreaseAmmo(.float ammo_type, float ammo_use, float ammo_reload) // WEAPONTODO: why does this have ammo_type?
 +{
 +      if((self.items & IT_UNLIMITED_WEAPON_AMMO) && !ammo_reload)
 +              return;
 +
 +      // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
 +      if(ammo_reload)
 +      {
 +              self.clip_load -= ammo_use;
 +              self.(weapon_load[self.weapon]) = self.clip_load;
 +      }
 +      else
 +              self.(self.current_ammo) -= ammo_use;
 +}
 +
 +// weapon reloading code
 +
 +.float reload_ammo_amount, reload_ammo_min, reload_time;
 +.float reload_complain;
 +.string reload_sound;
 +
 +void W_ReloadedAndReady()
 +{
 +      // finish the reloading process, and do the ammo transfer
 +
 +      self.clip_load = self.old_clip_load; // restore the ammo counter, in case we still had ammo in the weapon before reloading
 +
 +      // if the gun uses no ammo, max out weapon load, else decrease ammo as we increase weapon load
 +      if(!self.reload_ammo_min || self.items & IT_UNLIMITED_WEAPON_AMMO)
 +              self.clip_load = self.reload_ammo_amount;
 +      else
 +      {
 +              while(self.clip_load < self.reload_ammo_amount && self.(self.current_ammo)) // make sure we don't add more ammo than we have
 +              {
 +                      self.clip_load += 1;
 +                      self.(self.current_ammo) -= 1;
 +              }
 +      }
 +      self.(weapon_load[self.weapon]) = self.clip_load;
 +
 +      // do not set ATTACK_FINISHED in reload code any more. This causes annoying delays if eg: You start reloading a weapon,
 +      // then quickly switch to another weapon and back. Reloading is canceled, but the reload delay is still there,
 +      // so your weapon is disabled for a few seconds without reason
 +
 +      //ATTACK_FINISHED(self) -= self.reload_time - 1;
 +
 +      w_ready();
 +}
 +
 +void W_Reload(float sent_ammo_min, string sent_sound)
 +{
 +      // set global values to work with
 +      entity e;
 +      e = get_weaponinfo(self.weapon);
 +
 +      self.reload_ammo_min = sent_ammo_min;
 +      self.reload_ammo_amount = e.reloading_ammo;;
 +      self.reload_time = e.reloading_time;
 +      self.reload_sound = sent_sound;
 +
 +      // don't reload weapons that don't have the RELOADABLE flag
-       if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
++      if (!(e.spawnflags & WEP_FLAG_RELOADABLE))
 +      {
 +              dprint("Warning: Attempted to reload a weapon that does not have the WEP_FLAG_RELOADABLE flag. Fix your code!\n");
 +              return;
 +      }
 +
 +      // return if reloading is disabled for this weapon
 +      if(!self.reload_ammo_amount)
 +              return;
 +
 +      // our weapon is fully loaded, no need to reload
 +      if (self.clip_load >= self.reload_ammo_amount)
 +              return;
 +
 +      // no ammo, so nothing to load
 +      if(!self.(self.current_ammo) && self.reload_ammo_min)
-               if not(WEP_ACTION(self.weapon, WR_CHECKAMMO1) + WEP_ACTION(self.weapon, WR_CHECKAMMO2))
++      if (!(self.items & IT_UNLIMITED_WEAPON_AMMO))
 +      {
 +              if(IS_REAL_CLIENT(self) && self.reload_complain < time)
 +              {
 +                      play2(self, "weapons/unavailable.wav");
 +                      sprint(self, strcat("You don't have enough ammo to reload the ^2", W_Name(self.weapon), "\n"));
 +                      self.reload_complain = time + 1;
 +              }
 +              // switch away if the amount of ammo is not enough to keep using this weapon
++              if (!(WEP_ACTION(self.weapon, WR_CHECKAMMO1) + WEP_ACTION(self.weapon, WR_CHECKAMMO2)))
 +              {
 +                      self.clip_load = -1; // reload later
 +                      W_SwitchToOtherWeapon(self);
 +              }
 +              return;
 +      }
 +
 +      if (self.weaponentity)
 +      {
 +              if (self.weaponentity.wframe == WFRAME_RELOAD)
 +                      return;
 +
 +              // allow switching away while reloading, but this will cause a new reload!
 +              self.weaponentity.state = WS_READY;
 +      }
 +
 +      // now begin the reloading process
 +
 +      sound(self, CH_WEAPON_SINGLE, self.reload_sound, VOL_BASE, ATTEN_NORM);
 +
 +      // do not set ATTACK_FINISHED in reload code any more. This causes annoying delays if eg: You start reloading a weapon,
 +      // then quickly switch to another weapon and back. Reloading is canceled, but the reload delay is still there,
 +      // so your weapon is disabled for a few seconds without reason
 +
 +      //ATTACK_FINISHED(self) = max(time, ATTACK_FINISHED(self)) + self.reload_time + 1;
 +
 +      weapon_thinkf(WFRAME_RELOAD, self.reload_time, W_ReloadedAndReady);
 +
 +      if(self.clip_load < 0)
 +              self.clip_load = 0;
 +      self.old_clip_load = self.clip_load;
 +      self.clip_load = self.(weapon_load[self.weapon]) = -1;
 +}