]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into mirceakitsune/damage_effects
authorMircea Kitsune <sonichedgehog_hyperblast00@yahoo.com>
Wed, 19 Oct 2011 20:20:15 +0000 (23:20 +0300)
committerMircea Kitsune <sonichedgehog_hyperblast00@yahoo.com>
Wed, 19 Oct 2011 20:20:15 +0000 (23:20 +0300)
1  2 
defaultXonotic.cfg
effectinfo.txt
qcsrc/client/Main.qc
qcsrc/client/autocvars.qh
qcsrc/client/damage.qc
qcsrc/common/constants.qh
qcsrc/server/cl_player.qc
qcsrc/server/g_damage.qc

diff --combined defaultXonotic.cfg
index 4d28f23ed8a9621ea48c6cd9ac7945600c2d96bc,f92882f4424da8b0ca0f2693e7be3a64e0916e95..bcab7c195f6958f802f24178f4bf7078ff6bdee0
@@@ -53,6 -53,8 +53,8 @@@ alias asay_drop "say_team (%l) dropped 
  alias +hook +button6
  alias -hook -button6
  alias use "impulse 21"
+ alias +use use // always send that impulse AND press the key (+use is engine internal command and executes anyway)
+ set cl_newusekeysupported 1 // indicates that we always send the use impulse too, so they do not need to be synthesized
  alias ready "cmd ready"
  alias lockteams "sv_cmd lockteams"
  alias unlockteams "sv_cmd unlockteams"
@@@ -177,7 -179,7 +179,7 @@@ seta crosshair_seeker_size 0.8     "crossha
  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_rifle_size 0.5 "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"
@@@ -351,19 -353,12 +353,18 @@@ set sv_timeout_resumetime 3     "how long t
  
  set g_allow_oldnexbeam 0 "If enabled, clients are allowed to use old v2.3 Nexgun beam"
  seta cl_particles_oldnexbeam 0 "Uses the old v2.3 Nexgun beam instead of the new beam, only works if server allows it (g_allow_oldnexbeam 1)"
- set sv_qcweaponanimation 0
  
  set g_telefrags 1 "telefragging, i.e. killing someone who stands in the way of someone who is teleporting"
  set g_telefrags_teamplay 1 "never telefrag team mates"
  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 cl_damageeffect_player 0.05 "enable weapon damage effects on players, value specifies how often to show the effect"
 +set cl_damageeffect_gibs 0.125 "enable weapon damage effects on gibs, value specifies how often to show the effect"
 +set cl_damageeffect_gibs_randomize 0.5 "probability for effects to show on gibs each tick, used so gibs don't generate particles at the same time and look ugly"
 +set cl_damageeffect_lifetime 0.04 "how much a damage effect lasts, multiplied by damage amount"
 +set cl_damageeffect_lifetime_max 5 "maximum amount of lifetime a damage effect may have at a time"
 +
  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"
@@@ -387,11 -382,11 +388,11 @@@ set sv_player_crouch_viewoffset "0 0 20
  set sv_player_crouch_mins "-16 -16 -24" "mins of a crouched playermodel"
  set sv_player_crouch_maxs "16 16 25" "maxs of a crouched playermodel"
  
- set sv_pogostick 1 "don't require releasing the space bar for jumping again"
  set sv_doublejump 0 "allow Quake 2-style double jumps"
  set sv_jumpspeedcap_min "" "lower bound on the baseline velocity of a jump; final velocity will be >= (jumpheight * min + jumpheight)"
  set sv_jumpspeedcap_max "" "upper bound on the baseline velocity of a jump; final velocity will be <= (jumpheight * max + jumpheight)"
  set sv_jumpspeedcap_max_disable_on_ramps 0 "disable upper baseline velocity bound on ramps to preserve the old rampjump style"
+ set sv_player_jumpanim_minfall 48 "minimum distance player has to have below their feet before the jump animation will be activated (only when falling, +jump will play anim instantly)"
  
  seta sv_precacheplayermodels 1
  seta sv_precacheweapons 0
@@@ -438,7 -433,7 +439,7 @@@ set bot_wander_enable 1 "Have bots wand
  // general bot AI cvars
  set bot_ai_thinkinterval 0.05
  set bot_ai_strategyinterval 5 "How often a new objective is chosen"
- set bot_ai_enemydetectioninterval 3 "How often bots pick a new target"
+ set bot_ai_enemydetectioninterval 2 "How often bots pick a new target"
  set bot_ai_enemydetectionradius 10000 "How far bots can see enemies"
  set bot_ai_dodgeupdateinterval 0.2 "How often scan for items to dodge. Currently not in use."
  set bot_ai_chooseweaponinterval 0.5 "How often the best weapon according to the situation will be chosen"
@@@ -463,8 -458,8 +464,8 @@@ set bot_ai_weapon_combo_threshold 0.4      "
  set bot_ai_friends_aware_pickup_radius "500"  "Bots will not pickup items if a team mate is this distance near the item"
  set bot_ai_ignoregoal_timeout 3       "Ignore goals making bots to get stuck in front of a wall for N seconds"
  set bot_ai_bunnyhop_skilloffset 7     "Bots with skill equal or greater than this value will perform the  \"bunnyhop\" technique"
- set bot_ai_bunnyhop_startdistance 100 "Run to goals located further than this distance"
- set bot_ai_bunnyhop_stopdistance 125 "Stop jumping after reaching this distance to the goal"
+ set bot_ai_bunnyhop_startdistance 200 "Run to goals located further than this distance"
+ set bot_ai_bunnyhop_stopdistance 200 "Stop jumping after reaching this distance to the goal"
  set bot_ai_bunnyhop_firstjumpdelay 0.2 "Start running to the goal only if it was seen for more than N seconds"
  set bot_god 0 "god mode for bots"
  set bot_ai_navigation_jetpack 0 "Enable bots to navigate maps using the jetpack"
@@@ -495,8 -490,8 +496,8 @@@ alias g_waypointeditor_unreachable "imp
  
  locs_enable 0
  pausable 0
- seta g_spawnshieldtime 1.000000 "number of seconds you are invincible after you spawned, this shield is lost after you fire"
- seta g_antilag 2      "AntiLag (0 = no AntiLag, 1 = verified client side hit scan, 2 = server side hit scan in the past, 3 = unverified client side hit scan)"
+ set g_spawnshieldtime 1 "number of seconds you are invincible after you spawned, this shield is lost after you fire"
+ set g_antilag 2       "AntiLag (0 = no AntiLag, 1 = verified client side hit scan, 2 = server side hit scan in the past, 3 = unverified client side hit scan)"
  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)"
@@@ -542,7 -537,6 +543,6 @@@ seta g_maplist_selectrandom 0      "if 1, a 
  seta g_maplist_shuffle 1      "new randomization method: like selectrandom, but avoid playing the same maps in short succession. This works by taking out the first element and inserting it into g_maplist with a bias to the end of the list"
  set g_maplist_check_waypoints 0       "when 1, maps are skipped if there currently are bots, but the map has no waypoints"
  set samelevel 0 "when 1, always play the same level over and over again"
- set g_maxpushtime 8.0 "timeout for kill credit when your damage knocks someone into a death trap"
  
  set g_cloaked 0 "display all players mostly invisible"
  set g_player_alpha 1
@@@ -558,6 -552,7 +558,7 @@@ alias clearmap "disconnect
  
  set g_grappling_hook 0 "let players spawn with the grappling hook which allows them to pull themselves up"
  
