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"
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"
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"
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
// 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"
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"
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)"
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
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"
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
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
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
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
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"
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
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
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"
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"
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"
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"
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"
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
// 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"
type static
color 0xffdf72 0x811200
tex 48 55
- size 1 2
+ size 5 2
sizeincrease -15
alpha 100 144 988
airfriction 8
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
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;
argc = tokenize_console(strMessage);
// Acquire Command
- local string strCmd;
+ string strCmd;
strCmd = argv(0);
if(strCmd == "hud_configure") { // config hud
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))
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.
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:
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;
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;
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;
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;
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;
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);
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;
+}
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;
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;
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 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;
float CH_PAIN = 6; // only on players and csqc
float CH_PAIN_SINGLE = 6; // only on players and csqc
float CH_PLAYER = 7; // only on players and entities
+ float CH_TUBA = 5; // only on csqc
#else
float CH_INFO = 0;
float CH_TRIGGER = -3;
float CH_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;
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
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;
#define SERVERFLAG_ALLOW_FULLBRIGHT 1
#define SERVERFLAG_TEAMPLAY 2
+ #define SERVERFLAG_PLAYERSTATS 4
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");
}
}
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;
}
}
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
{
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;
}
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)
{
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
}
}
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")
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);
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)
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)
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