]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into mirceakitsune/damage_effects
authorMircea Kitsune <sonichedgehog_hyperblast00@yahoo.com>
Thu, 25 Aug 2011 12:36:41 +0000 (15:36 +0300)
committerMircea Kitsune <sonichedgehog_hyperblast00@yahoo.com>
Thu, 25 Aug 2011 12:36:41 +0000 (15:36 +0300)
Conflicts:
effectinfo.txt
qcsrc/client/Main.qc
qcsrc/client/autocvars.qh
qcsrc/client/gibs.qc

12 files changed:
1  2 
defaultXonotic.cfg
effectinfo.txt
qcsrc/client/Main.qc
qcsrc/client/autocvars.qh
qcsrc/client/gibs.qc
qcsrc/common/constants.qh
qcsrc/server/autocvars.qh
qcsrc/server/cl_client.qc
qcsrc/server/cl_player.qc
qcsrc/server/defs.qh
qcsrc/server/g_damage.qc
qcsrc/server/miscfunctions.qc

diff --combined defaultXonotic.cfg
index fc5f98ef95bcc669860ec7eeb82f221cab9cf1a5,8a76f7a99e6a463b2aef6573f56f993090806a44..b896923f7fb3f7f05f40ed0a0a67e0e8ca3d5d43
@@@ -10,7 -10,7 +10,7 @@@
  // e.g. Xonotic 1.5.1 RC1 will be 15101
  set g_xonoticversion git "Xonotic version (formatted for humans)"
  
- gameversion 100 // 0.1.0
+ gameversion 500 // 0.5.0
  gameversion_min 0 // git builds see all versions
  gameversion_max 65535 // git builds see all versions
  
@@@ -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"
@@@ -173,10 -174,10 +174,10 @@@ seta crosshair_seeker ""        "crosshair to 
  seta crosshair_seeker_color "1 0.35 0.35"     "crosshair color to display when wielding the TAG seeker"
  seta crosshair_seeker_alpha 0.9       "crosshair alpha value to display when wielding the TAG seeker"
  seta crosshair_seeker_size 0.8        "crosshair size when wielding the TAG seeker"
- seta crosshair_sniperrifle "" "crosshair to display when wielding the sniperrifle"
- seta crosshair_sniperrifle_color "0.85 0.5 0.25"      "crosshair color to display when wielding the sniperrifle"
- seta crosshair_sniperrifle_alpha 1    "crosshair alpha value to display when wielding the sniperrifle"
- seta crosshair_sniperrifle_size 0.65  "crosshair size when wielding the sniperrifle"
+ seta crosshair_rifle ""       "crosshair to display when wielding the rifle"
+ seta crosshair_rifle_color "0.85 0.5 0.25"    "crosshair color to display when wielding the rifle"
+ seta crosshair_rifle_alpha 1  "crosshair alpha value to display when wielding the rifle"
+ seta crosshair_rifle_size 0.65        "crosshair size when wielding the rifle"
  seta crosshair_tuba ""        "crosshair to display when wielding the tuba"
  seta crosshair_tuba_color "0.85 0.5 0.25"     "crosshair color to display when wielding the tuba"
  seta crosshair_tuba_alpha 1   "crosshair alpha value to display when wielding the tuba"
@@@ -281,13 -282,13 +282,13 @@@ 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
+ r_bloom_blur 16
+ r_bloom_brighten 2.5
  r_bloom_colorexponent 1
  r_bloom_colorscale 1
- r_bloom_colorsubtract 0.25
+ r_bloom_colorsubtract 0.15
  r_bloom_resolution 320
  r_hdr_range 4
  
@@@ -319,8 -320,7 +320,7 @@@ set sv_ready_restart_repeatable 0  "allo
  seta cl_hitsound 1 "play a hit notifier sound when you have hit an enemy"
  set cl_hitsound_antispam_time 0.05 "don't play the hitsound more often than this"
  
- seta cl_eventchase_death 0 "camera goes into 3rd person mode when the player is dead"
- seta cl_eventchase_intermission 0 "camera goes into 3rd person mode when the match ends"
+ seta cl_eventchase_death 1 "camera goes into 3rd person mode when the player is dead"
  seta cl_eventchase_distance 140 "final camera distance"
  seta cl_eventchase_speed 1.3 "how fast the camera slides back, 0 is instant"
  
@@@ -358,12 -358,6 +358,12 @@@ set g_telefrags_teamplay 1 "never telef
  set g_telefrags_avoid 1 "when teleporters have a random destination, avoid teleporting to locations where a telefrag would happen"
  set g_teleport_maxspeed 0 "maximum speed that a player can keep when going through a teleporter (if a misc_teleporter_dest also has a cap the smallest one of these will be used), 0 = don't limit, -1 = keep no speed"
  
 +set sv_damageeffect_tick 0.05 "how often the damage effect is updated (particles per second), low values might cause lag"
 +set sv_damageeffect_lifetime 0.04 "how much a damage effect lasts, multiplied by damage amount"
 +set sv_damageeffect_lifetime_max 5 "maximum amount of lifetime a damage effect may have at a time"
 +set cl_damageeffect 1 "enable weapon damage effects on players, values between 0 and 1 specify probability of the effect showing on players each tick (used to reduce the effect)"
 +set cl_damageeffect_gibs 0.15 "probability of the effect showing on gibs each tick (used to reduce the effect)"
 +
  set g_respawn_ghosts 1 "if 1 dead bodies become ghosts and float away when the player respawns"
  set g_respawn_ghosts_speed 5 "the speed with which respawn ghosts float and rotate"
  set g_respawn_ghosts_maxtime 6 "maximum amount of time a respawn ghost can last, minimum time is half this value. 0 disables and ghosts fade when the body would"
@@@ -455,9 -449,9 +455,9 @@@ set bot_ai_keyboard_threshold 0.5
  set bot_ai_aimskill_offset 0.3 "Amount of error induced to the bots aim"
  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 sniperrifle 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 sniperrifle 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 sniperrifle rocketlauncher laser fireball minelayer"        "Desired weapons for close distances ordered by priority"
+ 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 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"
@@@ -500,7 -494,7 +500,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"
@@@ -708,7 -702,7 +708,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
  
@@@ -905,6 -899,8 +905,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
@@@ -916,7 -912,7 +918,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"
@@@ -1011,20 -1007,30 +1013,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
@@@ -1032,6 -1038,7 +1044,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
@@@ -1191,21 -1198,21 +1204,21 @@@ alias cl_fbskin_green "playermodel mode
  alias cl_fbskin_red "playermodel models/player/erebus.iqm; playerskin 1; color 4 4"
  alias cl_fbskin_orange "playermodel models/player/erebus.iqm; playerskin 1; color 14 14"
  alias cl_fbskin_off "playermodel models/player/erebus.iqm; playerskin 0"
- alias sv_fbskin_green "sv_defaultcharacter 1; sv_defaultplayermodel models/player/erebus.iqm; sv_defaultplayerskin 1; sv_defaultplayercolors 51"
- alias sv_fbskin_red "sv_defaultcharacter 1; sv_defaultplayermodel models/player/erebus.iqm; sv_defaultplayerskin 1; sv_defaultplayercolors 68"
- alias sv_fbskin_orange "sv_defaultcharacter 1; sv_defaultplayermodel models/player/erebus.iqm; sv_defaultplayerskin 1; sv_defaultplayercolors 238"
+ alias sv_fbskin_green "sv_defaultcharacter 1; sv_defaultplayermodel models/player/megaerebus.iqm; sv_defaultplayerskin 1; sv_defaultplayercolors 51"
+ alias sv_fbskin_red "sv_defaultcharacter 1; sv_defaultplayermodel models/player/megaerebus.iqm; sv_defaultplayerskin 1; sv_defaultplayercolors 68"
+ alias sv_fbskin_orange "sv_defaultcharacter 1; sv_defaultplayermodel models/player/megaerebus.iqm; sv_defaultplayerskin 1; sv_defaultplayercolors 238"
  alias sv_fbskin_off "sv_defaultcharacter 0; sv_defaultplayerskin 0; sv_defaultplayercolors \"\""
  
  seta sv_servermodelsonly 1
  
  cl_curl_enabled 1
- cl_curl_maxspeed 300
- sv_curl_defaulturl "http://www.xonotic.com/contentdownload/getmap.php?file="
+ cl_curl_maxspeed 400
+ sv_curl_defaulturl "http://www.xonotic.org/contentdownload/getmap.php?file="
  set sv_curl_serverpackages_auto 1 "automatically add packs with *.serverpackage files to sv_curl_serverpackages"
  
  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
@@@ -1233,6 -1240,7 +1246,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
@@@ -1243,16 -1251,22 +1257,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"
@@@ -1265,7 -1279,7 +1285,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"
  
@@@ -1291,7 -1305,6 +1311,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
@@@ -1369,6 -1382,7 +1388,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"
@@@ -1478,6 -1492,8 +1498,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"
@@@ -1490,7 -1506,15 +1512,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"
@@@ -1608,14 -1632,15 +1638,15 @@@ set con_completion_playermodel       models/p
  seta cl_port $cl_port
  seta r_showsurfaces $r_showsurfaces
  seta r_ambient $r_ambient
- seta skill $skill
+ seta skill 4
  seta gl_finish $gl_finish
  seta v_kicktime $v_kicktime
  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
@@@ -1670,7 -1695,6 +1701,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
@@@ -1683,12 -1707,12 +1713,12 @@@ set g_jump_grunt 0   "Do you make a grunt
  
  alias allready "sv_cmd allready"
  
- seta cl_weaponpriority "minstanex rocketlauncher nex grenadelauncher minelayer fireball hlac hagar seeker crylink sniperrifle uzi electro tuba shotgun laser hook porto" "weapon priority list"
+ seta cl_weaponpriority "minstanex rocketlauncher nex grenadelauncher minelayer fireball hlac hagar seeker crylink rifle uzi electro tuba shotgun laser hook porto" "weapon priority list"
  seta cl_weaponpriority_useforcycling 0 "when set, weapon cycling by the mouse wheel makes use of the weapon priority list (the special value 2 uses the weapon ID list for cycling)"
  seta cl_weaponpriority0 "rocketlauncher grenadelauncher hagar seeker fireball" "use impulse 200 for prev gun from this list, 210 for best gun, 220 for next gun.  Default value: explosives"
  seta cl_weaponpriority1 "minstanex nex crylink hlac electro laser"             "use impulse 201 for prev gun from this list, 211 for best gun, 221 for next gun.  Default value: energy"
- seta cl_weaponpriority2 "minstanex nex sniperrifle"                           "use impulse 202 for prev gun from this list, 212 for best gun, 222 for next gun.  Default value: hitscan exact"
- seta cl_weaponpriority3 "minstanex nex sniperrifle uzi shotgun"               "use impulse 203 for prev gun from this list, 213 for best gun, 223 for next gun.  Default value: hitscan all"
+ seta cl_weaponpriority2 "minstanex nex rifle"                           "use impulse 202 for prev gun from this list, 212 for best gun, 222 for next gun.  Default value: hitscan exact"
+ seta cl_weaponpriority3 "minstanex nex rifle uzi shotgun"               "use impulse 203 for prev gun from this list, 213 for best gun, 223 for next gun.  Default value: hitscan all"
  seta cl_weaponpriority4 "grenadelauncher minelayer hlac hagar crylink seeker shotgun"    "use impulse 204 for prev gun from this list, 214 for best gun, 224 for next gun.  Default value: spam weapons"
  seta cl_weaponpriority5 "laser hook porto"                                     "use impulse 205 for prev gun from this list, 215 for best gun, 225 for next gun.  Default value: weapons for moving"
  seta cl_weaponpriority6 "" "use impulse 206 for prev gun from this list, 216 for best gun, 226 for next gun"
@@@ -1718,7 -1742,9 +1748,9 @@@ alias gl_flashblend_update "_gl_flashbl
  
  set sv_clones 0       "number of clones a player may make (reset by the \"kill\" command)"
  
- set cl_handicap 1     "the higher, the more damage you will receive (client setting)"
+ set cl_handicap 1     "the higher, the more damage you will receive (client setting) NOTE: reconnect or use sendcvar command to update the choice."
+ seta cl_clippedspectating 1 "movement collision for spectators so that you can't pass through walls and such. (client setting) NOTE: reconnect or use sendcvar command to update the choice." 
  
  // must be at the bottom of this file:
  // alias for switching the teamselect menu
@@@ -1908,7 -1934,7 +1940,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"
@@@ -1957,6 -1983,7 +1989,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"
@@@ -2016,7 -2043,7 +2049,7 @@@ set g_weaponreplace_porto "
  set g_weaponreplace_minstanex ""
  set g_weaponreplace_hook ""
  set g_weaponreplace_hlac ""
- set g_weaponreplace_sniperrifle ""
+ set g_weaponreplace_rifle ""
  set g_weaponreplace_tuba ""
  set g_weaponreplace_fireball ""
  set g_weaponreplace_seeker ""
@@@ -2043,8 -2070,8 +2076,8 @@@ scr_conforcewhiledisconnected 
  scr_infobar_height 12
  
  // DP cannot properly detect this, so rather turn off the detection
- r_texture_dds_load_dxt1_noalpha 1
- r_texture_dds_load_swdecode 1 // SW decode to quarter res if we want to load DDS but don't support the extension for it
+ r_texture_dds_load_alphamode 2
+ r_texture_dds_swdecode 1 // SW decode to quarter res if we want to load DDS but don't support the extension for it
  r_texture_dds_load_logfailure 0 // this engine feature SUCKS
  set vid_netwmfullscreen 0 // doesn't support non-native res
  
@@@ -2057,10 -2084,11 +2090,11 @@@ 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
+ r_shadow_glossintensity 1
  
  // use fake light if map has no lightmaps
  r_fakelight 1
@@@ -2126,11 -2154,15 +2160,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
@@@ -2145,6 -2177,7 +2183,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
diff --combined effectinfo.txt
index 15563178d10b6362591e97012b519851a41a874a,bf631fb254197ed732145f2538180345fddaea2d..f69cdc907ddce77eacc3179c4fc104b4c98c37db
@@@ -5258,646 -5258,1152 +5258,1796 @@@ originjitter 1 1 
  velocityjitter 100 100 100
  velocitymultiplier -0.31
  
