Merge remote branch 'origin/master' into fruitiex/animations
authorSamual <samual@xonotic.org>
Thu, 18 Aug 2011 07:58:57 +0000 (03:58 -0400)
committerSamual <samual@xonotic.org>
Thu, 18 Aug 2011 07:58:57 +0000 (03:58 -0400)
Conflicts:
defaultXonotic.cfg

1  2 
defaultXonotic.cfg
qcsrc/server/autocvars.qh
qcsrc/server/cl_client.qc
qcsrc/server/cl_physics.qc
qcsrc/server/cl_player.qc
qcsrc/server/cl_weaponsystem.qc
qcsrc/server/defs.qh
qcsrc/server/t_jumppads.qc
qcsrc/server/w_shotgun.qc

diff --combined defaultXonotic.cfg
index edfa00f4d1a6005ffb51de56c98fbb5e7c145faf,3dc51da56553df8c0ceb4a05c886bfeec4b16ceb..6da1710d16562ad7e3855c64201b0e199ff8999a
@@@ -52,6 -52,7 +52,7 @@@ alias asay_drop "say_team (%l) dropped 
  // other aliases
  alias +hook +button6
  alias -hook -button6
+ alias use "impulse 21"
  alias ready "cmd ready"
  alias lockteams "sv_cmd lockteams"
  alias unlockteams "sv_cmd unlockteams"
@@@ -281,7 -282,7 +282,7 @@@ cl_rollangle 0 // amount of view tilt w
  v_kicktime 0 // how long damage kicks of the view last, default is 0 seconds
  gl_polyblend 0 // whether to use screen tints, this has now been replaced by a better system in CSQC
  r_motionblur 0 // motion blur value, default is 0
- r_damageblur 0 // motion blur when damaged, default is 0
+ r_damageblur 0 // motion blur when damaged, default is 0 (removed in Xonotic)
  
  r_bloom_blur 8
  r_bloom_brighten 3
@@@ -320,7 -321,6 +321,6 @@@ seta cl_hitsound 1 "play a hit notifie
  set cl_hitsound_antispam_time 0.05 "don't play the hitsound more often than this"
  
  seta cl_eventchase_death 1 "camera goes into 3rd person mode when the player is dead"
- seta cl_eventchase_intermission 1 "camera goes into 3rd person mode when the match ends"
  seta cl_eventchase_distance 140 "final camera distance"
  seta cl_eventchase_speed 1.3 "how fast the camera slides back, 0 is instant"
  
@@@ -386,7 -386,6 +386,7 @@@ set sv_doublejump 0 "allow Quake 2-styl
  set sv_jumpspeedcap_min "" "lower bound on the baseline velocity of a jump; final velocity will be >= (jumpheight * min + jumpheight)"
  set sv_jumpspeedcap_max "" "upper bound on the baseline velocity of a jump; final velocity will be <= (jumpheight * max + jumpheight)"
  set sv_jumpspeedcap_max_disable_on_ramps 0 "disable upper baseline velocity bound on ramps to preserve the old rampjump style"
 +set sv_player_jumpanim_minfall 48 "minimum distance player has to have below their feet before the jump animation will be activated (only when falling, +jump will play anim instantly)"
  
  seta sv_precacheplayermodels 1
  seta sv_precacheweapons 0
@@@ -451,8 -450,8 +451,8 @@@ set bot_ai_aimskill_offset 0.3 "Amount 
  set bot_ai_aimskill_think 1 "Aiming velocity. Use values below 1 for slower aiming"
  set bot_ai_custom_weapon_priority_distances "300 850" "Define close and far distances in any order. Based on the distance to the enemy bots will choose different weapons"
  set bot_ai_custom_weapon_priority_far   "minstanex nex rifle electro rocketlauncher grenadelauncher hagar hlac crylink laser uzi fireball seeker shotgun tuba minelayer"      "Desired weapons for far distances ordered by priority"
- set bot_ai_custom_weapon_priority_mid   "minstanex rocketlauncher nex fireball seeker grenadelauncher electro uzi rifle crylink hlac hagar shotgun laser tuba minelayer"      "Desired weapons for middle distances ordered by priority"
- set bot_ai_custom_weapon_priority_close "minstanex shotgun nex uzi hlac tuba seeker hagar crylink grenadelauncher electro rifle rocketlauncher laser fireball minelayer"      "Desired weapons for close distances ordered by priority"
+ set bot_ai_custom_weapon_priority_mid   "minstanex rocketlauncher nex fireball seeker grenadelauncher electro uzi crylink hlac hagar shotgun laser rifle tuba minelayer"      "Desired weapons for middle distances ordered by priority"
+ set bot_ai_custom_weapon_priority_close "minstanex shotgun nex uzi hlac tuba seeker hagar crylink grenadelauncher electro rocketlauncher laser fireball rifle minelayer"      "Desired weapons for close distances ordered by priority"
  set bot_ai_weapon_combo 1     "Enable bots to do weapon combos"
  set bot_ai_weapon_combo_threshold 0.4 "Try to make a combo N seconds after the last attack"
  set bot_ai_friends_aware_pickup_radius "500"  "Bots will not pickup items if a team mate is this distance near the item"
@@@ -495,7 -494,7 +495,7 @@@ seta g_antilag 2   "AntiLag (0 = no AntiL
  set g_trueaim_minrange 44 "TrueAim minimum range (TrueAim adjusts shots so they hit the crosshair point even though the gun is not at the screen center)"
  set g_antilag_nudge 0 "don't touch"
  set g_antilag_bullets 1 "Bullets AntiLag (0 = no AntiLag, 1 = server side hit scan in the past) - DO NOT TOUCH (severely changes weapon balance)"
- set g_shootfromclient 1 "let client decide if it has the gun left or right; if set to 2, center handedness is allowed, and defaulted to, too; see also cl_gunalign"
+ set g_shootfromclient 2 "let client decide if it has the gun left or right; if set to 2, center handedness is allowed; see also cl_gunalign"
  set g_shootfromeye 0 "shots are fired from your eye/crosshair; visual gun position can still be influenced by cl_gunalign 1 and 2"
  set g_shootfromcenter 0 "weapon gets moved to the center, shots still come from the barrel of your weapon; visual gun position can still be influenced by cl_gunalign 1 and 2"
  set g_shootfromfixedorigin "" "if set to a string like 0 y z, the gun is moved to the given y and z coordinates. If set to a string like x y z, the whole shot origin is used"
@@@ -703,7 -702,7 +703,7 @@@ set g_ctf_flagcarrier_selfforce 
  set g_ctf_fullbrightflags 0
  set g_ctf_dynamiclights 0
  set g_ctf_allow_drop 1        "dropping allows circumventing carrierkill score, so enable this with care!"
- set g_ctf_reverse 0   "when 1, bases/flags are switched :P you have to capture your OWN flag by bringing it to the ENEMY's"
+ set g_ctf_reverse 0   "if enabled, flags positions are switched: you have to capture the enemy's flag from your own base by bringing it to your own flag in the enemy base"
  set g_balance_ctf_delay_collect 1.0
  set g_balance_ctf_damageforcescale 1
  
@@@ -900,6 -899,8 +900,8 @@@ set g_multijump_add 0      "0 = make the cur
  set g_multijump_speed -999999 "Minimum vertical speed a player must have in order to jump again"
  
  // effects
+ r_glsl_vertextextureblend_usebothalphas 1 // allows to abuse texture blending as detail texture
+ r_glsl_postprocess 1
  r_picmipsprites 0 // Xonotic uses sprites that should never be picmipped (team mate, typing, waypoints)
  r_picmipworld 1
  gl_picmip_world 0
@@@ -911,7 -912,7 +913,7 @@@ r_shadow_realtime_world_lightmaps 
  seta r_ambient 4
  cl_decals_fadetime 5
  cl_decals_time 2
- seta cl_gunalign 3 "Gun alignment; 1 = right, 2 = left, 3 = center or right, 4 = center or left"
+ seta cl_gunalign 3 "Gun alignment; 1 = center (if allowed by g_shootfromclient) or right, 2 = center (if allowed by g_shootfromclient) or left, 3 = right only, 4 = left only"
  seta cl_nogibs 0 "reduce number of violence effects, or remove them totally"
  seta cl_particlegibs 0 "simpler gibs"
  seta cl_gibs_damageforcescale 3.5 "force to push around gibs"
@@@ -1006,20 -1007,30 +1008,30 @@@ bind ENTER +jum
  bind SPACE +jump
  
  // weapons
- bind 1 "impulse 1"
- bind 2 "impulse 2"
- bind 3 "impulse 3"
- bind 4 "impulse 4"
- bind 5 "impulse 5"
- bind 6 "impulse 6"
- bind 7 "impulse 7"
- bind 8 "impulse 8"
- bind 9 "impulse 9"
- bind 0 "impulse 14" // cycles the superweapons
+ alias weapon_group_1 "impulse 1"
+ alias weapon_group_2 "impulse 2"
+ alias weapon_group_3 "impulse 3"
+ alias weapon_group_4 "impulse 4"
+ alias weapon_group_5 "impulse 5"
+ alias weapon_group_6 "impulse 6"
+ alias weapon_group_7 "impulse 7"
+ alias weapon_group_8 "impulse 8"
+ alias weapon_group_9 "impulse 9"
+ alias weapon_group_0 "impulse 14" // cycles the superweapons
+ bind 0 weapon_group_0
+ bind 1 weapon_group_1
+ bind 2 weapon_group_2
+ bind 3 weapon_group_3
+ bind 4 weapon_group_4
+ bind 5 weapon_group_5
+ bind 6 weapon_group_6
+ bind 7 weapon_group_7
+ bind 8 weapon_group_8
+ bind 9 weapon_group_9
  bind q weaplast
  bind MOUSE1 +fire
  bind MOUSE2 +fire2
- bind MOUSE3 +zoom
+ bind MOUSE3 togglezoom
  bind MOUSE4 weaplast
  bind MOUSE5 +hook
  bind MWHEELUP weapnext
@@@ -1027,6 -1038,7 +1039,7 @@@ bind MWHEELDOWN weappre
  bind r reload
  bind BACKSPACE dropweapon
  bind g dropweapon
+ // TODO change this to "use" once we can
  bind f +use
  
  // misc
@@@ -1200,7 -1212,7 +1213,7 @@@ set sv_curl_serverpackages_auto 1 "auto
  
  set sv_motd ""
  
- set g_waypoints_for_items 1   "make waypoints out of items, values: 0 = never, 1 = unless the mapper prevents it by worldspawn.spawnflags & 1, 2 = always"
+ set g_waypoints_for_items 0   "make waypoints out of items, values: 0 = never, 1 = unless the mapper prevents it by worldspawn.spawnflags & 1, 2 = always"
  
  seta g_maplist_votable 6 "number of maps that are shown in the map voting at the end of a match"
  seta g_maplist_votable_keeptwotime 15
@@@ -1228,6 -1240,7 +1241,7 @@@ set g_nick_flood_penalty 0.5 "duration 
  set g_nick_flood_penalty_yellow 3 "number of changes to allow before warning and movement blocking"
  set g_nick_flood_penalty_red 30 "number of changes to allow before totally disorienting the player"
  
+ seta g_waypointsprite_uppercase 1
  set g_waypointsprite_normdistance 512
  set g_waypointsprite_minscale 0.5
  set g_waypointsprite_minalpha 0.4
@@@ -1238,16 -1251,22 +1252,22 @@@ set g_waypointsprite_deadlifetime 
  set g_waypointsprite_limitedrange 5120
  set g_waypointsprite_stuffbinds 0
  seta g_waypointsprite_scale 1