+ set g_invincible_projectiles 0 "set to 1 to disable any damage to projectiles in all balance configs, regardless of g_projectiles_damage"
  set g_dodging 0 "set to 1 to enable dodging in games"
  set g_rocket_flying 0 "set to 1 to enable rocket flying in all balance configs"
  
@@@ -712,8 -707,8 +713,8 @@@ set g_ctf_reverse 0        "if enabled, flags 
  set g_balance_ctf_delay_collect 1.0
  set g_balance_ctf_damageforcescale 1
  
- set g_ctf_shield_max_ratio 0  "shield at most 0% of a team from the enemy flag (try: 0.4 for 40%)"
- set g_ctf_shield_min_negscore 20      "shield the player from the flag if he's got -20 points or less"
+ set g_ctf_shield_max_ratio 0  "shield at most this percentage of a team from the enemy flag (try: 0.4 for 40%)"
+ set g_ctf_shield_min_negscore 20      "shield the player from the flag if he's got this negative amount of points or less"
  set g_ctf_shield_force 100    "push force of the shield"
  
  // fun for server admins
@@@ -814,6 -809,7 +815,7 @@@ set g_arena_powerups 0     "enables powerup
  set g_ca 0 "Clan Arena: Played in rounds, once you're dead you're out! The team with survivors wins the round."
  set g_ca_point_limit 10 "point limit 10 is standard for clan arena"
  set g_ca_point_leadlimit 0
+ set g_ca_spectate_enemies 0 "Allow spectating enemy player by dead player during clan arena games."
  set g_ca_warmup 10 "how long the players will have time to run around the map before the round starts"
  
  // onslaught
@@@ -1044,8 -1040,7 +1046,7 @@@ bind MWHEELDOWN weappre
  bind r reload
  bind BACKSPACE dropweapon
  bind g dropweapon
- // TODO change this to "use" once we can
- bind f +use
+ bind f use
  
  // misc
  bind e +hook
@@@ -1057,6 -1052,7 +1058,7 @@@ bind t messagemod
  bind y messagemode2
  bind z messagemode2
  bind u "+con_chat_maximize"
+ bind m +hud_panel_radar_maximized
  bind i +show_info
  bind PAUSE pause
  bind F10 quit
@@@ -1192,8 -1188,7 +1194,7 @@@ set g_campaign 
  set g_campaign_forceteam 0 "Forces the player to a given team in campaign mode, 1 = red, 2 = blue, 3 = yellow, 4 = pink"
  seta g_campaign_name "xonoticbeta"
  set g_campaign_skill 0
- set g_campaignxonotic20_index 0
- set g_campaignxonotic25_index 1
+ alias warp "sv_cmd warp $*"
  
  alias singleplayer_start "g_campaign_index 0; set scmenu_campaign_goto 0"
  alias singleplayer_continue "set scmenu_campaign_goto -1"
@@@ -1246,15 -1241,16 +1247,16 @@@ 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"
  
+ set sv_waypointsprite_deployed_lifetime 10
+ set sv_waypointsprite_deadlifetime 1
+ set sv_waypointsprite_limitedrange 5120
  seta g_waypointsprite_uppercase 1
  set g_waypointsprite_normdistance 512
  set g_waypointsprite_minscale 0.5
  set g_waypointsprite_minalpha 0.4
  set g_waypointsprite_distancealphaexponent 2
  set g_waypointsprite_timealphaexponent 1
- set g_waypointsprite_deployed_lifetime 10
- set g_waypointsprite_deadlifetime 1
- set g_waypointsprite_limitedrange 5120
  set g_waypointsprite_stuffbinds 0
  seta g_waypointsprite_scale 1
  seta g_waypointsprite_fontsize 12
@@@ -1412,11 -1408,12 +1414,12 @@@ alias +userbind "_userbind_call userbin
  alias -userbind "_userbind_call userbind${1}_release"
  
  // we must change its default from 1.0 to 1 to be consistent with menuqc
- seta slowmo 1
+ set slowmo 1
  
  seta menu_skin "luminos"
  set menu_slowmo 1
  seta menu_sounds 0 "enables menu sound effects. 1 enables click sounds, 2 also enables hover sounds"
+ seta menu_tooltips 1 "menu tooltips: 0 disabled, 1 enabled, 2 also shows cvar or console command (when available) changed or executed by the item"
  set menu_picmip_bypass 0 "bypass texture quality enforcement based on system resources, not recommended and may cause crashes!"
  
  r_textbrightness 0.2
@@@ -1442,7 -1439,7 +1445,7 @@@ seta hud_configure_grid_alpha 0.15 "alp
  
  seta sbar_info_pos 0 "Y-axis distance from lower right corner for engine info prints"
  
- // user preference cvars (i.e. shouldn't be adjusted by a skin config) 
+ // user preference cvars (i.e. shouldn't be adjusted by a skin config)
  seta hud_panel_weapons_label 1 "1 = show number of weapon, 2 = show bound key of weapon"
  seta hud_panel_weapons_complainbubble_time 1 "time that a new entry stays until it fades out"
  seta hud_panel_weapons_complainbubble_fadetime 0.25 "fade out time"
@@@ -1453,6 -1450,7 +1456,7 @@@ seta hud_panel_weapons_ammo_full_nails 
  seta hud_panel_weapons_ammo_full_cells 80 "show 100% of the status bar at this ammo count"
  seta hud_panel_weapons_ammo_full_rockets 80 "show 100% of the status bar at this ammo count"
  seta hud_panel_weapons_ammo_full_fuel 100 "show 100% of the status bar at this ammo count"
+ seta hud_panel_weapons_onlyowned 1 "show only owned weapons"
  
  seta hud_panel_ammo_maxammo "40" "when you have this much ammo, the ammo status bar is full"
  
@@@ -1474,6 -1472,11 +1478,11 @@@ seta hud_panel_radar_scale 4096 "distan
  seta hud_panel_radar_rotation 0       "rotation mode: you set what points up. 0 = player, 1 = west, 2 = south, 3 = east, 4 = north"
  seta hud_panel_radar_zoommode 0       "zoom mode: 0 = zoomed by default, 1 = zoomed when +zoom, 2 = always zoomed, 3 = always zoomed out"
  alias hud_panel_radar_rotate "toggle hud_panel_radar_rotation 0 1 2 3 4"
+ seta hud_panel_radar_maximized_scale 8192 "distance you can see on the radar when maximized"
+ seta hud_panel_radar_maximized_size "0.5 0.5" "size of the radar when maximized"
+ alias +hud_panel_radar_maximized "cl_cmd hud_panel_radar_maximized 1"
+ alias -hud_panel_radar_maximized "cl_cmd hud_panel_radar_maximized 0"
+ alias hud_panel_radar_maximized "cl_cmd hud_panel_radar_maximized"
  
  seta hud_panel_score_rankings 0 "show rankings: 1 always show my own score; 2 pure rankings"
  
@@@ -1533,6 -1536,7 +1542,7 @@@ seta hud_contents_water_color "0.4 0.3 
  
  seta hud_shownames 1 "draw names and health/armor of nearby players"
  seta hud_shownames_enemies 2 "1 = draw names of enemies you point at (TODO), 2 = draw names of all enemies in view"