- // hook does not use the weapon damage effect
+ // --------------- vehicles
+ effect spiderbot_minigun_trail
+ notunderwater
+ trailspacing 10
+ type smoke
+ color 0xd0d0a0 0xffffff
+ tex 0 8
+ size 1 2
+ alpha 20 50 100
+ sizeincrease 2
+ velocityjitter 5 5 5
+ gravity -0.03
+ airfriction 1
+ effect spiderbot_minigun_muzzleflash
+ count 3
+ type spark
+ color 0xff9c00 0xff8400
+ tex 48 55
+ size 10 15
+ alpha 256 512 6280
+ airfriction 10
+ originjitter 2 2 2
+ velocityjitter 150 150 150
+ velocitymultiplier 0.35
+ sizeincrease -100
+ stretchfactor 1.3
+ rotate -180 180 4000 -4000
+ // fire
+ effect spiderbot_minigun_muzzleflash
+ count 6
+ type spark
+ color 0xff9c00 0xff8400
+ tex 8 15
+ size 5 7
+ alpha 256 512 6280
+ airfriction 12
+ originjitter 2 2 2
+ velocityjitter 200 200 200
+ velocitymultiplier 0.2
+ sizeincrease -10
+ stretchfactor 0.8
+ effect spiderbot_minigun_muzzleflash
+ countabsolute 2
+ type static
+ tex 48 55
+ color 0xff9c00 0xff8400
+ size 32 32
+ alpha 256 512 6680
+ sizeincrease -100
+ stretchfactor 0.1
+ rotate -180 180 4000 -4000
+ lightradius 120
+ lightradiusfade 8000
+ lightcolor 3 3 0
+ effect spiderbot_minigun_impact
+ countabsolute 1
+ type static
+ tex 65 65
+ color 0xff9c00 0xf6ff00
+ size 52 52
+ alpha 50 100 1680
+ sizeincrease -100
+ stretchfactor 0.1
+ rotate -180 180 4000 -4000
+ // fire
+ effect spiderbot_minigun_impact
+ count 7
+ type spark
+ color 0xff9c00 0xff8400
+ tex 48 55
+ size 9 15
+ alpha 256 512 6280
+ airfriction 10
+ originjitter 2 2 2
+ velocityjitter 250 250 150
+ velocitymultiplier 0.2
+ sizeincrease 100
+ stretchfactor 3
+ airfriction 6
+ rotate -180 180 4000 -4000
+ // smoke 
+ effect spiderbot_minigun_impact
+ count 6
+ type smoke
+ color 0xd0d0a0 0xffffff
+ tex 0 8
+ size 10 20
+ alpha 50 50 190
+ sizeincrease 80
+ velocityjitter 100 100 250
+ velocitymultiplier 0.49
+ gravity 1.3
+ airfriction 10
+ rotate -180 180 0 0
+ // smoke 2
+ effect spiderbot_minigun_impact
+ count 7
+ type spark
+ color 0xd0d0a0 0xffffff
+ tex 0 8
+ size 15 19
+ alpha 25 51 128
+ airfriction 6
+ originjitter 2 2 2
+ velocityjitter 250 250 150
+ velocitymultiplier 0.2
+ sizeincrease 100
+ stretchfactor 7.6
+ // derbis
+ effect spiderbot_minigun_impact
+ notunderwater
+ count 3
+ type alphastatic
+ tex 66 68
+ color 0x99977D 0xFFFFFF
+ size 6 8
+ alpha 644 756 1484
+ gravity 1.1
+ airfriction 0.4
+ sizeincrease -10
+ velocitymultiplier 0.15
+ originjitter 16 16 16
+ velocityjitter 124 124 224
+ rotate -180 180 -1000 1000
+ // decal
+ effect spiderbot_minigun_impact
+ countabsolute 1
+ type decal
+ tex 56 59
+ size 20 25
+ alpha 256 256 0
+ originjitter 16 16 16
+ rotate -180 180 0 0
+ effect spiderbot_rocket_explode
+ countabsolute 1
+ type decal
+ tex 8 16
+ size 72 72
+ alpha 256 256 0
+ originjitter 23 23 23
+ lightradius 300
+ lightradiusfade 1750
+ lightcolor 8 4 0
+ // shockwave
+ effect spiderbot_rocket_explode
+ countabsolute 1
+ type static
+ tex 33 33 
+ size 22 22
+ alpha 56 56 230
+ color 0x8f0d00 0xff5a00
+ sizeincrease 2400
+ // glow
+ effect spiderbot_rocket_explode
+ countabsolute 1
+ type static
+ tex 64 64
+ size 120 120
+ alpha 156 156 830
+ color 0x8f0d00 0xff5a00
+ sizeincrease 240
+ // fire effect
+ effect spiderbot_rocket_explode
+ notunderwater
+ count 32
+ type static
+ tex 48 55
+ color 0x8f0d00 0xff5a00
+ size 12 21
+ sizeincrease 495
+ alpha 200 256 812
+ airfriction 8
+ liquidfriction 8
+ originjitter 100 100 100
+ velocityjitter 512 512 512
+ rotate -180 180 -50 50
+ // fire effect 2
+ effect spiderbot_rocket_explode
+ notunderwater
+ count 16
+ type spark
+ tex 48 55
+ color 0x8f0d00 0xff5a00
+ size 3 3
+ sizeincrease 120
+ alpha 200 256 912
+ airfriction -2
+ liquidfriction 8
+ velocityjitter 412 412 412
+ rotate -180 180 -150 150
+ stretchfactor 10
+ // fire rays
+ effect spiderbot_rocket_explode
+ notunderwater
+ count 10
+ type spark
+ tex 48 55
+ color 0x8f0d00 0xff5a00
+ size 13 54
+ sizeincrease 120
+ alpha 200 256 1600
+ airfriction -3
+ liquidfriction 8
+ originjitter 40 40 40
+ velocityjitter 712 712 712
+ stretchfactor 10
+ // smoke
+ effect spiderbot_rocket_explode
+ type alphastatic
+ notunderwater
+ tex 0 8
+ count 10
+ size 10 15
+ sizeincrease 280
+ alpha 300 650 756
+ originjitter 100 100 100
+ velocityjitter 200 200 200
+ airfriction 3
+ color 0x4F4B46 0x000000
+ rotate -180 180 -20 20
+ // smoke2
+ effect spiderbot_rocket_explode
+ type alphastatic
+ notunderwater
+ tex 0 8
+ count 3
+ size 100 150
+ sizeincrease 30
+ alpha 300 650 556
+ originjitter 10 10 10
+ velocityjitter 200 200 200
+ airfriction 2
+ gravity -0.5
+ color 0x4F4B46 0x000000
+ rotate -180 180 -20 20
+ // underwater bubbles
+ effect spiderbot_rocket_explode
+ underwater
+ count 32
+ type bubble
+ tex 62 62
+ color 0x404040 0x808080
+ size 1 3
+ alpha 128 256 64
+ gravity -0.125
+ bounce 1.5
+ liquidfriction 0.25
+ originjitter 160 160 160
+ velocityjitter 144 144 144
+ // underwatershockwave
+ effect spiderbot_rocket_explode
+ underwater
+ type smoke
+ countabsolute 1
+ tex 33 33
+ size 30 30
+ sizeincrease 1200
+ alpha 40 40 300
+ effect spiderbot_rocket_thrust
+ notunderwater
+ count 3
+ type spark
+ tex 48 55
+ color 0x8f0d00 0xff5a00
+ size 5 10
+ sizeincrease -40
+ alpha 200 256 1600
+ velocityjitter 20 20 20
+ velocitymultiplier -1.4
+ stretchfactor 0.9
+ effect spiderbot_rocket_thrust
+ notunderwater
+ count 4
+ type static
+ tex 48 55
+ color 0x8f0d00 0xff5a00
+ size 25 25
+ sizeincrease -3000
+ alpha 200 200 9000
+ velocityjitter 60 60 60
+ velocitymultiplier -1.4
+ stretchfactor 1
+ rotate -180 180 -500 500
+ // long lasting smoke
+ effect spiderbot_rocket_launch
+ notunderwater
+ count 8
+ type smoke
+ tex 0 8
+ color 0xFFFFFF 0xD9C4B0
+ size 30 30
+ sizeincrease 20
+ alpha 100 156 60
+ velocityjitter 60 60 60
+ velocitymultiplier -0.1
+ airfriction 0.3
+ gravity -0.01
+ // fast smoke
+ effect spiderbot_rocket_launch
+ notunderwater
+ count 14
+ type smoke
+ tex 0 8
+ color 0xFFFFFF 0xD9C4B0
+ size 30 30
+ sizeincrease 20
+ alpha 100 156 260
+ gravity -0.3
+ velocityjitter 160 160 60
+ airfriction 0.3
+ // fire
+ effect spiderbot_rocket_launch
+ notunderwater
+ count 14
+ type spark
+ tex 48 55
+ color 0x8f0d00 0xff5a00
+ size 30 30
+ sizeincrease 40
+ velocitymultiplier 0.5
+ alpha 200 256 1960
+ velocityjitter 60 60 60
+ airfriction 0.3
+ stretchfactor 3
+ airfriction 0.3
+ //sparks
+ effect spiderbot_rocket_launch
+ notunderwater
+ count 10
+ type spark
+ tex 40 40
+ color 0xFFFFFF 0xD9C4B0
+ size 1 4
+ alpha 200 256 1000
+ velocityjitter 160 160 160
+ velocitymultiplier -0.5
+ effect wakizashi_gun_impact
+ count 15
+ type spark
+ color 0xff0000 0xc03535
+ tex 41 41
+ size 4 7
+ alpha 256 512 1180
+ airfriction 4
+ gravity 3
+ originjitter 40 40 10
+ velocityjitter 350 350 550
+ velocityoffset 0 0 700
+ stretchfactor 0.9
+ effect wakizashi_gun_impact
+ type smoke
+ count 24
+ color 0xd0d0a0 0xc03535
+ tex 0 8
+ size 10 20
+ alpha 50 90 150
+ sizeincrease 80
+ velocityjitter 250 250 450
+ velocityoffset 0 0 600
+ originjitter 40 40 10
+ airfriction 4
+ sizeincrease 80
+ rotate -180 180 0 0
+ effect wakizashi_gun_impact
+ countabsolute 1
+ type smoke
+ tex 65 65
+ color 0xff0000 0xc03535
+ size 82 82
+ alpha 250 300 680
+ sizeincrease -180
+ effect wakizashi_gun_impact
+ countabsolute 1
+ type smoke
+ tex 33 33
+ color 0xff0000 0xc03535
+ size 40 40
+ alpha 50 100 620
+ sizeincrease 900
+ rotate -180 180 400 -400
+ effect wakizashi_gun_impact
+ countabsolute 1
+ type decal
+ tex 59 59
+ size 14 14
+ alpha 256 256 0
+ originjitter 16 16 16
+ rotate -180 180 0 0
+ effect wakizashi_gun_muzzleflash
+ count 16
+ type spark
+ color 0xff0000 0xc03535
+ tex 8 15
+ size 5 7
+ alpha 256 512 6280
+ airfriction 12
+ originjitter 2 2 2
+ velocityjitter 200 200 200
+ velocitymultiplier 0.2
+ sizeincrease -10
+ stretchfactor 0.7
+ effect wakizashi_rocket_explode
+ countabsolute 1
+ type decal
+ tex 8 16
+ size 72 72
+ alpha 256 256 0
+ originjitter 23 23 23
+ lightradius 300
+ lightradiusfade 1750
+ lightcolor 8 4 0
+ // shockwave
+ effect wakizashi_rocket_explode
+ countabsolute 1
+ type static
+ tex 33 33 
+ size 22 22
+ alpha 56 56 230
+ color 0x8f0d00 0xff5a00
+ sizeincrease 2400
+ // glow
+ effect wakizashi_rocket_explode
+ countabsolute 1
+ type static
+ tex 64 64
+ size 120 120
+ alpha 156 156 830
+ color 0x8f0d00 0xff5a00
+ sizeincrease 240
+ // fire effect
+ effect wakizashi_rocket_explode
+ notunderwater
+ count 64
+ type static
+ tex 48 55
+ color 0xFFAE00 0xff5a00
+ size 12 21
+ sizeincrease 195
+ alpha 200 256 512
+ airfriction 2
+ liquidfriction 8
+ originjitter 10 10 10
+ velocityjitter 512 512 512
+ rotate -180 180 -50 50
+ // fire rays
+ effect wakizashi_rocket_explode
+ notunderwater
+ count 10
+ type spark
+ tex 48 55
+ color 0xFFEA00 0xff5a00
+ size 43 54
+ sizeincrease 120
+ alpha 200 256 1600
+ airfriction -3
+ liquidfriction 8
+ originjitter 40 40 40
+ velocityjitter 512 512 512
+ stretchfactor 10
+ // smoke
+ effect wakizashi_rocket_explode
+ type alphastatic
+ notunderwater
+ tex 0 8
+ count 32
+ size 10 15
+ sizeincrease 230
+ alpha 300 450 556
+ originjitter 100 100 100
+ velocityjitter 200 200 200
+ airfriction 3
+ color 0x4F4B46 0x000000
+ rotate -180 180 -20 20
+ // bouncing sparks
+ effect wakizashi_rocket_explode
+ notunderwater
+ count 14
+ type spark
+ tex 40 40
+ color 0xffa35b 0xfff2be
+ size 1 2
+ alpha 644 956 884
+ gravity 1
+ airfriction 1
+ liquidfriction 0.8
+ velocityoffset 0 0 170
+ originjitter 60 60 60
+ velocityjitter 524 524 524
+ // underwater bubbles
+ effect wakizashi_rocket_explode
+ underwater
+ count 32
+ type bubble
+ tex 62 62
+ color 0x404040 0x808080
+ size 1 3
+ alpha 128 256 64
+ gravity -0.125
+ bounce 1.5
+ liquidfriction 0.25
+ originjitter 160 160 160
+ velocityjitter 144 144 144
+ // underwatershockwave
+ effect wakizashi_rocket_explode
+ underwater
+ type smoke
+ countabsolute 1
+ tex 33 33
+ size 30 30
+ sizeincrease 1200
+ alpha 40 40 300
+ effect wakizashi_rocket_thrust
+ notunderwater
+ countabsolute 3
+ type spark
+ tex 48 55
+ color 0x00FFDD 0x6200FF
+ size 14 19
+ sizeincrease -2
+ alpha 200 256 1600
+ velocityjitter 60 60 60
+ velocitymultiplier -1.1
+ stretchfactor 1
+ effect wakizashi_rocket_thrust
+ notunderwater
+ countabsolute 2
+ type spark
+ tex 48 55
+ color 0xFFFF33 0xFFEE00
+ size 5 10
+ sizeincrease -2
+ alpha 200 256 1900
+ velocityjitter 60 60 60
+ velocitymultiplier -0.3
+ stretchfactor 3
+ // long lasting smoke
+ effect wakizashi_rocket_launch
+ notunderwater
+ count 8
+ type smoke
+ tex 0 8
+ color 0xFFFFFF 0xD9C4B0
+ size 3 30
+ sizeincrease 20
+ alpha 100 156 60
+ velocityjitter 160 160 60
+ velocitymultiplier -0.1
+ airfriction 0.3
+ // fast smoke
+ effect wakizashi_rocket_launch
+ notunderwater
+ count 14
+ type smoke
+ tex 0 8
+ color 0xFFFFFF 0xD9C4B0
+ size 30 30
+ sizeincrease 20
+ alpha 100 156 260
+ velocityjitter 160 160 60
+ velocitymultiplier 0.4
+ airfriction 0.3
+ //sparks
+ effect wakizashi_rocket_launch
+ notunderwater
+ count 10
+ type spark
+ tex 40 40
+ color 0xFFFFFF 0xD9C4B0
+ size 1 4
+ alpha 200 256 1000
+ velocityjitter 60 60 60
+ velocitymultiplier -1.5
+ effect wakizashi_booster_smoke
+ type alphastatic
+ notunderwater
+ tex 0 8
+ count 3
+ size 60 100
+ sizeincrease 10
+ gravity -0.1
+ alpha 200 750 200
+ velocityjitter 40 40 40
+ originjitter 60 60 60
+ airfriction 2
+ color 0xA69A80 0xB3B39F
+ rotate -180 180 -20 20
+ // decal
+ effect raptor_cannon_impact
+ countabsolute 1
+ type decal
+ tex 47 47
+ size 24 24
+ alpha 256 256 0
+ originjitter 16 16 16
+ rotate -180 180 0 0
+ //spark
+ effect raptor_cannon_impact
+ notunderwater
+ count 6
+ type spark
+ tex 40 40
+ color 0xD400FF 0x571863
+ size 1 1
+ alpha 644 956 784
+ gravity 1
+ airfriction 0.2
+ velocityoffset 0 0 150
+ originjitter 16 16 16
+ velocityjitter 124 124 524
+ // smoke
+ effect raptor_cannon_impact
+ count 4
+ type alphastatic
+ tex 0 7
+ size 50 50
+ color 0x646364 0x151515
+ alpha 428 428 600
+ rotate -180 180 0 0
+ velocityjitter 200 200 300
+ velocityoffset 0 0 340
+ gravity 0.7
+ airfriction 2
+ // fire
+ effect raptor_cannon_impact
+ notunderwater
+ count 10
+ type static
+ tex 48 55
+ color 0xD400FF 0x571863
+ size 33 44
+ sizeincrease 25
+ alpha 200 256 812
+ bounce 1.5
+ airfriction 8
+ liquidfriction 8
+ originjitter 8 8 8
+ velocityjitter 312 312 312
+ effect raptor_cannon_muzzleflash
+ count 16
+ type spark
+ color 0xD400FF 0x571863
+ tex 8 15
+ size 10 17
+ alpha 1256 1512 56280
+ airfriction 12
+ originjitter 2 2 2
+ velocityjitter 200 200 200
+ velocitymultiplier 0.2
+ sizeincrease -10
+ stretchfactor 0.6
+ effect raptor_cannon_muzzleflash
+ countabsolute 1
+ type static
+ tex 48 55
+ color 0xD400FF 0x571863
+ size 32 32
+ alpha 6056 20112 406280
+ sizeincrease -100
+ stretchfactor 0.1
+ rotate -180 180 4000 -4000
+ lightradius 150
+ lightradiusfade 6000
+ lightcolor 3 0 6
+ // decal
+ effect raptor_bomb_impact
+ countabsolute 1
+ type decal
+ tex 8 16
+ size 84 84
+ alpha 256 256 0
+ originjitter 16 16 16
+ rotate -180 180 0 0
+ //spark vertical
+ effect raptor_bomb_impact
+ count 3
+ type spark
+ color 0xff9c00 0xff3c00
+ tex 48 55
+ size 20 40
+ alpha 300 300 600
+ originjitter 10 10 10
+ velocityjitter 40 40 120
+ stretchfactor 210
+ sizeincrease 50
+ //fire
+ effect raptor_bomb_impact
+ count 4
+ type static 
+ color 0xff9c00 0xff3c00
+ tex 48 55
+ size 30 120
+ alpha 300 300 500
+ originjitter 10 10 10
+ velocityjitter 950 950 0
+ sizeincrease 230
+ airfriction 2
+ //smoke
+ effect raptor_bomb_impact
+ count 4
+ type spark
+ blend alpha
+ tex 0 7
+ size 120 180
+ color 0x646364 0x151515
+ alpha 428 428 600
+ rotate -180 180 0 0
+ velocityjitter 200 200 280
+ velocityoffset 0 0 280
+ originjitter 30 30 10
+ stretchfactor 10
+ //smoke 2
+ effect raptor_bomb_impact
+ count 4
+ //type alphastatic
+ type spark
+ blend alpha
+ tex 0 7
+ size 40 100
+ color 0x646364 0x151515
+ alpha 328 328 350
+ rotate -180 180 0 0
+ velocityjitter 200 200 300
+ velocityoffset 0 0 580
+ originjitter 30 30 10
+ sizeincrease 60
+ airfriction 0.6
+ gravity 2
+ // sparks
+ effect raptor_bomb_impact
+ notunderwater
+ count 5
+ type spark
+ tex 40 40
+ color 0xffa35b 0xfff2be
+ size 3 5
+ alpha 644 956 984
+ gravity 1
+ airfriction 0.3
+ velocityoffset 0 0 350
+ originjitter 16 16 16
+ velocityjitter 174 174 924
+ stretchfactor 2
+ effect raptor_bomb_spread
+ notunderwater
+ count 34
+ type spark
+ tex 40 40
+ color 0xffa35b 0xfff2be
+ size 1 2
+ alpha 644 956 1284
+ gravity 1
+ airfriction 1
+ liquidfriction 0.8
+ originjitter 110 110 110
+ velocityjitter 324 324 324
+ // generic explosion size:big (biggest explosion ever)
+ effect explosion_big
+ countabsolute 1
+ type decal
+ tex 8 16
+ size 172 172
+ alpha 256 256 0
+ originjitter 23 23 23
+ lightradius 600
+ lightradiusfade 1750
+ lightcolor 8 4 0
+ // shockwave
+ effect explosion_big
+ countabsolute 1
+ type static
+ tex 33 33 
+ size 72 72
+ alpha 56 56 330
+ color 0x8f0d00 0xff5a00
+ sizeincrease 4400
+ // fire effect
+ effect explosion_big
+ notunderwater
+ count 64
+ type static
+ tex 48 55
+ color 0x8f0d00 0xff5a00
+ size 133 144
+ sizeincrease 45
+ alpha 200 256 712
+ airfriction 8
+ liquidfriction 8
+ originjitter 80 80 80
+ velocityjitter 2512 2512 2512
+ // fire rays
+ effect explosion_big
+ notunderwater
+ count 64
+ type spark
+ tex 48 55
+ color 0x8f0d00 0xff5a00
+ size 133 144
+ sizeincrease 45
+ alpha 200 256 800
+ airfriction -5
+ liquidfriction 8
+ originjitter 40 40 40
+ velocityjitter 512 512 512
+ stretchfactor 10
+ // smoke
+ effect explosion_big
+ type alphastatic
+ notunderwater
+ tex 0 8
+ count 32
+ size 50 100
+ sizeincrease 244
+ alpha 300 650 456
+ velocityjitter 3444 3444 3444
+ airfriction 8
+ color 0x4F4B46 0x000000
+ // bouncing sparks
+ effect explosion_big
+ notunderwater
+ count 34
+ type spark
+ tex 40 40
+ color 0xffa35b 0xfff2be
+ size 3 4
+ alpha 644 956 1284
+ gravity 1
+ airfriction 1
+ liquidfriction 0.8
+ velocityoffset 0 0 370
+ originjitter 160 160 160
+ velocityjitter 924 924 924
+ stretchfactor 0.7
+ // derbis
+ effect explosion_big
+ notunderwater
+ count 16
+ type alphastatic
+ tex 66 68
+ color 0xFFFFFF 0xcac5b4
+ size 10 16
+ alpha 444 1356 1184
+ gravity 2.3
+ airfriction 0.5
+ velocityjitter 1800 1800 1800
+ velocityoffset 0 0 970
+ sizeincrease -5
+ rotate -180 180 -1000 1000
+ // underwater bubbles
+ effect explosion_big
+ underwater
+ count 32
+ type bubble
+ tex 62 62
+ color 0x404040 0x808080
+ size 3 3
+ alpha 128 256 64
+ gravity -0.125
+ bounce 1.5
+ liquidfriction 0.25
+ originjitter 160 160 160
+ velocityjitter 444 444 444
+ // underwatershockwave
+ effect explosion_big
+ underwater
+ type smoke
+ countabsolute 1
+ tex 33 33
+ size 30 30
+ sizeincrease 2900
+ alpha 40 40 300
+ velocitymultiplier 0.3
+ // generic explosion size:medium (it leaves rising smoke for a longer time)
+ // shockwave
+ effect explosion_medium
+ countabsolute 1
+ type static
+ tex 33 33 
+ size 72 72
+ alpha 56 56 330
+ color 0x8f0d00 0xff5a00
+ sizeincrease 2400
+ // fire effect
+ effect explosion_medium
+ notunderwater
+ count 32
+ type static
+ tex 48 55
+ color 0x8f0d00 0xff5a00
+ size 133 144
+ sizeincrease 45
+ alpha 200 256 712
+ airfriction 8
+ liquidfriction 8
+ originjitter 30 30 30
+ velocityjitter 1512 1512 1512
+ rotate -180 180 -500 500
+ // fire effect 2
+ effect explosion_medium
+ notunderwater
+ count 32
+ type static
+ tex 48 55
+ color 0x8f0d00 0xff5a00
+ size 73 94
+ sizeincrease 40
+ gravity -2
+ alpha 200 256 612
+ airfriction 8
+ liquidfriction 8
+ originjitter 30 30 30
+ velocityjitter 1512 1512 1512
+ rotate -180 180 -150 150
+ // fire rays
+ effect explosion_medium
+ notunderwater
+ count 14
+ type spark
+ tex 48 55
+ color 0x8f0d00 0xff5a00
+ size 43 74
+ sizeincrease 40
+ alpha 200 256 800
+ airfriction -3
+ liquidfriction 8
+ originjitter 40 40 40
+ velocityjitter 512 512 512
+ stretchfactor 8
+ // smoke 
+ effect explosion_medium
+ type alphastatic
+ notunderwater
+ tex 0 8
+ count 5
+ size 250 300
+ sizeincrease -30
+ alpha 300 650 756
+ originjitter 100 100 100
+ velocityjitter 200 200 200
+ airfriction 3
+ color 0x4F4B46 0x000000
+ rotate -180 180 -20 20
+ // smoke 2
+ effect explosion_medium
+ type alphastatic
+ notunderwater
+ tex 0 8
+ count 10
+ size 50 100
+ sizeincrease 50
+ gravity -0.3
+ alpha 300 650 256
+ originjitter 100 100 100
+ velocityjitter 500 500 500
+ velocityoffset 0 0 200
+ airfriction 3
+ color 0x4F4B46 0x000000
+ rotate -180 180 -20 20
+ // smoke rays
+ effect explosion_medium
+ type spark
+ notunderwater
+ tex 0 8
+ count 13
+ size 150 200
+ sizeincrease 100
+ alpha 140 255 350
+ velocityjitter 250 250 250
+ originjitter 40 40 40
+ color 0x4F4B46 0x000000
+ stretchfactor 50
+ // bouncing sparks
+ effect explosion_medium
+ notunderwater
+ count 14
+ type spark
+ tex 40 40
+ color 0xffa35b 0xfff2be
+ size 2 3
+ alpha 644 956 984
+ gravity 1
+ airfriction 1
+ liquidfriction 0.8
+ velocityoffset 0 0 370
+ originjitter 100 100 100
+ velocityjitter 624 624 624
+ stretchfactor 0.7
+ // underwater bubbles
+ effect explosion_medium
+ underwater
+ count 32
+ type bubble
+ tex 62 62
+ color 0x404040 0x808080
+ size 3 3
+ alpha 128 256 64
+ gravity -0.125
+ bounce 1.5
+ liquidfriction 0.25
+ originjitter 160 160 160
+ velocityjitter 444 444 444
+ // underwatershockwave
+ effect explosion_medium
+ underwater
+ type smoke
+ countabsolute 1
+ tex 33 33
+ size 30 30
+ sizeincrease 2900
+ alpha 40 40 300
+ velocitymultiplier 0.3
+ // generic explosion size:small (its fire only, made to support other explosions)
+ // shockwave
+ effect explosion_small
+ countabsolute 1
+ type static
+ tex 33 33 
+ size 22 22
+ alpha 56 56 330
+ color 0x8f0d00 0xff5a00
+ sizeincrease 2400
+ // fire effect
+ effect explosion_small
+ notunderwater
+ count 16
+ type static
+ tex 48 55
+ color 0x8f0d00 0xff5a00
+ size 1 44
+ sizeincrease 45
+ alpha 200 256 1212
+ airfriction 5
+ liquidfriction 8
+ velocityjitter 512 512 512
+ rotate -180 180 -500 500
+ // fire effect 2
+ effect explosion_small
+ notunderwater
+ count 16
+ type static
+ tex 48 55
+ color 0x8f0d00 0xff5a00
+ size 73 94
+ sizeincrease 40
+ alpha 200 256 812
+ airfriction 8
+ liquidfriction 8
+ velocityjitter 912 912 912
+ rotate -180 180 -150 150
+ // fire rays
+ effect explosion_small
+ notunderwater
+ count 14
+ type spark
+ tex 48 55
+ color 0x8f0d00 0xff5a00
+ size 13 54
+ sizeincrease 30
+ alpha 200 256 1300
+ airfriction -3
+ liquidfriction 8
+ originjitter 40 40 40
+ velocityjitter 512 512 512
+ stretchfactor 8
+ // underwater bubbles
+ effect explosion_small
+ underwater
+ count 32
+ type bubble
+ tex 62 62
+ color 0x404040 0x808080
+ size 1 3
+ alpha 128 256 64
+ gravity -0.125
+ bounce 1.5
+ liquidfriction 0.25
+ originjitter 160 160 160
+ velocityjitter 144 144 144
+ // underwatershockwave
+ effect explosion_small
+ underwater
+ type smoke
+ countabsolute 1
+ tex 33 33
+ size 30 30
+ sizeincrease 1200
+ alpha 40 40 300
+ // big smoke ( for spamming on damaged stuff )
+ effect smoke_big
+ type alphastatic
+ notunderwater
+ tex 0 8
+ count 3
+ size 30 60
+ sizeincrease 15
+ gravity -0.5
+ alpha 200 750 200
+ originjitter 55 55 55
+ velocityjitter 140 140 200
+ velocityoffset 0 0 200
+ airfriction 4
+ color 0x4F4B46 0x000000
+ rotate -180 180 -20 20
+ // small smoke ( more precise than big one, for spamming on damaged parts like raptors spinner )
+ effect smoke_small
+ type alphastatic
+ notunderwater
+ tex 0 8
+ count 3
+ size 60 100
+ sizeincrease -10
+ gravity -0.5
+ alpha 200 750 200
+ velocityjitter 40 40 400
+ velocityoffset 0 0 200
+ airfriction 4
+ color 0x4F4B46 0x000000
+ rotate -180 180 -20 20
++
 +// tuba does not use the weapon damage effect
 +
 +// laser damage effect
 +// used in qcsrc/client/gibs.qc:                      pointparticles(particleeffectnum(effectnum), org, '0 0 0', 1);
 +effect weapondamage_laser
 +count 3
 +type smoke
 +tex 0 8
 +color 0x880000 0xff4400
 +size 8 16
 +sizeincrease 10
 +alpha 128 16 128
 +gravity 0
 +originjitter 4 4 16
 +velocityjitter 0.4 0.4 0.6
 +velocitymultiplier 0
 +airfriction -0.35
 +rotate 0 180 -30 30
 +
 +// shotgun damage effect, normal blood
 +// used in qcsrc/client/gibs.qc:                      pointparticles(particleeffectnum(effectnum), org, '0 0 0', 1);
 +effect weapondamage_shotgun
 +count 0.5
 +type blood
 +tex 24 32
 +size 4 9
 +alpha 256 256 64
 +color 0xA8FFFF 0xA8FFFFF
 +bounce -1
 +airfriction 1
 +liquidfriction 4
 +velocityjitter 64 64 64
 +velocitymultiplier 5
 +staincolor 0x808080 0x808080
 +staintex 16 24
 +//blood mist
 +effect weapondamage_shotgun
 +countabsolute 1
 +type alphastatic
 +tex 0 8
 +size 8 16
 +alpha 100 256 400
 +color 0x000000 0x420000
 +originjitter 11 11 11
 +
 +// shotgun damage effect, alien blood
 +// used in qcsrc/client/gibs.qc:                      pointparticles(particleeffectnum(effectnum), org, '0 0 0', 1);
 +effect weapondamage_shotgun_alien
 +count 0.5
 +type blood
 +tex 24 32
 +size 4 9
 +alpha 256 256 64
 +color 0xDC9BCD 0xDC9BCD
 +bounce -1
 +airfriction 1
 +liquidfriction 4
 +velocityjitter 64 64 64
 +velocitymultiplier 5
 +staincolor 0x808080 0x808080
 +staintex 16 24
 +//blood mist
 +effect weapondamage_shotgun_alien
 +countabsolute 1
 +type alphastatic
 +tex 0 8
 +size 8 16
 +alpha 100 256 400
 +color 0x000000 0x204010
 +originjitter 11 11 11
 +
 +// shotgun damage effect, robot blood
 +// used in qcsrc/client/gibs.qc:                      pointparticles(particleeffectnum(effectnum), org, '0 0 0', 1);
 +effect weapondamage_shotgun_robot
 +count 0.5
 +type blood
 +tex 24 32
 +size 4 9
 +alpha 256 256 64
 +color 0xC0D890 0xC0D890
 +bounce -1
 +airfriction 1
 +liquidfriction 4
 +velocityjitter 64 64 64
 +velocitymultiplier 5
 +staincolor 0x808080 0x808080
 +staintex 16 24
 +//blood mist
 +effect weapondamage_shotgun_robot
 +countabsolute 1
 +type alphastatic
 +tex 0 8
 +size 8 16
 +alpha 100 256 400
 +color 0x000000 0x301860
 +originjitter 11 11 11
 +
 +// uzi damage effect, normal blood
 +// used in qcsrc/client/gibs.qc:                      pointparticles(particleeffectnum(effectnum), org, '0 0 0', 1);
 +effect weapondamage_uzi
 +count 0.25
 +type blood
 +tex 24 32
 +size 3 8
 +alpha 256 256 64
 +color 0xA8FFFF 0xA8FFFFF
 +bounce -1
 +airfriction 1
 +liquidfriction 4
 +velocityjitter 64 64 64
 +velocitymultiplier 5
 +staincolor 0x808080 0x808080
 +staintex 16 24
 +//blood mist
 +effect weapondamage_uzi
 +countabsolute 1
 +type alphastatic
 +tex 0 8
 +size 6 12
 +alpha 100 256 400
 +color 0x000000 0x420000
 +originjitter 11 11 11
 +
 +// uzi damage effect, alien blood
 +// used in qcsrc/client/gibs.qc:                      pointparticles(particleeffectnum(effectnum), org, '0 0 0', 1);
 +effect weapondamage_uzi_alien
 +count 0.25
 +type blood
 +tex 24 32
 +size 3 8
 +alpha 256 256 64
 +color 0xDC9BCD 0xDC9BCD
 +bounce -1
 +airfriction 1
 +liquidfriction 4
 +velocityjitter 64 64 64
 +velocitymultiplier 5
 +staincolor 0x808080 0x808080
 +staintex 16 24
 +//blood mist
 +effect weapondamage_uzi_alien
 +countabsolute 1
 +type alphastatic
 +tex 0 8
 +size 6 12
 +alpha 100 256 400
 +color 0x000000 0x204010
 +originjitter 11 11 11
 +
 +// uzi damage effect, robot blood
 +// used in qcsrc/client/gibs.qc:                      pointparticles(particleeffectnum(effectnum), org, '0 0 0', 1);
 +effect weapondamage_uzi_robot
 +count 0.25
 +type blood
 +tex 24 32
 +size 3 8
 +alpha 256 256 64
 +color 0xC0D890 0xC0D890
 +bounce -1
 +airfriction 1
 +liquidfriction 4
 +velocityjitter 64 64 64
 +velocitymultiplier 5
 +staincolor 0x808080 0x808080
 +staintex 16 24
 +//blood mist
 +effect weapondamage_uzi_robot
 +countabsolute 1
 +type alphastatic
 +tex 0 8
 +size 6 12
 +alpha 100 256 400
 +color 0x000000 0x301860
 +originjitter 11 11 11
 +
 +// minelayer damage effect
 +// used in qcsrc/client/gibs.qc:                      pointparticles(particleeffectnum(effectnum), org, '0 0 0', 1);
 +effect weapondamage_minelayer
 +//notunderwater
 +count 2
 +type smoke
 +tex 48 55
 +size 6 12
 +alpha 256 16 256
 +gravity -0.5
 +color 0x8f0d00 0xff5a00
 +sizeincrease -10
 +originoffset 0 0 10
 +originjitter 6 6 8
 +velocityjitter 22 22 50
 +// smoke
 +effect weapondamage_minelayer
 +type alphastatic
 +count 2
 +tex 0 8
 +size 4 8
 +sizeincrease 5
 +alpha 128 32 128
 +color 0x000000 0x111111
 +gravity -0.3
 +originoffset 0 0 10
 +originjitter 6 6 8
 +velocityjitter 11 11 50
 +// light
 +effect weapondamage_minelayer
 +trailspacing 8
 +lightradius 60
 +lightradiusfade 280
 +lightcolor 0.9 0.6 0.2
 +
 +// grenadelauncher damage effect
 +// used in qcsrc/client/gibs.qc:                      pointparticles(particleeffectnum(effectnum), org, '0 0 0', 1);
 +effect weapondamage_grenadelauncher
 +//notunderwater
 +count 2
 +type smoke
 +tex 48 55
 +size 6 12
 +alpha 256 16 256
 +gravity -0.5
 +color 0x8f0d00 0xff5a00
 +sizeincrease -10
 +originoffset 0 0 10
 +originjitter 6 6 8
 +velocityjitter 22 22 50
 +// smoke
 +effect weapondamage_grenadelauncher
 +type alphastatic
 +count 2
 +tex 0 8
 +size 4 8
 +sizeincrease 5
 +alpha 128 32 128
 +color 0x000000 0x111111
 +gravity -0.3
 +originoffset 0 0 10
 +originjitter 6 6 8
 +velocityjitter 11 11 50
 +// light
 +effect weapondamage_grenadelauncher
 +trailspacing 8
 +lightradius 60
 +lightradiusfade 280
 +lightcolor 0.9 0.6 0.2
 +
 +// electro damage effect
 +// used in qcsrc/client/gibs.qc:                      pointparticles(particleeffectnum(effectnum), org, '0 0 0', 1);
 +effect weapondamage_electro
 +count 2
 +type static
 +tex 47 47
 +color 0x66ffff 0x2288ff
 +size 10 20
 +sizeincrease -16
 +alpha 48 8 48
 +gravity -0.0001
 +airfriction 0.2
 +liquidfriction 0.8
 +originjitter 16 16 32
 +velocityjitter 8 8 16
 +velocitymultiplier 0
 +airfriction -0.5
 +rotate 180 360 -30 30
 +// plasma smoke
 +effect weapondamage_electro
 +count 4
 +type smoke
 +tex 0 8
 +color 0x2244ff 0x002266
 +size 8 16
 +sizeincrease 10
 +alpha 64 16 64
 +gravity 0
 +originjitter 4 4 16
 +velocityjitter 0.4 0.4 0.6
 +velocitymultiplier 0
 +airfriction -0.35
 +rotate 0 180 -30 30
 +// light
 +effect weapondamage_electro
 +trailspacing 8
 +lightradius 50
 +lightradiusfade 220
 +lightcolor 0.2 0.8 1.0
 +
 +// crylink damage effect
 +// used in qcsrc/client/gibs.qc:                      pointparticles(particleeffectnum(effectnum), org, '0 0 0', 1);
 +effect weapondamage_crylink
 +count 2
 +type static
 +tex 38 38
 +color 0xff44ff 0x9966ff
 +size 8 16
 +sizeincrease -8
 +alpha 48 16 48
 +gravity -0.0001
 +airfriction 0.6
 +liquidfriction 0.8
 +originjitter 8 8 16
 +velocityjitter 10 10 20
 +velocitymultiplier 0
 +airfriction -0.5
 +rotate 180 360 -30 30
 +// plasma smoke
 +effect weapondamage_crylink
 +count 4
 +type smoke
 +tex 0 8
 +color 0x8844ff 0x662244
 +size 10 20
 +sizeincrease 6
 +alpha 64 16 64
 +gravity 0.001
 +originjitter 6 6 12
 +velocityjitter 0.4 0.4 0.6
 +velocitymultiplier 0
 +airfriction -0.35
 +rotate 0 180 -30 30
 +// light
 +effect weapondamage_crylink
 +trailspacing 8
 +lightradius 50
 +lightradiusfade 240
 +lightcolor 0.8 0.2 1.0
 +
 +// hlac damage effect
 +// used in qcsrc/client/gibs.qc:                      pointparticles(particleeffectnum(effectnum), org, '0 0 0', 1);
 +effect weapondamage_hlac
 +count 3
 +type smoke
 +tex 0 8
 +color 0x880000 0xff4400
 +size 8 16
 +sizeincrease 10
 +alpha 128 16 128
 +gravity 0
 +originjitter 4 4 16
 +velocityjitter 0.4 0.4 0.6
 +velocitymultiplier 0
 +airfriction -0.35
 +rotate 0 180 -30 30
 +
 +// nex damage effect
 +// used in qcsrc/client/gibs.qc:                      pointparticles(particleeffectnum(effectnum), org, '0 0 0', 1);
 +effect weapondamage_nex
 +count 1
 +type static
 +tex 47 47
 +color 0xffffff 0x88ffff
 +size 7 14
 +sizeincrease -14
 +alpha 64 8 64
 +gravity -0.0001
 +airfriction 0.1
 +liquidfriction 0.6
 +originjitter 4 4 8
 +velocityjitter 8 8 16
 +velocitymultiplier 0
 +airfriction -0.5
 +rotate 180 360 -30 30
 +// plasma smoke
 +effect weapondamage_nex
 +count 2
 +type smoke
 +tex 0 8
 +color 0x6688ff 0x226688
 +size 5 10
 +sizeincrease 8
 +alpha 64 16 64
 +gravity 0
 +originjitter 6 6 12
 +velocityjitter 0.5 0.5 0.8
 +velocitymultiplier 0
 +airfriction -0.35
 +rotate 0 180 -30 30
 +// light
 +effect weapondamage_nex
 +trailspacing 8
 +lightradius 60
 +lightradiusfade 280
 +lightcolor 0.8 1.0 1.0
 +
 +// minstanex damage effect
 +// used in qcsrc/client/gibs.qc:                      pointparticles(particleeffectnum(effectnum), org, '0 0 0', 1);
 +effect weapondamage_minstanex
 +count 2
 +type static
 +tex 47 47
 +color 0xffffff 0x88ffff
 +size 10 20
 +sizeincrease -14
 +alpha 64 8 64
 +gravity -0.0001
 +airfriction 0.1
 +liquidfriction 0.6
 +originjitter 4 4 8
 +velocityjitter 8 8 16
 +velocitymultiplier 0
 +airfriction -0.5
 +rotate 180 360 -30 30
 +// plasma smoke
 +effect weapondamage_minstanex
 +count 4
 +type smoke
 +tex 0 8
 +color 0x6688ff 0x226688
 +size 8 16
 +sizeincrease 8
 +alpha 64 16 64
 +gravity 0
 +originjitter 6 6 12
 +velocityjitter 0.5 0.5 0.8
 +velocitymultiplier 0
 +airfriction -0.35
 +rotate 0 180 -30 30
 +// light
 +effect weapondamage_minstanex
 +trailspacing 8
 +lightradius 60
 +lightradiusfade 240
 +lightcolor 0.8 1.0 1.0
 +
 +// sniperrifle damage effect, normal blood
 +// used in qcsrc/client/gibs.qc:                      pointparticles(particleeffectnum(effectnum), org, '0 0 0', 1);
 +effect weapondamage_sniperrifle
 +count 0.25
 +type blood
 +tex 24 32
 +size 3 8
 +alpha 256 256 64
 +color 0xA8FFFF 0xA8FFFFF
 +bounce -1
 +airfriction 1
 +liquidfriction 4
 +velocityjitter 64 64 64
 +velocitymultiplier 5
 +staincolor 0x808080 0x808080
 +staintex 16 24
 +//blood mist
 +effect weapondamage_sniperrifle
 +countabsolute 1
 +type alphastatic
 +tex 0 8
 +size 6 12
 +alpha 100 256 400
 +color 0x000000 0x420000
 +originjitter 11 11 11
 +
 +// sniperrifle damage effect, alien blood
 +// used in qcsrc/client/gibs.qc:                      pointparticles(particleeffectnum(effectnum), org, '0 0 0', 1);
 +effect weapondamage_sniperrifle_alien
 +count 0.25
 +type blood
 +tex 24 32
 +size 3 8
 +alpha 256 256 64
 +color 0xDC9BCD 0xDC9BCD
 +bounce -1
 +airfriction 1
 +liquidfriction 4
 +velocityjitter 64 64 64
 +velocitymultiplier 5
 +staincolor 0x808080 0x808080
 +staintex 16 24
 +//blood mist
 +effect weapondamage_sniperrifle_alien
 +countabsolute 1
 +type alphastatic
 +tex 0 8
 +size 6 12
 +alpha 100 256 400
 +color 0x000000 0x204010
 +originjitter 11 11 11
 +
 +// sniperrifle damage effect, robot blood
 +// used in qcsrc/client/gibs.qc:                      pointparticles(particleeffectnum(effectnum), org, '0 0 0', 1);
 +effect weapondamage_sniperrifle_robot
 +count 0.25
 +type blood
 +tex 24 32
 +size 3 8
 +alpha 256 256 64
 +color 0xC0D890 0xC0D890
 +bounce -1
 +airfriction 1
 +liquidfriction 4
 +velocityjitter 64 64 64
 +velocitymultiplier 5
 +staincolor 0x808080 0x808080
 +staintex 16 24
 +//blood mist
 +effect weapondamage_sniperrifle_robot
 +countabsolute 1
 +type alphastatic
 +tex 0 8
 +size 6 12
 +alpha 100 256 400
 +color 0x000000 0x301860
 +originjitter 11 11 11
 +
 +// seeker damage effect
 +// used in qcsrc/client/gibs.qc:                      pointparticles(particleeffectnum(effectnum), org, '0 0 0', 1);
 +effect weapondamage_seeker
 +//notunderwater
 +count 2
 +type smoke
 +tex 48 55
 +size 5 10
 +alpha 256 16 256
 +gravity -0.5
 +color 0x8f0d00 0xff5a00
 +sizeincrease -10
 +originoffset 0 0 10
 +originjitter 5 5 7
 +velocityjitter 22 22 50
 +// smoke
 +effect weapondamage_seeker
 +type alphastatic
 +count 2
 +tex 0 8
 +size 3 6
 +sizeincrease 5
 +alpha 128 32 128
 +color 0x000000 0x111111
 +gravity -0.3
 +originoffset 0 0 10
 +originjitter 5 5 7
 +velocityjitter 11 11 50
 +// light
 +effect weapondamage_seeker
 +trailspacing 8
 +lightradius 65
 +lightradiusfade 280
 +lightcolor 0.9 0.7 0.2
 +
 +// hagar damage effect
 +// used in qcsrc/client/gibs.qc:                      pointparticles(particleeffectnum(effectnum), org, '0 0 0', 1);
 +effect weapondamage_hagar
 +//notunderwater
 +count 2
 +type smoke
 +tex 48 55
 +size 5 10
 +alpha 256 16 256
 +gravity -0.5
 +color 0x8f0d00 0xff5a00
 +sizeincrease -10
 +originoffset 0 0 10
 +originjitter 5 5 7
 +velocityjitter 22 22 50
 +// smoke
 +effect weapondamage_hagar
 +type alphastatic
 +count 2
 +tex 0 8
 +size 3 6
 +sizeincrease 5
 +alpha 128 32 128
 +color 0x000000 0x111111
 +gravity -0.3
 +originoffset 0 0 10
 +originjitter 5 5 7
 +velocityjitter 11 11 50
 +// light
 +effect weapondamage_hagar
 +trailspacing 8
 +lightradius 65
 +lightradiusfade 280
 +lightcolor 0.9 0.7 0.2
 +
 +// fireball damage effect
 +// used in qcsrc/client/gibs.qc:                      pointparticles(particleeffectnum(effectnum), org, '0 0 0', 1);
 +effect weapondamage_fireball
 +//notunderwater
 +count 4
 +type smoke
 +tex 48 55
 +size 10 20
 +alpha 192 16 192
 +gravity -0.5
 +color 0x8f0d00 0xff5a00
 +sizeincrease -10
 +originoffset 0 0 10
 +originjitter 8 8 24
 +velocityjitter 22 22 50
 +// smoke
 +effect weapondamage_fireball
 +type alphastatic
 +count 4
 +tex 0 8
 +size 8 16
 +sizeincrease 5
 +alpha 128 32 128
 +color 0x000000 0x111111
 +gravity -0.3
 +originoffset 0 0 10
 +originjitter 8 8 24
 +velocityjitter 11 11 50
 +// light
 +effect weapondamage_fireball
 +trailspacing 8
 +lightradius 65
 +lightradiusfade 280
 +lightcolor 0.9 0.6 0.2
 +
 +// rocketlauncher damage effect
 +// used in qcsrc/client/gibs.qc:                      pointparticles(particleeffectnum(effectnum), org, '0 0 0', 1);
 +effect weapondamage_rocketlauncher
 +//notunderwater
 +count 3
 +type smoke
 +tex 48 55
 +size 7 14
 +alpha 256 16 256
 +gravity -0.5
 +color 0x8f0d00 0xff5a00
 +sizeincrease -10
 +originoffset 0 0 10
 +originjitter 6 6 8
 +velocityjitter 22 22 50
 +// smoke
 +effect weapondamage_rocketlauncher
 +type alphastatic
 +count 3
 +tex 0 8
 +size 5 10
 +sizeincrease 5
 +alpha 128 32 128
 +color 0x000000 0x111111
 +gravity -0.3
 +originoffset 0 0 10
 +originjitter 6 6 8
 +velocityjitter 11 11 50
 +// light
 +effect weapondamage_rocketlauncher
 +trailspacing 8
 +lightradius 60
 +lightradiusfade 280
 +lightcolor 0.9 0.6 0.2
 +
 +// porto does not use the weapon damage effect
 +