+ seta g_waypointsprite_fontsize 12
  seta g_waypointsprite_alpha 1 "This allows the client to control transparency of the waypoint"
  seta g_waypointsprite_edgefadealpha 0.5 "alpha multiplier near the edge"
  seta g_waypointsprite_edgefadescale 1 "scale multiplier near the edge"
  seta g_waypointsprite_edgefadedistance 50 "distance in virtual pixels from edge where to start fading"
+ seta g_waypointsprite_edgeoffset_bottom 0 "offset of how close the waypoint can be to the bottom edge of the screen"
+ seta g_waypointsprite_edgeoffset_left 0 "offset of how close the waypoint can be to the left edge of the screen"
+ seta g_waypointsprite_edgeoffset_right 0 "offset of how close the waypoint can be to the right edge of the screen"
+ seta g_waypointsprite_edgeoffset_top 0 "offset of how close the waypoint can be to the top edge of the screen"
  seta g_waypointsprite_crosshairfadealpha 0.25 "alpha multiplier near crosshair"
  seta g_waypointsprite_crosshairfadescale 1 "scale multiplier near the crosshair"
  seta g_waypointsprite_crosshairfadedistance 150 "distance in virtual pixels from crosshair where to start fading"
  seta g_waypointsprite_distancefadealpha 1 "alpha multiplier near distance"
  seta g_waypointsprite_distancefadescale 0.7 "scale multiplier near the distance"
  seta g_waypointsprite_distancefadedistancemultiplier 0.5 "distance in map sizes from distance where to stop fading"
+ set g_waypointsprite_spam 0 "Debugging feature. Set to 10 and load courtfun in race mode to test."
  alias "g_waypointsprite_personal"     "impulse 30"
  alias "g_waypointsprite_personal_p"   "impulse 31"
  alias "g_waypointsprite_personal_d"   "impulse 32"
@@@ -1260,7 -1279,7 +1280,7 @@@ alias "g_waypointsprite_team_danger_p"  
  alias "g_waypointsprite_team_danger_d"        "impulse 39"
  alias "g_waypointsprite_clear_personal"       "impulse 47"
  alias "g_waypointsprite_clear"        "impulse 48"
- alias "g_waypointsprite_toggle"       "impulse 49"
+ alias "g_waypointsprite_toggle"       "toggle cl_hidewaypoints"
  // key for that?
  seta cl_hidewaypoints 0 "disable static waypoints, only show team waypoints"
  
@@@ -1286,7 -1305,6 +1306,6 @@@ set g_balance_keyhunt_delay_round 
  set g_balance_keyhunt_delay_tracking 10
  set g_balance_keyhunt_delay_fadeout 2
  set g_balance_keyhunt_delay_collect 1.5
- set g_balance_keyhunt_delay_drop 0.4
  set g_balance_keyhunt_maxdist 150
  set g_balance_keyhunt_score_collect 3
  set g_balance_keyhunt_score_carrierfrag 2
@@@ -1364,6 -1382,7 +1383,7 @@@ seta "userbind11_press" "say_team attac
  seta "userbind12_press" "say_team killed flagcarrier (l:%y^7); g_waypointsprite_team_p"; seta "userbind12_release" ""; seta "userbind12_description" "team: killed flag, icon"
  seta "userbind13_press" "say_team dropped flag (l:%d^7); g_waypointsprite_team_here_d"; seta "userbind13_release" ""; seta "userbind13_description" "team: dropped flag, icon"
  seta "userbind14_press" "say_team dropped gun %w^7 (l:%l^7); g_waypointsprite_team_here; wait; dropweapon"; seta "userbind14_release" ""; seta "userbind14_description" "team: drop gun, icon"
+ // TODO change this to "use" once we can
  seta "userbind15_press" "say_team dropped flag/key %w^7 (l:%l^7); g_waypointsprite_team_here; wait; +use"; seta "userbind15_release" "-use"; seta "userbind15_description" "team: drop flag/key, icon"
  seta "userbind16_press" "say :-) / nice one"; seta "userbind16_release" ""; seta "userbind16_description" "chat: nice one"
  seta "userbind17_press" "say good game"; seta "userbind17_release" ""; seta "userbind17_description" "chat: good game"
@@@ -1473,6 -1492,8 +1493,8 @@@ seta hud_showbinds_limit 2      "maximum num
  seta hud_colorflash_alpha 0.5 "starting alpha of the color flash"
  
  seta hud_damage 0.55 "an improved version of gl_polyblend for damage, draw an image instead when hurt"
+ seta hud_damage_blur 10 "Use postprocessing to blur the screen when you have taken damage. This can be paired with current hud damage or just used alone. Higher values = more blur"
+ seta hud_damage_blur_alpha 0.5 "Amount of alpha to use when merging the blurred layers back into the render. Turning this up higher will remove bloom, so it's best to find a balance"
  seta hud_damage_gentle_alpha_multiplier 0.10 "how much to multiply alpha of flash when using the cl_gentle version, it's much more opaque than the non-gentle version"
  seta hud_damage_gentle_color "1 0.7 1" "color of flash for cl_gentle version"
  seta hud_damage_color "1 0 0" "color of flash"
@@@ -1485,7 -1506,15 +1507,15 @@@ seta hud_damage_pain_threshold_lower_he
  seta hud_damage_pain_threshold_pulsating_min 0.6 "minimum value when calculating the pulse: max(pulsating_min, fabs(sin(PI * time / period))"
  seta hud_damage_pain_threshold_pulsating_period 0.8 "one pulse every X seconds"
  
+ seta hud_powerup 0 "power of the sharpen effect when owning the shield or strength powerups, default is 0.5"
+ seta hud_postprocessing 1 "enables the ability for effects such as hud_damage_blur and hud_contents to apply a postprocessing method upon the screen - enabling this disables manual editing of the postprocess cvars"
+ seta hud_postprocessing_maxbluralpha 0 "maximum alpha which the blur postprocess can be, default is 0.5"
+ seta hud_postprocessing_maxblurradius 8 "maximum radius which the blur postprocess can be, default is 8"
  seta hud_contents 1 "an improved version of gl_polyblend for liquids such as water/lava/slime, draw a filler when inside the liquid"
+ seta hud_contents_blur 10 "Use postprocessing to blur the screen when you are inside a liquid. Higher values = more blur"
+ seta hud_contents_blur_alpha 0.5 "Amount of alpha to use when merging the blurred layers back into the render. Turning this up higher will remove bloom, so it's best to find a balance"
  seta hud_contents_factor 1 "factor at which to multiply the current faded value."
  seta hud_contents_fadeintime 0.02 "factor of time it takes for the alpha level to reach normal value when entering the liquid"
  seta hud_contents_fadeouttime 0.1 "factor of time it takes for the alpha level to reach normal value when leaving the liquid"
@@@ -1609,8 -1638,9 +1639,9 @@@ seta v_kicktime $v_kicktim
  seta r_subdivisions_tolerance $r_subdivisions_tolerance
  
  // ticrate
- sys_ticrate 0.0166667
- cl_netfps 60 // should match
+ //sys_ticrate 0.0166667
+ sys_ticrate 0.0333333
+ cl_netfps 60 // should match or be a multiple
  sv_gameplayfix_delayprojectiles 0
  sv_gameplayfix_q2airaccelerate 1
  sv_gameplayfix_stepmultipletimes 1
@@@ -1665,7 -1695,6 +1696,6 @@@ set capturelimit 
  
  // hud: font size
  seta hud_fontsize 11
- seta scr_centersize 12
  seta hud_width 560
  
  // these entities are not referenced by anything directly, they just represent
@@@ -1903,7 -1932,7 +1933,7 @@@ seta cl_vehicle_spiderbot_cross_alpha 0
  seta cl_vehicle_spiderbot_cross_size 1
  
  //cl_gunalign calculator
- seta menu_cl_gunalign 3 "Gun alignment; 1 = right, 2 = left, 3 = center or right, 4 = center or left"
+ seta menu_cl_gunalign 3 "Gun alignment; 1 = center (if allowed by g_shootfromclient) or right, 2 = center (if allowed by g_shootfromclient) or left, 3 = right only, 4 = left only"
  alias _gunalign_01 "cl_gunalign 1"
  alias _gunalign_02 "cl_gunalign 2"
  alias _gunalign_03 "cl_gunalign 3"
@@@ -1952,6 -1981,7 +1982,7 @@@ set speedmeter 0 "print landing speeds
  set developer_shtest 0 "experimental speedhack detection"
  set waypoint_benchmark 0 "quit after waypoint loading to benchmark bot navigation code"
  set g_debug_bot_commands 0 "print scripted bot commands before executing"
+ set g_debug_defaultsounds 0 "always use default sounds"
  
  // debug cvars for keyhunt attaching
  set _angles "0 0 0"
@@@ -2052,7 -2082,7 +2083,7 @@@ sv_cullentities_trace 
  r_cullentities_trace 0
  
  // less "lagging" of other players, but also less PL tolerant... let's try this
- sv_clmovement_inputtimeout 0.05
+ sv_clmovement_inputtimeout 0.07 // more than 2, less than 3 server frames
  
  // exact gloss looks better, e.g. on g-23
  r_shadow_glossexact 1
@@@ -2121,11 -2151,15 +2152,15 @@@ set g_playerstats_debug 0 "when 1, play
  // create this cvar in case the engine did not
  set snd_soundradius 1200
  
+ // declare the channels we use
+ seta snd_channel8volume 1 "QuakeC controlled background music volume"
+ seta snd_channel9volume 1 "QuakeC controlled ambient sound volume"
  // loading screen
  scr_loadingscreen_background 0
  scr_loadingscreen_barcolor "0 0.5 1"
  scr_loadingscreen_barheight 12
- scr_loadingscreen_count 12
+ scr_loadingscreen_count 13
  scr_loadingscreen_scale 999
  scr_loadingscreen_scale_base 1
  scr_loadingscreen_scale_limit 2
@@@ -2140,6 -2174,7 +2175,7 @@@ exec ctfscoring-ai.cf
  exec effects-normal.cfg
  exec physicsX.cfg
  exec turrets.cfg
+ exec vehicles.cfg
  
  // hud cvar descriptions
  exec _hud_descriptions.cfg
index 50e46f33776090e078e2f83fff103ba8f29ab990,ff99823330df8ac13212d5d79facd93fc7b3f5a3..675af0397a9779e6d8eefc5bace1ecfecc20a8f1
@@@ -289,7 -289,7 +289,7 @@@ float autocvar_g_balance_grenadelaunche
  float autocvar_g_balance_grenadelauncher_primary_force;
  float autocvar_g_balance_grenadelauncher_primary_health;
  float autocvar_g_balance_grenadelauncher_primary_lifetime;
- float autocvar_g_balance_grenadelauncher_primary_lifetime2;
+ float autocvar_g_balance_grenadelauncher_primary_lifetime_stick;
  float autocvar_g_balance_grenadelauncher_primary_radius;
  float autocvar_g_balance_grenadelauncher_primary_refire;
  float autocvar_g_balance_grenadelauncher_primary_remote_minbouncecnt;
@@@ -304,7 -304,8 +304,8 @@@ float autocvar_g_balance_grenadelaunche
  float autocvar_g_balance_grenadelauncher_secondary_force;
  float autocvar_g_balance_grenadelauncher_secondary_health;
  float autocvar_g_balance_grenadelauncher_secondary_lifetime;
- float autocvar_g_balance_grenadelauncher_secondary_lifetime2;
+ float autocvar_g_balance_grenadelauncher_secondary_lifetime_bounce;
+ float autocvar_g_balance_grenadelauncher_secondary_lifetime_stick;
  float autocvar_g_balance_grenadelauncher_secondary_radius;
  float autocvar_g_balance_grenadelauncher_secondary_refire;
  float autocvar_g_balance_grenadelauncher_secondary_speed;