+ seta hud_shownames_self 0 "also include your own name to be shown when third person camera mode is on (chase_active/cl_eventchase)"
  seta hud_shownames_status 1 "1 = draw health/armor status of teammates"
  seta hud_shownames_statusbar_height 4 "height of status bar"
  seta hud_shownames_aspect 8 "aspect ratio of total drawing area per name"
@@@ -1957,6 -1961,7 +1967,7 @@@ set g_triggerimpulse_accel_power 1 "tri
  set g_triggerimpulse_accel_multiplier 1 "trigger_impulse accelerator multiplier (applied AFTER the power)"
  set g_triggerimpulse_directional_multiplier 1 "trigger_impulse directional field multiplier"
  set g_triggerimpulse_radial_multiplier 1 "trigger_impulse radial field multiplier"
+ set the_goggles "they do nothing" "but the googles, they do"
  
  seta g_ghost_items 1 "enable ghosted items (when between 0 and 1, overrides the alpha value)"
  seta g_ghost_items_color "-1 -1 -1" "color of ghosted items, 0 0 0 leaves the color unchanged"
@@@ -1999,6 -2004,9 +2010,9 @@@ set _origin "0 0 0
  set _campaign_index ""
  set _campaign_name ""
  
+ // debug
+ set _independent_players 0 "DO NOT TOUCH"
  // define some engine cvars that we need even on dedicated server
  set r_showbboxes 0
  
@@@ -2159,11 -2167,23 +2173,23 @@@ set g_playerstats_debug 0 "when 1, play
  
  // create this cvar in case the engine did not
  set snd_soundradius 1200
+ set snd_softclip 1
+ set snd_maxchannelvolume 0
+ set snd_streaming_length 2
+ seta menu_snd_attenuation_method 1 "Use exponential instead of linear falloff for sound attenuation"
+ alias snd_attenuation_method_0 "set menu_snd_attenuation_method 0; set snd_soundradius 1200; set snd_attenuation_exponent 1; set snd_attenuation_decibel 0" // Quake default
+ alias snd_attenuation_method_1 "set menu_snd_attenuation_method 1; set snd_soundradius 2400; set snd_attenuation_exponent 4; set snd_attenuation_decibel 0" // nice approximation for method 2
+ alias snd_attenuation_method_2 "set menu_snd_attenuation_method 2; set snd_soundradius 1200; set snd_attenuation_exponent 0; set snd_attenuation_decibel 10" // warning: plays sounds within up to 6000qu
+ snd_attenuation_method_1
  
  // declare the channels we use
  seta snd_channel8volume 1 "QuakeC controlled background music volume"
  seta snd_channel9volume 1 "QuakeC controlled ambient sound volume"
  
+ // sound randomization
+ snd_identicalsoundrandomization_time -0.1
+ snd_identicalsoundrandomization_tics    1
  // loading screen
  scr_loadingscreen_background 0
  scr_loadingscreen_barcolor "0 0.5 1"
diff --combined effectinfo.txt
index f69cdc907ddce77eacc3179c4fc104b4c98c37db,70f5fbb4c6f8fd7f03468ae16cc2e9e7bd80399d..b90186feca2b2bc060a8857a0c4b7893a7bed2e4
@@@ -1225,7 -1225,7 +1225,7 @@@ trailspacing 
  type static
  color 0xffdf72 0x811200
  tex 48 55
- size 1 2
+ size 5 2
  sizeincrease -15
  alpha 100 144 988
  airfriction 8
@@@ -6407,647 -6407,3 +6407,647 @@@ velocityoffset 0 0 20
  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 0c7643d0efa2019452f9eb1468cd572adf36fc9c,9aa81be98e0ccf5b555705bfaf10d1761a0a18bd..7e480ada3bf179bdfc20ed86dad45c958a40ab34
@@@ -25,17 -25,17 +25,17 @@@ void cvar_clientsettemp_restore(
                        cvar_set(e.netname, e.message);
  }
  
- void() menu_show_error =
+ void menu_show_error()
  {
        drawstring('0 200 0', _("ERROR - MENU IS VISIBLE BUT NO MENU WAS DEFINED!"), '8 8 0', '1 0 0', 1, 0);
- };
+ }
  
  // CSQC_Init : Called every time the CSQC code is initialized (essentially at map load)
  // Useful for precaching things
  
- void() menu_sub_null =
+ void menu_sub_null()
  {
- };
+ }
  
  #ifdef USE_FTE
  float __engine_check;