++// hook does not use the weapon damage effect
diff --combined qcsrc/client/Main.qc
index 211191bc738640f93356ea2a99622c0ab2ef592f,f5dfec4e4a12f09649e3ff800e48c8cd732ff901..0c7643d0efa2019452f9eb1468cd572adf36fc9c
@@@ -47,7 -47,7 +47,7 @@@ void WaypointSprite_Load()
  void CSQC_Init(void)
  {
        prvm_language = cvar_string("prvm_language");
-       
  #ifdef USE_FTE
  #pragma target ID
        __engine_check = checkextension("DP_SV_WRITEPICTURE");
        GibSplash_Precache();
        Casings_Precache();
        DamageInfo_Precache();
+       Vehicles_Precache();
+       turrets_precache();
        if(autocvar_cl_announcer != cl_announcer_prev) {
                Announcer_Precache();
                if(cl_announcer_prev)
@@@ -824,8 -827,6 +827,6 @@@ void Ent_ClientData(
  
        if(newspectatee_status != spectatee_status)
        {
-               float i;
                // clear race stuff
                race_laptime = 0;
                race_checkpointtime = 0;
@@@ -846,7 -847,27 +847,27 @@@ void Ent_Nagger(
  {
        float nags, i, j, b, f;
  
-       nags = ReadByte();
+       nags = ReadByte(); // NAGS NAGS NAGS NAGS NAGS NAGS NADZ NAGS NAGS NAGS
+       if(!(nags & 4))
+       {
+               if(vote_called_vote)
+                       strunzone(vote_called_vote);
+               vote_called_vote = string_null;
+               vote_active = 0;
+       }
+       else
+       {
+               vote_active = 1;
+       }
+       if(nags & 64)
+       {
+               vote_yescount = ReadByte();
+               vote_nocount = ReadByte();
+               vote_needed = ReadByte();
+               vote_highlighted = ReadChar();
+       }
  
        if(nags & 128)
        {
@@@ -895,7 -916,7 +916,7 @@@ void Ent_ReadAccuracy(void
                        weapon_accuracy[w] = -1;
                return;
        }
-       
        for(w = 0, f = 1; w <= WEP_LAST - WEP_FIRST; ++w, f *= 2)
        {
                if(sf & f)
@@@ -977,7 -998,8 +998,9 @@@ void(float bIsNewEntity) CSQC_Ent_Updat
                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_ACCURACY: Ent_ReadAccuracy(); break;
+               case ENT_CLIENT_AUXILIARYXHAIR: Net_AuXair2(bIsNewEntity); break;
+               case ENT_CLIENT_TURRET: ent_turret(); break; 
 +              case ENT_CLIENT_DAMAGEEFFECT: Ent_DamageEffect(); break;
                default:
                        //error(strcat(_("unknown entity type in CSQC_Ent_Update: %d\n"), self.enttype));
                        error(sprintf(_("Unknown entity type in CSQC_Ent_Update (enttype: %d, edict: %d, classname: %s)\n"), self.enttype, num_for_edict(self), self.classname));
@@@ -1096,7 -1118,7 +1119,7 @@@ void Ent_Init(
        g_balance_electro_secondary_bouncestop = ReadCoord();
  
        nex_scope = !ReadByte();
-       sniperrifle_scope = !ReadByte();
+       rifle_scope = !ReadByte();
  
        serverflags = ReadByte();
  
@@@ -1291,22 -1313,6 +1314,6 @@@ void Net_ReadPingPLReport(
        playerslots[e].ping_movementloss = ml / 255.0;
  }
  
- void Net_VoteDialog(float highlight) {
-       if(highlight) {
-               vote_highlighted = ReadByte();
-               return;
-       }
-       vote_yescount = ReadByte();
-       vote_nocount = ReadByte();
-       vote_needed = ReadByte();
-       vote_active = 1;
- }
- void Net_VoteDialogReset() {
-       vote_active = 0;
- }
  void Net_Notify() {
        float type;
        type = ReadByte();
        {
                HUD_Centerprint(ReadString(), ReadString(), ReadShort(), ReadByte());
        }
+       else if(type == CSQC_CENTERPRINT_GENERIC)
+       {
+               float id;
+               string s;
+               id = ReadByte();
+               s = ReadString();
+               if (id != 0 && s != "")
+                       centerprint_generic(id, s, ReadByte(), ReadByte());
+               else
+                       centerprint_generic(id, s, 0, 0);
+       }
  }
  
  void Net_WeaponComplain() {
@@@ -1376,14 -1393,6 +1394,6 @@@ float CSQC_Parse_TempEntity(
                        Net_TeamNagger();
                        bHandled = true;
                        break;
-               case TE_CSQC_VOTE:
-                       Net_VoteDialog(ReadByte());
-                       bHandled = true;
-                       break;
-               case TE_CSQC_VOTERESET:
-                       Net_VoteDialogReset();
-                       bHandled = true;
-                       break;
                case TE_CSQC_LIGHTNINGARC:
                        Net_ReadLightningarc();
                        bHandled = true;
                        Net_WeaponComplain();
                        bHandled = true;
                        break;
+         case TE_CSQC_VEHICLESETUP:
+             Net_VehicleSetup();
+             bHandled = true;
+             break;
                default:
                        // No special logic for this temporary entity; return 0 so the engine can handle it
                        bHandled = false;
index 262abbe44e7124bdb6eccb46a9d9db18a859e1fb,2f2b80cc5971eb4ab07dc93f33e2edbf8515fdb7..10fee189451b52495bf98672d0e0756d4f774e6f
@@@ -122,6 -122,7 +122,7 @@@ float autocvar_g_balance_tuba_attenuati
  float autocvar_g_balance_tuba_fadetime;
  float autocvar_g_balance_tuba_volume;
  float autocvar_g_warmup_limit;
+ var float autocvar_g_waypointsprite_uppercase = 1;
  var float autocvar_g_waypointsprite_alpha = 1;
  var float autocvar_g_waypointsprite_crosshairfadealpha = 1;
  float autocvar_g_waypointsprite_crosshairfadedistance;
@@@ -133,10 -134,16 +134,16 @@@ var float autocvar_g_waypointsprite_dis
  var float autocvar_g_waypointsprite_edgefadealpha = 1;
  float autocvar_g_waypointsprite_edgefadedistance;
  var float autocvar_g_waypointsprite_edgefadescale = 1;
+ var float autocvar_g_waypointsprite_edgeoffset_bottom = 0;
+ var float autocvar_g_waypointsprite_edgeoffset_left = 0;
+ var float autocvar_g_waypointsprite_edgeoffset_right = 0;
+ var float autocvar_g_waypointsprite_edgeoffset_top = 0;
+ var float autocvar_g_waypointsprite_fontsize = 12;
  float autocvar_g_waypointsprite_minalpha;
  float autocvar_g_waypointsprite_minscale;
  float autocvar_g_waypointsprite_normdistance;
  var float autocvar_g_waypointsprite_scale = 1;
+ float autocvar_g_waypointsprite_spam;
  float autocvar_g_waypointsprite_timealphaexponent;
  var float autocvar_hud_colorflash_alpha = 0.5;
  float autocvar_hud_configure_bg_minalpha;
@@@ -147,6 -154,8 +154,8 @@@ float autocvar_hud_configure_grid_xsize
  float autocvar_hud_configure_grid_ysize;
  float autocvar_hud_configure_teamcolorforced;
  float autocvar_hud_contents;
+ float autocvar_hud_contents_blur;
+ float autocvar_hud_contents_blur_alpha;
  float autocvar_hud_contents_factor;
  float autocvar_hud_contents_fadeintime;
  float autocvar_hud_contents_fadeouttime;
@@@ -157,6 -166,8 +166,8 @@@ string autocvar_hud_contents_slime_colo
  float autocvar_hud_contents_water_alpha;
  string autocvar_hud_contents_water_color;
  float autocvar_hud_damage;
+ float autocvar_hud_damage_blur;
+ float autocvar_hud_damage_blur_alpha;
  string autocvar_hud_damage_color;
  float autocvar_hud_damage_factor;
  float autocvar_hud_damage_fade_rate;
@@@ -168,6 -179,10 +179,10 @@@ float autocvar_hud_damage_pain_threshol
  float autocvar_hud_damage_pain_threshold_lower_health;
  float autocvar_hud_damage_pain_threshold_pulsating_min;
  float autocvar_hud_damage_pain_threshold_pulsating_period;
+ float autocvar_hud_powerup;
+ float autocvar_hud_postprocessing;
+ float autocvar_hud_postprocessing_maxbluralpha;
+ float autocvar_hud_postprocessing_maxblurradius;
  string autocvar_hud_dock;
  float autocvar_hud_dock_alpha;
  string autocvar_hud_dock_color;
@@@ -205,6 -220,21 +220,21 @@@ float autocvar_hud_panel_healtharmor_pr
  float autocvar_hud_panel_healtharmor_progressbar_gfx_lowhealth;
  float autocvar_hud_panel_healtharmor_progressbar_gfx_smooth;
  
+ // TEMPORARY hard coded default for compatibility - remove after 0.2 release
+ var float autocvar_hud_panel_centerprint = 1;
+ noref var string autocvar_hud_panel_centerprint_pos = "0.180000 0.260000";
+ noref var string autocvar_hud_panel_centerprint_size = "0.650000 0.210000";
+ noref var string autocvar_hud_panel_centerprint_bg = "";
+ noref var string autocvar_hud_panel_centerprint_bg_color = "";
+ noref var string autocvar_hud_panel_centerprint_bg_color_team = "";
+ noref var string autocvar_hud_panel_centerprint_bg_alpha = "";
+ noref var string autocvar_hud_panel_centerprint_bg_border = "";
+ noref var string autocvar_hud_panel_centerprint_bg_padding = "";
+ var float autocvar_hud_panel_centerprint_align = 0.5;
+ var float autocvar_hud_panel_centerprint_fadetime = 0.25;
+ var float autocvar_hud_panel_centerprint_flip = 1;
+ var float autocvar_hud_panel_centerprint_fontscale = 1;
+ var float autocvar_hud_panel_centerprint_time = 3;
  float autocvar_hud_panel_healtharmor_text;
  float autocvar_hud_panel_infomessages;
  float autocvar_hud_panel_infomessages_flip;
@@@ -319,9 -349,6 +349,6 @@@ var float autocvar_scoreboard_highlight
  var float autocvar_scoreboard_highlight_alpha_self = 0.25;
  float autocvar_scoreboard_offset_left;
  float autocvar_scoreboard_offset_right;
- float autocvar_scr_centerpos;
- float autocvar_scr_centersize;
- float autocvar_scr_centertime;
  float autocvar_v_flipped;
  float autocvar_vid_conheight;
  float autocvar_vid_conwidth;
@@@ -331,8 -358,7 +358,9 @@@ float autocvar_crosshair_color_by_healt
  float autocvar_cl_hitsound;
  float autocvar_cl_hitsound_antispam_time;
  var float autocvar_cl_eventchase_death = 1;
- var float autocvar_cl_eventchase_intermission = 1;
  var float autocvar_cl_eventchase_distance = 140;
  var float autocvar_cl_eventchase_speed = 1.3;
+ float autocvar_cl_lerpexcess;
+ string autocvar__togglezoom;
 +float autocvar_cl_damageeffect;
 +float autocvar_cl_damageeffect_gibs;
diff --combined qcsrc/client/gibs.qc
index 30cb786c9666b1b3af952471a7d83da00d77dc6b,409f8094264abd9c943250431f109ad246a857d5..78aee37752dc2b7fc8efbe9f6e4dcb4018abcf88
@@@ -73,7 -73,7 +73,7 @@@ void Gib_Touch(
        }
  
        if(!self.silent)
-               sound(self, CHAN_PAIN, strcat("misc/gib_splat0", ftos(floor(prandom() * 4 + 1)), ".wav"), VOL_BASE, ATTN_NORM);
+               sound(self, CH_PAIN, strcat("misc/gib_splat0", ftos(floor(prandom() * 4 + 1)), ".wav"), VOL_BASE, ATTN_NORM);
        pointparticles(particleeffectnum(strcat(species_prefix(self.cnt), "blood")), self.origin + '0 0 1', '0 0 30', 10);
  
        Gib_Delete();
@@@ -103,19 -103,17 +103,19 @@@ void Gib_Draw(
        }
  }
  
- void TossGib (string mdlname, vector org, vector vconst, vector vrand, float specnum, float destroyontouch, float issilent, float gibownernum)
 -void TossGib (string mdlname, vector safeorg, vector org, vector vconst, vector vrand, float specnum, float destroyontouch, float issilent)
++void TossGib (string mdlname, vector safeorg, vector org, vector vconst, vector vrand, float specnum, float destroyontouch, float issilent, float gibownernum)
  {
        entity gib;
  
        // TODO remove some gibs according to cl_nogibs
        gib = RubbleNew("gib");
 +      gib.classname = "gib";
        gib.move_movetype = MOVETYPE_BOUNCE;
        gib.gravity = 1;
        gib.solid = SOLID_CORPSE;
        gib.cnt = specnum;
        gib.silent = issilent;
 +      gib.team = gibownernum;
        Gib_setmodel(gib, mdlname, specnum);
  
        setsize (gib, '-8 -8 -8', '8 8 8');
        else
                gib.move_touch = SUB_RemoveOnNoImpact;
  
+       // don't spawn gibs inside solid - just don't
+       if(org != safeorg)
+       {
+               tracebox(safeorg, gib.mins, gib.maxs, org, MOVE_NOMONSTERS, gib);
+               org = trace_endpos;
+       }
        gib.move_origin = gib.origin = org;
        gib.move_velocity = vconst * autocvar_cl_gibs_velocity_scale + vrand * autocvar_cl_gibs_velocity_random + '0 0 1' * autocvar_cl_gibs_velocity_up;
        gib.move_avelocity = prandomvec() * vlen(gib.move_velocity);
  
  void Ent_GibSplash(float isNew)
  {
 -      float amount, type, specnum;
 +      float amount, type, specnum, entnumber;
        vector org, vel;
        string specstr;
        float issilent;
  
        type = ReadByte(); // gibbage type
        amount = ReadByte() / 16.0; // gibbage amount
 +      entnumber = ReadByte(); // player num
        org_x = ReadShort() * 4 + 2;
        org_y = ReadShort() * 4 + 2;
        org_z = ReadShort() * 4 + 2;
        {
                case 0x01:
                        if(!issilent)
-                               sound (self, CHAN_PAIN, "misc/gib.wav", VOL_BASE, ATTN_NORM);
+                               sound (self, CH_PAIN, "misc/gib.wav", VOL_BASE, ATTN_NORM);
  
                        if(prandom() < amount)
-                               TossGib ("models/gibs/eye.md3", org, vel, prandomvec() * 150, specnum, 0, issilent, entnumber);
 -                              TossGib ("models/gibs/eye.md3", org, org, vel, prandomvec() * 150, specnum, 0, issilent);
++                              TossGib ("models/gibs/eye.md3", org, org, vel, prandomvec() * 150, specnum, 0, issilent, entnumber);
                        new_te_bloodshower(particleeffectnum(strcat(specstr, "bloodshower")), org, 1200, amount);
                        if(prandom() < amount)
-                               TossGib ("models/gibs/bloodyskull.md3", org + 16 * prandomvec(), vel, prandomvec() * 100, specnum, 0, issilent, entnumber);
 -                              TossGib ("models/gibs/bloodyskull.md3", org, org + 16 * prandomvec(), vel, prandomvec() * 100, specnum, 0, issilent);
++                              TossGib ("models/gibs/bloodyskull.md3", org, org + 16 * prandomvec(), vel, prandomvec() * 100, specnum, 0, issilent, entnumber);
  
                        for(c = 0; c < amount; ++c)
                        {
                                randomvalue = amount - c;
  
                                if(prandom() < randomvalue)
-                                       TossGib ("models/gibs/arm.md3", org + 16 * prandomvec() + '0 0 8', vel, prandomvec() * (prandom() * 120 + 90), specnum,0, issilent, entnumber);
 -                                      TossGib ("models/gibs/arm.md3", org, org + 16 * prandomvec() + '0 0 8', vel, prandomvec() * (prandom() * 120 + 90), specnum,0, issilent);
++                                      TossGib ("models/gibs/arm.md3", org, org + 16 * prandomvec() + '0 0 8', vel, prandomvec() * (prandom() * 120 + 90), specnum,0, issilent, entnumber);
                                if(prandom() < randomvalue)
-                                       TossGib ("models/gibs/arm.md3", org + 16 * prandomvec() + '0 0 8', vel, prandomvec() * (prandom() * 120 + 90), specnum,0, issilent, entnumber);
 -                                      TossGib ("models/gibs/arm.md3", org, org + 16 * prandomvec() + '0 0 8', vel, prandomvec() * (prandom() * 120 + 90), specnum,0, issilent);
++                                      TossGib ("models/gibs/arm.md3", org, org + 16 * prandomvec() + '0 0 8', vel, prandomvec() * (prandom() * 120 + 90), specnum,0, issilent, entnumber);
                                if(prandom() < randomvalue)
-                                       TossGib ("models/gibs/chest.md3", org + 16 * prandomvec(), vel, prandomvec() * (prandom() * 120 + 80), specnum,0, issilent, entnumber);
 -                                      TossGib ("models/gibs/chest.md3", org, org + 16 * prandomvec(), vel, prandomvec() * (prandom() * 120 + 80), specnum,0, issilent);
++                                      TossGib ("models/gibs/chest.md3", org, org + 16 * prandomvec(), vel, prandomvec() * (prandom() * 120 + 80), specnum,0, issilent, entnumber);
                                if(prandom() < randomvalue)
-                                       TossGib ("models/gibs/smallchest.md3", org + 16 * prandomvec(), vel, prandomvec() * (prandom() * 120 + 80), specnum,0, issilent, entnumber);
 -                                      TossGib ("models/gibs/smallchest.md3", org, org + 16 * prandomvec(), vel, prandomvec() * (prandom() * 120 + 80), specnum,0, issilent);
++                                      TossGib ("models/gibs/smallchest.md3", org, org + 16 * prandomvec(), vel, prandomvec() * (prandom() * 120 + 80), specnum,0, issilent, entnumber);
                                if(prandom() < randomvalue)
-                                       TossGib ("models/gibs/leg1.md3", org + 16 * prandomvec() + '0 0 -5', vel, prandomvec() * (prandom() * 120 + 85), specnum,0, issilent, entnumber);
 -                                      TossGib ("models/gibs/leg1.md3", org, org + 16 * prandomvec() + '0 0 -5', vel, prandomvec() * (prandom() * 120 + 85), specnum,0, issilent);
++                                      TossGib ("models/gibs/leg1.md3", org, org + 16 * prandomvec() + '0 0 -5', vel, prandomvec() * (prandom() * 120 + 85), specnum,0, issilent, entnumber);
                                if(prandom() < randomvalue)
-                                       TossGib ("models/gibs/leg2.md3", org + 16 * prandomvec() + '0 0 -5', vel, prandomvec() * (prandom() * 120 + 85), specnum,0, issilent, entnumber);
 -                                      TossGib ("models/gibs/leg2.md3", org, org + 16 * prandomvec() + '0 0 -5', vel, prandomvec() * (prandom() * 120 + 85), specnum,0, issilent);
++                                      TossGib ("models/gibs/leg2.md3", org, org + 16 * prandomvec() + '0 0 -5', vel, prandomvec() * (prandom() * 120 + 85), specnum,0, issilent, entnumber);
  
                                // these splat on impact
                                if(prandom() < randomvalue)
-                                       TossGib ("models/gibs/chunk.mdl", org + 16 * prandomvec(), vel, prandomvec() * 450, specnum,1, issilent, entnumber);
 -                                      TossGib ("models/gibs/chunk.mdl", org, org + 16 * prandomvec(), vel, prandomvec() * 450, specnum,1, issilent);
++                                      TossGib ("models/gibs/chunk.mdl", org, org + 16 * prandomvec(), vel, prandomvec() * 450, specnum,1, issilent, entnumber);
                                if(prandom() < randomvalue)
-                                       TossGib ("models/gibs/chunk.mdl", org + 16 * prandomvec(), vel, prandomvec() * 450, specnum,1, issilent, entnumber);
 -                                      TossGib ("models/gibs/chunk.mdl", org, org + 16 * prandomvec(), vel, prandomvec() * 450, specnum,1, issilent);
++                                      TossGib ("models/gibs/chunk.mdl", org, org + 16 * prandomvec(), vel, prandomvec() * 450, specnum,1, issilent, entnumber);
                                if(prandom() < randomvalue)
-                                       TossGib ("models/gibs/chunk.mdl", org + 16 * prandomvec(), vel, prandomvec() * 450, specnum,1, issilent, entnumber);
 -                                      TossGib ("models/gibs/chunk.mdl", org, org + 16 * prandomvec(), vel, prandomvec() * 450, specnum,1, issilent);
++                                      TossGib ("models/gibs/chunk.mdl", org, org + 16 * prandomvec(), vel, prandomvec() * 450, specnum,1, issilent, entnumber);
                                if(prandom() < randomvalue)
-                                       TossGib ("models/gibs/chunk.mdl", org + 16 * prandomvec(), vel, prandomvec() * 450, specnum,1, issilent, entnumber);
 -                                      TossGib ("models/gibs/chunk.mdl", org, org + 16 * prandomvec(), vel, prandomvec() * 450, specnum,1, issilent);
++                                      TossGib ("models/gibs/chunk.mdl", org, org + 16 * prandomvec(), vel, prandomvec() * 450, specnum,1, issilent, entnumber);
                        }
                        break;
                case 0x02:
                        break;
                case 0x03:
                        if(prandom() < amount)
-                               TossGib ("models/gibs/chunk.mdl", org, vel, prandomvec() * (prandom() * 30 + 20), specnum, 1, issilent, entnumber); // TODO maybe adjust to more randomization?
 -                              TossGib ("models/gibs/chunk.mdl", org, org, vel, prandomvec() * (prandom() * 30 + 20), specnum, 1, issilent); // TODO maybe adjust to more randomization?
++                              TossGib ("models/gibs/chunk.mdl", org, org, vel, prandomvec() * (prandom() * 30 + 20), specnum, 1, issilent, entnumber); // TODO maybe adjust to more randomization?
                        break;
                case 0x81:
                        pointparticles(particleeffectnum(strcat(gentle_prefix, "damage_dissolve")), org, vel, amount);
@@@ -277,63 -281,3 +284,63 @@@ void GibSplash_Precache(
      precache_sound ("misc/gib_splat03.wav");
      precache_sound ("misc/gib_splat04.wav");
  }
-       if(type == WEP_SHOTGUN || type == WEP_UZI || type == WEP_SNIPERRIFLE)
 +
 +void Ent_DamageEffect()
 +{
 +      float type, specnum1, specnum2, entnumber, body;
 +      vector org;
 +      string specstr, effectnum;
 +      entity e;
 +
 +      type = ReadByte(); // damage weapon
 +      specnum1 = ReadByte(); // player species
 +      entnumber = ReadByte(); // player entnum
 +      body = ReadByte(); // is dead body / gibbed
 +      org_x = ReadCoord();
 +      org_y = ReadCoord();
 +      org_z = ReadCoord();
 +
 +      if not(autocvar_cl_damageeffect)
 +              return;
 +      if(autocvar_cl_gentle || autocvar_cl_gentle_damage)
 +              return;
 +
 +      e = get_weaponinfo(type);
 +
 +      specnum2 = (specnum1 & 0x78) / 8; // blood type: using four bits (0..7, bit indexes 3,4,5)
 +      specstr = species_prefix(specnum2);
 +
 +      effectnum = strcat("weapondamage_", e.netname);
 +      // If the weapon is a bullet weapon, its damage effect is blood.
 +      // Since blood is species dependent, we make this effect per-species.
++      if(type == WEP_SHOTGUN || type == WEP_UZI || type == WEP_RIFLE)
 +      if(specstr != "")
 +      {
 +              effectnum = strcat(effectnum, "_", specstr);
 +              effectnum = substring(effectnum, 0, strlen(effectnum) - 1); // remove the _ symbol at the end of the species name
 +      }
 +
 +      entity head;
 +
 +      // Scan the owner of all gibs in the world. If a gib owner is the same as the player we're applying the
 +      // effect to, it means our player is gibbed. Therefore, apply the particles to the gibs as well.
 +      if(autocvar_cl_damageeffect_gibs && body > 1)
 +      for(head = world; (head = find(head, classname, "gib")); )
 +      {
 +              if(head.team == entnumber)
 +              if(random() < autocvar_cl_damageeffect_gibs)
 +                      pointparticles(particleeffectnum(effectnum), head.origin, '0 0 0', 1);
 +      }
 +
 +      // if we aren't in third person mode, hide our own damage effect
 +      if(entnumber == player_localentnum && !body)
 +      if(!autocvar_chase_active)
 +              return;
 +      // if this is a gibbed dead body, don't apply the effects to it, only the gibs as done above
 +      if(body > 1)
 +              return;
 +
 +      // Now apply the effect to the actual player.
 +      if(random() < autocvar_cl_damageeffect)
 +              pointparticles(particleeffectnum(effectnum), org, '0 0 0', 1);
 +}
index 6d8591237993c863ad55f2bbf3153f1f5df5a3da,9180b668321a2e202eb80f702ef7059c267966a4..634ab397bdbbd2dc12c4d768832dd7367fa6be7b
@@@ -55,8 -55,6 +55,6 @@@ const float TE_CSQC_NEXGUNBEAMPARTICLE 
  const float TE_CSQC_LIGHTNINGARC = 105;
  const float TE_CSQC_TEAMNAGGER = 106;
  const float TE_CSQC_PINGPLREPORT = 107;
- const float TE_CSQC_VOTE = 108;
- const float TE_CSQC_VOTERESET = 109;
  const float TE_CSQC_ANNOUNCE = 110;
  const float TE_CSQC_TARGET_MUSIC = 111;
  const float TE_CSQC_NOTIFY = 112;
@@@ -64,6 -62,7 +62,7 @@@ const float TE_CSQC_WEAPONCOMPLAIN = 11
  const float TE_CSQC_NEX_SCOPE = 116;
  const float TE_CSQC_MINELAYER_MAXMINES = 117;
  const float TE_CSQC_HAGAR_MAXROCKETS = 118;
+ const float TE_CSQC_VEHICLESETUP = 119;
  
  const float RACE_NET_CHECKPOINT_HIT_QUALIFYING = 0; // byte checkpoint, short time, short recordtime, string recordholder
  const float RACE_NET_CHECKPOINT_CLEAR = 1;
@@@ -82,6 -81,7 +81,7 @@@ const float RANKINGS_CNT = 15
  
  const float CSQC_KILLNOTIFY = 0;
  const float CSQC_CENTERPRINT = 1;
+ const float CSQC_CENTERPRINT_GENERIC = 2;
  
  const float ENT_CLIENT = 0;
  const float ENT_CLIENT_DEAD = 1;
@@@ -116,13 -116,15 +116,16 @@@ const float ENT_CLIENT_GAUNTLET = 29
  const float ENT_CLIENT_ACCURACY = 30;
  const float ENT_CLIENT_SHOWNAMES = 31;
  const float ENT_CLIENT_WARPZONE_TELEPORTED = 32;
 +const float ENT_CLIENT_DAMAGEEFFECT = 33;
  
  const float ENT_CLIENT_TURRET = 40;
+ const float ENT_CLIENT_AUXILIARYXHAIR = 50;
+ const float ENT_CLIENT_VEHICLE = 60;
  
  const float SPRITERULE_DEFAULT = 0;
  const float SPRITERULE_TEAMPLAY = 1;
  
+ const float RADARICON_NONE = 0;
  const float RADARICON_FLAG = 1;
  const float RADARICON_FLAGCARRIER = 1;
  const float RADARICON_HERE = 1; // TODO make these 3 and 4, and make images for them
@@@ -134,6 -136,7 +137,7 @@@ const float RADARICON_GENERATOR = 1
  const float RADARICON_OBJECTIVE = 1;
  const float RADARICON_DOMPOINT = 1;
  const float RADARICON_POWERUP = 1;
+ const float RADARICON_TAGGED = 1;
  
  ///////////////////////////
  // key constants
@@@ -334,9 -337,13 +338,13 @@@ const float CTF_STATE_DEFEND = 2
  const float CTF_STATE_COMMANDER = 3;
  
  const float HUD_NORMAL = 0;
- const float HUD_SPIDERBOT = 10;
- const float HUD_WAKIZASHI = 11;
- const float HUD_RAPTOR    = 12;
+ const float HUD_VEHICLE_FIRST   = 10;
+ const float HUD_SPIDERBOT       = 10;
+ const float HUD_WAKIZASHI       = 11;
+ const float HUD_RAPTOR          = 12;
+ const float HUD_BUMBLEBEE       = 13;
+ const float HUD_VEHICLE_LAST    = 13;
  const vector eX = '1 0 0';
  const vector eY = '0 1 0';
  const vector eZ = '0 0 1';
@@@ -359,6 -366,7 +367,7 @@@ const float STAT_PINKALIVE = 103
  const float STAT_FROZEN = 104;
  const float STAT_REVIVE_PROGRESS = 105;
  
  const float STAT_DOM_TOTAL_PPS = 100;
  const float STAT_DOM_PPS_RED = 101;
  const float STAT_DOM_PPS_BLUE = 102;
@@@ -368,9 -376,6 +377,6 @@@ const float STAT_DOM_PPS_YELLOW = 104
  //const float STAT_SPIDERBOT_AIM     53 // compressShotOrigin
  //const float STAT_SPIDERBOT_TARGET  54 // compressShotOrigin
  
  // moved that here so the client knows the max.
  // # of maps, I'll use arrays for them :P
  #define MAPVOTE_COUNT 10
  #define SP_SCORE 3
  // game mode specific indices are not in common/, but in server/scores_rules.qc!
  
- // this assignment must match menu/xonotic/dialog_settings_misc.c!
- float CHAN_AUTO                               = 0;
-       // on world: announcers, ...                     INFO
-       // on players: item pickup                       ITEMS
-       // on entities: UNUSED
-       // on csqc: announcers                           INFO
- float CHAN_WEAPON                             = 1; // Weapon fire
-       // on world: UNUSED
-       // on players: weapon firing                     WEAPONS
-       // on entities: turret firing                    WEAPONS
-       // on csqc: UNUSED
- float CHAN_VOICE                              = 2; // Voice/Radio
-       // on world: UNUSED
-       // on players: voice                             VOICE
-       // on entities: ambient                          AMBIENT
-       // on csqc: background music                     BGM
- float CHAN_TRIGGER                    = 3; // Triggers/Items
-       // on world: UNUSED
-       // on players: item pickup                       ITEMS
-       // on entities: platforms moving etc.            ITEMS
-       // on csqc: platforms moving etc.                ITEMS
- float CHAN_PROJECTILE                 = 4; // Projectiles
-       // on world: UNUSED
-       // on players: projectiles hitting player        SHOTS
-       // on entities: projectiles                      SHOTS
-       // on csqc: projectile sounds                    SHOTS
- float CHAN_WEAPON2                    = 5; // Nex fire (separated as it is a very long sound)
-       // on world: UNUSED
-       // on players: weapon firing                     WEAPONS
-       // on entities: turret firing                    WEAPONS
-       // on csqc: UNUSED
- float CHAN_PAIN                               = 6; // Pain
-       // on world: UNUSED
-       // on players: pain                              PAIN
-       // on entities: projectiles flying               SHOTS
-       // on csqc: player pain                          PAIN
- float CHAN_PLAYER                             = 7; // Player body
-       // on world: UNUSED
-       // on players: player sounds                     PLAYER
-       // on entities: player sounds                    PLAYER
-       // on csqc: UNUSED
+ #ifdef COMPAT_XON010_CHANNELS
+ float CH_INFO = 0; // only on world and csqc
+ float CH_TRIGGER = 0; // only on players; compat: FALSELY CONTROLLED BY "Info"
+ float CH_WEAPON_A = 1; // only on players and entities
+ float CH_WEAPON_SINGLE = 5; // only on players and entities
+ float CH_VOICE = 2; // only on players
+ float CH_BGM_SINGLE = 2; // only on csqc; compat: FALSELY CONTROLLED BY "Voice"
+ float CH_AMBIENT = 2; // only on csqc; compat: FALSELY CONTROLLED BY "Voice"
+ float CH_TRIGGER_SINGLE = 3; // only on players, entities, csqc
+ float CH_SHOTS = 4; // only on players, entities, csqc
+ float CH_SHOTS_SINGLE = 4; // only on players, entities, csqc
+ float CH_WEAPON_B = 5; // only on players and entities
+ float CH_PAIN = 6; // only on players and csqc
+ float CH_PAIN_SINGLE = 6; // only on players and csqc
+ float CH_PLAYER = 7; // only on players and entities
+ #else
+ float CH_INFO = 0;
+ float CH_TRIGGER = -3;
+ float CH_WEAPON_A = -1;
+ float CH_WEAPON_SINGLE = 1;
+ float CH_VOICE = -2;
+ float CH_BGM_SINGLE = 8;
+ float CH_AMBIENT = -9;
+ float CH_TRIGGER_SINGLE = 3;
+ float CH_SHOTS = -4;
+ float CH_SHOTS_SINGLE = 4;
+ float CH_WEAPON_B = -1;
+ float CH_PAIN = -6;
+ float CH_PAIN_SINGLE = 6;
+ float CH_PLAYER = -7;
+ #endif
  
  float ATTN_NONE                               = 0;
  float ATTN_MIN                                = 0.015625;
@@@ -500,6 -495,13 +496,13 @@@ float PROJECTILE_FIREBALL = 21
  float PROJECTILE_FIREMINE = 22;
  float PROJECTILE_BULLET_GLOWING_TRACER = 23;
  
+ float PROJECTILE_RAPTORCANNON   = 24;
+ float PROJECTILE_RAPTORBOMB     = 25;
+ float PROJECTILE_RAPTORBOMBLET  = 26;
+ float PROJECTILE_SPIDERROCKET   = 27;
+ float PROJECTILE_WAKIROCKET     = 28;
+ float PROJECTILE_WAKICANNON     = 29;
  float SPECIES_HUMAN        =  0;
  float SPECIES_ROBOT_SOLID  =  1;
  float SPECIES_ALIEN        =  2;
@@@ -529,18 -531,23 +532,23 @@@ float DEATH_MIRRORDAMAGE = 10014
  float DEATH_TOUCHEXPLODE = 10015;
  float DEATH_CHEAT = 10016;
  float DEATH_FIRE = 10017;
- float DEATH_TURRET = 10020;
  float DEATH_QUIET = 10021;
  float DEATH_HEADSHOT = 10022;
  
- float DEATH_SBMINIGUN = 10030;
- float DEATH_SBROCKET  = 10031;
- float DEATH_SBCRUSH   = 10032;
- float DEATH_SBBLOWUP  = 10033;
- float DEATH_WAKIGUN    = 10040;
- float DEATH_WAKIROCKET = 10041;
- float DEATH_WAKIBLOWUP = 10042;
+ float  DEATH_VHFIRST       = 10030;
+ float  DEATH_VHCRUSH       = 10030;
+ float  DEATH_SBMINIGUN     = 10031;
+ float  DEATH_SBROCKET      = 10032;
+ float  DEATH_SBBLOWUP      = 10033;
+ float  DEATH_WAKIGUN       = 10034;
+ float  DEATH_WAKIROCKET    = 10035;
+ float  DEATH_WAKIBLOWUP    = 10036;
+ float  DEATH_RAPTOR_CANNON = 10037;
+ float  DEATH_RAPTOR_BOMB   = 10038;
+ float  DEATH_RAPTOR_BOMB_SPLIT = 10039;
+ float  DEATH_RAPTOR_DEATH  = 10040;
+ float  DEATH_VHLAST        = 10040;
+ #define DEATH_ISVEHICLE(t)  ((t) >= DEATH_VHFIRST && (t) <= DEATH_VHLAST)
  
  float DEATH_GENERIC = 10050;
  
@@@ -548,6 -555,20 +556,20 @@@ float DEATH_WEAPON = 10100
  
  float DEATH_CUSTOM = 10300;
  
+ float DEATH_TURRET                  = 10500;
+ float DEATH_TURRET_EWHEEL           = 10501;
+ float DEATH_TURRET_FLAC             = 10502;
+ float DEATH_TURRET_MACHINEGUN       = 10503;
+ float DEATH_TURRET_WALKER_GUN       = 10504;
+ float DEATH_TURRET_WALKER_MEELE     = 10505;
+ float DEATH_TURRET_WALKER_ROCKET    = 10506;
+ float DEATH_TURRET_HELLION          = 10507;
+ float DEATH_TURRET_HK               = 10508;
+ float DEATH_TURRET_MLRS             = 10509;
+ float DEATH_TURRET_PLASMA           = 10510;
+ float DEATH_TURRET_PHASER           = 10511;
+ float DEATH_TURRET_TESLA            = 10512;
+ float DEATH_TURRET_LAST            = 10512;
  
  float DEATH_WEAPONMASK = 0xFF;
  float DEATH_HITTYPEMASK = 0x1F00; // which is WAY below 10000 used for normal deaths
@@@ -558,6 -579,7 +580,7 @@@ float HITTYPE_HEADSHOT = 0x800
  float HITTYPE_RESERVED = 0x1000; // unused yet
  
  // macros to access these
+ #define DEATH_ISTURRET(t)            ((t) >= DEATH_TURRET && (t) <= DEATH_TURRET_LAST)
  #define DEATH_ISSPECIAL(t)            ((t) >= DEATH_SPECIAL_START)
  #define DEATH_WEAPONOFWEAPONDEATH(t)  ((t) & DEATH_WEAPONMASK)
  #define DEATH_ISWEAPON(t,w)           (!DEATH_ISSPECIAL(t) && DEATH_WEAPONOFWEAPONDEATH(t) == (w))
  #define FRAGS_PLAYER_NONSOLID -616
  // we can use this frags value for both
  
- //misc. stuff
- #define NEWLINES "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  // water levels
  float WATERLEVEL_NONE = 0;
  float WATERLEVEL_WETFEET = 1;
@@@ -581,6 -600,18 +601,18 @@@ float WATERLEVEL_SUBMERGED = 3
  
  float MAX_SHOT_DISTANCE = 32768;
  
+ //centerprint ID list
+ float CPID_TEAMCHANGE = 1;
+ float CPID_CTF_CAPTURESHIELD = 2;
+ float CPID_MINSTA_FINDAMMO = 3;
+ float CPID_NIX_WPNCHANGE = 4;
+ float CPID_DISCONNECT_IDLING = 5;
+ float CPID_ROUND_STARTING = 6;
+ float CPID_GAME_STARTING = 7;
+ float CPID_TIMEOUT_COUNTDOWN = 8;
+ float CPID_MOTD = 9;
+ float CPID_KH_MSG = 10;
  // CSQC centerprint/notify message types
  float MSG_SUICIDE = 0;
  float MSG_KILL = 1;
@@@ -638,6 -669,7 +670,7 @@@ float WR_RESETPLAYER    = 10; // (SVQC
  float WR_IMPACTEFFECT = 11; // (CSQC) impact effect
  float WR_SWITCHABLE   = 12; // (CSQC) impact effect
  float WR_PLAYERDEATH    = 13; // (SVQC) does not need to do anything
+ float WR_GONETHINK    = 14; // (SVQC) logic to run every frame, also if no longer having the weapon as long as the switch away has not been performed
  
  float HUD_PANEL_WEAPONS               = 0;
  float HUD_PANEL_AMMO          = 1;
@@@ -655,7 -687,8 +688,8 @@@ float HUD_PANEL_CHAT               = 12
  float HUD_PANEL_ENGINEINFO    = 13;
  float HUD_PANEL_INFOMESSAGES  = 14;
  float HUD_PANEL_PHYSICS       = 15;
- float HUD_PANEL_NUM           = 16; // always last panel id + 1, please increment when adding a new panel
+ float HUD_PANEL_CENTERPRINT   = 16;
+ float HUD_PANEL_NUM           = 17; // always last panel id + 1, please increment when adding a new panel
  
  string HUD_PANELNAME_WEAPONS          = "weapons";
  string HUD_PANELNAME_AMMO             = "ammo";
@@@ -673,6 -706,7 +707,7 @@@ string HUD_PANELNAME_CHAT          = "chat"
  string HUD_PANELNAME_ENGINEINFO               = "engineinfo";
  string HUD_PANELNAME_INFOMESSAGES     = "infomessages";
  string HUD_PANELNAME_PHYSICS  = "physics";
+ string HUD_PANELNAME_CENTERPRINT      = "centerprint";
  
  float HUD_MENU_ENABLE         = 0;
  
index dd1a484b1523317d94ec53947b4c096185921570,ff99823330df8ac13212d5d79facd93fc7b3f5a3..401dd079799e65073460a46e2bf0d2ac9b0b0cfa
@@@ -85,39 -85,39 +85,39 @@@ float autocvar_g_balance_armor_rot
  float autocvar_g_balance_armor_rotlinear;
  float autocvar_g_balance_armor_rotstable;
  float autocvar_g_balance_armor_start;
- float autocvar_g_balance_sniperrifle_bursttime;
- float autocvar_g_balance_sniperrifle_primary_ammo;
- float autocvar_g_balance_sniperrifle_primary_animtime;
- float autocvar_g_balance_sniperrifle_primary_bulletconstant;
- float autocvar_g_balance_sniperrifle_primary_bullethail;
- float autocvar_g_balance_sniperrifle_primary_burstcost;
- float autocvar_g_balance_sniperrifle_primary_damage;
- float autocvar_g_balance_sniperrifle_primary_force;
- float autocvar_g_balance_sniperrifle_primary_headshotaddeddamage;
- float autocvar_g_balance_sniperrifle_primary_lifetime;
- float autocvar_g_balance_sniperrifle_primary_refire;
- float autocvar_g_balance_sniperrifle_primary_shots;
- float autocvar_g_balance_sniperrifle_primary_speed;
- float autocvar_g_balance_sniperrifle_primary_spread;
- float autocvar_g_balance_sniperrifle_primary_tracer;
- float autocvar_g_balance_sniperrifle_secondary;
- float autocvar_g_balance_sniperrifle_secondary_ammo;
- float autocvar_g_balance_sniperrifle_secondary_animtime;
- float autocvar_g_balance_sniperrifle_secondary_bulletconstant;
- float autocvar_g_balance_sniperrifle_secondary_bullethail;
- float autocvar_g_balance_sniperrifle_secondary_burstcost;
- float autocvar_g_balance_sniperrifle_secondary_damage;
- float autocvar_g_balance_sniperrifle_secondary_force;
- float autocvar_g_balance_sniperrifle_secondary_headshotaddeddamage;
- float autocvar_g_balance_sniperrifle_secondary_lifetime;
- float autocvar_g_balance_sniperrifle_secondary_reload;
- float autocvar_g_balance_sniperrifle_secondary_refire;
- float autocvar_g_balance_sniperrifle_secondary_shots;
- float autocvar_g_balance_sniperrifle_secondary_speed;
- float autocvar_g_balance_sniperrifle_secondary_spread;
- float autocvar_g_balance_sniperrifle_secondary_tracer;
- float autocvar_g_balance_sniperrifle_reload_ammo;
- float autocvar_g_balance_sniperrifle_reload_time;
+ 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_headshotaddeddamage;
+ 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_headshotaddeddamage;
+ 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_crylink_primary_ammo;
  float autocvar_g_balance_crylink_primary_animtime;
@@@ -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;
@@@ -1227,9 -1170,6 +1170,9 @@@ float autocvar_sv_warsowbunny_topspeed
  float autocvar_sv_warsowbunny_turnaccel;
  string autocvar_sv_weaponstats_file;
  float autocvar_sv_gibhealth;
 +float autocvar_sv_damageeffect_tick;
 +float autocvar_sv_damageeffect_lifetime;
 +float autocvar_sv_damageeffect_lifetime_max;
  float autocvar_sys_ticrate;
  float autocvar_teamplay_lockonrestart;
  float autocvar_teamplay_mode;
@@@ -1247,3 -1187,4 +1190,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 dda18b9ad51e09cde85d3a33a8a1dd3672048780,f3d34bb47531dcef705aa032d86a40fb8fae9db2..61884b8780cd924c8af5b3c12b29022561117875
@@@ -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);
  
        accuracy_resend(self);
  
        self.spectatortime = time;
+       
        self.classname = "observer";
        self.iscreature = FALSE;
        self.health = -666;
        self.takedamage = DAMAGE_NO;
        self.solid = SOLID_NOT;
-       self.movetype = MOVETYPE_NOCLIP;
+       self.movetype = MOVETYPE_FLY_WORLDONLY; //(self.cvar_cl_clippedspectating ? MOVETYPE_NOCLIP : MOVETYPE_FLY); // it's too early for this anyway, lets just set it in playerprethink
        self.flags = FL_CLIENT | FL_NOTARGET;
        self.armorvalue = 666;
        self.effects = 0;
        self.fixangle = TRUE;
        self.crouch = FALSE;
  
-       self.view_ofs = PL_VIEW_OFS;
+       self.view_ofs = '0 0 0'; // so that your view doesn't go into the ceiling with MOVETYPE_FLY_WORLDONLY, previously "PL_VIEW_OFS"
        setorigin (self, spot.origin);
-       setsize (self, '0 0 0', '0 0 0');
+       setsize (self, PL_CROUCH_MIN, PL_CROUCH_MAX); // give the spectator some space between walls for MOVETYPE_FLY_WORLDONLY
        self.prevorigin = self.origin;
        self.items = 0;
        self.weapons = 0;
@@@ -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));
@@@ -881,8 -887,6 +887,8 @@@ void PutClientInServer (void
  
                RemoveGrapplingHook(self); // Wazat's Grappling Hook
  
 +              Violence_DamageEffect_Remove(self);
 +
                self.classname = "player";
                self.wasplayer = TRUE;
                self.iscreature = TRUE;
                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)
                        if(e.spawnflags & WEP_FLAG_RELOADABLE) // prevent accessing undefined cvars
                                self.weapon_load[j] = cvar(strcat("g_balance_", e.netname, "_reload_ammo"));
                }
-               self.weapon_forbidchange = FALSE;
  
                oldself = self;
                self = spot;
                        activator = oldself;
+                               string s;
+                               s = self.target;
+                               self.target = string_null;
                                SUB_UseTargets();
+                               self.target = s;
                        activator = world;
                self = oldself;
  
@@@ -1136,7 -1144,7 +1146,7 @@@ float ClientInit_SendEntity(entity to, 
        WriteCoord(MSG_ENTITY, self.ebouncefactor); // g_balance_grenadelauncher_bouncefactor
        WriteCoord(MSG_ENTITY, self.ebouncestop); // g_balance_grenadelauncher_bouncestop
        WriteByte(MSG_ENTITY, autocvar_g_balance_nex_secondary); // client has to know if it should zoom or not
-       WriteByte(MSG_ENTITY, autocvar_g_balance_sniperrifle_secondary); // client has to know if it should zoom or not
+       WriteByte(MSG_ENTITY, autocvar_g_balance_rifle_secondary); // client has to know if it should zoom or not
        WriteByte(MSG_ENTITY, serverflags); // client has to know if it should zoom or not
        WriteByte(MSG_ENTITY, autocvar_g_balance_minelayer_limit); // minelayer max mines
        WriteByte(MSG_ENTITY, autocvar_g_balance_hagar_secondary_load_max); // hagar max loadable rockets
@@@ -1262,7 -1270,19 +1272,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;
@@@ -1322,6 -1338,10 +1340,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
@@@ -1417,55 -1461,6 +1463,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
@@@ -1567,7 -1562,7 +1564,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);
        if(autocvar_sv_eventlog)
                GameLogEcho(strcat(":join:", ftos(self.playerid), ":", ftos(num_for_edict(self)), ":", ((clienttype(self) == CLIENTTYPE_REAL) ? self.netaddress : "bot"), ":", self.netname));
  
  
        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);
  }
  
  /*
@@@ -1785,6 -1786,9 +1788,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");
@@@ -1922,7 -1926,7 +1928,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';
@@@ -1947,7 -1951,6 +1953,7 @@@ void respawn(void
                pointparticles(particleeffectnum("respawn_ghost"), self.origin, '0 0 0', 1);
                if(autocvar_g_respawn_ghosts_maxtime)
                        SUB_SetFade (self, time + autocvar_g_respawn_ghosts_maxtime / 2 + random () * (autocvar_g_respawn_ghosts_maxtime - autocvar_g_respawn_ghosts_maxtime / 2), 1.5);
 +              Violence_DamageEffect_Remove(self);
        }
  
        CopyBody(1);
@@@ -1965,63 -1968,22 +1971,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);
  }
  
@@@ -2350,17 -2312,41 +2315,41 @@@ void SpectateCopy(entity spectatee) 
        self.dmg_save = spectatee.dmg_save;
        self.dmg_inflictor = spectatee.dmg_inflictor;
        self.angles = spectatee.v_angle;
-       self.fixangle = TRUE;
+       if(!self.BUTTON_USE)
+               self.fixangle = TRUE;
        setorigin(self, spectatee.origin);
        setsize(self, spectatee.mins, spectatee.maxs);
        SetZoomState(spectatee.zoomstate);
  
        anticheat_spectatecopy(spectatee);
+       //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 +2372,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 +2428,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);
        }
  }
  
@@@ -2505,17 -2503,20 +2506,20 @@@ void checkSpectatorBlock() 
  
  void ObserverThink()
  {
+       float prefered_movetype;
        if (self.flags & FL_JUMPRELEASED) {
                if (self.BUTTON_JUMP && !self.version_mismatch) {
-                       self.welcomemessage_time = 0;
                        self.flags &~= FL_JUMPRELEASED;
                        self.flags |= FL_SPAWNING;
                } else if(self.BUTTON_ATCK && !self.version_mismatch) {
-                       self.welcomemessage_time = 0;
                        self.flags &~= FL_JUMPRELEASED;
                        if(SpectateNext() == 1) {
                                self.classname = "spectator";
                        }
+               } else {
+                       prefered_movetype = ((!self.BUTTON_USE ? self.cvar_cl_clippedspectating : !self.cvar_cl_clippedspectating) ? MOVETYPE_FLY_WORLDONLY : MOVETYPE_NOCLIP);
+                       if (self.movetype != prefered_movetype)
+                               self.movetype = prefered_movetype;
                }
        } else {
                if (!(self.BUTTON_ATCK || self.BUTTON_JUMP)) {
                        }
                }
        }
-       PrintWelcomeMessage(self);
  }
  
  void SpectatorThink()
  {
        if (self.flags & FL_JUMPRELEASED) {
                if (self.BUTTON_JUMP && !self.version_mismatch) {
-                       self.welcomemessage_time = 0;
                        self.flags &~= FL_JUMPRELEASED;
                        self.flags |= FL_SPAWNING;
                } else if(self.BUTTON_ATCK) {
-                       self.welcomemessage_time = 0;
                        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 -2598,11 +2601,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
  
                //don't allow the player to turn around while game is paused!
                if(timeoutStatus == 2) {
+                       // FIXME turn this into CSQC stuff
                        self.v_angle = self.lastV_angle;
                        self.angles = self.lastV_angle;
                        self.fixangle = TRUE;
                        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)
                if(frametime)
                        player_anim();
  
-               if (g_minstagib)
-                       minstagib_ammocheck();
                if(g_ctf)
                        ctf_setstatus();
  
        }
  
        if(!zoomstate_set)
-               SetZoomState(self.BUTTON_ZOOM || self.BUTTON_ZOOMSCRIPT || (self.BUTTON_ATCK2 && self.weapon == WEP_NEX) || (self.BUTTON_ATCK2 && self.weapon == WEP_SNIPERRIFLE && autocvar_g_balance_sniperrifle_secondary == 0));
+               SetZoomState(self.BUTTON_ZOOM || self.BUTTON_ZOOMSCRIPT || (self.BUTTON_ATCK2 && self.weapon == WEP_NEX) || (self.BUTTON_ATCK2 && self.weapon == WEP_RIFLE && autocvar_g_balance_rifle_secondary == 0));
  
        float oldspectatee_status;
        oldspectatee_status = self.spectatee_status;
                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);
@@@ -3007,7 -3065,21 +3068,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 00810d2a0e09fede1e63b6958ea22eb106221171,63ba50d5ba2bec255afafce011e1a96f283a944b..4b8dc143f63438421c579b9fb992fae15511970e
@@@ -1,3 -1,6 +1,6 @@@
+ .entity accuracy;
+ .float accuracy_frags[WEP_MAXCOUNT];
  float weaponstats_buffer;
  
  void WeaponStats_Init()
  
  #define WEAPONSTATS_GETINDEX(awep,abot,vwep,vbot) (((vwep) + (awep) * (WEP_LAST - WEP_FIRST + 1) - (WEP_FIRST + WEP_FIRST * (WEP_LAST - WEP_FIRST + 1))) * 4 + (abot) * 2 + (vbot))
  
- void WeaponStats_Shutdown()
+ void WeaponStats_ready(entity fh, entity pass, float status)
  {
-       float i, j, ibot, jbot, idx;
-       float fh;
+       float i, j, n, ibot, jbot, idx;
        vector v;
-       string prefix;
-       if(weaponstats_buffer < 0)
-               return;
-       prefix = strcat(autocvar_hostname, "\t", GetGametype(), "_", GetMapname(), "\t");
-       if(autocvar_sv_weaponstats_file != "")
+       string prefix, s;
+       switch(status)
        {
-               fh = fopen(autocvar_sv_weaponstats_file, FILE_APPEND);
-               if(fh >= 0)
-               {
-                       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"));
+               case URL_READY_CANWRITE:
+                       // url_fopen returned, we can write
+                       prefix = strcat(autocvar_hostname, "\t", GetGametype(), "_", GetMapname(), "\t");
+                       url_fputs(fh, "#begin statsfile\n");
+                       url_fputs(fh, strcat("#date ", strftime(TRUE, "%a %b %e %H:%M:%S %Z %Y"), "\n"));
+                       url_fputs(fh, strcat("#config ", ftos(crc16(FALSE, cvar_purechanges)), "\n"));
+                       url_fputs(fh, strcat("#cvar_purechanges ", ftos(cvar_purechanges_count), "\n"));
+                       n = tokenizebyseparator(cvar_purechanges, "\n");
+                       for(i = 0; i < n; ++i)
+                               url_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)
                                {
                                        if(v != '0 0 0')
                                        {
                                                //vector is: kills hits damage
-                                               fputs(fh, sprintf("%s%d %d\t%d %d\t", prefix, i, ibot, j, jbot));
-                                               fputs(fh, sprintf("%d %d %g\n", v_x, v_y, v_z));
+                                               url_fputs(fh, sprintf("%s%d %d\t%d %d\t", prefix, i, ibot, j, jbot));
+                                               url_fputs(fh, sprintf("%d %d %g\n", v_x, v_y, v_z));
                                        }
                                }
-                       fputs(fh, "#end\n\n");
-                       fclose(fh);
+                       url_fputs(fh, "#end\n\n");
+                       url_fclose(fh, WeaponStats_ready, world);
+                       buf_del(weaponstats_buffer);
+                       weaponstats_buffer = -1;
+                       break;
+               case URL_READY_CANREAD:
+                       // url_fclose is processing, we got a response for writing the data
+                       // this must come from HTTP
+                       print("Got response from weapon stats server:\n");
+                       while((s = url_fgets(fh)))
+                               print("  ", s, "\n");
+                       print("End of response.\n");
+                       url_fclose(fh, WeaponStats_ready, world);
+                       break;
+               case URL_READY_CLOSED:
+                       // url_fclose has finished
                        print("Weapon stats written\n");
-               }
+                       break;
+               case URL_READY_ERROR:
+               default:
+                       print("Weapon stats writing failed: ", ftos(status), "\n");
+                       break;
+       }
+ }
+ void WeaponStats_Shutdown()
+ {
+       if(weaponstats_buffer < 0)
+               return;
+       if(autocvar_sv_weaponstats_file != "")
+       {
+               url_fopen(autocvar_sv_weaponstats_file, FILE_APPEND, WeaponStats_ready, world);
+       }
+       else
+       {
+               buf_del(weaponstats_buffer);
+               weaponstats_buffer = -1;
        }
-       buf_del(weaponstats_buffer);
-       weaponstats_buffer = -1;
  }
  
  void WeaponStats_LogItem(float awep, float abot, float vwep, float vbot, vector item)
@@@ -146,9 -180,6 +180,9 @@@ void CopyBody(float keepvelocity
  
        Drag_MoveDrag(oldself, self);
  
 +      Violence_DamageEffect_Copy(oldself, self);
 +
 +      self.owner = oldself;
        self = oldself;
  }
  
@@@ -340,11 -371,11 +374,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)
                Violence_GibSplash(self, 1, 1, attacker);
                self.modelindex = 0; // restore later
                self.solid = SOLID_NOT; // restore later
 +              self.takedamage = DAMAGE_NO; // restore later
        }
  }
  
@@@ -458,11 -488,11 +492,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)
                                        // 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
                race_PreDie();
                DropAllRunes(self);
  
+         // increment frag counter for used weapon type
+         float w;
+         w = DEATH_WEAPONOF(deathtype);
+         if(WEP_VALID(w))
+         if(self.classname == "player")
+         if(self != attacker)
+         attacker.accuracy.(accuracy_frags[w-1]) += 1;
                if(deathtype == DEATH_HURTTRIGGER && g_freezetag)
                {
                        PutClientInServer();
  
                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
@@@ -764,7 -802,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;
@@@ -1126,8 -1164,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)
@@@ -1253,7 -1292,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);
@@@ -1327,9 -1366,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)
diff --combined qcsrc/server/defs.qh
index dc4d146168c88752e4dfe9511a67ec8b0919e2c0,d5ef02034cee6f21751627f27af8ae25eed9b59d..d66a2187d99bfba75f211811f61d6c114f9c1a09
@@@ -210,7 -210,6 +210,6 @@@ void w_clear()
  void w_ready();
  // VorteX: standalone think for weapons, so normal think on weaponentity can be reserved by weaponflashes (which needs update even player dies)
  .float weapon_nextthink;
- .float weapon_forbidchange;
  .void() weapon_think;
  
  //float       PLAYER_WEAPONSELECTION_DELAY = );
@@@ -231,7 -230,6 +230,6 @@@ void weapon_defaultspawnfunc(float wpn)
  
  string w_deathtypestring;
  
- void(entity client, string s) centerprint_builtin = #73;
  .vector dest1, dest2;
  
  float gameover;
@@@ -243,7 -241,6 +241,6 @@@ float alreadychangedlevel
  .float runes;
  
  
- .float welcomemessage_time;
  .float version;
  
  // minstagib vars
@@@ -286,7 -283,6 +283,6 @@@ entity timeoutHandler; //responsible fo
  void timeoutHandler_Think();
  void evaluateTimeout();
  void evaluateTimein();
- string getTimeoutText(float addOneSecond);
  
  .float spawnshieldtime;
  
@@@ -312,7 -308,8 +308,8 @@@ float default_weapon_alpha
  .float() customizeentityforclient;
  .float cvar_cl_handicap;
  .float cvar_cl_playerdetailreduction;
- .float cvar_scr_centertime;
+ .float cvar_cl_clippedspectating;
  .string cvar_g_xonoticversion;
  .string cvar_cl_weaponpriority;
  .string cvar_cl_weaponpriorities[10];
@@@ -348,7 -345,6 +345,6 @@@ void AnnounceTo(entity e, string snd)
  .entity jumppadsused[NUM_JUMPPADSUSED];
  
  string gamemode_name;
- float teams_matter;
  
  float startitem_failed;
  
@@@ -369,10 -365,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;
@@@ -430,18 -422,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)
@@@ -451,24 -451,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;
@@@ -498,8 -492,6 +492,8 @@@ float GetPlayerSoundSampleField_notFoun
  .float cvar_cl_voice_directional;
  .float cvar_cl_voice_directional_taunt_attenuation;
  
 +.float cvar_cl_damageeffect;
 +
  .float version_mismatch;
  
  float independent_players;
@@@ -547,6 -539,7 +541,7 @@@ void target_voicescript_clear(entity pl
  .string target2;
  .string target3;
  .string target4;
+ .float target_random;
  .float trigger_reverse;
  
  // Nexball 
@@@ -564,10 -557,6 +559,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 -598,7 +600,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 -655,5 +657,5 @@@ float serverflags
  
  .entity muzzle_flash;
  .float misc_bulletcounter;    // replaces uzi & hlac bullet counter.
+ void PlayerUseKey();
diff --combined qcsrc/server/g_damage.qc
index 55dc6f645dc742136df45e96c020ee7b5554b58b,d6020bd349a8b7bf6955b838d5f094da1b80d7db..efdd9ed1cf921806917a107368a78058fe3b7b41
@@@ -41,8 -41,6 +41,6 @@@ void Damage_DamageInfo(vector org, floa
        Net_LinkEntity(e, FALSE, 0.2, Damage_DamageInfo_SendEntity);
  }
  
- #define DAMAGE_CENTERPRINT_SPACER NEWLINES
  float checkrules_firstblood;
  
  float yoda;
@@@ -61,7 -59,7 +59,7 @@@ float damage_headshotbonus; // bonus mu
  
  float IsDifferentTeam(entity a, entity b)
  {
-       if(teams_matter)
+       if(teamplay)
        {
                if(a.team == b.team)
                        return 0;
@@@ -126,6 -124,8 +124,8 @@@ void GiveFrags (entity attacker, entit
        {
                // regular frag
                PlayerScore_Add(attacker, SP_KILLS, 1);
+               if(targ.playerid)
+                       PlayerStats_Event(attacker, sprintf("kills-%d", targ.playerid), 1);
        }
  
        PlayerScore_Add(targ, SP_DEATHS, 1);
@@@ -299,13 -299,9 +299,9 @@@ void Obituary (entity attacker, entity 
        string  s, a, msg;
        float w, type;
  
-       if (targ.classname == "player" || targ.classname == "corpse")
+       if (targ.classname == "player")
        {
-               if (targ.classname == "corpse")
-                       s = "A corpse";
-               else
-                       s = targ.netname;
+               s = targ.netname;
                a = attacker.netname;
  
                if (targ == attacker) // suicides
  
                        if (targ.killcount > 2)
                                msg = ftos(targ.killcount);
-                       if(teams_matter && deathtype == DEATH_MIRRORDAMAGE)
+                       if(teamplay && deathtype == DEATH_MIRRORDAMAGE)
                        {
                                if(attacker.team == COLOR_TEAM1)
                                        deathtype = KILL_TEAM_RED;
  
                        Send_KillNotification(s, msg, ftos(w), deathtype, MSG_SUICIDE);
                }
-               else if (attacker.classname == "player" || attacker.classname == "gib")
+               else if (attacker.classname == "player")
                {
-                       if(teams_matter && attacker.team == targ.team)
+                       if(teamplay && attacker.team == targ.team)
                        {
                                if(attacker.team == COLOR_TEAM1)
                                        type = KILL_TEAM_RED;
@@@ -497,10 -493,6 +493,10 @@@ entity damage_attacker
  
  void Damage (entity targ, entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
  {
 +      // if the target is a player or dead body, activate damage effects
 +      if(targ.classname == "player" || targ.classname == "body")
 +              Violence_DamageEffect_SetRepeat(targ, damage, DEATH_WEAPONOF(deathtype));
 +
        float mirrordamage;
        float mirrorforce;
        float teamdamage0;
                                damage = 0;
                                force = '0 0 0';
                        }
-                       else if(teams_matter && attacker.team == targ.team)
+                       else if(teamplay && attacker.team == targ.team)
                        {
                                if(autocvar_teamplay_mode == 1)
                                        damage = 0;
                        if (targ.armorvalue && (deathtype == WEP_MINSTANEX) && damage)
                        {
                                targ.armorvalue -= 1;
-                               centerprint(targ, strcat(DAMAGE_CENTERPRINT_SPACER, "^3Remaining extra lives: ",ftos(targ.armorvalue)));
+                               centerprint(targ, strcat("^3Remaining extra lives: ",ftos(targ.armorvalue)));
                                damage = 0;
                                targ.hitsound += 1;
                                attacker.hitsound += 1; // TODO change this to a future specific hitsound for armor hit
                                if (targ != attacker)
                                {
                                        if ((targ.health >= 1) && (targ.classname == "player"))
-                                               centerprint(attacker, strcat(DAMAGE_CENTERPRINT_SPACER, "Secondary fire inflicts no damage!"));
+                                               centerprint(attacker, "Secondary fire inflicts no damage!");
                                        force = '0 0 0';
                                        // keep mirrorforce
                                        attacker = targ;
                        if(deathtype & HITTYPE_HEADSHOT)
                                damage *= 1 + damage_headshotbonus;
  
-                       if(targ.classname == "player")
+                       entity victim;
+                       if((targ.vehicle_flags & VHF_ISVEHICLE) && targ.owner)
+                               victim = targ.owner;
+                       else
+                               victim = targ;
+                       if(victim.classname == "player" || victim.turrcaps_flags & TFL_TURRCAPS_ISTURRET)
                        {
-                               if(IsDifferentTeam(targ, attacker))
+                               if(IsDifferentTeam(victim, attacker))
                                {
                                        if(damage > 0)
                                        {
                                                if(deathtype != DEATH_FIRE)
                                                {
-                                                       if(targ.BUTTON_CHAT)
+                                                       if(victim.BUTTON_CHAT)
                                                                attacker.typehitsound += 1;
                                                        else
                                                                attacker.hitsound += 1;
  
                                                if not(DEATH_ISSPECIAL(deathtype))
                                                {
+                                                       if(targ.classname == "player") // don't do this for vehicles
                                                        if(!g_minstagib)
-                                                       if(IsFlying(targ))
+                                                       if(IsFlying(victim))
                                                                yoda = 1;
  
                                                        if(g_minstagib)
-                                                       if(targ.items & IT_STRENGTH)
+                                                       if(victim.items & IT_STRENGTH)
                                                                yoda = 1;
  
                                                        if(deathtype & HITTYPE_HEADSHOT)
                        if(attacker.armorvalue > 0)
                        {
                                attacker.armorvalue = attacker.armorvalue - 1;
-                               centerprint(attacker, strcat(DAMAGE_CENTERPRINT_SPACER, "^3Remaining extra lives: ",ftos(attacker.armorvalue)));
+                               centerprint(attacker, strcat("^3Remaining extra lives: ",ftos(attacker.armorvalue)));
                                attacker.hitsound += 1;
                        }
                        mirrordamage = 0;
index 591bbf8b9fe670c9e749a0a6cf92400c67c35110,0dca3ab282030c4bc98969ddcbda261b16b2a90b..c49088156631df6221497b8ebfa51170381e9a78
@@@ -81,19 -81,20 +81,20 @@@ float logfile
  
  string GetAdvancedDeathReports(entity enPlayer) // Extra fragmessage information
  {
-       local float nPlayerHealth = rint(enPlayer.health);
-       local float nPlayerArmor = rint(enPlayer.armorvalue);
-       local float nPlayerHandicap = enPlayer.cvar_cl_handicap;
-       local float nPlayerPing = rint(enPlayer.ping);
-       local string strPlayerPingColor;
-       local string strMessage;
+       float nPlayerHealth = rint(enPlayer.health);
+       float nPlayerArmor = rint(enPlayer.armorvalue);
+       float nPlayerHandicap = enPlayer.cvar_cl_handicap;
+       float nPlayerPing = rint(enPlayer.ping);
+       string strPlayerPingColor;
+       string strMessage;
+       
        if(nPlayerPing >= 150)
                strPlayerPingColor = "^1";
        else
                strPlayerPingColor = "^2";
  
        if((autocvar_sv_fragmessage_information_stats) && (enPlayer.health >= 1))
-               strMessage = strcat(strMessage, "\n^7(Health ^1", ftos(nPlayerHealth), "^7 / Armor ^2", ftos(nPlayerArmor), "^7)");
+               strMessage = strcat(strMessage, "^7(Health ^1", ftos(nPlayerHealth), "^7 / Armor ^2", ftos(nPlayerArmor), "^7)");
  
        if(autocvar_sv_fragmessage_information_ping) {
                if(clienttype(enPlayer) == CLIENTTYPE_BOT) // Bots have no ping
        } else if(autocvar_sv_fragmessage_information_handicap) {
                if(autocvar_sv_fragmessage_information_handicap == 2)
                        if(nPlayerHandicap <= 1)
-                               strMessage = strcat(strMessage, "\n^7(Handicap ^2Off^7)");
+                               strMessage = strcat(strMessage, "^7(Handicap ^2Off^7)");
                        else
-                               strMessage = strcat(strMessage, "\n^7(Handicap ^2", ftos(nPlayerHandicap), "^7)");
+                               strMessage = strcat(strMessage, "^7(Handicap ^2", ftos(nPlayerHandicap), "^7)");
                else if(nPlayerHandicap > 1)
-                       strMessage = strcat(strMessage, "\n^7(Handicap ^2", ftos(nPlayerHandicap), "^7)");
+                       strMessage = strcat(strMessage, "^7(Handicap ^2", ftos(nPlayerHandicap), "^7)");
        }
+       
+       if(strMessage) // add new line to the beginning if there is a message
+               strMessage = strcat("\n", strMessage);
+               
        return strMessage;
  }
  void bcenterprint(string s)
@@@ -579,9 -584,9 +584,9 @@@ void GetCvars(float f
        MUTATOR_CALLHOOK(GetCvars);
        GetCvars_handleFloat(s, f, autoswitch, "cl_autoswitch");
        GetCvars_handleFloat(s, f, cvar_cl_playerdetailreduction, "cl_playerdetailreduction");
-       GetCvars_handleFloat(s, f, cvar_scr_centertime, "scr_centertime");
        GetCvars_handleString(s, f, cvar_g_xonoticversion, "g_xonoticversion");
        GetCvars_handleFloat(s, f, cvar_cl_handicap, "cl_handicap");
+       GetCvars_handleFloat(s, f, cvar_cl_clippedspectating, "cl_clippedspectating");
        GetCvars_handleString_Fixup(s, f, cvar_cl_weaponpriority, "cl_weaponpriority", W_FixWeaponOrder_ForceComplete_AndBuildImpulseList);
        GetCvars_handleString_Fixup(s, f, cvar_cl_weaponpriorities[0], "cl_weaponpriority0", W_FixWeaponOrder_AllowIncomplete);
        GetCvars_handleString_Fixup(s, f, cvar_cl_weaponpriorities[1], "cl_weaponpriority1", W_FixWeaponOrder_AllowIncomplete);
        GetCvars_handleString_Fixup(s, f, cvar_cl_weaponpriorities[9], "cl_weaponpriority9", W_FixWeaponOrder_AllowIncomplete);
        GetCvars_handleFloat(s, f, cvar_cl_weaponimpulsemode, "cl_weaponimpulsemode");
        GetCvars_handleFloat(s, f, cvar_cl_autotaunt, "cl_autotaunt");
 +      GetCvars_handleFloat(s, f, cvar_cl_damageeffect, "cl_damageeffect");
        GetCvars_handleFloat(s, f, cvar_cl_noantilag, "cl_noantilag");
        GetCvars_handleFloat(s, f, cvar_cl_voice_directional, "cl_voice_directional");
        GetCvars_handleFloat(s, f, cvar_cl_voice_directional_taunt_attenuation, "cl_voice_directional_taunt_attenuation");
@@@ -719,51 -723,11 +724,11 @@@ float NumberToTeamNumber(float number
        return -1;
  }
  
- #define CENTERPRIO_POINT 1
- #define CENTERPRIO_SPAM 2
- #define CENTERPRIO_VOTE 4
- #define CENTERPRIO_NORMAL 5
- #define CENTERPRIO_SHIELDING 7
- #define CENTERPRIO_MAPVOTE 9
- #define CENTERPRIO_IDLEKICK 50
- #define CENTERPRIO_ADMIN 99
- .float centerprint_priority;
- .float centerprint_expires;
- void centerprint_atprio(entity e, float prio, string s)
- {
-     if (intermission_running)
-         if (prio < CENTERPRIO_MAPVOTE)
-             return;
-     if (time > e.centerprint_expires)
-         e.centerprint_priority = 0;
-     if (prio >= e.centerprint_priority)
-     {
-         e.centerprint_priority = prio;
-         if (timeoutStatus == 2)
-             e.centerprint_expires = time + (e.cvar_scr_centertime * TIMEOUT_SLOWMO_VALUE);
-         else
-             e.centerprint_expires = time + e.cvar_scr_centertime;
-         centerprint_builtin(e, s);
-     }
- }
- void centerprint_expire(entity e, float prio)
- {
-     if (prio == e.centerprint_priority)
-     {
-         e.centerprint_priority = 0;
-         centerprint_builtin(e, "");
-     }
- }
- void centerprint(entity e, string s)
- {
-     centerprint_atprio(e, CENTERPRIO_NORMAL, s);
- }
  // decolorizes and team colors the player name when needed
  string playername(entity p)
  {
      string t;
-     if (teams_matter && !intermission_running && p.classname == "player")
+     if (teamplay && !intermission_running && p.classname == "player")
      {
          t = Team_ColorCode(p.team);
          return strcat(t, strdecolorize(p.netname));
@@@ -1314,7 -1278,6 +1279,6 @@@ void readlevelcvars(void
  
  // Sound functions
  string precache_sound (string s) = #19;
- void(entity e, float chan, string samp, float vol, float atten) sound_builtin = #8;
  float precache_sound_index (string s) = #19;
  
  #define SND_VOLUME      1
@@@ -1346,12 -1309,24 +1310,24 @@@ float sound_allowed(float dest, entity 
      return TRUE;
  }
  
+ #ifdef COMPAT_XON010_CHANNELS
+ void(entity e, float chan, string samp, float vol, float atten) sound_builtin = #8;
  void sound(entity e, float chan, string samp, float vol, float atten)
  {
      if (!sound_allowed(MSG_BROADCAST, e))
          return;
      sound_builtin(e, chan, samp, vol, atten);
  }
+ #else
+ #undef sound
+ void sound(entity e, float chan, string samp, float vol, float atten)
+ {
+     if (!sound_allowed(MSG_BROADCAST, e))
+         return;
+     sound7(e, chan, samp, vol, atten, 0, 0);
+ }
+ #endif
  void soundtoat(float dest, entity e, vector o, float chan, string samp, float vol, float atten)
  {
      float entno, idx;
          sflags |= SND_VOLUME;
      if (atten != 64)
          sflags |= SND_ATTENUATION;
-     if (entno >= 8192)
+     if (entno >= 8192 || chan < 0 || chan > 7)
          sflags |= SND_LARGEENTITY;
      if (idx >= 256)
          sflags |= SND_LARGESOUND;
@@@ -1413,7 -1388,7 +1389,7 @@@ void soundto(float dest, entity e, floa
  }
  void soundat(entity e, vector o, float chan, string samp, float vol, float atten)
  {
-     soundtoat(MSG_BROADCAST, e, o, chan, samp, vol, atten);
+     soundtoat(((chan & 8) ? MSG_ALL : MSG_BROADCAST), e, o, chan, samp, vol, atten);
  }
  void stopsoundto(float dest, entity e, float chan)
  {
  
      entno = num_for_edict(e);
  
-     if (entno >= 8192)
+     if (entno >= 8192 || chan < 0 || chan > 7)
      {
          float idx, sflags;
          idx = precache_sound_index("misc/null.wav");
@@@ -1462,7 -1437,7 +1438,7 @@@ void play2(entity e, string filename
  {
      //stuffcmd(e, strcat("play2 ", filename, "\n"));
      msg_entity = e;
-     soundtoat(MSG_ONE, world, '0 0 0', CHAN_AUTO, filename, VOL_BASE, ATTN_NONE);
+     soundtoat(MSG_ONE, world, '0 0 0', CH_INFO, filename, VOL_BASE, ATTN_NONE);
  }
  
  // use this one if you might be causing spam (e.g. from touch functions that might get called more than once per frame)
@@@ -1500,7 -1475,7 +1476,7 @@@ void play2all(string samp
      if (autocvar_bot_sound_monopoly)
          return;
  
-     sound(world, CHAN_AUTO, samp, VOL_BASE, ATTN_NONE);
+     sound(world, CH_INFO, samp, VOL_BASE, ATTN_NONE);
  }
  
  void PrecachePlayerSounds(string f);
@@@ -1690,6 -1665,30 +1666,30 @@@ void precache(
  #define WRITESPECTATABLE_MSG_ONE(statement) WRITESPECTATABLE_MSG_ONE_VARNAME(oldmsg_entity, statement)
  #define WRITESPECTATABLE(msg,statement) if(msg == MSG_ONE) { WRITESPECTATABLE_MSG_ONE(statement); } else statement float WRITESPECTATABLE_workaround = 0
  
+ void Send_CSQC_Centerprint_Generic(entity e, float id, string s, float duration, float countdown_num)
+ {
+       if (clienttype(e) == CLIENTTYPE_REAL)
+       {
+               msg_entity = e;
+               WRITESPECTATABLE_MSG_ONE({
+                       WriteByte(MSG_ONE, SVC_TEMPENTITY);
+                       WriteByte(MSG_ONE, TE_CSQC_NOTIFY);
+                       WriteByte(MSG_ONE, CSQC_CENTERPRINT_GENERIC);
+                       WriteByte(MSG_ONE, id);
+                       WriteString(MSG_ONE, s);
+                       if (id != 0 && s != "")
+                       {
+                               WriteByte(MSG_ONE, duration);
+                               WriteByte(MSG_ONE, countdown_num);
+                       }
+               });
+       }
+ }
+ void Send_CSQC_Centerprint_Generic_Expire(entity e, float id)
+ {
+       Send_CSQC_Centerprint_Generic(e, id, "", 1, 0);
+ }
  // WARNING: this kills the trace globals
  #define EXACTTRIGGER_TOUCH if(WarpZoneLib_ExactTrigger_Touch()) return
  #define EXACTTRIGGER_INIT  WarpZoneLib_ExactTrigger_Init()
@@@ -1755,6 -1754,8 +1755,8 @@@ void remove_except_protected(entity e
  
  void remove_unsafely(entity e)
  {
+     if(e.classname == "spike")
+         error("Removing spikes is forbidden (crylink bug), please report");
      remove_builtin(e);
  }
  
@@@ -2015,17 -2016,27 +2017,27 @@@ float SUB_NoImpactCheck(
  
  #define SUB_OwnerCheck() (other && (other == self.owner))
  
+ void RemoveGrapplingHook(entity pl);
+ void W_Crylink_Dequeue(entity e);
  float WarpZone_Projectile_Touch_ImpactFilter_Callback()
  {
        if(SUB_OwnerCheck())
                return TRUE;
        if(SUB_NoImpactCheck())
        {
-               remove(self);
+               if(self.classname == "grapplinghook")
+                       RemoveGrapplingHook(self.realowner);
+               else if(self.classname == "spike")
+               {
+                       W_Crylink_Dequeue(self);
+                       remove(self);
+               }
+               else
+                       remove(self);
                return TRUE;
        }
        if(trace_ent && trace_ent.solid > SOLID_TRIGGER)
-               UpdateCSQCProjectileNextFrame(self);
+               UpdateCSQCProjectile(self);
        return FALSE;
  }
  #define PROJECTILE_TOUCH if(WarpZone_Projectile_Touch()) return
@@@ -2043,7 -2054,11 +2055,11 @@@ void URI_Get_Callback(float id, float s
      dprint(data);
      dprint("\nEnd of data.\n");
  
-     if (id == URI_GET_DISCARD)
+     if(url_URI_Get_Callback(id, status, data))
+     {
+         // handled
+     }
+     else if (id == URI_GET_DISCARD)
      {
          // discard
      }
@@@ -2624,15 -2639,15 +2640,15 @@@ vector shotorg_adjustfromclient(vector 
  {
        switch(algn)
        {
-               case 1: // right
+               default:
+               case 3: // right
                        break;
  
-               case 2: // left
+               case 4: // left
                        vecs_y = -vecs_y;
                        break;
  
-               default:
-               case 3:
+               case 1:
                        if(allowcenter) // 2: allow center handedness
                        {
                                // center
                        }
                        break;
  
-               case 4:
+               case 2:
                        if(allowcenter) // 2: allow center handedness
                        {
                                // center
@@@ -2671,7 -2686,8 +2687,8 @@@ vector shotorg_adjust_values(vector vec
        {
                if (visual)
                {
-                       vecs = shotorg_adjustfromclient(vecs, y_is_right, TRUE, algn);
+                       vecs_y = 0;
+                       vecs_z -= 2;
                }
                else
                {
        }
        else if (autocvar_g_shootfromcenter)
        {
-               if (visual)
-               {
-                       vecs = shotorg_adjustfromclient(vecs, y_is_right, TRUE, algn);
-               }
-               else
-               {
-                       vecs_y = 0;
-                       vecs_z -= 2;
-               }
+               vecs_y = 0;
+               vecs_z -= 2;
        }
        else if ((s = autocvar_g_shootfromfixedorigin) != "")
        {
@@@ -3093,3 -3102,60 +3103,60 @@@ void defer(float fdelay, void() func
      e.think     = defer_think;
      e.nextthink = time + fdelay;
  }
+ .string aiment_classname;
+ .float aiment_deadflag;
+ void SetMovetypeFollow(entity ent, entity e)
+ {
+       // FIXME this may not be warpzone aware
+       ent.movetype = MOVETYPE_FOLLOW; // make the hole follow
+       ent.solid = SOLID_NOT; // MOVETYPE_FOLLOW is always non-solid - this means this cannot be teleported by warpzones any more! Instead, we must notice when our owner gets teleported.
+       ent.aiment = e; // make the hole follow bmodel
+       ent.punchangle = e.angles; // the original angles of bmodel
+       ent.view_ofs = ent.origin - e.origin; // relative origin
+       ent.v_angle = ent.angles - e.angles; // relative angles
+       ent.aiment_classname = strzone(e.classname);
+       ent.aiment_deadflag = e.deadflag;
+ }
+ void UnsetMovetypeFollow(entity ent)
+ {
+       ent.movetype = MOVETYPE_FLY;
+       PROJECTILE_MAKETRIGGER(ent);
+       ent.aiment = world;
+ }
+ float LostMovetypeFollow(entity ent)
+ {
+ /*
+       if(ent.movetype != MOVETYPE_FOLLOW)
+               if(ent.aiment)
+                       error("???");
+ */
+       if(ent.aiment)
+       {
+               if(ent.aiment.classname != ent.aiment_classname)
+                       return 1;
+               if(ent.aiment.deadflag != ent.aiment_deadflag)
+                       return 1;
+       }
+       return 0;
+ }
+ float isPushable(entity e)
+ {
+       if(e.iscreature)
+               return TRUE;
+       switch(e.classname)
+       {
+               case "body":
+               case "droppedweapon":
+               case "keepawayball":
+               case "nexball_basketball":
+               case "nexball_football":
+                       return TRUE;
+               case "bullet": // antilagged bullets can't hit this either
+                       return FALSE;
+       }
+       if (e.projectiledeathtype)
+               return TRUE;
+       return FALSE;
+ }