@@@ -393,7 -394,6 +394,6 @@@ float autocvar_g_balance_hook_secondary
  float autocvar_g_balance_hook_secondary_speed;
  float autocvar_g_balance_keyhunt_damageforcescale;
  float autocvar_g_balance_keyhunt_delay_collect;
- float autocvar_g_balance_keyhunt_delay_drop;
  float autocvar_g_balance_keyhunt_delay_return;
  float autocvar_g_balance_keyhunt_delay_round;
  float autocvar_g_balance_keyhunt_delay_tracking;
@@@ -1010,69 -1010,12 +1010,12 @@@ float autocvar_g_turrets_unit_walker_st
  float autocvar_g_turrets_unit_walker_std_rocket_turnrate;
  float autocvar_g_turrets_unit_walker_std_rockets_range;
  float autocvar_g_turrets_unit_walker_std_rockets_range_min;
+ float autocvar_g_turrets_unit_walker_turn;
+ float autocvar_g_turrets_unit_walker_turn_walk;
+ float autocvar_g_turrets_unit_walker_turn_run;
+ float autocvar_g_turrets_unit_walker_turn_strafe;
+ float autocvar_g_turrets_unit_walker_turn_swim;
  float autocvar_g_use_ammunition;
- float autocvar_g_vehicle_racer_afterburn_cost;
- float autocvar_g_vehicle_racer_anglestabilizer;
- float autocvar_g_vehicle_racer_downforce;
- float autocvar_g_vehicle_racer_energy;
- float autocvar_g_vehicle_racer_energy_usepause;
- float autocvar_g_vehicle_racer_health;
- float autocvar_g_vehicle_racer_laser_cost;
- float autocvar_g_vehicle_racer_laser_damage;
- float autocvar_g_vehicle_racer_laser_radius;
- float autocvar_g_vehicle_racer_laser_refire;
- float autocvar_g_vehicle_racer_laser_speed;
- float autocvar_g_vehicle_racer_pitchspeed;
- float autocvar_g_vehicle_racer_power_air;
- float autocvar_g_vehicle_racer_power_min;
- float autocvar_g_vehicle_racer_power_solid;
- float autocvar_g_vehicle_racer_reload;
- float autocvar_g_vehicle_racer_respawntime;
- float autocvar_g_vehicle_racer_rocket_accel;
- float autocvar_g_vehicle_racer_rocket_damage;
- float autocvar_g_vehicle_racer_rocket_radius;
- float autocvar_g_vehicle_racer_rocket_refire;
- float autocvar_g_vehicle_racer_rocket_speed;
- float autocvar_g_vehicle_racer_rocket_turnrate;
- float autocvar_g_vehicle_racer_shield;
- float autocvar_g_vehicle_racer_speed_afterburn;
- float autocvar_g_vehicle_racer_speed_forward;
- float autocvar_g_vehicle_racer_speed_strafe;
- float autocvar_g_vehicle_racer_springlength;
- float autocvar_g_vehicle_racer_turnroll;
- float autocvar_g_vehicle_racer_turnspeed;
- float autocvar_g_vehicle_raptor_reload;
- float autocvar_g_vehicle_spiderbot_crush_dmg;
- float autocvar_g_vehicle_spiderbot_crush_force;
- float autocvar_g_vehicle_spiderbot_head_pitchlimit_down;
- float autocvar_g_vehicle_spiderbot_head_pitchlimit_up;
- float autocvar_g_vehicle_spiderbot_head_pitchspeed;
- float autocvar_g_vehicle_spiderbot_head_turnlimit;
- float autocvar_g_vehicle_spiderbot_head_turnspeed;
- float autocvar_g_vehicle_spiderbot_health;
- float autocvar_g_vehicle_spiderbot_minigun_cooldown;
- float autocvar_g_vehicle_spiderbot_minigun_damage;
- float autocvar_g_vehicle_spiderbot_minigun_heat;
- float autocvar_g_vehicle_spiderbot_minigun_refire;
- float autocvar_g_vehicle_spiderbot_minigun_spread;
- float autocvar_g_vehicle_spiderbot_movement_inertia;
- float autocvar_g_vehicle_spiderbot_respawntime;
- float autocvar_g_vehicle_spiderbot_rocket_damage;
- float autocvar_g_vehicle_spiderbot_rocket_edgedamage;
- float autocvar_g_vehicle_spiderbot_rocket_force;
- float autocvar_g_vehicle_spiderbot_rocket_health;
- float autocvar_g_vehicle_spiderbot_rocket_lifetime;
- float autocvar_g_vehicle_spiderbot_rocket_noise;
- float autocvar_g_vehicle_spiderbot_rocket_radius;
- float autocvar_g_vehicle_spiderbot_rocket_refire;
- float autocvar_g_vehicle_spiderbot_rocket_reload;
- float autocvar_g_vehicle_spiderbot_rocket_speed;
- float autocvar_g_vehicle_spiderbot_rocket_turnrate;
- float autocvar_g_vehicle_spiderbot_shield;
- float autocvar_g_vehicle_spiderbot_speed_stop;
- float autocvar_g_vehicle_spiderbot_speed_strafe;
- float autocvar_g_vehicle_spiderbot_speed_walk;
- float autocvar_g_vehicle_spiderbot_turnspeed;
  float autocvar_g_waypointeditor;
  float autocvar_g_waypoints_for_items;
  float autocvar_g_waypointsprite_deadlifetime;
@@@ -1185,7 -1128,6 +1128,7 @@@ string autocvar_sv_player_headsize
  string autocvar_sv_player_maxs;
  string autocvar_sv_player_mins;
  string autocvar_sv_player_viewoffset;
 +float autocvar_sv_player_jumpanim_minfall;
  float autocvar_sv_precacheplayermodels;
  float autocvar_sv_precacheweapons;
  float autocvar_sv_q3acompat_machineshotgunswap;