@@@ -358,7 -358,7 +358,7 @@@ float CSQC_ConsoleCommand(string strMes
        argc = tokenize_console(strMessage);
  
        // Acquire Command
-       local string strCmd;
+       string strCmd;
        strCmd = argv(0);
  
        if(strCmd == "hud_configure") { // config hud
@@@ -507,6 -507,13 +507,13 @@@ void GameCommand(string msg
        if(cmd == "mv_download") {
                Cmd_MapVote_MapDownload(argc);
        }
+       else if(cmd == "hud_panel_radar_maximized")
+       {
+               if(argc == 1)
+                       hud_panel_radar_maximized = !hud_panel_radar_maximized;
+               else
+                       hud_panel_radar_maximized = (stof(argv(1)) != 0);
+       }
        else if(cmd == "settemp") {
                cvar_clientsettemp(argv(1), argv(2));
        }
          {
              vote_active = 0; // force the panel to disappear right as we have selected the value (to prevent it from fading out in the normal vote panel pos)
              vote_prev = 0;
-             cvar_set("cl_allow_uid2name", "1");
+             localcmd("setreport cl_allow_uid2name 1\n");
              vote_change = -9999;
                        uid2name_dialog = 0;
          }
          {
              vote_active = 0;
              vote_prev = 0;
-             cvar_set("cl_allow_uid2name", "0");
+             localcmd("setreport cl_allow_uid2name 0\n");
              vote_change = -9999;
                        uid2name_dialog = 0;
          }
  // In the case of mouse input, nPrimary is xdelta, nSecondary is ydelta.
  float CSQC_InputEvent(float bInputType, float nPrimary, float nSecondary)
  {
-       local float bSkipKey;
+       float bSkipKey;
        bSkipKey = false;
  
        if (HUD_Panel_InputEvent(bInputType, nPrimary, nSecondary))
@@@ -937,7 -944,7 +944,7 @@@ void Ent_ReadAccuracy(void
  void Ent_RadarLink();
  void Ent_Init();
  void Ent_ScoresInfo();
- void(float bIsNewEntity) CSQC_Ent_Update =
+ void CSQC_Ent_Update(float bIsNewEntity)
  {
        float t;
        float savetime;
                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));
        }
  
        time = savetime;
- };
+ }
  // Destructor, but does NOT deallocate the entity by calling remove(). Also
  // used when an entity changes its type. For an entity that someone interacts
  // with others, make sure it can no longer do so.
@@@ -1314,31 -1320,6 +1321,6 @@@ void Net_ReadPingPLReport(
        playerslots[e].ping_movementloss = ml / 255.0;
  }
  
- void Net_Notify() {
-       float type;
-       type = ReadByte();
-       if(type == CSQC_KILLNOTIFY)
-       {
-               HUD_KillNotify(ReadString(), ReadString(), ReadString(), ReadShort(), ReadByte());
-       }
-       else if(type == CSQC_CENTERPRINT)
-       {
-               HUD_Centerprint(ReadString(), ReadString(), ReadShort(), ReadByte());
-       }
-       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() {
        complain_weapon = ReadByte();
  
  // Return value should be 1 if CSQC handled the temporary entity, otherwise return 0 to have the engine process the event.
  float CSQC_Parse_TempEntity()
  {
-       local float bHandled;
+       float bHandled;
                bHandled  = true;
        // Acquire TE ID
-       local float nTEID;
+       float nTEID;
                nTEID = ReadByte();
  
                // NOTE: Could just do return instead of break...
                        announce_snd = strzone(ReadString());
                        bHandled = true;
                        break;
-               case TE_CSQC_NOTIFY:
-                       Net_Notify();
+               case TE_CSQC_KILLNOTIFY:
+                       HUD_KillNotify(ReadString(), ReadString(), ReadString(), ReadShort(), ReadByte());
+                       bHandled = true;
+                       break;
+               case TE_CSQC_KILLCENTERPRINT:
+                       HUD_KillCenterprint(ReadString(), ReadString(), ReadShort(), ReadByte());
+                       bHandled = true;
+                       break;
+               case TE_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);
                        bHandled = true;
                        break;
                case TE_CSQC_WEAPONCOMPLAIN:
index df681434907bba9629e3d19c9d74b47056921637,7259761c204406119b377876e73bd7377c6db012..308f0f4adfbb99e048ddb7c02e9ffe93842f0e14
@@@ -121,6 -121,7 +121,7 @@@ float autocvar_g_balance_damagepush_spe
  float autocvar_g_balance_tuba_attenuation;
  float autocvar_g_balance_tuba_fadetime;
  float autocvar_g_balance_tuba_volume;
+ float autocvar_g_balance_tuba_pitchstep;
  float autocvar_g_warmup_limit;
  var float autocvar_g_waypointsprite_uppercase = 1;
  var float autocvar_g_waypointsprite_alpha = 1;
@@@ -273,6 -274,8 +274,8 @@@ float autocvar_hud_panel_pressedkeys_as
  float autocvar_hud_panel_racetimer;
  float autocvar_hud_panel_radar;
  float autocvar_hud_panel_radar_foreground_alpha;
+ float autocvar_hud_panel_radar_maximized_scale;
+ vector autocvar_hud_panel_radar_maximized_size;
  float autocvar_hud_panel_radar_rotation;
  float autocvar_hud_panel_radar_scale;
  float autocvar_hud_panel_radar_zoommode;
@@@ -303,6 -306,7 +306,7 @@@ float autocvar_hud_panel_weapons_compla
  float autocvar_hud_panel_weapons_complainbubble_time;
  var float autocvar_hud_panel_weapons_fade = 1;
  float autocvar_hud_panel_weapons_label;
+ float autocvar_hud_panel_weapons_onlyowned;
  float autocvar_hud_panel_weapons_timeout;
  float autocvar_hud_panel_weapons_timeout_effect;
  float autocvar_hud_progressbar_alpha;
@@@ -310,6 -314,7 +314,7 @@@ float autocvar_hud_showbinds
  float autocvar_hud_showbinds_limit;
  float autocvar_hud_shownames;
  float autocvar_hud_shownames_enemies;
+ float autocvar_hud_shownames_self;
  float autocvar_hud_shownames_status;
  float autocvar_hud_shownames_statusbar_height;
  float autocvar_hud_shownames_aspect;
@@@ -362,8 -367,3 +367,8 @@@ var float autocvar_cl_eventchase_distan
  var float autocvar_cl_eventchase_speed = 1.3;
  float autocvar_cl_lerpexcess;
  string autocvar__togglezoom;
 +float autocvar_cl_damageeffect_player;
 +float autocvar_cl_damageeffect_gibs;
 +float autocvar_cl_damageeffect_gibs_randomize;
 +float autocvar_cl_damageeffect_lifetime;
 +float autocvar_cl_damageeffect_lifetime_max;
diff --combined qcsrc/client/damage.qc
index c264dd5eb61ff548b46461cda67bb2f1bcf67275,51029396a299e46ce1270781b905ed7c9db99f25..fa930e3231ab7a156753465d37abf216a6740db3
@@@ -145,6 -145,7 +145,7 @@@ void Ent_DamageInfo(float isNew
        
        if(DEATH_ISTURRET(w_deathtype))
        {           
+           string _snd;
            traceline(w_org - normalize(force) * 16, w_org + normalize(force) * 16, MOVE_NOMONSTERS, world);
            if(trace_plane_normal != '0 0 0')       
              w_backoff = trace_plane_normal;
            {   
               case DEATH_TURRET_EWHEEL:
                  sound(self, CH_SHOTS, "weapons/laserimpact.wav", VOL_BASE, ATTN_MIN);
-                 pointparticles(particleeffectnum("electro_impact"), self.origin, w_backoff * 1000, 1);
+                 pointparticles(particleeffectnum("laser_impact"), self.origin, w_backoff * 1000, 1);
                  break;
               
               case DEATH_TURRET_FLAC:
-                 vector org2;
-                 org2 = w_org + w_backoff * 6;
-                 pointparticles(particleeffectnum("hagar_explode"), org2, '0 0 0', 1);
-                 if (w_random<0.15)
-                     sound(self, CH_SHOTS, "weapons/hagexp1.wav", VOL_BASE, ATTN_NORM);
-                 else if (w_random<0.7)
-                     sound(self, CH_SHOTS, "weapons/hagexp2.wav", VOL_BASE, ATTN_NORM);
-                 else
-                     sound(self, CH_SHOTS, "weapons/hagexp3.wav", VOL_BASE, ATTN_NORM);
-                 
+                 pointparticles(particleeffectnum("hagar_explode"), w_org, '0 0 0', 1);
+                 _snd = strcat("weapons/hagexp", ftos(1 + rint(random() * 2)), ".waw");
+                 sound(self, CH_SHOTS, _snd, VOL_BASE, ATTN_NORM);                
                  break;
                  
               case DEATH_TURRET_MLRS:
               
               case DEATH_TURRET_MACHINEGUN:
               case DEATH_TURRET_WALKER_GUN:
-                 string _snd;
                  _snd = strcat("weapons/ric", ftos(1 + rint(random() * 2)), ".waw");
                  sound(self, CH_SHOTS, _snd, VOL_BASE, ATTN_NORM);
                  pointparticles(particleeffectnum("machinegun_impact"), self.origin, w_backoff * 1000, 1);
@@@ -234,109 -227,3 +227,109 @@@ void DamageInfo_Precache(
        for(i = WEP_FIRST; i <= WEP_LAST; ++i)
                (get_weaponinfo(i)).weapon_func(WR_PRECACHE);
  }
 +
 +// damage effect
 +
 +.entity dmgent;
 +.float dmgpartnum, dmgtime;
 +.float lifetime;
 +
 +void Ent_DamageEffect_Think()
 +{
 +      self.nextthink = time;
 +
 +      float foundgib;
 +      vector org;
 +
 +      if(time >= self.lifetime)
 +      {
 +              remove(self);
 +              self = world;
 +              return;
 +      }
 +      if(self.dmgtime > time)
 +              return;
 +      org = getplayerorigin(self.team);
 +      if(org == GETPLAYERORIGIN_ERROR)
 +              return;
 +
 +      // 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 particles to the gibs instead.
 +      entity head;
 +      for(head = world; (head = find(head, classname, "gib")); )
 +      {
 +              if(head.team == self.team)
 +              {
 +                      if(autocvar_cl_damageeffect_gibs)
 +                      {
 +                              if(autocvar_cl_damageeffect_gibs_randomize >= random())
 +                                      pointparticles(self.dmgpartnum, head.origin, '0 0 0', 1);
 +                              self.dmgtime = time + autocvar_cl_damageeffect_gibs;
 +                      }
 +                      foundgib = TRUE;
 +              }
 +      }
 +
 +      if(foundgib || !autocvar_cl_damageeffect_player)
 +              return; // don't show effects on the invisible dead body if gibs exist
 +      if(self.team == player_localentnum - 1 && !autocvar_chase_active)
 +              return; // if we aren't in third person mode, hide own damage effect
 +
 +      // Now apply the effect to actual players
 +      pointparticles(self.dmgpartnum, org, '0 0 0', 1);
 +      self.dmgtime = time + autocvar_cl_damageeffect_player;
 +}
 +
 +void Ent_DamageEffect()
 +{
 +      float dmg, type, specnum1, specnum2, entnumber, life;
 +      vector org;
 +      string specstr, effectnum;
 +      entity e;
 +
 +      dmg = ReadByte(); // damage amount
 +      type = ReadByte(); // damage weapon
 +      specnum1 = ReadByte(); // player species
 +      entnumber = ReadByte(); // player entnum
 +
 +      if(!autocvar_cl_damageeffect_player && !autocvar_cl_damageeffect_gibs)
 +              return;
 +      if(autocvar_cl_gentle || autocvar_cl_gentle_damage)
 +              return;
 +
 +      specnum2 = (specnum1 & 0x78) / 8; // blood type: using four bits (0..7, bit indexes 3,4,5)
 +      specstr = species_prefix(specnum2);
 +      life = bound(0, dmg * autocvar_cl_damageeffect_lifetime, autocvar_cl_damageeffect_lifetime_max);
 +
 +      e = get_weaponinfo(type);
 +      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
 +      }
 +
 +      // if the player already has a damage effect, update it instead of spawning a new one
 +      entity head;
 +      for(head = world; (head = find(head, classname, "damageeffect")); )
 +      {
 +              if(head.team == entnumber - 1)
 +              {
 +                      head.dmgpartnum = particleeffectnum(effectnum);
 +                      head.lifetime += life;
 +                      return;
 +              }
 +      }
 +
 +      entity e;
 +      e = spawn();
 +      e.classname = "damageeffect";
 +      e.team = entnumber - 1;
 +      e.dmgpartnum = particleeffectnum(effectnum);
 +      e.lifetime = time + life;
 +      e.think = Ent_DamageEffect_Think;
 +      e.nextthink = time;
 +}
index 634ab397bdbbd2dc12c4d768832dd7367fa6be7b,add142d22798664d12b791bb100dc7f5e1188806..bc9f5c8f1528d21a392bf6363c60db11187bb84e
@@@ -57,8 -57,10 +57,10 @@@ const float TE_CSQC_TEAMNAGGER = 106
  const float TE_CSQC_PINGPLREPORT = 107;
  const float TE_CSQC_ANNOUNCE = 110;
  const float TE_CSQC_TARGET_MUSIC = 111;
- const float TE_CSQC_NOTIFY = 112;
- const float TE_CSQC_WEAPONCOMPLAIN = 113;
+ const float TE_CSQC_KILLNOTIFY = 112;
+ const float TE_CSQC_KILLCENTERPRINT = 113;
+ const float TE_CSQC_CENTERPRINT_GENERIC = 114;
+ const float TE_CSQC_WEAPONCOMPLAIN = 115;
  const float TE_CSQC_NEX_SCOPE = 116;
  const float TE_CSQC_MINELAYER_MAXMINES = 117;
  const float TE_CSQC_HAGAR_MAXROCKETS = 118;
@@@ -79,10 -81,6 +81,6 @@@ const float RACE_NET_SERVER_RANKINGS = 
  const float RACE_NET_SERVER_STATUS = 12;
  const float RANKINGS_CNT = 15;
  
- const float CSQC_KILLNOTIFY = 0;
- const float CSQC_CENTERPRINT = 1;
- const float CSQC_CENTERPRINT_GENERIC = 2;
  const float ENT_CLIENT = 0;
  const float ENT_CLIENT_DEAD = 1;
  const float ENT_CLIENT_ENTCS = 2;
@@@ -116,7 -114,6 +114,7 @@@ 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;
@@@ -326,6 -323,7 +324,7 @@@ const float STAT_HIT_TIME = 54
  const float STAT_TYPEHIT_TIME = 55;
  const float STAT_LAYED_MINES = 56;
  const float STAT_HAGAR_LOAD = 57;
+ const float STAT_SWITCHINGWEAPON = 58;
  
  // see DP source, quakedef.h
  const float STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW = 222;
@@@ -444,6 -442,7 +443,7 @@@ float CH_WEAPON_B = 5; // only on playe
  float CH_PAIN = 6; // only on players and csqc
  float CH_PAIN_SINGLE = 6; // only on players and csqc
  float CH_PLAYER = 7; // only on players and entities
+ float CH_TUBA = 5; // only on csqc
  #else
  float CH_INFO = 0;
  float CH_TRIGGER = -3;
@@@ -459,11 -458,13 +459,13 @@@ float CH_WEAPON_B = -1
  float CH_PAIN = -6;
  float CH_PAIN_SINGLE = 6;
  float CH_PLAYER = -7;
+ float CH_TUBA = 5;
  #endif
  
  float ATTN_NONE                               = 0;
  float ATTN_MIN                                = 0.015625;
  float ATTN_NORM                               = 0.5;
+ float ATTN_LARGE                              = 1;
  float ATTN_IDLE                               = 2;
  float ATTN_STATIC                             = 3;
  float ATTN_MAX                                = 3.984375;
@@@ -574,9 -575,9 +576,9 @@@ float DEATH_TURRET_LAST            = 10
  float DEATH_WEAPONMASK = 0xFF;
  float DEATH_HITTYPEMASK = 0x1F00; // which is WAY below 10000 used for normal deaths
  float HITTYPE_SECONDARY = 0x100;
- float HITTYPE_SPLASH = 0x200;
+ float HITTYPE_SPLASH = 0x200; // automatically set by RadiusDamage
  float HITTYPE_BOUNCE = 0x400;
- float HITTYPE_HEADSHOT = 0x800;
+ float HITTYPE_HEADSHOT = 0x800; // automatically set by Damage (if headshotbonus is set)
  float HITTYPE_RESERVED = 0x1000; // unused yet
  
  // macros to access these
@@@ -612,6 -613,7 +614,7 @@@ float CPID_GAME_STARTING = 7
  float CPID_TIMEOUT_COUNTDOWN = 8;
  float CPID_MOTD = 9;
  float CPID_KH_MSG = 10;
+ float CPID_PREVENT_JOIN = 11;
  
  // CSQC centerprint/notify message types
  float MSG_SUICIDE = 0;
@@@ -713,3 -715,4 +716,4 @@@ float HUD_MENU_ENABLE              = 0
  
  #define SERVERFLAG_ALLOW_FULLBRIGHT 1
  #define SERVERFLAG_TEAMPLAY 2
+ #define SERVERFLAG_PLAYERSTATS 4
index 9182452e939d205b91051fc92ee9b6c3b84a99be,f9fb0aa61ebd0459f1621ec91074021447dc5468..5337219f5573223b46dc7ecc6bc0cea1c78eee37
@@@ -21,10 -21,13 +21,13 @@@ void WeaponStats_ready(entity fh, entit
        switch(status)
        {
                case URL_READY_CANWRITE:
-                       // url_fopen returned, we can write
+                       // 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"));
+ #ifdef WATERMARK
+                       url_fputs(fh, strcat("#version ", WATERMARK(), "\n"));
+ #endif
                        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");
@@@ -43,9 -46,7 +46,7 @@@
                                        }
                                }
                        url_fputs(fh, "#end\n\n");
-                       url_fclose(fh, WeaponStats_ready, world);
-                       buf_del(weaponstats_buffer);
-                       weaponstats_buffer = -1;
+                       url_fclose(fh);
                        break;
                case URL_READY_CANREAD:
                        // url_fclose is processing, we got a response for writing the data
                        while((s = url_fgets(fh)))
                                print("  ", s, "\n");
                        print("End of response.\n");
-                       url_fclose(fh, WeaponStats_ready, world);
+                       url_fclose(fh);
                        break;
                case URL_READY_CLOSED:
                        // url_fclose has finished
                        print("Weapon stats written\n");
+                       buf_del(weaponstats_buffer);
+                       weaponstats_buffer = -1;
                        break;
                case URL_READY_ERROR:
                default:
                        print("Weapon stats writing failed: ", ftos(status), "\n");
+                       buf_del(weaponstats_buffer);
+                       weaponstats_buffer = -1;
                        break;
        }
  }
@@@ -73,7 -78,7 +78,7 @@@ void WeaponStats_Shutdown(
                return;
        if(autocvar_sv_weaponstats_file != "")
        {
-               url_fopen(autocvar_sv_weaponstats_file, FILE_APPEND, WeaponStats_ready, world);
+               url_multi_fopen(autocvar_sv_weaponstats_file, FILE_APPEND, WeaponStats_ready, world);
        }
        else
        {
@@@ -121,7 -126,7 +126,7 @@@ void WeaponStats_LogKill(float awep, fl
  
  void CopyBody(float keepvelocity)
  {
-       local entity oldself;
+       entity oldself;
        if (self.effects & EF_NODRAW)
                return;
        oldself = self;
        self.colormap = oldself.colormap;
        self.glowmod = oldself.glowmod;
        self.iscreature = oldself.iscreature;
+       self.damagedbycontents = oldself.damagedbycontents;
        self.angles = oldself.angles;
        self.avelocity = oldself.avelocity;
        self.classname = "body";
  
        Drag_MoveDrag(oldself, self);
  
 +      self.owner = oldself;
        self = oldself;
  }
  
@@@ -197,74 -202,35 +203,35 @@@ float player_getspecies(
  
  void player_setupanimsformodel()
  {
-       local string animfilename;
-       local float animfile;
        // defaults for legacy .zym models without animinfo files
-       self.anim_die1 = '0 1 0.5'; // 2 seconds
-       self.anim_die2 = '1 1 0.5'; // 2 seconds
-       self.anim_draw = '2 1 3'; // TODO: analyze models and set framerate
-       self.anim_duck = '3 1 100'; // this anim seems bogus in most models, so make it play VERY briefly!
-       self.anim_duckwalk = '4 1 1';
-       self.anim_duckjump = '5 1 100'; // zym anims keep playing until changed, so this only has to start the anim, landing will end it
-       self.anim_duckidle = '6 1 1';
-       self.anim_idle = '7 1 1';
-       self.anim_jump = '8 1 100'; // zym anims keep playing until changed, so this only has to start the anim, landing will end it
-       self.anim_pain1 = '9 1 2'; // 0.5 seconds
-       self.anim_pain2 = '10 1 2'; // 0.5 seconds
-       self.anim_shoot = '11 1 5'; // TODO: analyze models and set framerate
-       self.anim_taunt = '12 1 0.33'; // FIXME?  there is no code using this anim
-       self.anim_run = '13 1 1';
-       self.anim_runbackwards = '14 1 1';
-       self.anim_strafeleft = '15 1 1';
-       self.anim_straferight = '16 1 1';
-       self.anim_dead1 = '17 1 1';
-       self.anim_dead2 = '18 1 1';
-       self.anim_forwardright = '19 1 1';
-       self.anim_forwardleft = '20 1 1';
-       self.anim_backright = '21 1 1';
-       self.anim_backleft  = '22 1 1';
-       self.anim_melee = '23 1 1';
-       animparseerror = FALSE;
-       animfilename = strcat(self.model, ".animinfo");
-       animfile = fopen(animfilename, FILE_READ);
-       if (animfile >= 0)
-       {
-               self.anim_die1         = animparseline(animfile);
-               self.anim_die2         = animparseline(animfile);
-               self.anim_draw         = animparseline(animfile);
-               self.anim_duck         = animparseline(animfile);
-               self.anim_duckwalk     = animparseline(animfile);
-               self.anim_duckjump     = animparseline(animfile);
-               self.anim_duckidle     = animparseline(animfile);
-               self.anim_idle         = animparseline(animfile);
-               self.anim_jump         = animparseline(animfile);
-               self.anim_pain1        = animparseline(animfile);
-               self.anim_pain2        = animparseline(animfile);
-               self.anim_shoot        = animparseline(animfile);
-               self.anim_taunt        = animparseline(animfile);
-               self.anim_run          = animparseline(animfile);
-               self.anim_runbackwards = animparseline(animfile);
-               self.anim_strafeleft   = animparseline(animfile);
-               self.anim_straferight  = animparseline(animfile);
-               self.anim_forwardright = animparseline(animfile);
-               self.anim_forwardleft  = animparseline(animfile);
-               self.anim_backright    = animparseline(animfile);
-               self.anim_backleft     = animparseline(animfile);
-               self.anim_melee        = animparseline(animfile);
-               fclose(animfile);
-               // derived anims
-               self.anim_dead1 = '0 1 1' + '1 0 0' * (self.anim_die1_x + self.anim_die1_y - 1);
-               self.anim_dead2 = '0 1 1' + '1 0 0' * (self.anim_die2_x + self.anim_die2_y - 1);
-               if (animparseerror)
-                       print("Parse error in ", animfilename, ", some player animations are broken\n");
-       }
-       else
-               dprint("File ", animfilename, " not found, assuming legacy .zym model animation timings\n");
+       self.anim_die1 = animfixfps(self, '0 1 0.5'); // 2 seconds
+       self.anim_die2 = animfixfps(self, '1 1 0.5'); // 2 seconds
+       self.anim_draw = animfixfps(self, '2 1 3');
+       // self.anim_duck = '3 1 100'; // This anim is broken, use slot 3 as a new free slot in the future ;)
+       self.anim_duckwalk = animfixfps(self, '4 1 1');
+       self.anim_duckjump = '5 1 100'; // NOTE: zym anims keep playing until changed, so this only has to start the anim, landing will end it
+       self.anim_duckidle = animfixfps(self, '6 1 1');
+       self.anim_idle = animfixfps(self, '7 1 1');
+       self.anim_jump = '8 1 100'; // NOTE: zym anims keep playing until changed, so this only has to start the anim, landing will end it
+       self.anim_pain1 = animfixfps(self, '9 1 2'); // 0.5 seconds
+       self.anim_pain2 = animfixfps(self, '10 1 2'); // 0.5 seconds
+       self.anim_shoot = animfixfps(self, '11 1 5'); // analyze models and set framerate
+       self.anim_taunt = animfixfps(self, '12 1 0.33');
+       self.anim_run = animfixfps(self, '13 1 1');
+       self.anim_runbackwards = animfixfps(self, '14 1 1');
+       self.anim_strafeleft = animfixfps(self, '15 1 1');
+       self.anim_straferight = animfixfps(self, '16 1 1');
+       self.anim_dead1 = animfixfps(self, '17 1 1');
+       self.anim_dead2 = animfixfps(self, '18 1 1');
+       self.anim_forwardright = animfixfps(self, '19 1 1');
+       self.anim_forwardleft = animfixfps(self, '20 1 1');
+       self.anim_backright = animfixfps(self, '21 1 1');
+       self.anim_backleft  = animfixfps(self, '22 1 1');
+       self.anim_melee = animfixfps(self, '23 1 1');
+       // TODO introspect models for finding right "fps" value (1/duration)
        // reset animstate now
        setanim(self, self.anim_idle, TRUE, FALSE, TRUE);
- };
+ }
  
  void player_anim (void)
  {
  
        if (!self.animstate_override)
        {
-               if (!(self.flags & FL_ONGROUND))
+               if (!(self.flags & FL_ONGROUND) || self.BUTTON_JUMP)
                {
                        if (self.crouch)
-                               setanim(self, self.anim_duckjump, FALSE, TRUE, self.restart_jump);
+                       {
+                               if (self.animstate_startframe != self.anim_duckjump_x) // don't perform another trace if already playing the crouch jump anim
+                               {
+                                       traceline(self.origin + '0 0 1' * PL_CROUCH_MIN_z, self.origin + '0 0 1' * (PL_CROUCH_MIN_z - autocvar_sv_player_jumpanim_minfall), TRUE, self);
+                                       if(!trace_startsolid && trace_fraction == 1 || !(self.animstate_startframe == self.anim_duckwalk_x || self.animstate_startframe == self.anim_duckidle_x)) // don't get stuck on non-crouch anims
+                                       {
+                                               setanim(self, self.anim_duckjump, FALSE, TRUE, self.restart_jump);
+                                               self.restart_jump = FALSE;
+                                       }
+                               }
+                       }
                        else
-                               setanim(self, self.anim_jump, FALSE, TRUE, self.restart_jump);
-                       self.restart_jump = FALSE;
+                       {
+                 if (self.animstate_startframe != self.anim_jump_x) // don't perform another trace if already playing the jump anim
+                 {
+                     traceline(self.origin + '0 0 1' * PL_MIN_z, self.origin + '0 0 1' * (PL_MIN_z - autocvar_sv_player_jumpanim_minfall), TRUE, self);
+                     if(!trace_startsolid && trace_fraction == 1 || self.animstate_startframe == self.anim_idle_x || (self.animstate_startframe == self.anim_melee_x && time - self.animstate_starttime >= 21/20)) // don't get stuck on idle animation in midair, nor melee after it finished
+                     {
+                         setanim(self, self.anim_jump, FALSE, TRUE, self.restart_jump);
+                         self.restart_jump = FALSE;
+                     }
+                 }
+                       }
                }
                else if (self.crouch)
                {
@@@ -358,7 -343,7 +344,7 @@@ void SpawnThrownWeapon (vector org, flo
  
  void PlayerCorpseDamage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
  {
-       local float take, save;
+       float take, save;
        vector v;
        Violence_GibSplash_At(hitloc, force, 2, bound(0, damage, 200) / 16, self, attacker);
  
                Violence_GibSplash(self, 1, 1, attacker);
                self.modelindex = 0; // restore later
                self.solid = SOLID_NOT; // restore later
 +              self.takedamage = DAMAGE_NO; // restore later
        }
  }
  
@@@ -415,12 -399,12 +401,12 @@@ void freezetag_CheckWinner()
  
  void PlayerDamage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
  {
-       local float take, save, waves, sdelay, dh, da, j;
+       float take, save, waves, sdelay, dh, da, j;
        vector v;
        float valid_damage_for_weaponstats;
        float excess;
  
-       if((g_arena && numspawned < 2) || (g_ca && ca_players < required_ca_players) && !inWarmupStage)
+       if((g_arena && numspawned < 2) || (g_ca && !ca_teams_ok) && !inWarmupStage)
                return;
  
        dh = max(self.health, 0);
                        self.armorvalue = self.armorvalue - save;
                        self.health = self.health - take;
                        // pause regeneration for 5 seconds
-                       self.pauseregen_finished = max(self.pauseregen_finished, time + autocvar_g_balance_pause_health_regen);
+                       if(take)
+                 self.pauseregen_finished = max(self.pauseregen_finished, time + autocvar_g_balance_pause_health_regen);
  
                        if (time > self.pain_finished)          //Don't switch pain sequences like crazy
                        {
                                if(sv_gentle < 1) {
                                        if(self.classname != "body") // pain anim is BORKED on our ZYMs, FIXME remove this once we have good models
                                        {
-                                               if (random() > 0.5)
-                                                       setanim(self, self.anim_pain1, FALSE, TRUE, TRUE);
-                                               else
-                                                       setanim(self, self.anim_pain2, FALSE, TRUE, TRUE);
+                                               if (!self.animstate_override)
+                                               {
+                                                       if (random() > 0.5)
+                                                               setanim(self, self.anim_pain1, FALSE, TRUE, TRUE);
+                                                       else
+                                                               setanim(self, self.anim_pain2, FALSE, TRUE, TRUE);
+                                               }
                                        }
  
                                        if(sound_allowed(MSG_BROADCAST, attacker))
                                }
  
                                // throw off bot aim temporarily
-                               local float shake;
+                               float shake;
                                shake = damage * 5 / (bound(0,skill,100) + 1);
                                self.v_angle_x = self.v_angle_x + (random() * 2 - 1) * shake;
                                self.v_angle_y = self.v_angle_y + (random() * 2 - 1) * shake;
                MUTATOR_CALLHOOK(PlayerDies);
                weapon_action(self.weapon, WR_PLAYERDEATH);
  
+               RemoveGrapplingHook(self);
                if(self.flagcarried)
                {
                        if(attacker.classname != "player")
diff --combined qcsrc/server/g_damage.qc
index 8985765cf077125fce57d80c4d5ada1fd40444af,5a583fc15ad101f07180877866f28641c5247c07..5c0f2c233ab0eecf50c2cfd718cd7cc1d65ba64e
@@@ -267,8 -267,7 +267,7 @@@ void LogDeath(string mode, float deatht
  void Send_KillNotification (string s1, string s2, string s3, float msg, float type)
  {
        WriteByte(MSG_ALL, SVC_TEMPENTITY);
-       WriteByte(MSG_ALL, TE_CSQC_NOTIFY);
-       WriteByte(MSG_ALL, CSQC_KILLNOTIFY);
+       WriteByte(MSG_ALL, TE_CSQC_KILLNOTIFY);
        WriteString(MSG_ALL, s1);
        WriteString(MSG_ALL, s2);
        WriteString(MSG_ALL, s3);
  }
  
  // Function is used to send a generic centerprint whose content CSQC gets to decide (gentle version or not in the below cases)
- void Send_CSQC_Centerprint(entity e, string s1, string s2, float msg, float type)
+ void Send_CSQC_KillCenterprint(entity e, string s1, string s2, float msg, float type)
  {
        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);
+                       WriteByte(MSG_ONE, TE_CSQC_KILLCENTERPRINT);
                        WriteString(MSG_ONE, s1);
                        WriteString(MSG_ONE, s2);
                        WriteShort(MSG_ONE, msg);
@@@ -309,7 -307,7 +307,7 @@@ void Obituary (entity attacker, entity 
                        if (deathtype == DEATH_TEAMCHANGE || deathtype == DEATH_AUTOTEAMCHANGE)
                                msg = ColoredTeamName(targ.team); // TODO: check if needed?
              if(!g_cts) // no "killed your own dumb self" message in CTS
-                 Send_CSQC_Centerprint(targ, msg, "", deathtype, MSG_SUICIDE);
+                 Send_CSQC_KillCenterprint(targ, msg, "", deathtype, MSG_SUICIDE);
  
                        if(deathtype != DEATH_TEAMCHANGE && deathtype != DEATH_QUIET)
                        {
  
                                GiveFrags(attacker, targ, -1, deathtype);
  
-                               Send_CSQC_Centerprint(attacker, s, "", type, MSG_KILL);
+                               Send_CSQC_KillCenterprint(attacker, s, "", type, MSG_KILL);
  
                                if (targ.killcount > 2) {
                                        msg = ftos(targ.killcount);
                                        checkrules_firstblood = TRUE;
                                        Send_KillNotification(a, "", "", KILL_FIRST_BLOOD, MSG_KILL);
                                        // TODO: make these print a newline if they dont
-                                       Send_CSQC_Centerprint(attacker, "", "", KILL_FIRST_BLOOD, MSG_KILL);
-                                       Send_CSQC_Centerprint(targ, "", "", KILL_FIRST_VICTIM, MSG_KILL);
+                                       Send_CSQC_KillCenterprint(attacker, "", "", KILL_FIRST_BLOOD, MSG_KILL);
+                                       Send_CSQC_KillCenterprint(targ, "", "", KILL_FIRST_VICTIM, MSG_KILL);
                                        PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_FIRSTBLOOD, 1);
                                        PlayerStats_Event(targ, PLAYERSTATS_ACHIEVEMENT_FIRSTVICTIM, 1);
                                }
  
                                if((autocvar_sv_fragmessage_information_typefrag) && (targ.BUTTON_CHAT)) {
-                                       Send_CSQC_Centerprint(attacker, s, GetAdvancedDeathReports(targ), KILL_TYPEFRAG, MSG_KILL);
-                                       Send_CSQC_Centerprint(targ, a, GetAdvancedDeathReports(attacker), KILL_TYPEFRAGGED, MSG_KILL);
+                                       Send_CSQC_KillCenterprint(attacker, s, GetAdvancedDeathReports(targ), KILL_TYPEFRAG, MSG_KILL);
+                                       Send_CSQC_KillCenterprint(targ, a, GetAdvancedDeathReports(attacker), KILL_TYPEFRAGGED, MSG_KILL);
                                } else {
-                                       Send_CSQC_Centerprint(attacker, s, GetAdvancedDeathReports(targ), KILL_FRAG, MSG_KILL);
-                                       Send_CSQC_Centerprint(targ, a, GetAdvancedDeathReports(attacker), KILL_FRAGGED, MSG_KILL);
+                                       Send_CSQC_KillCenterprint(attacker, s, GetAdvancedDeathReports(targ), KILL_FRAG, MSG_KILL);
+                                       Send_CSQC_KillCenterprint(targ, a, GetAdvancedDeathReports(attacker), KILL_FRAGGED, MSG_KILL);
                                }
  
                                attacker.taunt_soundtime = time + 1;
                }
                else
                {
-                       Send_CSQC_Centerprint(targ, "", "", deathtype, MSG_KILL_ACTION);
+                       Send_CSQC_KillCenterprint(targ, "", "", deathtype, MSG_KILL_ACTION);
                        if (deathtype == DEATH_HURTTRIGGER && inflictor.message != "")
                                msg = inflictor.message;
                        else if (deathtype == DEATH_CUSTOM)
@@@ -493,10 -491,6 +491,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(targ, damage, DEATH_WEAPONOF(deathtype));
 +
        float mirrordamage;
        float mirrorforce;
        float teamdamage0;
        if (gameover || targ.killcount == -666)
                return;
  
-       local entity oldself;
+       entity oldself;
        oldself = self;
        self = targ;
          damage_targ = targ;
        }
        else
        {
+               /*
+               skill based bot damage? gtfo. (tZork)
                if (targ.classname == "player")
                if (attacker.classname == "player")
                if (!targ.isbot)
                if (attacker.isbot)
                        damage = damage * bound(0.1, (skill + 5) * 0.1, 1);
+         */
+         
                // nullify damage if teamplay is on
                if(deathtype != DEATH_TELEFRAG)
                if(attacker.classname == "player")
                if(targ.takedamage == DAMAGE_AIM)
                if(targ != attacker)
                {
-                       if(targ.classname == "player")
+                       if(damage_headshotbonus > 0)
                        {
-                               // HEAD SHOT:
-                               // find height of hit on player axis
-                               // if above view_ofs and below maxs, and also in the middle half of the bbox, it is head shot
-                               vector headmins, headmaxs, org;
-                               org = antilag_takebackorigin(targ, time - ANTILAG_LATENCY(attacker));
-                               headmins = org + GetHeadshotMins(targ);
-                               headmaxs = org + GetHeadshotMaxs(targ);
-                               if(trace_hits_box(railgun_start, railgun_end, headmins, headmaxs))
+                               if(targ.classname == "player")
+                               {
+                                       // HEAD SHOT:
+                                       // find height of hit on player axis
+                                       // if above view_ofs and below maxs, and also in the middle half of the bbox, it is head shot
+                                       vector headmins, headmaxs, org;
+                                       org = antilag_takebackorigin(targ, time - ANTILAG_LATENCY(attacker));
+                                       headmins = org + GetHeadshotMins(targ);
+                                       headmaxs = org + GetHeadshotMaxs(targ);
+                                       if(trace_hits_box(railgun_start, railgun_end, headmins, headmaxs))
+                                       {
+                                               deathtype |= HITTYPE_HEADSHOT;
+                                       }
+                               }
+                               else if(targ.classname == "turret_head")
                                {
                                        deathtype |= HITTYPE_HEADSHOT;
                                }
+                               if(deathtype & HITTYPE_HEADSHOT)
+                                       damage *= 1 + damage_headshotbonus;
                        }
-                       else if(targ.classname == "turret_head")
-                       {
-                               deathtype |= HITTYPE_HEADSHOT;
-                       }
-                       if(deathtype & HITTYPE_HEADSHOT)
-                               damage *= 1 + damage_headshotbonus;
  
                        entity victim;
                        if((targ.vehicle_flags & VHF_ISVEHICLE) && targ.owner)
@@@ -988,13 -988,13 +992,13 @@@ float RadiusDamage (entity inflictor, e
                                        finaldmg = coredamage * power + edgedamage * (1 - power);
                                        if (finaldmg > 0)
                                        {
-                                               local float a;
-                                               local float c;
-                                               local float hits;
-                                               local float total;
-                                               local float hitratio;
-                                               local vector hitloc;
-                                               local vector myblastorigin;
+                                               float a;
+                                               float c;
+                                               float hits;
+                                               float total;
+                                               float hitratio;
+                                               vector hitloc;
+                                               vector myblastorigin;
                                                myblastorigin = WarpZone_TransformOrigin(targ, blastorigin);
                                                center = targ.origin + (targ.mins + targ.maxs) * 0.5;
                                                // if it's a player, use the view origin as reference