@@@ -1245,3 -1187,4 +1188,4 @@@ 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 d942784caca006f97de76bad6f054b3244cebaf1,0cf0d9ea512224843f2de8f7625cfb64cef2c84e..0513156a03f582f37bd4c4cc673f3815a90fa103
@@@ -112,7 -112,7 +112,7 @@@ void spawnfunc_info_player_deathmatch (
  
  void spawnpoint_use()
  {
-       if(teams_matter)
+       if(teamplay)
        if(have_team_spawns > 0)
        {
                self.team = activator.team;
@@@ -596,7 -596,7 +596,7 @@@ void FixPlayermodel()
  void PutObserverInServer (void)
  {
        entity  spot;
+     self.hud = HUD_NORMAL;
        race_PreSpawnObserver();
  
        spot = SelectSpawnPoint (TRUE);
        DropAllRunes(self);
        MUTATOR_CALLHOOK(MakePlayerObserver);
  
+       if (g_minstagib)
+               minstagib_stop_countdown();
        Portal_ClearAll(self);
  
        if(self.alivetime)
                self.alivetime = 0;
        }
  
+       if(self.vehicle)
+           vehicles_exit(VHEF_RELESE);
        if(self.flagcarried)
                DropFlag(self.flagcarried, world, world);
  
@@@ -748,7 -754,7 +754,7 @@@ void FixPlayermodel(
        if(autocvar_sv_defaultcharacter == 1) {
                defaultskin = 0;
  
-               if(teams_matter)
+               if(teamplay)
                {
                        string s;
                        s = Team_ColorNameLowerCase(self.team);
        if(chmdl || oldskin != self.skinindex)
                self.species = player_getspecies(); // model or skin has changed
  
-       if(!teams_matter)
+       if(!teamplay)
                if(strlen(autocvar_sv_defaultplayercolors))
                        if(self.clientcolors != stof(autocvar_sv_defaultplayercolors))
                                setcolor(self, stof(autocvar_sv_defaultplayercolors));
@@@ -1012,6 -1018,7 +1018,7 @@@ void PutClientInServer (void
                self.oldorigin = self.origin;
                self.prevorigin = self.origin;
                self.lastrocket = world; // stop rocket guiding, no revenge from the grave!
+               self.lastteleporttime = time; // prevent insane speeds due to changing origin
  
                if(g_arena)
                {
                //stuffcmd(self, "set viewsize $tmpviewsize \n");
  
                if (autocvar_g_spawnsound)
-                       sound (self, CHAN_TRIGGER, "misc/spawn.wav", VOL_BASE, ATTN_NORM);
+                       sound (self, CH_TRIGGER, "misc/spawn.wav", VOL_BASE, ATTN_NORM);
  
                if(g_assault) {
                        if(self.team == assault_attacker_team)
                oldself = self;
                self = spot;
                        activator = oldself;
+                               string s;
+                               s = self.target;
+                               self.target = string_null;
                                SUB_UseTargets();
+                               self.target = s;
                        activator = world;
                self = oldself;
  
@@@ -1260,7 -1271,19 +1271,19 @@@ void ClientKill_Now_TeamChange(
  
  void ClientKill_Now()
  {
-       remove(self.killindicator);
+       if(self.vehicle)
+       {
+           vehicles_exit(VHEF_RELESE);
+           if(!self.killindicator_teamchange)
+           {
+             self.vehicle_health = -1;
+             Damage(self, self, self, 1 , DEATH_KILL, self.origin, '0 0 0');           
+           }
+       }
+       if(self.killindicator && !wasfreed(self.killindicator))
+               remove(self.killindicator);
        self.killindicator = world;
  
        if(self.killindicator_teamchange)
  }
  void KillIndicator_Think()
  {
+       if (gameover)
+       {
+               self.owner.killindicator = world;
+               remove(self);
+               return;
+       }
        if (!self.owner.modelindex)
        {
                self.owner.killindicator = world;
                {
                        if(self.cnt <= 10)
                                AnnounceTo(self.owner, strcat(ftos(self.cnt), ""));
-                       if(self.owner.killindicator_teamchange)
-                       {
-                               if(self.owner.killindicator_teamchange == -1)
-                                       centerprint(self.owner, strcat("Changing team in ", ftos(self.cnt), " seconds"));
-                               else if(self.owner.killindicator_teamchange == -2)
-                                       centerprint(self.owner, strcat("Spectating in ", ftos(self.cnt), " seconds"));
-                               else
-                                       centerprint(self.owner, strcat("Changing to ", ColoredTeamName(self.owner.killindicator_teamchange), " in ", ftos(self.cnt), " seconds"));
-                       }
-                       else
-                               centerprint(self.owner, strcat("^1Suicide in ", ftos(self.cnt), " seconds"));
                }
                self.nextthink = time + 1;
                self.cnt -= 1;
@@@ -1320,6 -1339,10 +1339,10 @@@ void ClientKill_TeamChange (float targe
  {
        float killtime;
        entity e;
+       if (gameover)
+               return;
        killtime = autocvar_g_balance_kill_delay;
  
        if(g_race_qualifying || g_cts)
        if(self.killindicator)
        {
                if(targetteam == 0) // just die
+               {
                        self.killindicator.colormod = '0 0 0';
+                       if(clienttype(self) == CLIENTTYPE_REAL)
+                       if(self.killindicator.cnt > 0)
+                               Send_CSQC_Centerprint_Generic(self, CPID_TEAMCHANGE, "^1Suicide in %d seconds", 1, self.killindicator.cnt);
+               }
                else if(targetteam == -1) // auto
+               {
                        self.killindicator.colormod = '0 1 0';
+                       if(clienttype(self) == CLIENTTYPE_REAL)
+                       if(self.killindicator.cnt > 0)
+                               Send_CSQC_Centerprint_Generic(self, CPID_TEAMCHANGE, "Changing team in %d seconds", 1, self.killindicator.cnt);
+               }
                else if(targetteam == -2) // spectate
+               {
                        self.killindicator.colormod = '0.5 0.5 0.5';
+                       if(clienttype(self) == CLIENTTYPE_REAL)
+                       if(self.killindicator.cnt > 0)
+                               Send_CSQC_Centerprint_Generic(self, CPID_TEAMCHANGE, "Spectating in %d seconds", 1, self.killindicator.cnt);
+               }
                else
+               {
                        self.killindicator.colormod = TeamColor(targetteam);
+                       if(clienttype(self) == CLIENTTYPE_REAL)
+                       if(self.killindicator.cnt > 0)
+                               Send_CSQC_Centerprint_Generic(self, CPID_TEAMCHANGE, strcat("Changing to ", ColoredTeamName(targetteam), " in %d seconds"), 1, self.killindicator.cnt);
+               }
        }
  }
  
  void ClientKill (void)
  {
+       if (gameover)
+               return;
        if((g_arena || g_ca) && ((champion && champion.classname == "player" && player_count > 1) || player_count == 1)) // don't allow a kill in this case either
        {
                // do nothing
@@@ -1415,55 -1462,6 +1462,6 @@@ void CTS_ClientKill (entity e) // silen
      e.lip = 0;
  }
  
- void DoTeamChange(float destteam)
- {
-       float t, c0;
-       if(!teams_matter)
-       {
-               if(destteam >= 0)
-                       SetPlayerColors(self, destteam);
-               return;
-       }
-       if(self.classname == "player")
-       if(destteam == -1)
-       {
-               CheckAllowedTeams(self);
-               t = FindSmallestTeam(self, TRUE);
-               switch(self.team)
-               {
-                       case COLOR_TEAM1: c0 = c1; break;
-                       case COLOR_TEAM2: c0 = c2; break;
-                       case COLOR_TEAM3: c0 = c3; break;
-                       case COLOR_TEAM4: c0 = c4; break;
-                       default:          c0 = 999;
-               }
-               switch(t)
-               {
-                       case 1:
-                               if(c0 > c1)
-                                       destteam = COLOR_TEAM1;
-                               break;
-                       case 2:
-                               if(c0 > c2)
-                                       destteam = COLOR_TEAM2;
-                               break;
-                       case 3:
-                               if(c0 > c3)
-                                       destteam = COLOR_TEAM3;
-                               break;
-                       case 4:
-                               if(c0 > c4)
-                                       destteam = COLOR_TEAM4;
-                               break;
-               }
-               if(destteam == -1)
-                       return;
-       }
-       if(destteam == self.team && destteam >= 0 && !self.killindicator)
-               return;
-       ClientKill_TeamChange(destteam);
- }
  void FixClientCvars(entity e)
  {
        // send prediction settings to the client
@@@ -1565,7 -1563,7 +1563,7 @@@ void ClientConnect (void
        playerdemo_init();
  
        anticheat_init();
-       
        race_PreSpawnObserver();
  
        //if(g_domination)
        else
                self.team_forced = 0;
  
-       if(!teams_matter)
+       if(!teamplay)
                if(self.team_forced > 0)
                        self.team_forced = 0;
  
        if((autocvar_sv_spectate == 1 && !g_lms) || autocvar_g_campaign || self.team_forced < 0) {
                self.classname = "observer";
        } else {
-               if(teams_matter)
+               if(teamplay)
                {
                        if(autocvar_g_balance_teams || autocvar_g_balance_teams_force)
                        {
  
        self.playerid = (playerid_last = playerid_last + 1);
  
+       PlayerStats_AddEvent(sprintf("kills-%d", self.playerid));
      if(clienttype(self) == CLIENTTYPE_BOT)
          PlayerStats_AddPlayer(self);
  
  
        bprint("\n");
  
-       self.welcomemessage_time = 0;
        stuffcmd(self, strcat(clientstuff, "\n"));
        stuffcmd(self, strcat("exec maps/", mapname, ".cfg\n"));
        stuffcmd(self, "cl_particles_reloadeffects\n");
        GetCvars(0);
  
        // notify about available teams
-       if(teams_matter)
+       if(teamplay)
        {
                CheckAllowedTeams(self);
                t = 0; if(c1 >= 0) t |= 1; if(c2 >= 0) t |= 2; if(c3 >= 0) t |= 4; if(c4 >= 0) t |= 8;
                set_dom_state(self);
  
        CheatInitClient();
+       if(!autocvar_g_campaign)
+               Send_CSQC_Centerprint_Generic(self, CPID_MOTD, getwelcomemessage(), autocvar_welcome_message_time, 0);
  }
  
  /*
@@@ -1786,6 -1787,9 +1787,9 @@@ Called when a client disconnects from t
  void ReadyCount();
  void ClientDisconnect (void)
  {
+       if(self.vehicle)
+           vehicles_exit(VHEF_RELESE);
        if not(self.flags & FL_CLIENT)
        {
                print("Warning: ClientDisconnect without ClientConnect\n");
@@@ -1923,7 -1927,7 +1927,7 @@@ void UpdateChatBubble(
        local float c;
        c = self.clientcolors & 15;
        // LordHavoc: only bothering to support white, green, red, yellow, blue
-            if (!teams_matter) self.colormod = '0 0 0';
+            if (!teamplay) self.colormod = '0 0 0';
        else if (c ==  0) self.colormod = '1.00 1.00 1.00';
        else if (c ==  3) self.colormod = '0.10 1.73 0.10';
        else if (c ==  4) self.colormod = '1.73 0.10 0.10';
@@@ -1965,63 -1969,22 +1969,22 @@@ void play_countdown(float finished, str
        if(clienttype(self) == CLIENTTYPE_REAL)
                if(floor(finished - time - frametime) != floor(finished - time))
                        if(finished - time < 6)
-                               sound (self, CHAN_AUTO, samp, VOL_BASE, ATTN_NORM);
- }
- /**
-  * When sv_timeout is used this function returs strings like
-  * "Timeout begins in 2 seconds!\n" or "Timeout ends in 23 seconds!\n".
-  * Called by centerprint functions
-  * @param addOneSecond boolean, set to 1 if the welcome-message centerprint asks for the text
-  */
- string getTimeoutText(float addOneSecond) {
-       if (!autocvar_sv_timeout || !timeoutStatus)
-               return "";
-       local string retStr;
-       if (timeoutStatus == 1) {
-               if (addOneSecond == 1) {
-                       retStr = strcat("Timeout begins in ", ftos(remainingLeadTime + 1), " seconds!\n");
-               }
-               else {
-                       retStr = strcat("Timeout begins in ", ftos(remainingLeadTime), " seconds!\n");
-               }
-               return retStr;
-       }
-       else if (timeoutStatus == 2) {
-               if (addOneSecond) {
-                       retStr = strcat("Timeout ends in ", ftos(remainingTimeoutTime + 1), " seconds!\n");
-                       //don't show messages like "Timeout ends in 0 seconds"...
-                       if ((remainingTimeoutTime + 1) > 0)
-                               return retStr;
-                       else
-                               return "";
-               }
-               else {
-                       retStr = strcat("Timeout ends in ", ftos(remainingTimeoutTime), " seconds!\n");
-                       //don't show messages like "Timeout ends in 0 seconds"...
-                       if (remainingTimeoutTime > 0)
-                               return retStr;
-                       else
-                               return "";
-               }
-       }
-       else return "";
+                               sound (self, CH_INFO, samp, VOL_BASE, ATTN_NORM);
  }
  
  void player_powerups (void)
  {
        // add a way to see what the items were BEFORE all of these checks for the mutator hook
        olditems = self.items;
-       
        if((self.items & IT_USING_JETPACK) && !self.deadflag)
        {
-               SoundEntity_StartSound(self, CHAN_PLAYER, "misc/jetpack_fly.wav", VOL_BASE, autocvar_g_jetpack_attenuation);
+               SoundEntity_StartSound(self, CH_TRIGGER_SINGLE, "misc/jetpack_fly.wav", VOL_BASE, autocvar_g_jetpack_attenuation);
                self.modelflags |= MF_ROCKET;
        }
        else
        {
-               SoundEntity_StopSound(self, CHAN_PLAYER);
+               SoundEntity_StopSound(self, CH_TRIGGER_SINGLE);
                self.modelflags &~= MF_ROCKET;
        }
  
  
        if(!self.modelindex || self.deadflag) // don't apply the flags if the player is gibbed
                return;
-       
        Fire_ApplyDamage(self);
        Fire_ApplyEffect(self);
  
                if (time < self.spawnshieldtime)
                        self.effects = self.effects | (EF_ADDITIVE | EF_FULLBRIGHT);
        }
-       
        MUTATOR_CALLHOOK(PlayerPowerups);
  }
  
@@@ -2356,11 -2319,34 +2319,34 @@@ void SpectateCopy(entity spectatee) 
        SetZoomState(spectatee.zoomstate);
  
        anticheat_spectatecopy(spectatee);
+       //self.vehicle = spectatee.vehicle;
+       self.hud = spectatee.hud;
+       if(spectatee.vehicle)
+     {
+         setorigin(self, spectatee.origin);
+         self.velocity = spectatee.vehicle.velocity;
+         self.v_angle += spectatee.vehicle.angles;
+         //self.v_angle_x *= -1;
+         self.vehicle_health = spectatee.vehicle_health;
+         self.vehicle_shield = spectatee.vehicle_shield;
+         self.vehicle_energy = spectatee.vehicle_energy;
+         self.vehicle_ammo1 = spectatee.vehicle_ammo1;
+         self.vehicle_ammo2 = spectatee.vehicle_ammo2;
+         self.vehicle_reload1 = spectatee.vehicle_reload1;
+         self.vehicle_reload2 = spectatee.vehicle_reload2;
+         
+         msg_entity = self;
+         WriteByte (MSG_ONE, SVC_SETVIEWPORT);
+         WriteEntity(MSG_ONE, spectatee);
+         //self.tur_head = spectatee.vehicle.vehicle_viewport;
+     }
  }
  
  float SpectateUpdate() {
        if(!self.enemy)
-               return 0;
+           return 0;           
  
        if (self == self.enemy)
                return 0;
@@@ -2383,17 -2369,28 +2369,28 @@@ float SpectateNext() 
                self.enemy = other;
  
        if(self.enemy.classname == "player") {
-               msg_entity = self;
-               WriteByte(MSG_ONE, SVC_SETVIEW);
-               WriteEntity(MSG_ONE, self.enemy);
-               //stuffcmd(self, "set viewsize $tmpviewsize \n");
-               self.movetype = MOVETYPE_NONE;
-               accuracy_resend(self);
-               if(!SpectateUpdate())
-                       PutObserverInServer();
-               return 1;
+           if(self.enemy.vehicle)
+           {      
+             msg_entity = self;
+             WriteByte(MSG_ONE, SVC_SETVIEWPORT);
+             WriteEntity(MSG_ONE, self.enemy);
+             //stuffcmd(self, "set viewsize $tmpviewsize \n");
+             self.movetype = MOVETYPE_NONE;
+             accuracy_resend(self);
+           }
+           else 
+           {           
+             msg_entity = self;
+             WriteByte(MSG_ONE, SVC_SETVIEW);
+             WriteEntity(MSG_ONE, self.enemy);
+             //stuffcmd(self, "set viewsize $tmpviewsize \n");
+             self.movetype = MOVETYPE_NONE;
+             accuracy_resend(self);
+             if(!SpectateUpdate())
+                 PutObserverInServer();
+         }
+         return 1;
        } else {
                return 0;
        }
@@@ -2428,7 -2425,7 +2425,7 @@@ void ShowRespawnCountdown(
  void LeaveSpectatorMode()
  {
        if(nJoinAllowed(1)) {
-               if(!teams_matter || autocvar_g_campaign || autocvar_g_balance_teams || (self.wasplayer && autocvar_g_changeteam_banned) || self.team_forced > 0) {
+               if(!teamplay || autocvar_g_campaign || autocvar_g_balance_teams || (self.wasplayer && autocvar_g_changeteam_banned) || self.team_forced > 0) {
                        self.classname = "player";
  
                        if(autocvar_g_campaign || autocvar_g_balance_teams || autocvar_g_balance_teams_force)
                                bprint ("^4", self.netname, "^4 is playing now\n");
  
                        if(!autocvar_g_campaign)
-                               centerprint(self,""); // clear MOTD
+                       if (time < self.jointime + autocvar_welcome_message_time)
+                               Send_CSQC_Centerprint_Generic_Expire(self, CPID_MOTD); // clear MOTD
  
                        return;
                } else {
        }
        else {
                //player may not join because of g_maxplayers is set
-               centerprint_atprio(self, CENTERPRIO_MAPVOTE, PREVENT_JOIN_TEXT);
+               centerprint(self, PREVENT_JOIN_TEXT);
        }
  }
  
@@@ -2507,11 -2505,9 +2505,9 @@@ void ObserverThink(
  {
        if (self.flags & FL_JUMPRELEASED) {
                if (self.BUTTON_JUMP && !self.version_mismatch) {
-                       self.welcomemessage_time = 0;
                        self.flags &~= FL_JUMPRELEASED;
                        self.flags |= FL_SPAWNING;
                } else if(self.BUTTON_ATCK && !self.version_mismatch) {
-                       self.welcomemessage_time = 0;
                        self.flags &~= FL_JUMPRELEASED;
                        if(SpectateNext() == 1) {
                                self.classname = "spectator";
                        }
                }
        }
-       PrintWelcomeMessage(self);
  }
  
  void SpectatorThink()
  {
        if (self.flags & FL_JUMPRELEASED) {
                if (self.BUTTON_JUMP && !self.version_mismatch) {
-                       self.welcomemessage_time = 0;
                        self.flags &~= FL_JUMPRELEASED;
                        self.flags |= FL_SPAWNING;
                } else if(self.BUTTON_ATCK) {
-                       self.welcomemessage_time = 0;
                        self.flags &~= FL_JUMPRELEASED;
                        if(SpectateNext() == 1) {
                                self.classname = "spectator";
                                PutClientInServer();
                        }
                } else if (self.BUTTON_ATCK2) {
-                       self.welcomemessage_time = 0;
                        self.flags &~= FL_JUMPRELEASED;
                        self.classname = "observer";
                        PutClientInServer();
                                return;
                        }
                }
+               if(!SpectateUpdate())
+                       PutObserverInServer();
        }
  
-       PrintWelcomeMessage(self);
        self.flags |= FL_CLIENT | FL_NOTARGET;
  }
  
+ float ctf_usekey();
+ void PlayerUseKey()
+ {
+       if(self.classname != "player")
+               return;
+       if(self.vehicle)
+       {
+         vehicles_exit(VHEF_NORMAL);
+         return;
+       }
+       
+       // a use key was pressed; call handlers
+       if(ctf_usekey())
+               return;
+       MUTATOR_CALLHOOK(PlayerUseKey);
+ }
  .float touchexplode_time;
  
  /*
@@@ -2581,9 -2593,11 +2593,11 @@@ PlayerPreThin
  Called every frame for each client before the physics are run
  =============
  */
+ .float usekeypressed;
  void() ctf_setstatus;
  void() nexball_setstatus;
  .float items_added;
+ .float motd_actived_time; // used for both motd and campaign_message
  void PlayerPreThink (void)
  {
        WarpZone_PlayerPhysics_FixVAngle();
  
        MUTATOR_CALLHOOK(PlayerPreThink);
  
+       if(self.BUTTON_USE && !self.usekeypressed)
+               PlayerUseKey();
+       self.usekeypressed = self.BUTTON_USE;
+       if (self.motd_actived_time == 0) {
+               if (autocvar_g_campaign) {
+                       if (self.classname == "player" && self.BUTTON_INFO) {
+                               self.motd_actived_time = time;
+                               Send_CSQC_Centerprint_Generic(self, CPID_MOTD, campaign_message, -1, 0);
+                       }
+               } else {
+                       if ((self.classname == "player" || time - self.jointime > autocvar_welcome_message_time) && self.BUTTON_INFO) {
+                               self.motd_actived_time = time;
+                               Send_CSQC_Centerprint_Generic(self, CPID_MOTD, getwelcomemessage(), -1, 0);
+                       }
+               }
+       } else { // showing MOTD or campaign message
+               if (autocvar_g_campaign) {
+                       if (self.classname == "player") {
+                               if (self.BUTTON_INFO)
+                                       self.motd_actived_time = time;
+                               else if (time - self.motd_actived_time > 2) { // hide it some seconds after BUTTON_INFO has been released
+                                       self.motd_actived_time = 0;
+                                       Send_CSQC_Centerprint_Generic_Expire(self, CPID_MOTD);
+                               }
+                       }
+               } else {
+                       if (self.classname == "player" || (time - self.jointime) > autocvar_welcome_message_time) {
+                               if (self.BUTTON_INFO)
+                                       self.motd_actived_time = time;
+                               else if (time - self.motd_actived_time > 2) { // hide it some seconds after BUTTON_INFO has been released
+                                       self.motd_actived_time = 0;
+                                       Send_CSQC_Centerprint_Generic_Expire(self, CPID_MOTD);
+                               }
+                       }
+               }
+       }
        if(self.classname == "player") {
  //            if(self.netname == "Wazat")
  //                    bprint(self.classname, "\n");
  
                CheckRules_Player();
  
-               PrintWelcomeMessage(self);
                if (intermission_running)
                {
                        IntermissionThink ();   // otherwise a button could be missed between
                        player_powerups();
                }
  
+               if (g_minstagib)
+                       minstagib_ammocheck();
                if (self.deadflag != DEAD_NO)
                {
                        float button_pressed, force_respawn;
                        }
                        return;
                }
+               // FIXME from now on self.deadflag is always 0 (and self.health is never < 1)
+               // so (self.deadflag == DEAD_NO) is always true in the code below
  
                if(g_touchexplode)
                if(time > self.touchexplode_time)
  
                self.prevorigin = self.origin;
  
 -              if ((self.BUTTON_CROUCH && !self.hook.state) || self.health <= g_bloodloss)
 +              if (((self.BUTTON_CROUCH && !self.hook.state) || self.health <= g_bloodloss) && self.animstate_startframe != 23) // prevent crouching if using melee attack
                {
                        if (!self.crouch)
                        {
                if(frametime)
                        player_anim();
  
-               if (g_minstagib)
-                       minstagib_ammocheck();
                if(g_ctf)
                        ctf_setstatus();
  
                oldself = self; self = self.teamkill_soundsource;
                oldpusher = self.pusher; self.pusher = oldself;
  
-               PlayerSound(playersound_teamshoot, CHAN_VOICE, VOICETYPE_LASTATTACKER_ONLY);
+               PlayerSound(playersound_teamshoot, CH_VOICE, VOICETYPE_LASTATTACKER_ONLY);
  
                self.pusher = oldpusher;
                self = oldself;
        if(time > self.taunt_soundtime)
        {
                self.taunt_soundtime = 0;
-               PlayerSound(playersound_taunt, CHAN_VOICE, VOICETYPE_AUTOTAUNT);
+               PlayerSound(playersound_taunt, CH_VOICE, VOICETYPE_AUTOTAUNT);
        }
  
        target_voicescript_next(self);
@@@ -3008,7 -3060,21 +3060,21 @@@ void PlayerPostThink (void
        {
                // WORKAROUND: only use dropclient in server frames (frametime set). Never use it in cl_movement frames (frametime zero).
                float timeleft;
+               if (time - self.parm_idlesince < 1) // instead of (time == self.parm_idlesince) to support sv_maxidle <= 10
+               {
+                       if(self.idlekick_lasttimeleft)
+                       {
+                               Send_CSQC_Centerprint_Generic_Expire(self, CPID_DISCONNECT_IDLING);
+                               self.idlekick_lasttimeleft = 0;
+                       }
+                       return;
+               }
                timeleft = ceil(sv_maxidle - (time - self.parm_idlesince));
+               if(timeleft == min(10, sv_maxidle - 1)) // - 1 to support sv_maxidle <= 10
+               {
+                       if(!self.idlekick_lasttimeleft)
+                               Send_CSQC_Centerprint_Generic(self, CPID_DISCONNECT_IDLING, "^3Stop idling!\n^3Disconnecting in %d seconds...", 1, timeleft);
+               }
                if(timeleft <= 0)
                {
                        bprint("^3", self.netname, "^3 was kicked for idling.\n");
                else if(timeleft <= 10)
                {
                        if(timeleft != self.idlekick_lasttimeleft)
-                       {
-                               centerprint_atprio(self, CENTERPRIO_IDLEKICK, strcat("^3Stop idling!\n^3Disconnecting in ", ftos(timeleft), "..."));
-                               AnnounceTo(self, strcat(ftos(timeleft), ""));
-                       }
-               }
-               else
-               {
-                       centerprint_expire(self, CENTERPRIO_IDLEKICK);
+                               AnnounceTo(self, ftos(timeleft));
+                       self.idlekick_lasttimeleft = timeleft;
                }
-               self.idlekick_lasttimeleft = timeleft;
        }
  
  #ifdef TETRIS
        } else if (self.classname == "spectator") {
                //do nothing
        }
+       
        /*
        float i;
        for(i = 0; i < 1000; ++i)
  
        if(self.waypointsprite_attachedforcarrier)
                WaypointSprite_UpdateHealth(self.waypointsprite_attachedforcarrier, '1 0 0' * healtharmor_maxdamage(self.health, self.armorvalue, autocvar_g_balance_armor_blockpercent));
-       
        if(self.classname == "player" && self.deadflag == DEAD_NO && autocvar_r_showbboxes)
        {
                if(!self.showheadshotbbox)
        else
        {
                if(self.showheadshotbbox)
-                       remove(self.showheadshotbbox);
+                       if(self.showheadshotbbox && !wasfreed(self.showheadshotbbox))
+                 remove(self.showheadshotbbox);
        }
  
        playerdemo_write();
index 7f43fe66ef9dc2a9d9d17d30106a27791817fdb8,83c438b47600f7b07bd8fbf3fe54e99f2c992d15..e6a8f9999ddb3d8018308c9fb1c0c8db76eeaee4
@@@ -163,11 -163,11 +163,11 @@@ void PlayerJump (void
  
        if (self.crouch)
                setanim(self, self.anim_duckjump, FALSE, TRUE, TRUE);
 -      else
 +      else if (self.animstate_startframe != self.anim_melee_x || (self.animstate_startframe == self.anim_melee_x && time - self.animstate_starttime >= 21/20)) // jump animation shouldn't override melee until we have animation blending (or until the anim finished, 21/20 = numframes/fps)
                setanim(self, self.anim_jump, FALSE, TRUE, TRUE);
  
        if(g_jump_grunt)
-               PlayerSound(playersound_jump, CHAN_PLAYER, VOICETYPE_PLAYERSOUND);
+               PlayerSound(playersound_jump, CH_PLAYER, VOICETYPE_PLAYERSOUND);
  
        self.restart_jump = -1; // restart jump anim next time
        // value -1 is used to not use the teleport bit (workaround for tiny hitch when re-jumping)
@@@ -918,9 -918,9 +918,9 @@@ void SV_PlayerPhysics(
                        if not(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOSTEPS)
                        {
                                if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_METALSTEPS)
-                                       GlobalSound(globalsound_metalfall, CHAN_PLAYER, VOICETYPE_PLAYERSOUND);
+                                       GlobalSound(globalsound_metalfall, CH_PLAYER, VOICETYPE_PLAYERSOUND);
                                else
-                                       GlobalSound(globalsound_fall, CHAN_PLAYER, VOICETYPE_PLAYERSOUND);
+                                       GlobalSound(globalsound_fall, CH_PLAYER, VOICETYPE_PLAYERSOUND);
                        }
                }
        }
index 57732e6be3c884a35ba00bdb2b9090caa068d15a,cd7c81d0c616d0cb1762a3aef893dff81dde214a..18817bdc6c48283d60eb0113b160f2125ccadcbe
@@@ -1,6 -1,5 +1,5 @@@
  .entity accuracy;
  .float accuracy_frags[WEP_MAXCOUNT];
- FTEQCC_YOU_SUCK_THIS_IS_NOT_UNREFERENCED(accuracy_frags);
  
  float weaponstats_buffer;
  
@@@ -16,7 -15,7 +15,7 @@@ void WeaponStats_Init(
  
  void WeaponStats_Shutdown()
  {
-       float i, j, ibot, jbot, idx;
+       float i, j, n, ibot, jbot, idx;
        float fh;
        vector v;
        string prefix;
                {
                        fputs(fh, "#begin statsfile\n");
                        fputs(fh, strcat("#date ", strftime(TRUE, "%a %b %e %H:%M:%S %Z %Y"), "\n"));
-                       fputs(fh, strcat("#config ", ftos(crc16(FALSE, cvar_changes)), "\n"));
+                       fputs(fh, strcat("#config ", ftos(crc16(FALSE, cvar_purechanges)), "\n"));
+                       fputs(fh, strcat("#cvar_purechanges ", ftos(cvar_purechanges_count), "\n"));
+                       n = tokenizebyseparator(cvar_purechanges, "\n");
+                       for(i = 0; i < n; ++i)
+                               fputs(fh, strcat("#cvar_purechange ", argv(i), "\n"));
                        for(i = WEP_FIRST; i <= WEP_LAST; ++i) for(ibot = 0; ibot <= 1; ++ibot)
                                for(j = WEP_FIRST; j <= WEP_LAST; ++j) for(jbot = 0; jbot <= 1; ++jbot)
                                {
@@@ -193,7 -196,6 +196,7 @@@ void player_setupanimsformodel(
        self.anim_backright = '21 1 1';
        self.anim_backleft  = '22 1 1';
        self.anim_melee = '23 1 1';
 +      self.anim_fly = '24 1 1';
        animparseerror = FALSE;
        animfilename = strcat(self.model, ".animinfo");
        animfile = fopen(animfilename, FILE_READ);
                self.anim_backright    = animparseline(animfile);
                self.anim_backleft     = animparseline(animfile);
                self.anim_melee        = animparseline(animfile);
 +              self.anim_fly          = animparseline(animfile);
                fclose(animfile);
  
                // derived anims
@@@ -259,39 -260,13 +262,39 @@@ void player_anim (void
  
        if (!self.animstate_override)
        {
 -              if (!(self.flags & FL_ONGROUND))
 +              if (!(self.flags & FL_ONGROUND) || self.BUTTON_JUMP)
                {
                        if (self.crouch)
 -                              setanim(self, self.anim_duckjump, FALSE, TRUE, self.restart_jump);
 +                      {
 +                              if (self.animstate_startframe != self.anim_duckjump_x) // don't perform another trace if already playing the crouch jump anim
 +                              {
 +                                      traceline(self.origin + '0 0 1' * PL_CROUCH_MIN_z, self.origin + '0 0 1' * (PL_CROUCH_MIN_z - autocvar_sv_player_jumpanim_minfall), TRUE, self);
 +                                      if(!trace_startsolid && trace_fraction == 1 || !(self.animstate_startframe == self.anim_duckwalk_x || self.animstate_startframe == self.anim_duckidle_x)) // don't get stuck on non-crouch anims
 +                                      {
 +                                              setanim(self, self.anim_duckjump, FALSE, TRUE, self.restart_jump);
 +                                              self.restart_jump = FALSE;
 +                                      }
 +                              }
 +                      }
                        else
 -                              setanim(self, self.anim_jump, FALSE, TRUE, self.restart_jump);
 -                      self.restart_jump = FALSE;
 +                      {
 +                              // 21/25 is the magic number here for how long the jump animation takes to play once (numframes/framerate)
 +                              if((self.animstate_startframe == self.anim_jump_x && time - self.animstate_starttime >= 21/25))
 +                                      setanim(self, self.anim_fly, TRUE, FALSE, FALSE);
 +
 +                              if(self.animstate_startframe != self.anim_fly_x) // no tracing if we're in the fly anim
 +                              {
 +                                      if (self.animstate_startframe != self.anim_jump_x) // don't perform another trace if already playing the jump anim
 +                                      {
 +                                              traceline(self.origin + '0 0 1' * PL_MIN_z, self.origin + '0 0 1' * (PL_MIN_z - autocvar_sv_player_jumpanim_minfall), TRUE, self);
 +                                              if(!trace_startsolid && trace_fraction == 1 || self.animstate_startframe == self.anim_idle_x || (self.animstate_startframe == self.anim_melee_x && time - self.animstate_starttime >= 21/20)) // don't get stuck on idle animation in midair, nor melee after it finished
 +                                              {
 +                                                      setanim(self, self.anim_jump, FALSE, TRUE, self.restart_jump);
 +                                                      self.restart_jump = FALSE;
 +                                              }
 +                                      }
 +                              }
 +                      }
                }
                else if (self.crouch)
                {
@@@ -369,11 -344,11 +372,11 @@@ void PlayerCorpseDamage (entity inflict
        if(sound_allowed(MSG_BROADCAST, attacker))
        {
                if (save > 10)
-                       sound (self, CHAN_PROJECTILE, "misc/armorimpact.wav", VOL_BASE, ATTN_NORM);
+                       sound (self, CH_SHOTS, "misc/armorimpact.wav", VOL_BASE, ATTN_NORM);
                else if (take > 30)
-                       sound (self, CHAN_PROJECTILE, "misc/bodyimpact2.wav", VOL_BASE, ATTN_NORM);
+                       sound (self, CH_SHOTS, "misc/bodyimpact2.wav", VOL_BASE, ATTN_NORM);
                else if (take > 10)
-                       sound (self, CHAN_PROJECTILE, "misc/bodyimpact1.wav", VOL_BASE, ATTN_NORM);
+                       sound (self, CH_SHOTS, "misc/bodyimpact1.wav", VOL_BASE, ATTN_NORM);
        }
  
        if (take > 50)
@@@ -486,11 -461,11 +489,11 @@@ void PlayerDamage (entity inflictor, en
        if(sound_allowed(MSG_BROADCAST, attacker))
        {
                if (save > 10)
-                       sound (self, CHAN_PROJECTILE, "misc/armorimpact.wav", VOL_BASE, ATTN_NORM);
+                       sound (self, CH_SHOTS, "misc/armorimpact.wav", VOL_BASE, ATTN_NORM);
                else if (take > 30)
-                       sound (self, CHAN_PROJECTILE, "misc/bodyimpact2.wav", VOL_BASE, ATTN_NORM);
+                       sound (self, CH_SHOTS, "misc/bodyimpact2.wav", VOL_BASE, ATTN_NORM);
                else if (take > 10)
-                       sound (self, CHAN_PROJECTILE, "misc/bodyimpact1.wav", VOL_BASE, ATTN_NORM); // FIXME possibly remove them?
+                       sound (self, CH_SHOTS, "misc/bodyimpact1.wav", VOL_BASE, ATTN_NORM); // FIXME possibly remove them?
        }
  
        if (take > 50)
                                if(sv_gentle < 1) {
                                        if(self.classname != "body") // pain anim is BORKED on our ZYMs, FIXME remove this once we have good models
                                        {
 -                                              if (random() > 0.5)
 -                                                      setanim(self, self.anim_pain1, FALSE, TRUE, TRUE);
 -                                              else
 -                                                      setanim(self, self.anim_pain2, FALSE, TRUE, TRUE);
 +                                              if (!self.animstate_override)
 +                                              {
 +                                                      if (random() > 0.5)
 +                                                              setanim(self, self.anim_pain1, FALSE, TRUE, TRUE);
 +                                                      else
 +                                                              setanim(self, self.anim_pain2, FALSE, TRUE, TRUE);
 +                                              }
                                        }
  
                                        if(sound_allowed(MSG_BROADCAST, attacker))
                                        // exclude pain sounds for laserjumps as long as you aren't REALLY low on health and would die of the next two
                                        {
                                                if(deathtype == DEATH_FALL)
-                                                       PlayerSound(playersound_fall, CHAN_PAIN, VOICETYPE_PLAYERSOUND);
+                                                       PlayerSound(playersound_fall, CH_PAIN, VOICETYPE_PLAYERSOUND);
                                                else if(self.health > 75) // TODO make a "gentle" version?
-                                                       PlayerSound(playersound_pain100, CHAN_PAIN, VOICETYPE_PLAYERSOUND);
+                                                       PlayerSound(playersound_pain100, CH_PAIN, VOICETYPE_PLAYERSOUND);
                                                else if(self.health > 50)
-                                                       PlayerSound(playersound_pain75, CHAN_PAIN, VOICETYPE_PLAYERSOUND);
+                                                       PlayerSound(playersound_pain75, CH_PAIN, VOICETYPE_PLAYERSOUND);
                                                else if(self.health > 25)
-                                                       PlayerSound(playersound_pain50, CHAN_PAIN, VOICETYPE_PLAYERSOUND);
+                                                       PlayerSound(playersound_pain50, CH_PAIN, VOICETYPE_PLAYERSOUND);
                                                else
-                                                       PlayerSound(playersound_pain25, CHAN_PAIN, VOICETYPE_PLAYERSOUND);
+                                                       PlayerSound(playersound_pain25, CH_PAIN, VOICETYPE_PLAYERSOUND);
                                        }
                                }
  
                // escape a lava pit or similar
                //self.pushltime = 0;
        }
-       else if(attacker.classname == "player" || attacker.classname == "gib")
+       else if(attacker.classname == "player")
        {
                self.pusher = attacker;
                self.pushltime = time + autocvar_g_maxpushtime;
                        awep = DEATH_WEAPONOF(deathtype);
                valid_damage_for_weaponstats = 1;
        }
-       
        if(valid_damage_for_weaponstats)
        {
                dh = dh - max(self.health, 0);
                if(sound_allowed(MSG_BROADCAST, attacker))
                {
                        if(deathtype == DEATH_DROWN)
-                               PlayerSound(playersound_drown, CHAN_PAIN, VOICETYPE_PLAYERSOUND);
+                               PlayerSound(playersound_drown, CH_PAIN, VOICETYPE_PLAYERSOUND);
                        else
-                               PlayerSound(playersound_death, CHAN_PAIN, VOICETYPE_PLAYERSOUND);
+                               PlayerSound(playersound_death, CH_PAIN, VOICETYPE_PLAYERSOUND);
                }
  
                // get rid of kill indicator
  
                if(self.flagcarried)
                {
-                       if(attacker.classname != "player" && attacker.classname != "gib")
+                       if(attacker.classname != "player")
                                DropFlag(self.flagcarried, self, attacker); // penalty for flag loss by suicide
                        else if(attacker.team == self.team)
                                DropFlag(self.flagcarried, attacker, attacker); // penalty for flag loss by suicide/teamkill
@@@ -803,7 -775,7 +806,7 @@@ float Say(entity source, float teamsay
  
        if(source.classname != "player")
                colorstr = "^0"; // black for spectators
-       else if(teams_matter)
+       else if(teamplay)
                colorstr = Team_ColorCode(source.team);
        else
                teamsay = FALSE;
@@@ -1165,8 -1137,9 +1168,9 @@@ void UpdatePlayerSounds(
        self.skinindex_for_playersound = self.skinindex;
        ClearPlayerSounds();
        LoadPlayerSounds("sound/player/default.sounds", 1);
-       if(!LoadPlayerSounds(get_model_datafilename(self.model, self.skinindex, "sounds"), 0))
-               LoadPlayerSounds(get_model_datafilename(self.model, 0, "sounds"), 0);
+       if(!autocvar_g_debug_defaultsounds)
+               if(!LoadPlayerSounds(get_model_datafilename(self.model, self.skinindex, "sounds"), 0))
+                       LoadPlayerSounds(get_model_datafilename(self.model, 0, "sounds"), 0);
  }
  
  void FakeGlobalSound(string sample, float chan, float voicetype)
@@@ -1292,7 -1265,7 +1296,7 @@@ void GlobalSound(string sample, float c
                        break;
                case VOICETYPE_TEAMRADIO:
                        FOR_EACH_REALCLIENT(msg_entity)
-                               if(!teams_matter || msg_entity.team == self.team)
+                               if(!teamplay || msg_entity.team == self.team)
                                {
                                        if(msg_entity.cvar_cl_voice_directional == 1)
                                                soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTN_MIN);
@@@ -1366,9 -1339,9 +1370,9 @@@ void VoiceMessage(string type, string m
        flood = Say(self, ownteam, world, msg, 1);
  
        if (flood > 0)
-               GlobalSound(self.sample, CHAN_VOICE, voicetype);
+               GlobalSound(self.sample, CH_VOICE, voicetype);
        else if (flood < 0)
-               FakeGlobalSound(self.sample, CHAN_VOICE, voicetype);
+               FakeGlobalSound(self.sample, CH_VOICE, voicetype);
  }
  
  void MoveToTeam(entity client, float team_colour, float type, float show_message)
index b18e1c847cbe8feef94c0f547c577ccadd3b48a5,3d7a33278d15201ce89b789f1a03f9441e0d0be8..f6fc12a68e3b4b7409aa4cd9a45a4d40a81882b0
@@@ -255,7 -255,7 +255,7 @@@ void W_SetupShot_Dir_ProjectileSize_Ran
                (time > ent.prevstrengthsoundattempt + autocvar_sv_strengthsound_antispam_refire_threshold)
        ) // prevent insane sound spam
        {
-               sound(ent, CHAN_AUTO, "weapons/strength_fire.wav", VOL_BASE, ATTN_NORM);
+               sound(ent, CH_TRIGGER, "weapons/strength_fire.wav", VOL_BASE, ATTN_NORM);
                ent.prevstrengthsound = time;
        }
        ent.prevstrengthsoundattempt = time;
@@@ -986,7 -986,8 +986,8 @@@ float client_hasweapon(entity cl, floa
                                                world, e.origin,
                                                self, 0,
                                                world, enemy,
-                                               0
+                                               0,
+                                               RADARICON_NONE, '0 0 0'
                                        );
                                }
                        }
@@@ -1062,7 -1063,7 +1063,7 @@@ float weapon_prepareattack_checkammo(fl
  
                if(self.weapon == self.switchweapon && time - self.prevdryfire > 1) // only play once BEFORE starting to switch weapons
                {
-                       sound (self, CHAN_AUTO, "weapons/dryfire.wav", VOL_BASE, ATTN_NORM);
+                       sound (self, CH_WEAPON_A, "weapons/dryfire.wav", VOL_BASE, ATTN_NORM);
                        self.prevdryfire = time;
                }
  
@@@ -1272,12 -1273,6 +1273,12 @@@ void weapon_thinkf(float fr, float t, v
                        anim = self.anim_melee;
                        anim_z = anim_y / (t + sys_frametime);
                        setanim(self, anim, FALSE, TRUE, TRUE);
 +              }
 +              else if (self.animstate_startframe == self.anim_idle_x) // only allow shoot anim to override idle animation until we have animation blending
 +              {
 +                      anim = self.anim_shoot;
 +                      anim_z = anim_y / (t + sys_frametime);
 +                      setanim(self, anim, FALSE, TRUE, TRUE);
                }
        }
  };
@@@ -1738,7 -1733,7 +1739,7 @@@ void W_Reload(float sent_ammo_min, floa
  
        // now begin the reloading process
  
-       sound (self, CHAN_WEAPON2, self.reload_sound, VOL_BASE, ATTN_NORM);
+       sound (self, CH_WEAPON_B, self.reload_sound, VOL_BASE, ATTN_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,
diff --combined qcsrc/server/defs.qh
index 147e88f966f613f0b19f1ccd07a1d499f77b8033,9e6a73b5e3642fe9e9ae952a9b6a318120e32ad7..e42dfe086ce50d67f8082d64867af7992c491cc6
@@@ -149,7 -149,6 +149,7 @@@ float maxclients
  .vector anim_backright; // player running backward and right
  .vector anim_backleft; // player running back and left
  .vector anim_melee; // player doing the melee action
 +.vector anim_fly; // player animation played after jump, if player is still in air. Also if falling from a ledge
  
  // weapon animation vectors:
  .vector anim_fire1;
@@@ -232,7 -231,6 +232,6 @@@ void weapon_defaultspawnfunc(float wpn)
  
  string w_deathtypestring;
  
- void(entity client, string s) centerprint_builtin = #73;
  .vector dest1, dest2;
  
  float gameover;
@@@ -244,7 -242,6 +243,6 @@@ float alreadychangedlevel
  .float runes;
  
  
- .float welcomemessage_time;
  .float version;
  
  // minstagib vars
@@@ -287,7 -284,6 +285,6 @@@ entity timeoutHandler; //responsible fo
  void timeoutHandler_Think();
  void evaluateTimeout();
  void evaluateTimein();
- string getTimeoutText(float addOneSecond);
  
  .float spawnshieldtime;
  
@@@ -313,7 -309,6 +310,6 @@@ float default_weapon_alpha
  .float() customizeentityforclient;
  .float cvar_cl_handicap;
  .float cvar_cl_playerdetailreduction;
- .float cvar_scr_centertime;
  .string cvar_g_xonoticversion;
  .string cvar_cl_weaponpriority;
  .string cvar_cl_weaponpriorities[10];
@@@ -349,7 -344,6 +345,6 @@@ void AnnounceTo(entity e, string snd)
  .entity jumppadsused[NUM_JUMPPADSUSED];
  
  string gamemode_name;
- float teams_matter;
  
  float startitem_failed;
  
@@@ -370,10 -364,6 +365,6 @@@ void FixClientCvars(entity e)
  
  float weaponsInMap;
  
- void centerprint_atprio(entity e, float prio, string s);
- void centerprint_expire(entity e, float prio);
- void centerprint(entity e, string s);
  .float respawn_countdown; // next number to count
  
  float bot_waypoints_for_items;
@@@ -431,18 -421,26 +422,26 @@@ float next_pingtime
  // TODO implemented fall and falling
  #define ALLPLAYERSOUNDS \
                _VOICEMSG(death) \
-               _VOICEMSG(fall) \
                _VOICEMSG(drown) \
+               _VOICEMSG(fall) \
+               _VOICEMSG(fall) \
+               _VOICEMSG(falling) \
                _VOICEMSG(gasp) \
                _VOICEMSG(jump) \
+               _VOICEMSG(pain100) \
                _VOICEMSG(pain25) \
                _VOICEMSG(pain50) \
-               _VOICEMSG(pain75) \
-               _VOICEMSG(pain100)
+               _VOICEMSG(pain75)
  #define ALLVOICEMSGS \
                _VOICEMSG(attack) \
                _VOICEMSG(attackinfive) \
+               _VOICEMSG(coverme) \
+               _VOICEMSG(defend) \
+               _VOICEMSG(freelance) \
+               _VOICEMSG(incoming) \
                _VOICEMSG(meet) \
+               _VOICEMSG(needhelp) \
                _VOICEMSG(seenflag) \
                _VOICEMSG(taunt) \
                _VOICEMSG(teamshoot)
@@@ -452,24 -450,18 +451,18 @@@ ALLPLAYERSOUND
  ALLVOICEMSGS
  #undef _VOICEMSG
  
- // reserved sound names for the future (models lack sounds for them):
+ // reserved sound names for the future (some models lack sounds for them):
+ //            _VOICEMSG(flagcarriertakingdamage) \
+ //            _VOICEMSG(getflag) \
+ // reserved sound names for the future (ALL models lack sounds for them):
  //            _VOICEMSG(affirmative) \
  //            _VOICEMSG(attacking) \
  //            _VOICEMSG(defending) \
  //            _VOICEMSG(roaming) \
  //            _VOICEMSG(onmyway) \
  //            _VOICEMSG(droppedflag) \
- //            _VOICEMSG(flagcarriertakingdamage) \
  //            _VOICEMSG(negative) \
  //            _VOICEMSG(seenenemy) \
- //            _VOICEMSG(fall) \
- //            _VOICEMSG(getflag) \
- //            _VOICEMSG(incoming) \
- //            _VOICEMSG(coverme) \
- //            _VOICEMSG(needhelp) \
- //            _VOICEMSG(defend) \
- //            _VOICEMSG(freelance) \
- //            _VOICEMSG(falling) \
  
  string globalsound_fall;
  string globalsound_metalfall;
@@@ -564,10 -556,6 +557,6 @@@ void ClientData_Touch(entity e)
  
  vector debug_shotorg; // if non-zero, overrides the shot origin of all weapons
  
- // the QC VM sucks
- #define BITXOR(v,b)        ((v) + (b) - 2 * ((v) & (b)))
- #define BITXOR_ASSIGN(v,b) ((v) += ((b) - 2 * ((v) & (b))))
  .float wasplayer;
  
  float servertime, serverprevtime, serverframetime;
@@@ -609,7 -597,7 +598,7 @@@ float client_cefc_accumulatortime
  
  ..float current_ammo;
  
- .float weapon_load[WEP_MAXCOUNT]; FTEQCC_YOU_SUCK_THIS_IS_NOT_UNREFERENCED(weapon_load);
+ .float weapon_load[WEP_MAXCOUNT];
  .float ammo_none; // used by the reloading system, must always be 0
  .float clip_load;
  .float old_clip_load;
@@@ -666,3 -654,5 +655,5 @@@ float serverflags
  
  .entity muzzle_flash;
  .float misc_bulletcounter;    // replaces uzi & hlac bullet counter.
+ void PlayerUseKey();
index 19d0d1cff92cc12963a21897d0811fd418cd4bc8,888b94456ff6496223698d7a2bce47054f7276d6..64dc74b9840b52524495488dd4a31685878ad7d3
@@@ -10,7 -10,7 +10,7 @@@ float trigger_push_calculatevelocity_fl
  
  void trigger_push_use()
  {
-       if(teams_matter)
+       if(teamplay)
                self.team = activator.team;
  }
  
@@@ -127,21 -127,12 +127,12 @@@ vector trigger_push_calculatevelocity(v
  
  void trigger_push_touch()
  {
-       if (self.active == ACTIVE_NOT)
-               return;
+       vector move;
  
-       // FIXME: add a .float for whether an entity should be tossed by jumppads
-       if (!other.iscreature)
-       if (other.classname != "corpse")
-       if (other.classname != "body")
-       if (other.classname != "gib")
-       if (other.classname != "casing")
-       if (other.classname != "droppedweapon")
-       if (other.classname != "keepawayball")
-       if (!other.projectiledeathtype || other.classname == "bullet")
+       if (self.active == ACTIVE_NOT)
                return;
  
-       if (other.deadflag && other.iscreature)
+       if (!isPushable(other))
                return;
  
        if(self.team)
  
        EXACTTRIGGER_TOUCH;
  
-       if(self.target)
-               self.movedir = trigger_push_calculatevelocity(other.origin, self.enemy, self.height);
+       if(self.enemy)
+       {
+               other.velocity = trigger_push_calculatevelocity(other.origin, self.enemy, self.height);
+       }
+       else if(self.target)
+       {
+               entity e;
+               RandomSelection_Init();
+               for(e = world; (e = find(e, targetname, self.target)); )
+               {
+                       if(e.cnt)
+                               RandomSelection_Add(e, 0, string_null, e.cnt, 1);
+                       else
+                               RandomSelection_Add(e, 0, string_null, 1, 1);
+               }
+               other.velocity = trigger_push_calculatevelocity(other.origin, RandomSelection_chosen_ent, self.height);
+       }
+       else
+       {
+               other.velocity = self.movedir;
+       }
  
        other.flags &~= FL_ONGROUND;
  
-       other.velocity = self.movedir;
        if (other.classname == "player")
        {
                // reset tracking of oldvelocity for impact damage (sudden velocity changes)
                {
                        // flash when activated
                        pointparticles(particleeffectnum("jumppad_activate"), other.origin, other.velocity, 1);
-                       sound (other, CHAN_AUTO, self.noise, VOL_BASE, ATTN_NORM);
+                       sound (other, CH_TRIGGER, self.noise, VOL_BASE, ATTN_NORM);
                        self.pushltime = time + 0.2;
                }
                local float ct;
                        }
                        else
                                other.lastteleporttime = time;
 +
 +                      if (!other.animstate_override)
 +                      {
 +                              if (other.crouch)
 +                                      setanim(other, other.anim_duckjump, FALSE, TRUE, TRUE);
 +                              else
 +                                      setanim(other, other.anim_jump, FALSE, TRUE, TRUE);
 +                      }
                }
                else
                        other.jumppadcount = TRUE;
  .vector dest;
  void trigger_push_findtarget()
  {
-       local entity e;
+       local entity e, t;
        local vector org;
        local float flighttime;
  
  
        if (self.target)
        {
-               // find the target
-               self.enemy = find(world, targetname, self.target);
-               if (!self.enemy)
+               float n;
+               n = 0;
+               for(t = world; (t = find(t, targetname, self.target)); )
                {
-                       objerror("trigger_push: target not found\n");
-                       remove(self);
-                       return;
+                       ++n;
+                       e = spawn();
+                       setorigin(e, org);
+                       setsize(e, PL_MIN, PL_MAX);
+                       e.velocity = trigger_push_calculatevelocity(org, t, self.height);
+                       tracetoss(e, e);
+                       if(e.movetype == MOVETYPE_NONE)
+                               waypoint_spawnforteleporter(self, trace_endpos, vlen(trace_endpos - org) / vlen(e.velocity));
+                       remove(e);
                }
  
-               self.movedir = trigger_push_calculatevelocity(org, self.enemy, self.height);
-               flighttime = trigger_push_calculatevelocity_flighttime;
+               if(n == 0)
+               {
+                       // no dest!
+                       objerror ("Jumppad with nonexistant target");
+                       return;
+               }
+               else if(n == 1)
+               {
+                       // exactly one dest - bots love that
+                       self.enemy = find(e, targetname, self.target);
+               }
+               else
+               {
+                       // have to use random selection every single time
+                       self.enemy = world;
+               }
        }
        else
-               flighttime = 0;
-       // calculate the destination and spawn a teleporter spawnfunc_waypoint
-       e = spawn();
-       setorigin(e, org);
-       setsize(e, PL_MIN, PL_MAX);
-       e.velocity = self.movedir;
-       tracetoss(e, e);
-       self.dest = trace_endpos;
-       remove(e);
-       waypoint_spawnforteleporter(self, self.dest, flighttime);
+       {
+               e = spawn();
+               setorigin(e, org);
+               setsize(e, PL_MIN, PL_MAX);
+               e.velocity = self.movedir;
+               tracetoss(e, e);
+               waypoint_spawnforteleporter(self, trace_endpos, vlen(trace_endpos - org) / vlen(e.velocity));
+               remove(e);
+       }
  };
  
  /*
index f9bcc251f46c8084e454dc52d0bd972149b44158,b77ed92252eb640d7131ac40431caf54dfc9458e..bdd42ea379363c0ccba65784d71ac192e96f7f5b
@@@ -25,7 -25,7 +25,7 @@@ void W_Shotgun_Attack (void
  
        W_DecreaseAmmo(ammo_shells, ammoamount, autocvar_g_balance_shotgun_reload_ammo);
  
-       W_SetupShot (self, autocvar_g_antilag_bullets && bulletspeed >= autocvar_g_antilag_bullets, 5, "weapons/shotgun_fire.wav", CHAN_WEAPON, d * bullets);
+       W_SetupShot (self, autocvar_g_antilag_bullets && bulletspeed >= autocvar_g_antilag_bullets, 5, "weapons/shotgun_fire.wav", CH_WEAPON_A, d * bullets);
        for (sc = 0;sc < bullets;sc = sc + 1)
                fireBallisticBullet(w_shotorg, w_shotdir, spread, bulletspeed, 5, d, 0, f, WEP_SHOTGUN, 0, 1, bulletconstant);
        endFireBallisticBullet();
        W_AttachToShotorg(flash, '5 0 0');
  }
  
+ entity lgbeam_owner_ent;
  void shotgun_meleethink (void)
  {
        // store time when we started swinging down inside self.cnt
        if(!self.cnt)
                self.cnt = time;
  
-       makevectors(self.owner.v_angle);
+       makevectors(self.realowner.v_angle);
        vector angle;
        angle = v_forward;
  
        float f;
        f = (self.cnt + meleetime - time) / meleetime * 2 - 1;
        vector targpos;
-       targpos = self.owner.origin + self.owner.view_ofs + angle * autocvar_g_balance_shotgun_secondary_melee_range + v_right * f * autocvar_g_balance_shotgun_secondary_melee_swing + v_up * f * autocvar_g_balance_shotgun_secondary_melee_swing;
+       targpos = self.realowner.origin + self.realowner.view_ofs + angle * autocvar_g_balance_shotgun_secondary_melee_range + v_right * f * autocvar_g_balance_shotgun_secondary_melee_swing + v_up * f * autocvar_g_balance_shotgun_secondary_melee_swing;
  
-       WarpZone_traceline_antilag(self.owner, self.owner.origin + self.owner.view_ofs, targpos, FALSE, self.owner, ANTILAG_LATENCY(self.owner));
+       if(!lgbeam_owner_ent)
+       {
+               lgbeam_owner_ent = spawn();
+               lgbeam_owner_ent.classname = "lgbeam_owner_ent";
+       }
+       WarpZone_traceline_antilag(lgbeam_owner_ent, self.realowner.origin + self.realowner.view_ofs, targpos, FALSE, lgbeam_owner_ent, ANTILAG_LATENCY(self.realowner));
  
        // apply the damage, also remove self
        if(trace_fraction < 1 && trace_ent.takedamage == DAMAGE_AIM && (trace_ent.classname == "player" || trace_ent.classname == "body"))
        {
                vector force;
                force = angle * autocvar_g_balance_shotgun_secondary_force;
-               if(accuracy_isgooddamage(self.owner, trace_ent))
-                       accuracy_add(self.owner, WEP_SHOTGUN, 0, autocvar_g_balance_shotgun_secondary_damage * min(1, f + 1));
-               Damage (trace_ent, self.owner, self.owner, autocvar_g_balance_shotgun_secondary_damage * min(1, f + 1), WEP_SHOTGUN | HITTYPE_SECONDARY , self.owner.origin + self.owner.view_ofs, force);
+               if(accuracy_isgooddamage(self.realowner, trace_ent))
+                       accuracy_add(self.realowner, WEP_SHOTGUN, 0, autocvar_g_balance_shotgun_secondary_damage * min(1, f + 1));
+               Damage (trace_ent, self.realowner, self.realowner, autocvar_g_balance_shotgun_secondary_damage * min(1, f + 1), WEP_SHOTGUN | HITTYPE_SECONDARY , self.realowner.origin + self.realowner.view_ofs, force);
                remove(self);
        }
-       else if(time >= self.cnt + meleetime || (self.owner.deadflag != DEAD_NO && autocvar_g_balance_shotgun_secondary_melee_no_doubleslap)) // missed or owner died, remove ent
+       else if(time >= self.cnt + meleetime || (self.realowner.deadflag != DEAD_NO && autocvar_g_balance_shotgun_secondary_melee_no_doubleslap)) // missed or owner died, remove ent
                remove(self);
        else // continue swinging the weapon in hope of hitting someone :)
                self.nextthink = time;
  
  void W_Shotgun_Attack2 (void)
  {
-       sound (self, CHAN_PROJECTILE, "weapons/shotgun_melee.wav", VOL_BASE, ATTN_NORM);
+       sound (self, CH_SHOTS, "weapons/shotgun_melee.wav", VOL_BASE, ATTN_NORM);
        weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_shotgun_secondary_animtime, w_ready);
  
        entity meleetemp;
        meleetemp = spawn();
-       meleetemp.owner = self;
+       meleetemp.owner = meleetemp.realowner = self;
        meleetemp.think = shotgun_meleethink;
        meleetemp.nextthink = time + autocvar_g_balance_shotgun_secondary_melee_delay;
        W_SetupShot_Range(self, TRUE, 0, "", 0, autocvar_g_balance_shotgun_secondary_damage, autocvar_g_balance_shotgun_secondary_melee_range);
@@@ -132,7 -138,6 +138,7 @@@ float w_shotgun(float req
                        }
                }
                if (self.clip_load >= 0) // we are not currently reloading
 +              if (!self.crouch) // we are not currently crouching; this fixes an exploit where your melee anim is not visible, and besides wouldn't make much sense
                if (self.BUTTON_ATCK2 && autocvar_g_balance_shotgun_secondary)
                if (weapon_prepareattack(1, autocvar_g_balance_shotgun_secondary_refire))
                {
@@@ -186,11 -191,11 +192,11 @@@ float w_shotgun(float req
                if(!w_issilent && time - self.prevric > 0.25)
                {
                        if(w_random < 0.0165)
-                               sound(self, CHAN_PROJECTILE, "weapons/ric1.wav", VOL_BASE, ATTN_NORM);
+                               sound(self, CH_SHOTS, "weapons/ric1.wav", VOL_BASE, ATTN_NORM);
                        else if(w_random < 0.033)
-                               sound(self, CHAN_PROJECTILE, "weapons/ric2.wav", VOL_BASE, ATTN_NORM);
+                               sound(self, CH_SHOTS, "weapons/ric2.wav", VOL_BASE, ATTN_NORM);
                        else if(w_random < 0.05)
-                               sound(self, CHAN_PROJECTILE, "weapons/ric3.wav", VOL_BASE, ATTN_NORM);
+                               sound(self, CH_SHOTS, "weapons/ric3.wav", VOL_BASE, ATTN_NORM);
                        self.prevric = time;
                }
        }
                precache_sound("weapons/ric3.wav");
        }
        else if (req == WR_SUICIDEMESSAGE)
-               w_deathtypestring = _("%s did the impossible");
+               w_deathtypestring = _("%s is now thinking with portals");
        else if (req == WR_KILLMESSAGE)
        {
                if(w_deathtype & HITTYPE_SECONDARY)