Merge remote branch 'origin/master' into fruitiex/fruitbalance
authorFruitieX <fruitiex@gmail.com>
Fri, 5 Nov 2010 06:15:58 +0000 (08:15 +0200)
committerFruitieX <fruitiex@gmail.com>
Fri, 5 Nov 2010 06:15:58 +0000 (08:15 +0200)
90 files changed:
Makefile
balanceTest.cfg
balancetZork.cfg [new file with mode: 0644]
defaultXonotic.cfg
effectinfo.txt
gfx/crosshair1.tga
gfx/crosshair10.tga
gfx/crosshair11.tga
gfx/crosshair12.tga
gfx/crosshair13.tga
gfx/crosshair14.tga
gfx/crosshair15.tga
gfx/crosshair16.tga
gfx/crosshair17.tga
gfx/crosshair18.tga
gfx/crosshair19.tga
gfx/crosshair2.tga
gfx/crosshair20.tga
gfx/crosshair21.tga [deleted file]
gfx/crosshair3.tga
gfx/crosshair4.tga
gfx/crosshair5.tga
gfx/crosshair6.tga
gfx/crosshair7.tga
gfx/crosshair8.tga
gfx/crosshair9.tga
gfx/crosshairdot.tga
gfx/menu/default/icon_aeslevel0.tga [new file with mode: 0644]
gfx/menu/default/icon_aeslevel1.tga [new file with mode: 0644]
gfx/menu/default/icon_aeslevel2.tga [new file with mode: 0644]
gfx/menu/default/icon_aeslevel3.tga [new file with mode: 0644]
gfx/menu/default/icon_aeslevel4.tga [new file with mode: 0644]
gfx/menu/default/icon_aeslevel5.tga [new file with mode: 0644]
gfx/menu/default/icon_pure0.tga [new file with mode: 0644]
gfx/menu/default/icon_pure1.tga [new file with mode: 0644]
gfx/menu/luminos/icon_aeslevel0.tga [new file with mode: 0644]
gfx/menu/luminos/icon_aeslevel1.tga [new file with mode: 0644]
gfx/menu/luminos/icon_aeslevel2.tga [new file with mode: 0644]
gfx/menu/luminos/icon_aeslevel3.tga [new file with mode: 0644]
gfx/menu/luminos/icon_aeslevel4.tga [new file with mode: 0644]
gfx/menu/luminos/icon_aeslevel5.tga [new file with mode: 0644]
gfx/menu/luminos/icon_pure0.tga [new file with mode: 0644]
gfx/menu/luminos/icon_pure1.tga [new file with mode: 0644]
gfx/menu/xaw/icon_aeslevel0.tga [new file with mode: 0644]
gfx/menu/xaw/icon_aeslevel1.tga [new file with mode: 0644]
gfx/menu/xaw/icon_aeslevel2.tga [new file with mode: 0644]
gfx/menu/xaw/icon_aeslevel3.tga [new file with mode: 0644]
gfx/menu/xaw/icon_aeslevel4.tga [new file with mode: 0644]
gfx/menu/xaw/icon_aeslevel5.tga [new file with mode: 0644]
gfx/menu/xaw/icon_pure0.tga [new file with mode: 0644]
gfx/menu/xaw/icon_pure1.tga [new file with mode: 0644]
qcsrc/client/Main.qc
qcsrc/client/View.qc
qcsrc/client/autocvars.qh
qcsrc/client/hook.qc
qcsrc/client/hud.qc
qcsrc/client/scoreboard.qc
qcsrc/client/tuba.qc
qcsrc/common/constants.qh
qcsrc/common/gamecommand.qc
qcsrc/common/mapinfo.qc
qcsrc/common/util-pre.qh
qcsrc/common/util.qh
qcsrc/menu/skin-customizables.inc
qcsrc/menu/xonotic/crosshairbutton.c
qcsrc/menu/xonotic/dialog_multiplayer_create_advanced.c
qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfo.c
qcsrc/menu/xonotic/dialog_multiplayer_playersetup.c
qcsrc/menu/xonotic/serverlist.c
qcsrc/server/bot/scripting.qc
qcsrc/server/cl_client.qc
qcsrc/server/cl_physics.qc
qcsrc/server/cl_player.qc
qcsrc/server/clientcommands.qc
qcsrc/server/defs.qh
qcsrc/server/g_hook.qc
qcsrc/server/g_violence.qc
qcsrc/server/g_world.qc
qcsrc/server/gamecommand.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/race.qc
qcsrc/server/scores.qc
qcsrc/server/sv_main.qc
qcsrc/server/t_items.qc
qcsrc/server/t_plats.qc
qcsrc/server/t_quake3.qc
qcsrc/server/w_campingrifle.qc
qcsrc/server/w_nex.qc
qcsrc/server/w_seeker.qc
qcsrc/server/w_tuba.qc

index 9910a39..e71d9d1 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -6,8 +6,7 @@ ZIPEXCLUDE ?= -x\!*.pk3 -xr\!\.svn -x\!qcsrc
 DIFF ?= diff
 
 FTEQCCFLAGS_WATERMARK ?= -DWATERMARK='"^1$(shell git describe) TEST BUILD"'
-#FTEQCCFLAGS ?= -Werror -Wno-Q205 -Wno-Q302 -O3 -Ono-c -Ono-cs -flo $(FTEQCCFLAGS_EXTRA) $(FTEQCCFLAGS_WATERMARK)
-FTEQCCFLAGS ?= -Wno-Q302 -O3 -Ono-c -Ono-cs -flo $(FTEQCCFLAGS_EXTRA) $(FTEQCCFLAGS_WATERMARK)
+FTEQCCFLAGS ?= -Werror -Wno-Q302 -O3 -Ono-c -Ono-cs $(FTEQCCFLAGS_EXTRA) $(FTEQCCFLAGS_WATERMARK)
 FTEQCCFLAGS_PROGS ?=
 FTEQCCFLAGS_MENU ?=
 
index 66b3833..c6ecf95 100644 (file)
@@ -17,7 +17,7 @@ set g_start_weapon_campingrifle -1 "0 = never provide the weapon, 1 = always pro
 set g_start_weapon_tuba -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
 set g_start_weapon_fireball -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
 set g_start_weapon_seeker -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
-set g_balance_health_start 125
+set g_balance_health_start 150
 set g_balance_armor_start 0
 set g_start_ammo_shells 20
 set g_start_ammo_nails 0
@@ -115,18 +115,18 @@ set g_balance_health_regenlinear 0
 set g_balance_pause_health_regen 5
 set g_balance_pause_health_regen_spawn 0
 set g_balance_health_rot 0.1
-set g_balance_health_rotlinear 0
-set g_balance_pause_health_rot 5
-set g_balance_pause_health_rot_spawn 10
+set g_balance_health_rotlinear 2.5
+set g_balance_pause_health_rot 4
+set g_balance_pause_health_rot_spawn 15
 set g_balance_health_regenstable 100
 set g_balance_health_rotstable 100
 set g_balance_health_limit 999
 set g_balance_armor_regen 0
 set g_balance_armor_regenlinear 0
 set g_balance_armor_rot 0.1
-set g_balance_armor_rotlinear 0
-set g_balance_pause_armor_rot 5
-set g_balance_pause_armor_rot_spawn 10
+set g_balance_armor_rotlinear 2.5
+set g_balance_pause_armor_rot 4
+set g_balance_pause_armor_rot_spawn 15
 set g_balance_armor_regenstable 100
 set g_balance_armor_rotstable 100
 set g_balance_armor_limit 999
@@ -136,8 +136,8 @@ set g_balance_fuel_regenlinear 0
 set g_balance_pause_fuel_regen 2 // other than this, fuel uses the health regen counter
 set g_balance_fuel_rot 0.05
 set g_balance_fuel_rotlinear 0
-set g_balance_pause_fuel_rot 5
-set g_balance_pause_fuel_rot_spawn 10
+set g_balance_pause_fuel_rot 4
+set g_balance_pause_fuel_rot_spawn 15
 set g_balance_fuel_regenstable 50
 set g_balance_fuel_rotstable 100
 set g_balance_fuel_limit 999
@@ -214,7 +214,7 @@ set g_balance_grapplehook_health 130
 // {{{ laser
 set g_balance_laser_primary_damage 20 // dps 33, hope that's not too high
 set g_balance_laser_primary_edgedamage 20
-set g_balance_laser_primary_force 235
+set g_balance_laser_primary_force 270
 set g_balance_laser_primary_radius 60
 set g_balance_laser_primary_speed 4000
 set g_balance_laser_primary_spread 0
@@ -239,11 +239,11 @@ set g_balance_laser_secondary_delay 0
 set g_balance_laser_secondary_gauntlet 0
 // }}}
 // {{{ shotgun
-set g_balance_shotgun_primary_bullets 6
-set g_balance_shotgun_primary_damage 9
+set g_balance_shotgun_primary_bullets 10
+set g_balance_shotgun_primary_damage 5
 set g_balance_shotgun_primary_force 60
 set g_balance_shotgun_primary_spread 0.07
-set g_balance_shotgun_primary_refire 0.5
+set g_balance_shotgun_primary_refire 0.8
 set g_balance_shotgun_primary_animtime 0.2
 set g_balance_shotgun_primary_ammo 1
 set g_balance_shotgun_primary_speed 12000
@@ -263,11 +263,11 @@ set g_balance_uzi_first 1
 set g_balance_uzi_first_damage 30
 set g_balance_uzi_first_force 50
 set g_balance_uzi_first_spread 0.015
-set g_balance_uzi_first_refire 0.2
+set g_balance_uzi_first_refire 0.3
 set g_balance_uzi_first_ammo 1
 set g_balance_uzi_sustained_damage 15
-set g_balance_uzi_sustained_force 27
-set g_balance_uzi_sustained_spread 0.05
+set g_balance_uzi_sustained_force 10
+set g_balance_uzi_sustained_spread 0.08
 set g_balance_uzi_sustained_refire 0.1
 set g_balance_uzi_sustained_ammo 1
 set g_balance_uzi_speed 18000
@@ -275,7 +275,7 @@ set g_balance_uzi_bulletconstant 115 // 13.1qu
 // }}}
 // {{{ mortar
 set g_balance_grenadelauncher_primary_type 0
-set g_balance_grenadelauncher_primary_damage 70
+set g_balance_grenadelauncher_primary_damage 60
 set g_balance_grenadelauncher_primary_edgedamage 38
 set g_balance_grenadelauncher_primary_force 400
 set g_balance_grenadelauncher_primary_radius 140
@@ -338,12 +338,12 @@ set g_balance_minelayer_remote_force 300
 // }}}
 // {{{ electro
 set g_balance_electro_lightning 1
-set g_balance_electro_primary_damage 85
+set g_balance_electro_primary_damage 110
 set g_balance_electro_primary_edgedamage 0
 set g_balance_electro_primary_force 425
 set g_balance_electro_primary_force_up 125
 set g_balance_electro_primary_radius 850
-set g_balance_electro_primary_comboradius 75
+set g_balance_electro_primary_comboradius 150
 set g_balance_electro_primary_speed 0
 set g_balance_electro_primary_spread 0
 set g_balance_electro_primary_lifetime 0
@@ -358,19 +358,19 @@ set g_balance_electro_secondary_damage 25
 set g_balance_electro_secondary_edgedamage 0
 set g_balance_electro_secondary_force 100
 set g_balance_electro_secondary_radius 100
-set g_balance_electro_secondary_speed 700
-set g_balance_electro_secondary_speed_up 200
+set g_balance_electro_secondary_speed 500
+set g_balance_electro_secondary_speed_up 150
 set g_balance_electro_secondary_speed_z 0
 set g_balance_electro_secondary_spread 0.08
 set g_balance_electro_secondary_lifetime 3.5
-set g_balance_electro_secondary_refire 0.2
+set g_balance_electro_secondary_refire 0.1
 set g_balance_electro_secondary_refire2 2
 set g_balance_electro_secondary_animtime 0.2
 set g_balance_electro_secondary_ammo 2
 set g_balance_electro_secondary_health 10
 set g_balance_electro_secondary_damageforcescale 4
 set g_balance_electro_secondary_count 3
-set g_balance_electro_combo_damage 40
+set g_balance_electro_combo_damage 60
 set g_balance_electro_combo_edgedamage 0
 set g_balance_electro_combo_force 80
 set g_balance_electro_combo_radius 250
@@ -378,15 +378,15 @@ set g_balance_electro_combo_comboradius 0
 set g_balance_electro_combo_speed 400
 // }}}
 // {{{ crylink
-set g_balance_crylink_primary_damage 8
-set g_balance_crylink_primary_edgedamage 6
-set g_balance_crylink_primary_force 40
-set g_balance_crylink_primary_radius 80
-set g_balance_crylink_primary_speed 1100
-set g_balance_crylink_primary_spread 0.05
-set g_balance_crylink_primary_shots 7
-set g_balance_crylink_primary_bounces 2
-set g_balance_crylink_primary_refire 0.8
+set g_balance_crylink_primary_damage 5
+set g_balance_crylink_primary_edgedamage 2.5
+set g_balance_crylink_primary_force 25
+set g_balance_crylink_primary_radius 50
+set g_balance_crylink_primary_speed 2500
+set g_balance_crylink_primary_spread 0.04
+set g_balance_crylink_primary_shots 12
+set g_balance_crylink_primary_bounces 1
+set g_balance_crylink_primary_refire 1
 set g_balance_crylink_primary_animtime 0.4
 set g_balance_crylink_primary_ammo 2
 set g_balance_crylink_primary_bouncedamagefactor 0.2
@@ -418,9 +418,9 @@ set g_balance_crylink_secondary_line_lifetime 2 // range: 4000 full, fades to 80
 set g_balance_crylink_secondary_line_fadetime 2
 // }}}
 // {{{ nex
-set g_balance_nex_primary_damage 120
+set g_balance_nex_primary_damage 100
 set g_balance_nex_primary_force 600
-set g_balance_nex_primary_refire 1.5
+set g_balance_nex_primary_refire 0.75
 set g_balance_nex_primary_animtime 0.3
 set g_balance_nex_primary_ammo 5
 set g_balance_nex_primary_damagefalloff_mindist 0
@@ -428,9 +428,9 @@ set g_balance_nex_primary_damagefalloff_maxdist 0
 set g_balance_nex_primary_damagefalloff_halflife 0
 set g_balance_nex_primary_damagefalloff_forcehalflife 0
 
-set g_balance_nex_secondary 0
+set g_balance_nex_secondary 1
 set g_balance_nex_secondary_charge 1
-set g_balance_nex_secondary_charge_rate 0.25
+set g_balance_nex_secondary_charge_rate 0.7
 set g_balance_nex_secondary_damage 100
 set g_balance_nex_secondary_force 600
 set g_balance_nex_secondary_refire 1.5
@@ -442,11 +442,11 @@ set g_balance_nex_secondary_damagefalloff_halflife 0
 set g_balance_nex_secondary_damagefalloff_forcehalflife 0
 
 set g_balance_nex_charge 1
-set g_balance_nex_charge_mindmg 40
+set g_balance_nex_charge_mindmg 10
 set g_balance_nex_charge_start 0
-set g_balance_nex_charge_rate 0.1
+set g_balance_nex_charge_rate 0.35
 set g_balance_nex_charge_limit 0.5
-set g_balance_nex_charge_shot_multiplier 0.5
+set g_balance_nex_charge_shot_multiplier 0
 set g_balance_nex_charge_velocity_rate 0
 set g_balance_nex_charge_minspeed 400
 set g_balance_nex_charge_maxspeed 1000
@@ -457,9 +457,9 @@ set g_balance_minstanex_animtime 0.3
 set g_balance_minstanex_ammo 10
 // }}}
 // {{{ hagar
-set g_balance_hagar_primary_damage 37
+set g_balance_hagar_primary_damage 30
 set g_balance_hagar_primary_edgedamage 15
-set g_balance_hagar_primary_force 100
+set g_balance_hagar_primary_force 50
 set g_balance_hagar_primary_radius 65
 set g_balance_hagar_primary_spread 0.010
 set g_balance_hagar_primary_speed 3000
@@ -467,9 +467,9 @@ set g_balance_hagar_primary_lifetime 30
 set g_balance_hagar_primary_refire 0.15
 set g_balance_hagar_primary_ammo 1
 set g_balance_hagar_secondary 1
-set g_balance_hagar_secondary_damage 37
+set g_balance_hagar_secondary_damage 30
 set g_balance_hagar_secondary_edgedamage 15
-set g_balance_hagar_secondary_force 100
+set g_balance_hagar_secondary_force 50
 set g_balance_hagar_secondary_radius 65
 set g_balance_hagar_secondary_spread 0.015
 set g_balance_hagar_secondary_speed 1400
@@ -479,8 +479,8 @@ set g_balance_hagar_secondary_refire 0.15
 set g_balance_hagar_secondary_ammo 1
 // }}}
 // {{{ rocketlauncher // TODO
-set g_balance_rocketlauncher_damage 100
-set g_balance_rocketlauncher_edgedamage 33
+set g_balance_rocketlauncher_damage 110
+set g_balance_rocketlauncher_edgedamage 25
 set g_balance_rocketlauncher_force 350
 set g_balance_rocketlauncher_radius 125
 set g_balance_rocketlauncher_speed 1000
@@ -490,7 +490,7 @@ set g_balance_rocketlauncher_lifetime 5
 set g_balance_rocketlauncher_refire 1
 set g_balance_rocketlauncher_animtime 0.4
 set g_balance_rocketlauncher_ammo 3
-set g_balance_rocketlauncher_health 0
+set g_balance_rocketlauncher_health 10
 set g_balance_rocketlauncher_damageforcescale 0
 set g_balance_rocketlauncher_detonatedelay -1 // positive: timer till detonation is allowed, negative: "security device" that prevents ANY remote detonation if it could hurt its owner, zero: detonatable at any time
 set g_balance_rocketlauncher_guiderate 45 // max degrees per second
@@ -503,9 +503,9 @@ set g_balance_rocketlauncher_laserguided_speedaccel 0
 set g_balance_rocketlauncher_laserguided_speedstart 1000
 set g_balance_rocketlauncher_laserguided_turnrate 0.75 //0.5
 set g_balance_rocketlauncher_laserguided_allow_steal 1
-set g_balance_rocketlauncher_remote_damage 100
-set g_balance_rocketlauncher_remote_edgedamage 33
-set g_balance_rocketlauncher_remote_radius 75
+set g_balance_rocketlauncher_remote_damage 90
+set g_balance_rocketlauncher_remote_edgedamage 20
+set g_balance_rocketlauncher_remote_radius 125
 set g_balance_rocketlauncher_remote_force 350
 // }}}
 // {{{ porto
@@ -537,32 +537,32 @@ set g_balance_hook_secondary_power 3 // effect behaves like a square function
 set g_balance_hook_secondary_duration 1.5 // effect runs for three seconds
 // }}}
 // {{{ hlac
-set g_balance_hlac_primary_spread_min 0
-set g_balance_hlac_primary_spread_max 0
-set g_balance_hlac_primary_spread_add 0
-set g_balance_hlac_primary_spread_crouchmod 0
+set g_balance_hlac_primary_spread_min 0.01
+set g_balance_hlac_primary_spread_max 0.6
+set g_balance_hlac_primary_spread_add 0.01
+set g_balance_hlac_primary_spread_crouchmod 0.5
 
-set g_balance_hlac_primary_damage 15
-set g_balance_hlac_primary_edgedamage 0
-set g_balance_hlac_primary_force 70
-set g_balance_hlac_primary_radius 30
-set g_balance_hlac_primary_speed 2500
-set g_balance_hlac_primary_lifetime 5
+set g_balance_hlac_primary_damage 22
+set g_balance_hlac_primary_edgedamage 2
+set g_balance_hlac_primary_force -100
+set g_balance_hlac_primary_radius 100
+set g_balance_hlac_primary_speed 5000
+set g_balance_hlac_primary_lifetime 3
 
 set g_balance_hlac_primary_refire 0.1
 set g_balance_hlac_primary_animtime 0.4
 set g_balance_hlac_primary_ammo 1
 
 set g_balance_hlac_secondary 1
-set g_balance_hlac_secondary_spread 0.15
+set g_balance_hlac_secondary_spread 0.2
 set g_balance_hlac_secondary_spread_crouchmod 0.5
 
 set g_balance_hlac_secondary_damage 20
-set g_balance_hlac_secondary_edgedamage 0
-set g_balance_hlac_secondary_force 40
-set g_balance_hlac_secondary_radius 35
-set g_balance_hlac_secondary_speed 2500
-set g_balance_hlac_secondary_lifetime 5
+set g_balance_hlac_secondary_edgedamage 3
+set g_balance_hlac_secondary_force 100
+set g_balance_hlac_secondary_radius 50
+set g_balance_hlac_secondary_speed 9000
+set g_balance_hlac_secondary_lifetime 3
 
 set g_balance_hlac_secondary_refire 1
 set g_balance_hlac_secondary_animtime 0.7
@@ -657,14 +657,14 @@ set g_balance_seeker_flac_animtime 0.1
 set g_balance_seeker_flac_damage 15
 set g_balance_seeker_flac_edgedamage 10
 set g_balance_seeker_flac_force 50
-set g_balance_seeker_flac_lifetime 0.1
-set g_balance_seeker_flac_lifetime_rand 0.05
+set g_balance_seeker_flac_lifetime 0.05
+set g_balance_seeker_flac_lifetime_rand 0.02
 set g_balance_seeker_flac_radius 100
 set g_balance_seeker_flac_refire 0.1
-set g_balance_seeker_flac_speed 3000
-set g_balance_seeker_flac_speed_up 1000
+set g_balance_seeker_flac_speed 5000
+set g_balance_seeker_flac_speed_up 500
 set g_balance_seeker_flac_speed_z 0
-set g_balance_seeker_flac_spread 0.4
+set g_balance_seeker_flac_spread 0.25
 set g_balance_seeker_missile_accel 1.05
 set g_balance_seeker_missile_ammo 2
 set g_balance_seeker_missile_animtime 0.3
diff --git a/balancetZork.cfg b/balancetZork.cfg
new file mode 100644 (file)
index 0000000..7ab11ed
--- /dev/null
@@ -0,0 +1,706 @@
+// {{{ starting gear
+set g_start_weapon_laser -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_shotgun -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_uzi -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_grenadelauncher -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_minelayer -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_electro -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_crylink -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_nex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_hagar -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_rocketlauncher -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_minstanex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_porto -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_hook -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_hlac -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_campingrifle -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_tuba -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_fireball -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_seeker -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_balance_health_start 125
+set g_balance_armor_start 0
+set g_start_ammo_shells 20
+set g_start_ammo_nails 0
+set g_start_ammo_rockets 0
+set g_start_ammo_cells 0
+set g_start_ammo_fuel 0
+set g_warmup_start_health 200 "starting values when being in warmup-stage"
+set g_warmup_start_armor 100 "starting values when being in warmup-stage"
+set g_warmup_start_ammo_shells 50 "starting values when being in warmup-stage"
+set g_warmup_start_ammo_nails 150 "starting values when being in warmup-stage"
+set g_warmup_start_ammo_rockets 50 "starting values when being in warmup-stage"
+set g_warmup_start_ammo_cells 50 "starting values when being in warmup-stage"
+set g_warmup_start_ammo_fuel 0 "starting values when being in warmup-stage"
+set g_lms_start_health 200
+set g_lms_start_armor 100
+set g_lms_start_ammo_shells 30
+set g_lms_start_ammo_nails 250
+set g_lms_start_ammo_rockets 100
+set g_lms_start_ammo_cells 200
+set g_lms_start_ammo_fuel 0
+set g_balance_nix_roundtime 25
+set g_balance_nix_incrtime 1.6
+set g_balance_nix_ammo_shells 15
+set g_balance_nix_ammo_nails 45
+set g_balance_nix_ammo_rockets 15
+set g_balance_nix_ammo_cells 15
+set g_balance_nix_ammo_fuel 0
+set g_balance_nix_ammoincr_shells 2
+set g_balance_nix_ammoincr_nails 6
+set g_balance_nix_ammoincr_rockets 2
+set g_balance_nix_ammoincr_cells 2
+set g_balance_nix_ammoincr_fuel 2
+// }}}
+
+// {{{ pickup items
+set g_pickup_ammo_anyway 1
+set g_pickup_weapons_anyway 1
+set g_pickup_shells 20
+set g_pickup_shells_weapon 10
+set g_pickup_shells_max 45
+set g_pickup_nails 120
+set g_pickup_nails_weapon 60
+set g_pickup_nails_max 300
+set g_pickup_rockets 25
+set g_pickup_rockets_weapon 15
+set g_pickup_rockets_max 150
+set g_pickup_cells 30
+set g_pickup_cells_weapon 20
+set g_pickup_cells_max 200
+set g_pickup_fuel 25
+set g_pickup_fuel_weapon 15
+set g_pickup_fuel_jetpack 50
+set g_pickup_fuel_max 999
+set g_pickup_armorsmall 5
+set g_pickup_armorsmall_max 999
+set g_pickup_armorsmall_anyway 0
+set g_pickup_armormedium 25
+set g_pickup_armormedium_max 999
+set g_pickup_armormedium_anyway 0
+set g_pickup_armorbig 50
+set g_pickup_armorbig_max 999
+set g_pickup_armorbig_anyway 0
+set g_pickup_armorlarge 100
+set g_pickup_armorlarge_max 999
+set g_pickup_armorlarge_anyway 0
+set g_pickup_healthsmall 5
+set g_pickup_healthsmall_max 999
+set g_pickup_healthsmall_anyway 0
+set g_pickup_healthmedium 25
+set g_pickup_healthmedium_max 999
+set g_pickup_healthmedium_anyway 0
+set g_pickup_healthlarge 50
+set g_pickup_healthlarge_max 999
+set g_pickup_healthlarge_anyway 0
+set g_pickup_healthmega 100
+set g_pickup_healthmega_max 999
+set g_pickup_healthmega_anyway 0
+set g_pickup_respawntime_short 15
+set g_pickup_respawntime_medium 20
+set g_pickup_respawntime_long 30
+set g_pickup_respawntime_powerup 120
+set g_pickup_respawntime_weapon 5
+set g_pickup_respawntime_ammo 25
+set g_pickup_respawntimejitter_short 0
+set g_pickup_respawntimejitter_medium 0
+set g_pickup_respawntimejitter_long 0
+set g_pickup_respawntimejitter_powerup 10
+set g_pickup_respawntimejitter_weapon 0
+set g_pickup_respawntimejitter_ammo 0
+// }}}
+
+// {{{ regen/rot
+set g_balance_health_regen 0.1
+set g_balance_health_regenlinear 0
+set g_balance_pause_health_regen 5
+set g_balance_pause_health_regen_spawn 0
+set g_balance_health_rot 0.1
+set g_balance_health_rotlinear 0
+set g_balance_pause_health_rot 5
+set g_balance_pause_health_rot_spawn 10
+set g_balance_health_regenstable 100
+set g_balance_health_rotstable 100
+set g_balance_health_limit 999
+set g_balance_armor_regen 0
+set g_balance_armor_regenlinear 0
+set g_balance_armor_rot 0.1
+set g_balance_armor_rotlinear 0
+set g_balance_pause_armor_rot 5
+set g_balance_pause_armor_rot_spawn 10
+set g_balance_armor_regenstable 100
+set g_balance_armor_rotstable 100
+set g_balance_armor_limit 999
+set g_balance_armor_blockpercent 0.7
+set g_balance_fuel_regen 0.1 "fuel regeneration (only applies if the player owns IT_FUEL_REGEN)"
+set g_balance_fuel_regenlinear 0
+set g_balance_pause_fuel_regen 2 // other than this, fuel uses the health regen counter
+set g_balance_fuel_rot 0.05
+set g_balance_fuel_rotlinear 0
+set g_balance_pause_fuel_rot 5
+set g_balance_pause_fuel_rot_spawn 10
+set g_balance_fuel_regenstable 50
+set g_balance_fuel_rotstable 100
+set g_balance_fuel_limit 999
+// }}}
+
+// {{{ misc
+set g_balance_selfdamagepercent 0.65
+set g_balance_weaponswitchdelay 0.15
+set g_weaponspeedfactor 1 "weapon projectile speed multiplier"
+set g_weaponratefactor 1 "weapon fire rate multiplier"
+set g_weapondamagefactor 1 "weapon damage multiplier"
+set g_weaponforcefactor 1 "weapon force multiplier"
+set g_weaponspreadfactor 1 "weapon spread multiplier"
+set g_balance_firetransfer_time 0.9
+set g_balance_firetransfer_damage 0.8
+set g_throughfloor_damage 0.5
+set g_throughfloor_force 0.7
+set g_projectiles_newton_style 2
+// possible values:
+// 0: absolute velocity projectiles (like Quake)
+// 1: relative velocity projectiles, "Newtonian" (like Tribes 2)
+// 2: relative velocity projectiles, but aim is precorrected so projectiles hit the crosshair (note: strafe rockets then are SLOWER than ones shot while standing, happens in 1 too when aiming correctly which is hard)
+// 3: absolute velocity + player velocity component in shot direction (note: does NOT yield the right relative velocity, but may be good enough, but it is somewhat prone to sniper rockets)
+// 4: just add the player velocity length to the absolute velocity (tZork's sniper rockets)
+set g_projectiles_newton_style_2_minfactor 0.7
+set g_projectiles_newton_style_2_maxfactor 5
+set g_projectiles_spread_style 7
+// possible values:
+// 0: forward + solid sphere (like Quake) - varies velocity
+// 1: forward + flattened solid sphere
+// 2: forward + solid circle
+// 3: forward + normal distribution 3D - varies velocity
+// 4: forward + normal distribution on a plane
+// 5: forward + circle with 1-r falloff
+// 6: forward + circle with 1-r^2 falloff
+// 7: forward + circle with (1-r)(2-r) falloff
+set g_balance_falldamage_deadminspeed 150
+set g_balance_falldamage_minspeed 800
+set g_balance_falldamage_factor 0.20
+set g_balance_falldamage_maxdamage 15
+// }}}
+
+// {{{ powerups
+set g_balance_powerup_invincible_takedamage 0.3
+set g_balance_powerup_invincible_time 30
+set g_balance_powerup_strength_damage 3
+set g_balance_powerup_strength_force 4
+set g_balance_powerup_strength_time 30
+set g_balance_powerup_strength_selfdamage 1.5
+set g_balance_powerup_strength_selfforce 1.5
+// }}}
+
+// {{{ jetpack/hook
+set g_jetpack_antigravity 0.8 "factor of gravity compensation of the jetpack"
+set g_jetpack_acceleration_side 1200 "acceleration of the jetpack in xy direction"
+set g_jetpack_acceleration_up 600 "acceleration of the jetpack in z direction (note: you have to factor in gravity here, if antigravity is not 1)"
+set g_jetpack_maxspeed_side 1500 "max speed of the jetpack in xy direction"
+set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
+set g_jetpack_fuel 8 "fuel per second for jetpack"
+set g_jetpack_attenuation 2 "jetpack sound attenuation"
+
+set g_grappling_hook_tarzan 2 // 2: can also pull players
+set g_balance_grapplehook_speed_fly 1800
+set g_balance_grapplehook_speed_pull 2000
+set g_balance_grapplehook_force_rubber 2000
+set g_balance_grapplehook_force_rubber_overstretch 1000
+set g_balance_grapplehook_length_min 50
+set g_balance_grapplehook_stretch 50
+set g_balance_grapplehook_airfriction 0.2
+set g_balance_grapplehook_health 130
+// }}}
+
+// {{{ weapon properties
+// {{{ laser
+set g_balance_laser_primary_damage 20 // dps 33, hope that's not too high
+set g_balance_laser_primary_edgedamage 20
+set g_balance_laser_primary_force 270
+set g_balance_laser_primary_radius 60
+set g_balance_laser_primary_speed 4000
+set g_balance_laser_primary_spread 0
+set g_balance_laser_primary_refire 0.6
+set g_balance_laser_primary_animtime 0.6
+set g_balance_laser_primary_lifetime 5
+set g_balance_laser_primary_shotangle 0
+set g_balance_laser_primary_delay 0
+set g_balance_laser_primary_gauntlet 0
+set g_balance_laser_secondary 0 // when 1, a secondary laser mode exists
+set g_balance_laser_secondary_damage 35
+set g_balance_laser_secondary_edgedamage 10
+set g_balance_laser_secondary_force 400
+set g_balance_laser_secondary_radius 70
+set g_balance_laser_secondary_speed 9000
+set g_balance_laser_secondary_spread 0
+set g_balance_laser_secondary_refire 0.7
+set g_balance_laser_secondary_animtime 0.3
+set g_balance_laser_secondary_lifetime 30
+set g_balance_laser_secondary_shotangle 0
+set g_balance_laser_secondary_delay 0
+set g_balance_laser_secondary_gauntlet 0
+// }}}
+// {{{ shotgun
+set g_balance_shotgun_primary_bullets 10
+set g_balance_shotgun_primary_damage 5
+set g_balance_shotgun_primary_force 60
+set g_balance_shotgun_primary_spread 0.07
+set g_balance_shotgun_primary_refire 0.8
+set g_balance_shotgun_primary_animtime 0.2
+set g_balance_shotgun_primary_ammo 1
+set g_balance_shotgun_primary_speed 12000
+set g_balance_shotgun_primary_bulletconstant 75 // 3.8qu
+set g_balance_shotgun_secondary 1
+set g_balance_shotgun_secondary_melee_delay 0.35 // match the anim
+set g_balance_shotgun_secondary_melee_range 85
+set g_balance_shotgun_secondary_melee_swing 50
+set g_balance_shotgun_secondary_melee_time 0.1
+set g_balance_shotgun_secondary_damage 110
+set g_balance_shotgun_secondary_force 150
+set g_balance_shotgun_secondary_refire 1.1
+set g_balance_shotgun_secondary_animtime 1
+// }}}
+// {{{ uzi
+set g_balance_uzi_first 1
+set g_balance_uzi_first_damage 30
+set g_balance_uzi_first_force 50
+set g_balance_uzi_first_spread 0.015
+set g_balance_uzi_first_refire 0.3
+set g_balance_uzi_first_ammo 1
+set g_balance_uzi_sustained_damage 15
+set g_balance_uzi_sustained_force 10
+set g_balance_uzi_sustained_spread 0.08
+set g_balance_uzi_sustained_refire 0.1
+set g_balance_uzi_sustained_ammo 1
+set g_balance_uzi_speed 18000
+set g_balance_uzi_bulletconstant 115 // 13.1qu
+// }}}
+// {{{ mortar
+set g_balance_grenadelauncher_primary_type 0
+set g_balance_grenadelauncher_primary_damage 60
+set g_balance_grenadelauncher_primary_edgedamage 38
+set g_balance_grenadelauncher_primary_force 400
+set g_balance_grenadelauncher_primary_radius 140
+set g_balance_grenadelauncher_primary_speed 2000
+set g_balance_grenadelauncher_primary_speed_up 200
+set g_balance_grenadelauncher_primary_speed_z 0
+set g_balance_grenadelauncher_primary_spread 0
+set g_balance_grenadelauncher_primary_lifetime 30
+set g_balance_grenadelauncher_primary_lifetime2 1
+set g_balance_grenadelauncher_primary_refire 0.8
+set g_balance_grenadelauncher_primary_animtime 0.3
+set g_balance_grenadelauncher_primary_ammo 2
+set g_balance_grenadelauncher_primary_health 25
+set g_balance_grenadelauncher_primary_damageforcescale 4
+set g_balance_grenadelauncher_primary_bouncefactor 0.5
+set g_balance_grenadelauncher_primary_bouncestop 0.075
+set g_balance_grenadelauncher_primary_remote_minbouncecnt 0
+
+set g_balance_grenadelauncher_secondary_type 1
+set g_balance_grenadelauncher_secondary_damage 70
+set g_balance_grenadelauncher_secondary_edgedamage 38
+set g_balance_grenadelauncher_secondary_force 400
+set g_balance_grenadelauncher_secondary_radius 140
+set g_balance_grenadelauncher_secondary_speed 1400
+set g_balance_grenadelauncher_secondary_speed_up 200
+set g_balance_grenadelauncher_secondary_speed_z 0
+set g_balance_grenadelauncher_secondary_spread 0
+set g_balance_grenadelauncher_secondary_lifetime 2.5
+set g_balance_grenadelauncher_secondary_lifetime2 0
+set g_balance_grenadelauncher_secondary_refire 0.7
+set g_balance_grenadelauncher_secondary_animtime 0.3
+set g_balance_grenadelauncher_secondary_ammo 2
+set g_balance_grenadelauncher_secondary_health 10
+set g_balance_grenadelauncher_secondary_damageforcescale 4
+set g_balance_grenadelauncher_secondary_bouncefactor 0.5
+set g_balance_grenadelauncher_secondary_bouncestop 0.075
+set g_balance_grenadelauncher_secondary_remote_detonateprimary 0
+// }}}
+// {{{ minelayer // TODO
+set g_balance_minelayer_damage 35
+set g_balance_minelayer_edgedamage 30
+set g_balance_minelayer_force 250
+set g_balance_minelayer_radius 175
+set g_balance_minelayer_proximityradius 150
+set g_balance_minelayer_speed 750
+set g_balance_minelayer_lifetime 60
+set g_balance_minelayer_refire 1.5
+set g_balance_minelayer_animtime 0.4
+set g_balance_minelayer_ammo 5
+set g_balance_minelayer_health 15
+set g_balance_minelayer_limit 4 // 0 disables the limit
+set g_balance_minelayer_protection 1 // don't explode if the mine would hurt the owner or a team mate
+set g_balance_minelayer_damageforcescale 0
+set g_balance_minelayer_detonatedelay -1 // positive: timer till detonation is allowed, negative: "security device" that prevents ANY remote detonation if it could hurt its owner, zero: detonatable at any time
+set g_balance_minelayer_time 0.5
+set g_balance_minelayer_remote_damage 45
+set g_balance_minelayer_remote_edgedamage 40
+set g_balance_minelayer_remote_radius 200
+set g_balance_minelayer_remote_force 300
+// }}}
+// {{{ electro
+set g_balance_electro_lightning 1
+set g_balance_electro_primary_damage 110
+set g_balance_electro_primary_edgedamage 0
+set g_balance_electro_primary_force 425
+set g_balance_electro_primary_force_up 125
+set g_balance_electro_primary_radius 850
+set g_balance_electro_primary_comboradius 150
+set g_balance_electro_primary_speed 0
+set g_balance_electro_primary_spread 0
+set g_balance_electro_primary_lifetime 0
+set g_balance_electro_primary_refire 0.4
+set g_balance_electro_primary_animtime 0.03333333
+set g_balance_electro_primary_ammo 7
+set g_balance_electro_primary_range 800
+set g_balance_electro_primary_falloff_mindist 255 // 0.3 * radius
+set g_balance_electro_primary_falloff_maxdist 850
+set g_balance_electro_primary_falloff_halflifedist 425
+
+set g_balance_electro_secondary_damage 25
+set g_balance_electro_secondary_edgedamage 0
+set g_balance_electro_secondary_force 100
+set g_balance_electro_secondary_radius 100
+set g_balance_electro_secondary_speed 500
+set g_balance_electro_secondary_speed_up 150
+set g_balance_electro_secondary_speed_z 0
+set g_balance_electro_secondary_spread 0.08
+set g_balance_electro_secondary_lifetime 3.5
+set g_balance_electro_secondary_refire 0.1
+set g_balance_electro_secondary_refire2 2
+set g_balance_electro_secondary_animtime 0.2
+set g_balance_electro_secondary_ammo 2
+set g_balance_electro_secondary_health 10
+set g_balance_electro_secondary_damageforcescale 4
+set g_balance_electro_secondary_count 3
+set g_balance_electro_combo_damage 60
+set g_balance_electro_combo_edgedamage 0
+set g_balance_electro_combo_force 80
+set g_balance_electro_combo_radius 250
+set g_balance_electro_combo_comboradius 0
+set g_balance_electro_combo_speed 400
+// }}}
+// {{{ crylink
+set g_balance_crylink_primary_damage 5
+set g_balance_crylink_primary_edgedamage 2.5
+set g_balance_crylink_primary_force 25
+set g_balance_crylink_primary_radius 50
+set g_balance_crylink_primary_speed 2500
+set g_balance_crylink_primary_spread 0.04
+set g_balance_crylink_primary_shots 12
+set g_balance_crylink_primary_bounces 1
+set g_balance_crylink_primary_refire 1
+set g_balance_crylink_primary_animtime 0.4
+set g_balance_crylink_primary_ammo 2
+set g_balance_crylink_primary_bouncedamagefactor 0.2
+
+set g_balance_crylink_primary_middle_lifetime 5 // range: 10000 full, fades to 20000
+set g_balance_crylink_primary_middle_fadetime 5
+set g_balance_crylink_primary_star_lifetime 2 // range: 800 full, fades to 1300
+set g_balance_crylink_primary_star_fadetime 0.25
+set g_balance_crylink_primary_other_lifetime 2 // range: 800 full, fades to 1300
+set g_balance_crylink_primary_other_fadetime 0.25
+
+set g_balance_crylink_secondary 1
+set g_balance_crylink_secondary_damage 2
+set g_balance_crylink_secondary_edgedamage 0
+set g_balance_crylink_secondary_force -20
+set g_balance_crylink_secondary_radius 5
+set g_balance_crylink_secondary_speed 1600
+set g_balance_crylink_secondary_spread 0.03
+set g_balance_crylink_secondary_shots 3
+set g_balance_crylink_secondary_bounces 0
+set g_balance_crylink_secondary_refire 0.15
+set g_balance_crylink_secondary_animtime 0.15
+set g_balance_crylink_secondary_ammo 1
+set g_balance_crylink_secondary_bouncedamagefactor 0.5
+
+set g_balance_crylink_secondary_middle_lifetime 5 // range: 10000 full, fades to 10000
+set g_balance_crylink_secondary_middle_fadetime 5
+set g_balance_crylink_secondary_line_lifetime 2 // range: 4000 full, fades to 8000
+set g_balance_crylink_secondary_line_fadetime 2
+// }}}
+// {{{ nex
+set g_balance_nex_primary_damage 100
+set g_balance_nex_primary_force 600
+set g_balance_nex_primary_refire 0.75
+set g_balance_nex_primary_animtime 0.3
+set g_balance_nex_primary_ammo 5
+set g_balance_nex_primary_damagefalloff_mindist 0
+set g_balance_nex_primary_damagefalloff_maxdist 0
+set g_balance_nex_primary_damagefalloff_halflife 0
+set g_balance_nex_primary_damagefalloff_forcehalflife 0
+
+set g_balance_nex_secondary 1
+set g_balance_nex_secondary_charge 1
+set g_balance_nex_secondary_charge_rate 0.7
+set g_balance_nex_secondary_damage 100
+set g_balance_nex_secondary_force 600
+set g_balance_nex_secondary_refire 1.5
+set g_balance_nex_secondary_animtime 0.3
+set g_balance_nex_secondary_ammo 5
+set g_balance_nex_secondary_damagefalloff_mindist 0
+set g_balance_nex_secondary_damagefalloff_maxdist 0
+set g_balance_nex_secondary_damagefalloff_halflife 0
+set g_balance_nex_secondary_damagefalloff_forcehalflife 0
+
+set g_balance_nex_charge 1
+set g_balance_nex_charge_mindmg 10
+set g_balance_nex_charge_start 0
+set g_balance_nex_charge_rate 0.35
+set g_balance_nex_charge_limit 0.5
+set g_balance_nex_charge_shot_multiplier 0
+set g_balance_nex_charge_velocity_rate 0
+set g_balance_nex_charge_minspeed 400
+set g_balance_nex_charge_maxspeed 1000
+// }}}
+// {{{ minstanex
+set g_balance_minstanex_refire 1
+set g_balance_minstanex_animtime 0.3
+set g_balance_minstanex_ammo 10
+// }}}
+// {{{ hagar
+set g_balance_hagar_primary_damage 30
+set g_balance_hagar_primary_edgedamage 15
+set g_balance_hagar_primary_force 50
+set g_balance_hagar_primary_radius 65
+set g_balance_hagar_primary_spread 0.010
+set g_balance_hagar_primary_speed 3000
+set g_balance_hagar_primary_lifetime 30
+set g_balance_hagar_primary_refire 0.15
+set g_balance_hagar_primary_ammo 1
+set g_balance_hagar_secondary 1
+set g_balance_hagar_secondary_damage 30
+set g_balance_hagar_secondary_edgedamage 15
+set g_balance_hagar_secondary_force 50
+set g_balance_hagar_secondary_radius 65
+set g_balance_hagar_secondary_spread 0.015
+set g_balance_hagar_secondary_speed 1400
+set g_balance_hagar_secondary_lifetime_min 30
+set g_balance_hagar_secondary_lifetime_rand 0
+set g_balance_hagar_secondary_refire 0.15
+set g_balance_hagar_secondary_ammo 1
+// }}}
+// {{{ rocketlauncher // TODO
+set g_balance_rocketlauncher_damage 110
+set g_balance_rocketlauncher_edgedamage 25
+set g_balance_rocketlauncher_force 350
+set g_balance_rocketlauncher_radius 125
+set g_balance_rocketlauncher_speed 1000
+set g_balance_rocketlauncher_speedaccel 0
+set g_balance_rocketlauncher_speedstart 1000
+set g_balance_rocketlauncher_lifetime 5
+set g_balance_rocketlauncher_refire 1
+set g_balance_rocketlauncher_animtime 0.4
+set g_balance_rocketlauncher_ammo 3
+set g_balance_rocketlauncher_health 10
+set g_balance_rocketlauncher_damageforcescale 0
+set g_balance_rocketlauncher_detonatedelay -1 // positive: timer till detonation is allowed, negative: "security device" that prevents ANY remote detonation if it could hurt its owner, zero: detonatable at any time
+set g_balance_rocketlauncher_guiderate 45 // max degrees per second
+set g_balance_rocketlauncher_guideratedelay 0.01 // immediate
+set g_balance_rocketlauncher_guidegoal 512 // goal distance for (non-laser) guiding (higher = less control, lower = erratic)
+set g_balance_rocketlauncher_guidedelay 0.15 // delay before guiding kicks in
+set g_balance_rocketlauncher_guidestop 0 // stop guiding when firing again
+set g_balance_rocketlauncher_laserguided_speed 1000 //650
+set g_balance_rocketlauncher_laserguided_speedaccel 0
+set g_balance_rocketlauncher_laserguided_speedstart 1000
+set g_balance_rocketlauncher_laserguided_turnrate 0.75 //0.5
+set g_balance_rocketlauncher_laserguided_allow_steal 1
+set g_balance_rocketlauncher_remote_damage 90
+set g_balance_rocketlauncher_remote_edgedamage 20
+set g_balance_rocketlauncher_remote_radius 125
+set g_balance_rocketlauncher_remote_force 350
+// }}}
+// {{{ porto
+set g_balance_porto_primary_refire 1.5
+set g_balance_porto_primary_animtime 0.3
+set g_balance_porto_primary_speed 2000
+set g_balance_porto_primary_lifetime 30
+set g_balance_portal_health 200 // these get recharged whenever the portal is used
+set g_balance_portal_lifetime 15 // these get recharged whenever the portal is used
+// }}}
+// {{{ hook
+set g_balance_hook_primary_fuel 5 // hook monkeys set 0
+set g_balance_hook_primary_refire 0 // hook monkeys set 0
+set g_balance_hook_primary_animtime 0.3 // good shoot anim
+set g_balance_hook_primary_hooked_time_max 0 // infinite
+set g_balance_hook_primary_hooked_time_free 2 // 2s being hooked are free
+set g_balance_hook_primary_hooked_fuel 5 // fuel per second hooked
+set g_balance_hook_secondary_damage 25 // not much
+set g_balance_hook_secondary_edgedamage 5 // not much
+set g_balance_hook_secondary_radius 500 // LOTS
+set g_balance_hook_secondary_force -2000 // LOTS
+set g_balance_hook_secondary_ammo 50 // a whole pack
+set g_balance_hook_secondary_lifetime 5 // infinite
+set g_balance_hook_secondary_speed 0 // not much throwing
+set g_balance_hook_secondary_gravity 5 // fast falling
+set g_balance_hook_secondary_refire 3 // don't drop too many bombs...
+set g_balance_hook_secondary_animtime 0.3 // good shoot anim
+set g_balance_hook_secondary_power 3 // effect behaves like a square function
+set g_balance_hook_secondary_duration 1.5 // effect runs for three seconds
+// }}}
+// {{{ hlac
+set g_balance_hlac_primary_spread_min 0.01
+set g_balance_hlac_primary_spread_max 0.6
+set g_balance_hlac_primary_spread_add 0.01
+set g_balance_hlac_primary_spread_crouchmod 0.5
+
+set g_balance_hlac_primary_damage 22
+set g_balance_hlac_primary_edgedamage 2
+set g_balance_hlac_primary_force -100
+set g_balance_hlac_primary_radius 100
+set g_balance_hlac_primary_speed 5000
+set g_balance_hlac_primary_lifetime 3
+
+set g_balance_hlac_primary_refire 0.1
+set g_balance_hlac_primary_animtime 0.4
+set g_balance_hlac_primary_ammo 1
+
+set g_balance_hlac_secondary 1
+set g_balance_hlac_secondary_spread 0.2
+set g_balance_hlac_secondary_spread_crouchmod 0.5
+
+set g_balance_hlac_secondary_damage 20
+set g_balance_hlac_secondary_edgedamage 3
+set g_balance_hlac_secondary_force 100
+set g_balance_hlac_secondary_radius 50
+set g_balance_hlac_secondary_speed 9000
+set g_balance_hlac_secondary_lifetime 3
+set g_balance_hlac_secondary_refire 1
+set g_balance_hlac_secondary_animtime 0.7
+set g_balance_hlac_secondary_ammo 10
+set g_balance_hlac_secondary_shots 6
+// }}}
+// {{{ campingrifle
+set g_balance_campingrifle_magazinecapacity 8 // make it pretty much useless in close combat
+set g_balance_campingrifle_reloadtime 2 // matches reload anim
+set g_balance_campingrifle_auto_reload_after_changing_weapons 0
+set g_balance_campingrifle_bursttime 0
+set g_balance_campingrifle_primary_tracer 1
+set g_balance_campingrifle_primary_damage 75
+set g_balance_campingrifle_primary_headshotaddeddamage 75
+set g_balance_campingrifle_primary_spread 0
+set g_balance_campingrifle_primary_force 2
+set g_balance_campingrifle_primary_speed 40000
+set g_balance_campingrifle_primary_lifetime 5
+set g_balance_campingrifle_primary_refire 1.5
+set g_balance_campingrifle_primary_animtime 0.6
+set g_balance_campingrifle_primary_ammo 10
+set g_balance_campingrifle_primary_bulletconstant 110 // 62.2qu
+set g_balance_campingrifle_primary_burstcost 0
+set g_balance_campingrifle_primary_bullethail 0 // empty magazine on shot
+set g_balance_campingrifle_secondary 1
+set g_balance_campingrifle_secondary_tracer 0
+set g_balance_campingrifle_secondary_damage 50
+set g_balance_campingrifle_secondary_headshotaddeddamage 50 // 50 damage only on head
+set g_balance_campingrifle_secondary_spread 0
+set g_balance_campingrifle_secondary_force 2
+set g_balance_campingrifle_secondary_speed 20000
+set g_balance_campingrifle_secondary_lifetime 5
+set g_balance_campingrifle_secondary_refire 1.5
+set g_balance_campingrifle_secondary_animtime 0.6
+set g_balance_campingrifle_secondary_ammo 10
+set g_balance_campingrifle_secondary_bulletconstant 110 // 15.5qu
+set g_balance_campingrifle_secondary_burstcost 0
+set g_balance_campingrifle_secondary_bullethail 0 // empty magazine on shot
+// }}}
+// {{{ tuba
+set g_balance_tuba_refire 0.05
+set g_balance_tuba_animtime 0.05
+set g_balance_tuba_attenuation 0.5
+set g_balance_tuba_volume 1
+set g_balance_tuba_fadetime 0.25
+set g_balance_tuba_damage 5
+set g_balance_tuba_edgedamage 0
+set g_balance_tuba_radius 200
+set g_balance_tuba_force 40
+// }}}
+// {{{ fireball
+set g_balance_fireball_primary_ammo 40
+set g_balance_fireball_primary_animtime 0.15
+set g_balance_fireball_primary_bfgdamage 100
+set g_balance_fireball_primary_bfgforce 0
+set g_balance_fireball_primary_bfgradius 1000
+set g_balance_fireball_primary_damage 200
+set g_balance_fireball_primary_damageforcescale 4
+set g_balance_fireball_primary_edgedamage 0
+set g_balance_fireball_primary_force 700
+set g_balance_fireball_primary_health 50
+set g_balance_fireball_primary_laserburntime 0.5
+set g_balance_fireball_primary_laserdamage 80
+set g_balance_fireball_primary_laseredgedamage 20
+set g_balance_fireball_primary_laserradius 256
+set g_balance_fireball_primary_lifetime 15
+set g_balance_fireball_primary_radius 200
+set g_balance_fireball_primary_refire 5
+set g_balance_fireball_primary_refire2 0
+set g_balance_fireball_primary_speed 650
+set g_balance_fireball_primary_spread 0
+set g_balance_fireball_secondary_ammo 5
+set g_balance_fireball_secondary_animtime 0.3
+set g_balance_fireball_secondary_damage 40
+set g_balance_fireball_secondary_damageforcescale 4
+set g_balance_fireball_secondary_damagetime 5
+set g_balance_fireball_secondary_force 100
+set g_balance_fireball_secondary_laserburntime 0.5
+set g_balance_fireball_secondary_laserdamage 50
+set g_balance_fireball_secondary_laseredgedamage 20
+set g_balance_fireball_secondary_laserradius 110
+set g_balance_fireball_secondary_lifetime 7
+set g_balance_fireball_secondary_refire 2
+set g_balance_fireball_secondary_speed 900
+set g_balance_fireball_secondary_speed_up 100
+set g_balance_fireball_secondary_speed_z 0
+set g_balance_fireball_secondary_spread 0
+// }}}
+// {{{ seeker
+set g_balance_seeker_flac_ammo 0.5
+set g_balance_seeker_flac_animtime 0.1
+set g_balance_seeker_flac_damage 15
+set g_balance_seeker_flac_edgedamage 10
+set g_balance_seeker_flac_force 50
+set g_balance_seeker_flac_lifetime 0.05
+set g_balance_seeker_flac_lifetime_rand 0.02
+set g_balance_seeker_flac_radius 100
+set g_balance_seeker_flac_refire 0.1
+set g_balance_seeker_flac_speed 5000
+set g_balance_seeker_flac_speed_up 500
+set g_balance_seeker_flac_speed_z 0
+set g_balance_seeker_flac_spread 0.25
+
+set g_balance_seeker_missile_accel 1.05
+set g_balance_seeker_missile_ammo 2
+set g_balance_seeker_missile_animtime 0.3
+set g_balance_seeker_missile_count 4
+set g_balance_seeker_missile_damage 40
+set g_balance_seeker_missile_damageforcescale 4
+set g_balance_seeker_missile_decel 0.9
+set g_balance_seeker_missile_delay 0.25
+set g_balance_seeker_missile_edgedamage 10
+set g_balance_seeker_missile_force 250
+set g_balance_seeker_missile_health 5
+set g_balance_seeker_missile_lifetime 15
+set g_balance_seeker_missile_proxy 0
+set g_balance_seeker_missile_proxy_delay 0.2
+set g_balance_seeker_missile_proxy_maxrange 45
+set g_balance_seeker_missile_radius 80
+set g_balance_seeker_missile_refire 0.5
+set g_balance_seeker_missile_smart 1
+set g_balance_seeker_missile_smart_mindist 800
+set g_balance_seeker_missile_smart_trace_max 2500
+set g_balance_seeker_missile_smart_trace_min 1000
+set g_balance_seeker_missile_speed 700
+set g_balance_seeker_missile_speed_accel 0
+set g_balance_seeker_missile_speed_up 300
+set g_balance_seeker_missile_speed_z 0
+set g_balance_seeker_missile_speed_max 1250
+set g_balance_seeker_missile_spread 0
+set g_balance_seeker_missile_turnrate 0.65
+
+set g_balance_seeker_tag_ammo 1
+set g_balance_seeker_tag_animtime 0.3
+set g_balance_seeker_tag_damageforcescale 4
+set g_balance_seeker_tag_health 5
+set g_balance_seeker_tag_lifetime 15
+set g_balance_seeker_tag_refire 0.7
+set g_balance_seeker_tag_speed 9000
+set g_balance_seeker_tag_spread 0
+// End new seeker
index b89fdda..b340e5d 100644 (file)
@@ -26,11 +26,13 @@ gameversion_max 65535 // git builds see all versions
 alias setreport "set \"$1\" \"$2\" ; sendcvar \"$1\""
 
 // detect dedicated server or client
-alias "_detect_dedicated_$qport" "$*"
+alias "_detect_dedicated_$qport" "${* asis}"
 alias "_detect_dedicated_0" ""
-alias if_dedicated "_detect_dedicated_$qport ${* asis}"
+alias _if_dedicated "_detect_dedicated_$qport ${* asis}"
 alias if_client "${* asis}"
-if_dedicated alias if_client ""
+alias if_dedicated "${* asis}"
+_if_dedicated alias if_client ""
+if_client alias if_dedicated ""
 
 seta g_configversion 0 "Configuration file version (used to upgrade settings) 0: first run, or previous start was <2.4.1  Later, it's overridden by config.cfg, version ranges are defined in config_update.cfg"
 
@@ -96,6 +98,8 @@ seta crosshair_size 0.35
 seta crosshair_dot 1
 seta crosshair_dot_alpha 1
 seta crosshair_dot_size 1
+seta crosshair_pickup 0.25
+seta crosshair_pickup_speed 4
 seta crosshair_per_weapon 0    "when 1, each gun will display a different crosshair"
 seta crosshair_color_override 0        "when 1, crosshair_color_* overrides the per-weapon color"
 seta crosshair_effect_speed -1 "how fast (in seconds) some crosshair effects should take place, 0 = instant, -1 = 2x weapon switch time"
@@ -107,109 +111,109 @@ seta crosshair_laser "" "crosshair to display when wielding the laser"
 seta crosshair_laser_color_red 1       "crosshair color red component to display when wielding the laser"
 seta crosshair_laser_color_green 0.35  "crosshair color green component to display when wielding the laser"
 seta crosshair_laser_color_blue 0.2    "crosshair color blue component to display when wielding the laser"
-seta crosshair_laser_color_alpha 0.75  "crosshair alpha value to display when wielding the laser"
+seta crosshair_laser_alpha 0.75        "crosshair alpha value to display when wielding the laser"
 seta crosshair_laser_size 0.4  "crosshair size when wielding the laser"
 seta crosshair_shotgun ""      "crosshair to display when wielding the shotgun"
 seta crosshair_shotgun_color_red 0.7   "crosshair color red component to display when wielding the shotgun"
 seta crosshair_shotgun_color_green 0.7 "crosshair color green component to display when wielding the shotgun"
 seta crosshair_shotgun_color_blue 0.7  "crosshair color blue component to display when wielding the shotgun"
-seta crosshair_shotgun_color_alpha 1.1 "crosshair alpha value to display when wielding the shotgun"
+seta crosshair_shotgun_alpha 1.1       "crosshair alpha value to display when wielding the shotgun"
 seta crosshair_shotgun_size 0.65       "crosshair size when wielding the shotgun"
 seta crosshair_uzi ""  "crosshair to display when wielding the machinegun"
 seta crosshair_uzi_color_red 0.4       "crosshair color red component to display when wielding the machinegun"
 seta crosshair_uzi_color_green 0.9     "crosshair color green component to display when wielding the machinegun"
 seta crosshair_uzi_color_blue 0.35     "crosshair color blue component to display when wielding the machinegun"
-seta crosshair_uzi_color_alpha 0.9     "crosshair alpha value to display when wielding the machinegun"
+seta crosshair_uzi_alpha 0.9   "crosshair alpha value to display when wielding the machinegun"
 seta crosshair_uzi_size 0.6    "crosshair size when wielding the machinegun"
 seta crosshair_grenadelauncher ""      "crosshair to display when wielding the mortar"
 seta crosshair_grenadelauncher_color_red 1     "crosshair color red component to display when wielding the mortar"
 seta crosshair_grenadelauncher_color_green 0.15        "crosshair color green component to display when wielding the mortar"
 seta crosshair_grenadelauncher_color_blue 0    "crosshair color blue component to display when wielding the mortar"
-seta crosshair_grenadelauncher_color_alpha 1.15        "crosshair alpha value to display when wielding the mortar"
+seta crosshair_grenadelauncher_alpha 1.15      "crosshair alpha value to display when wielding the mortar"
 seta crosshair_grenadelauncher_size 0.7        "crosshair size when wielding the mortar"
 seta crosshair_minelayer ""    "crosshair to display when wielding the mortar"
 seta crosshair_minelayer_color_red 0.75        "crosshair color red component to display when wielding the mortar"
 seta crosshair_minelayer_color_green 0.75      "crosshair color green component to display when wielding the mortar"
 seta crosshair_minelayer_color_blue 0  "crosshair color blue component to display when wielding the mortar"
-seta crosshair_minelayer_color_alpha 1.15      "crosshair alpha value to display when wielding the mortar"
+seta crosshair_minelayer_alpha 1.15    "crosshair alpha value to display when wielding the mortar"
 seta crosshair_minelayer_size 0.9      "crosshair size when wielding the mortar"
 seta crosshair_electro ""      "crosshair to display when wielding the electro"
 seta crosshair_electro_color_red 0.35  "crosshair color red component to display when wielding the electro"
 seta crosshair_electro_color_green 0.5 "crosshair color green component to display when wielding the electro"
 seta crosshair_electro_color_blue 1    "crosshair color blue component to display when wielding the electro"
-seta crosshair_electro_color_alpha 1   "crosshair alpha value to display when wielding the electro"
+seta crosshair_electro_alpha 1 "crosshair alpha value to display when wielding the electro"
 seta crosshair_electro_size 0.5        "crosshair size when wielding the electro"
 seta crosshair_crylink ""      "crosshair to display when wielding the crylink"
 seta crosshair_crylink_color_red 0.85  "crosshair color red component to display when wielding the crylink"
 seta crosshair_crylink_color_green 0.25        "crosshair color green component to display when wielding the crylink"
 seta crosshair_crylink_color_blue 1    "crosshair color blue component to display when wielding the crylink"
-seta crosshair_crylink_color_alpha 0.85        "crosshair alpha value to display when wielding the crylink"
+seta crosshair_crylink_alpha 0.85      "crosshair alpha value to display when wielding the crylink"
 seta crosshair_crylink_size 0.4        "crosshair size when wielding the crylink"
 seta crosshair_nex ""  "crosshair to display when wielding the nex gun"
 seta crosshair_nex_color_red 0 "crosshair color red component to display when wielding the nex gun"
 seta crosshair_nex_color_green 0.9     "crosshair color green component to display when wielding the nex gun"
 seta crosshair_nex_color_blue 1        "crosshair color blue component to display when wielding the nex gun"
-seta crosshair_nex_color_alpha 0.85    "crosshair alpha value to display when wielding the nex gun"
+seta crosshair_nex_alpha 0.85  "crosshair alpha value to display when wielding the nex gun"
 seta crosshair_nex_size 0.65   "crosshair size when wielding the nex gun"
 seta crosshair_hagar ""        "crosshair to display when wielding the hagar"
 seta crosshair_hagar_color_red 0.85    "crosshair color red component to display when wielding the hagar"
 seta crosshair_hagar_color_green 0.5   "crosshair color green component to display when wielding the hagar"
 seta crosshair_hagar_color_blue 0.35   "crosshair color blue component to display when wielding the hagar"
-seta crosshair_hagar_color_alpha 1     "crosshair alpha value to display when wielding the hagar"
+seta crosshair_hagar_alpha 1   "crosshair alpha value to display when wielding the hagar"
 seta crosshair_hagar_size 0.8  "crosshair size when wielding the hagar"
 seta crosshair_rocketlauncher ""       "crosshair to display when wielding the rocketlauncher"
 seta crosshair_rocketlauncher_color_red 1      "crosshair color red component to display when wielding the rocketlauncher"
 seta crosshair_rocketlauncher_color_green 0.75 "crosshair color green component to display when wielding the rocketlauncher"
 seta crosshair_rocketlauncher_color_blue 0.2   "crosshair color blue component to display when wielding the rocketlauncher"
-seta crosshair_rocketlauncher_color_alpha 1    "crosshair alpha value to display when wielding the rocketlauncher"
+seta crosshair_rocketlauncher_alpha 1  "crosshair alpha value to display when wielding the rocketlauncher"
 seta crosshair_rocketlauncher_size 0.5875      "crosshair size when wielding the rocketlauncher"
 seta crosshair_porto ""        "crosshair to display when wielding the porto"
 seta crosshair_porto_color_red 0.5     "crosshair color red component to display when wielding the porto"
 seta crosshair_porto_color_green 1     "crosshair color green component to display when wielding the porto"
 seta crosshair_porto_color_blue 0.5    "crosshair color blue component to display when wielding the porto"
-seta crosshair_porto_color_alpha 0.85  "crosshair alpha value to display when wielding the porto"
+seta crosshair_porto_alpha 0.85        "crosshair alpha value to display when wielding the porto"
 seta crosshair_porto_size 0.6  "crosshair size when wielding the porto"
 seta crosshair_minstanex ""    "crosshair to display when wielding the minstanex gun"
 seta crosshair_minstanex_color_red 0.65        "crosshair color red component to display when wielding the minstanex gun"
 seta crosshair_minstanex_color_green 0.65      "crosshair color green component to display when wielding the minstanex gun"
 seta crosshair_minstanex_color_blue 1  "crosshair color blue component to display when wielding the minstanex gun"
-seta crosshair_minstanex_color_alpha 1 "crosshair alpha value to display when wielding the minstanex gun"
+seta crosshair_minstanex_alpha 1       "crosshair alpha value to display when wielding the minstanex gun"
 seta crosshair_minstanex_size 0.4      "crosshair size when wielding the minstanex gun"
 seta crosshair_hook "" "crosshair to display when wielding the hook"
 seta crosshair_hook_color_red 0.65     "crosshair color red component to display when wielding the hook"
 seta crosshair_hook_color_green 1      "crosshair color green component to display when wielding the hook"
 seta crosshair_hook_color_blue 0.85    "crosshair color blue component to display when wielding the hook"
-seta crosshair_hook_color_alpha 0.85   "crosshair alpha value to display when wielding the hook"
+seta crosshair_hook_alpha 0.85 "crosshair alpha value to display when wielding the hook"
 seta crosshair_hook_size 0.5   "crosshair size when wielding the hook"
 seta crosshair_hlac "" "crosshair to display when wielding the H.L.A.C"
 seta crosshair_hlac_color_red 1        "crosshair color red component to display when wielding the H.L.A.C."
 seta crosshair_hlac_color_green 0.65   "crosshair color green component to display when wielding the H.L.A.C."
 seta crosshair_hlac_color_blue 0.2     "crosshair color blue component to display when wielding the H.L.A.C."
-seta crosshair_hlac_color_alpha 1      "crosshair alpha value to display when wielding the H.L.A.C."
+seta crosshair_hlac_alpha 1    "crosshair alpha value to display when wielding the H.L.A.C."
 seta crosshair_hlac_size 0.6   "crosshair size when wielding the H.L.A.C."
 seta crosshair_seeker ""       "crosshair to display when wielding the TAG Seeker"
 seta crosshair_seeker_color_red 1      "crosshair color red component to display when wielding the TAG seeker"
 seta crosshair_seeker_color_green 0.35 "crosshair color green component to display when wielding the TAG seeker"
 seta crosshair_seeker_color_blue 0.35  "crosshair color blue component to display when wielding the TAG seeker"
-seta crosshair_seeker_color_alpha 0.9  "crosshair alpha value to display when wielding the TAG seeker"
+seta crosshair_seeker_alpha 0.9        "crosshair alpha value to display when wielding the TAG seeker"
 seta crosshair_seeker_size 0.8 "crosshair size when wielding the TAG seeker"
 seta crosshair_campingrifle "" "crosshair to display when wielding the campingrifle"
 seta crosshair_campingrifle_color_red 0.85     "crosshair color red component to display when wielding the campingrifle"
 seta crosshair_campingrifle_color_green 0.5    "crosshair color green component to display when wielding the campingrifle"
 seta crosshair_campingrifle_color_blue 0.25    "crosshair color blue component to display when wielding the campingrifle"
-seta crosshair_campingrifle_color_alpha 1      "crosshair alpha value to display when wielding the campingrifle"
+seta crosshair_campingrifle_alpha 1    "crosshair alpha value to display when wielding the campingrifle"
 seta crosshair_campingrifle_size 0.65  "crosshair size when wielding the campingrifle"
 seta crosshair_tuba "" "crosshair to display when wielding the tuba"
 seta crosshair_tuba_color_red 0.85     "crosshair color red component to display when wielding the tuba"
 seta crosshair_tuba_color_green 0.5    "crosshair color green component to display when wielding the tuba"
 seta crosshair_tuba_color_blue 0.25    "crosshair color blue component to display when wielding the tuba"
-seta crosshair_tuba_color_alpha 1      "crosshair alpha value to display when wielding the tuba"
+seta crosshair_tuba_alpha 1    "crosshair alpha value to display when wielding the tuba"
 seta crosshair_tuba_size 1     "crosshair size when wielding the tuba"
 seta crosshair_fireball ""     "crosshair to display when wielding the fireball"
 seta crosshair_fireball_color_red 0.2  "crosshair color red component to display when wielding the fireball"
 seta crosshair_fireball_color_green 1.0        "crosshair color green component to display when wielding the fireball"
 seta crosshair_fireball_color_blue 0.2 "crosshair color blue component to display when wielding the fireball"
-seta crosshair_fireball_color_alpha 1  "crosshair alpha value to display when wielding the fireball"
+seta crosshair_fireball_alpha 1        "crosshair alpha value to display when wielding the fireball"
 seta crosshair_fireball_size 1 "crosshair size when wielding the fireball"
 seta crosshair_ring_size 2     "bullet counter ring size for Rifle, velocity ring for Nex"
 seta crosshair_campingrifle_bulletcounter_alpha 0.15
@@ -487,7 +491,7 @@ alias g_waypointeditor_unreachable "impulse 107"
 
 locs_enable 0
 pausable 0
-seta g_spawnshieldtime 0.3 "number of seconds you are invincible after you spawned, this shield is lost after you fire"
+seta g_spawnshieldtime 0.300000 "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_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)"
@@ -626,8 +630,9 @@ set g_ons_respawn_waves 0
 set g_rc_respawn_waves 0
 set g_rc_respawn_delay 0
 set g_cts_respawn_waves 0
-set g_cts_respawn_delay 0
+set g_cts_respawn_delay 0.25
 set g_cts_selfdamage 1 "0 = disable all selfdamage and falldamage in cts"
+set g_cts_finish_kill_delay 10 "prevent cheating by running back to the start line, and starting out with more speed than otherwise possible"
 
 // overtime
 seta timelimit_overtime 2 "duration in minutes of one added overtime, added to the timelimit"
@@ -638,8 +643,8 @@ seta timelimit_suddendeath 5 "number of minutes suddendeath mode lasts after all
 set g_tdm 0 "Team Deathmatch: the team who kills their opponents most often wins"
 
 seta teamplay_default 4 "default teamplay setting in team games. 1 = no friendly fire, self damage. 2 = friendly fire and self damage enabled. 3 = no friendly fire, but self damage enabled. 4 = obey the following four cvars"
-seta g_mirrordamage 0.3        "for teamplay 4: mirror damage factor"
-seta g_friendlyfire 0.1        "for teamplay 4: fiendly fire factor"
+seta g_mirrordamage 0.300000   "for teamplay 4: mirror damage factor"
+seta g_friendlyfire 0.100000   "for teamplay 4: fiendly fire factor"
 seta g_teamdamage_threshold 50 "for teamplay 4: threshold over which to apply mirror damage"
 seta g_teamdamage_resetspeed 30        "for teamplay 4: how fast player's teamdamage count decreases"
 
@@ -1337,6 +1342,9 @@ alias _userbind_call "${$1}"
 alias +userbind "_userbind_call userbind${1}_press"
 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
+
 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"
@@ -1590,8 +1598,8 @@ seta sv_status_privacy 1  "hide IP addresses from \"status\" replies shown to cli
 set g_maplist_allow_hidden 0           "allow hidden maps to be, e.g., voted for and in the maplist"
 set g_maplist_allow_frustrating 0      "allow impossible maps to be, e.g., voted for and in the maplist (if set to 2, ONLY impossible maps are allowed)"
 
-seta g_start_delay 0   "delay before the game starts, so everyone can join; recommended to set this to like 15 on a public server"
-       if_dedicated set g_start_delay 15
+if_client set g_start_delay 0  "delay before the game starts, so everyone can join; recommended to set this to like 15 on a public server"
+if_dedicated set g_start_delay 15      "delay before the game starts, so everyone can join; recommended to set this to like 15 on a public server"
 
 alias ons_map           "cl_cmd radar" // legacy alias
 alias radar             "cl_cmd radar"
@@ -1650,6 +1658,7 @@ set g_showweaponspawns 1  "display sprites for weapon spawns found on the map whe
 
 alias records "cmd records"
 alias rankings "cmd rankings"
+alias ladder "cmd ladder"
 
 // ballistics use physical units, but qu based
 //   Quake-Newton: 1 qN  = 1 qu * 1 g / 1 s^2
@@ -1994,3 +2003,6 @@ r_font_size_snapping 2
 // database management
 set sv_db_saveasdump 0 "write server.db in dump format (loads slower, easier to read/parse)"
 set cl_db_saveasdump 0 "write client.db in dump format (loads slower, easier to read/parse)"
+
+// uid2name
+seta cl_allow_uid2name -1 "-1 = ask if the player wants to disable/enable this feature, 0 = disable, 1 = enable uid2name (allows showing your name in race rankings for instance)"
index b36570a..3ad766d 100644 (file)
@@ -4662,7 +4662,7 @@ lightcolor 0.9 0.9 0.2
 // used in qcsrc/server/w_common.qc:                           zcurveparticles_from_tracetoss(particleeffectnum("tr_bullet"), self.origin, trace_endpos, self.velocity)
 // used in qcsrc/client/projectile.qc:                 trailparticles(self, particleeffectnum("tr_bullet"), from, to)
 effect tr_rifle
-trailspacing 256
+trailspacing 128
 type spark
 color 0x800000 0xFF8020
 alpha 256 256 2560
@@ -4672,22 +4672,22 @@ velocitymultiplier 0.7
 effect tr_rifle
 notunderwater
 tex 0 8
-trailspacing 16
+trailspacing 8
 type static
 color 0x202020 0x404040
-size 2 2
-sizeincrease 0.2
+size 4 4
+sizeincrease 0.4
 alpha 256 256 256
 airfriction -4
 velocityjitter 4 4 4
 type smoke
 effect tr_rifle
 underwater
-trailspacing 64
+trailspacing 32
 type bubble
 tex 62 62
 color 0x404040 0x808080
-size 1 1
+size 2 2
 alpha 256 256 128
 gravity -0.125
 bounce 1.5
@@ -4983,7 +4983,7 @@ size 16 16
 alpha 256 256 0
 originjitter 2 2 2
 lightradius 50
-lightradiusfade 200
+lightradiusfade 500
 lightcolor 3.125 4.375 10
 effect electro_lightning
 count 300
index d6c09e9..fd0f477 100644 (file)
Binary files a/gfx/crosshair1.tga and b/gfx/crosshair1.tga differ
index e7b5774..7d3f97a 100644 (file)
Binary files a/gfx/crosshair10.tga and b/gfx/crosshair10.tga differ
index d1486ad..ed66200 100644 (file)
Binary files a/gfx/crosshair11.tga and b/gfx/crosshair11.tga differ
index 95892ab..a9e9128 100644 (file)
Binary files a/gfx/crosshair12.tga and b/gfx/crosshair12.tga differ
index e9f17a7..257e149 100644 (file)
Binary files a/gfx/crosshair13.tga and b/gfx/crosshair13.tga differ
index b03e14d..95a2914 100644 (file)
Binary files a/gfx/crosshair14.tga and b/gfx/crosshair14.tga differ
index 3fcdd0b..858bc07 100644 (file)
Binary files a/gfx/crosshair15.tga and b/gfx/crosshair15.tga differ
index 8e9d2d9..7424f0a 100644 (file)
Binary files a/gfx/crosshair16.tga and b/gfx/crosshair16.tga differ
index c22551a..385f6fb 100644 (file)
Binary files a/gfx/crosshair17.tga and b/gfx/crosshair17.tga differ
index 5a6bfb7..8e9d2d9 100644 (file)
Binary files a/gfx/crosshair18.tga and b/gfx/crosshair18.tga differ
index 13cf4b7..6c59762 100644 (file)
Binary files a/gfx/crosshair19.tga and b/gfx/crosshair19.tga differ
index 4e2bd79..8bd44ed 100644 (file)
Binary files a/gfx/crosshair2.tga and b/gfx/crosshair2.tga differ
index 6c59762..2dc7a60 100644 (file)
Binary files a/gfx/crosshair20.tga and b/gfx/crosshair20.tga differ
diff --git a/gfx/crosshair21.tga b/gfx/crosshair21.tga
deleted file mode 100644 (file)
index 4a7e5f5..0000000
Binary files a/gfx/crosshair21.tga and /dev/null differ
index db5f2cc..aef62e3 100644 (file)
Binary files a/gfx/crosshair3.tga and b/gfx/crosshair3.tga differ
index 2c4f312..5ebc4ff 100644 (file)
Binary files a/gfx/crosshair4.tga and b/gfx/crosshair4.tga differ
index 905045f..fc3410c 100644 (file)
Binary files a/gfx/crosshair5.tga and b/gfx/crosshair5.tga differ
index b005d96..1d3e83d 100644 (file)
Binary files a/gfx/crosshair6.tga and b/gfx/crosshair6.tga differ
index 64f6d5d..f76ef23 100644 (file)
Binary files a/gfx/crosshair7.tga and b/gfx/crosshair7.tga differ
index df9e414..8e71e06 100644 (file)
Binary files a/gfx/crosshair8.tga and b/gfx/crosshair8.tga differ
index a1e7694..1d3e7ec 100644 (file)
Binary files a/gfx/crosshair9.tga and b/gfx/crosshair9.tga differ
index a2ffef2..8d8741b 100644 (file)
Binary files a/gfx/crosshairdot.tga and b/gfx/crosshairdot.tga differ
diff --git a/gfx/menu/default/icon_aeslevel0.tga b/gfx/menu/default/icon_aeslevel0.tga
new file mode 100644 (file)
index 0000000..5c9e66a
Binary files /dev/null and b/gfx/menu/default/icon_aeslevel0.tga differ
diff --git a/gfx/menu/default/icon_aeslevel1.tga b/gfx/menu/default/icon_aeslevel1.tga
new file mode 100644 (file)
index 0000000..f1e9273
Binary files /dev/null and b/gfx/menu/default/icon_aeslevel1.tga differ
diff --git a/gfx/menu/default/icon_aeslevel2.tga b/gfx/menu/default/icon_aeslevel2.tga
new file mode 100644 (file)
index 0000000..7153820
Binary files /dev/null and b/gfx/menu/default/icon_aeslevel2.tga differ
diff --git a/gfx/menu/default/icon_aeslevel3.tga b/gfx/menu/default/icon_aeslevel3.tga
new file mode 100644 (file)
index 0000000..c31bfe8
Binary files /dev/null and b/gfx/menu/default/icon_aeslevel3.tga differ
diff --git a/gfx/menu/default/icon_aeslevel4.tga b/gfx/menu/default/icon_aeslevel4.tga
new file mode 100644 (file)
index 0000000..88963f8
Binary files /dev/null and b/gfx/menu/default/icon_aeslevel4.tga differ
diff --git a/gfx/menu/default/icon_aeslevel5.tga b/gfx/menu/default/icon_aeslevel5.tga
new file mode 100644 (file)
index 0000000..0ed332d
Binary files /dev/null and b/gfx/menu/default/icon_aeslevel5.tga differ
diff --git a/gfx/menu/default/icon_pure0.tga b/gfx/menu/default/icon_pure0.tga
new file mode 100644 (file)
index 0000000..5c9e66a
Binary files /dev/null and b/gfx/menu/default/icon_pure0.tga differ
diff --git a/gfx/menu/default/icon_pure1.tga b/gfx/menu/default/icon_pure1.tga
new file mode 100644 (file)
index 0000000..62980d2
Binary files /dev/null and b/gfx/menu/default/icon_pure1.tga differ
diff --git a/gfx/menu/luminos/icon_aeslevel0.tga b/gfx/menu/luminos/icon_aeslevel0.tga
new file mode 100644 (file)
index 0000000..5c9e66a
Binary files /dev/null and b/gfx/menu/luminos/icon_aeslevel0.tga differ
diff --git a/gfx/menu/luminos/icon_aeslevel1.tga b/gfx/menu/luminos/icon_aeslevel1.tga
new file mode 100644 (file)
index 0000000..f1e9273
Binary files /dev/null and b/gfx/menu/luminos/icon_aeslevel1.tga differ
diff --git a/gfx/menu/luminos/icon_aeslevel2.tga b/gfx/menu/luminos/icon_aeslevel2.tga
new file mode 100644 (file)
index 0000000..7153820
Binary files /dev/null and b/gfx/menu/luminos/icon_aeslevel2.tga differ
diff --git a/gfx/menu/luminos/icon_aeslevel3.tga b/gfx/menu/luminos/icon_aeslevel3.tga
new file mode 100644 (file)
index 0000000..c31bfe8
Binary files /dev/null and b/gfx/menu/luminos/icon_aeslevel3.tga differ
diff --git a/gfx/menu/luminos/icon_aeslevel4.tga b/gfx/menu/luminos/icon_aeslevel4.tga
new file mode 100644 (file)
index 0000000..88963f8
Binary files /dev/null and b/gfx/menu/luminos/icon_aeslevel4.tga differ
diff --git a/gfx/menu/luminos/icon_aeslevel5.tga b/gfx/menu/luminos/icon_aeslevel5.tga
new file mode 100644 (file)
index 0000000..0ed332d
Binary files /dev/null and b/gfx/menu/luminos/icon_aeslevel5.tga differ
diff --git a/gfx/menu/luminos/icon_pure0.tga b/gfx/menu/luminos/icon_pure0.tga
new file mode 100644 (file)
index 0000000..5c9e66a
Binary files /dev/null and b/gfx/menu/luminos/icon_pure0.tga differ
diff --git a/gfx/menu/luminos/icon_pure1.tga b/gfx/menu/luminos/icon_pure1.tga
new file mode 100644 (file)
index 0000000..62980d2
Binary files /dev/null and b/gfx/menu/luminos/icon_pure1.tga differ
diff --git a/gfx/menu/xaw/icon_aeslevel0.tga b/gfx/menu/xaw/icon_aeslevel0.tga
new file mode 100644 (file)
index 0000000..5c9e66a
Binary files /dev/null and b/gfx/menu/xaw/icon_aeslevel0.tga differ
diff --git a/gfx/menu/xaw/icon_aeslevel1.tga b/gfx/menu/xaw/icon_aeslevel1.tga
new file mode 100644 (file)
index 0000000..f1e9273
Binary files /dev/null and b/gfx/menu/xaw/icon_aeslevel1.tga differ
diff --git a/gfx/menu/xaw/icon_aeslevel2.tga b/gfx/menu/xaw/icon_aeslevel2.tga
new file mode 100644 (file)
index 0000000..7153820
Binary files /dev/null and b/gfx/menu/xaw/icon_aeslevel2.tga differ
diff --git a/gfx/menu/xaw/icon_aeslevel3.tga b/gfx/menu/xaw/icon_aeslevel3.tga
new file mode 100644 (file)
index 0000000..c31bfe8
Binary files /dev/null and b/gfx/menu/xaw/icon_aeslevel3.tga differ
diff --git a/gfx/menu/xaw/icon_aeslevel4.tga b/gfx/menu/xaw/icon_aeslevel4.tga
new file mode 100644 (file)
index 0000000..88963f8
Binary files /dev/null and b/gfx/menu/xaw/icon_aeslevel4.tga differ
diff --git a/gfx/menu/xaw/icon_aeslevel5.tga b/gfx/menu/xaw/icon_aeslevel5.tga
new file mode 100644 (file)
index 0000000..0ed332d
Binary files /dev/null and b/gfx/menu/xaw/icon_aeslevel5.tga differ
diff --git a/gfx/menu/xaw/icon_pure0.tga b/gfx/menu/xaw/icon_pure0.tga
new file mode 100644 (file)
index 0000000..5c9e66a
Binary files /dev/null and b/gfx/menu/xaw/icon_pure0.tga differ
diff --git a/gfx/menu/xaw/icon_pure1.tga b/gfx/menu/xaw/icon_pure1.tga
new file mode 100644 (file)
index 0000000..62980d2
Binary files /dev/null and b/gfx/menu/xaw/icon_pure1.tga differ
index 9c50d7a..4846a9f 100644 (file)
@@ -627,6 +627,56 @@ float CSQC_InputEvent(float bInputType, float nPrimary, float nSecondary)
        local float bSkipKey;
        bSkipKey = false;
 
+       if(autocvar_cl_allow_uid2name == -1 && (gametype == GAME_CTS || gametype == GAME_RACE) && panel_fg_alpha && !scoreboard_active) // don't lock keys before we actually see what's going on
+       {
+               /*
+               string vyes_keys;
+               float keys;
+               vyes_keys = findkeysforcommand("vyes");
+               keys = tokenize(vyes_keys);
+
+               float i;
+               for (i = 0; i < keys; ++i)
+               {
+                       print(ftos(nPrimary), " ", argv(i), "\n"); 
+                       if(nPrimary == stof(argv(i)))
+                       {
+                               vote_active = 0;
+                               cvar_set("cl_allow_uid2name", "1");
+                               return TRUE;
+                       }
+               }
+
+               string vno_keys;
+               vno_keys = findkeysforcommand("vno");
+               keys = tokenize(vno_keys);
+
+               float i;
+               for (i = 0; i < keys; ++i)
+               {
+                       if(nPrimary == stof(argv(i)))
+                       {
+                               vote_active = 0;
+                               cvar_set("cl_allow_uid2name", "0");
+                               return TRUE;
+                       }
+               }
+               */ // If only I could grab F1-F12 in CSQC... but no
+
+               if(nPrimary == 121) // ascii value for y
+               {
+                       vote_active = 0;
+                       cvar_set("cl_allow_uid2name", "1");
+                       return TRUE;
+               }
+               else if(nPrimary == 110) // ascii value for n
+               {
+                       vote_active = 0;
+                       cvar_set("cl_allow_uid2name", "0");
+                       return TRUE;
+               }
+       }
+
        if (HUD_Panel_InputEvent(bInputType, nPrimary, nSecondary))
                return true;
 
@@ -636,6 +686,7 @@ float CSQC_InputEvent(float bInputType, float nPrimary, float nSecondary)
        if(menu_visible)
                if(menu_action(bInputType, nPrimary, nSecondary))
                        return TRUE;
+
        return bSkipKey;
 }
 
index 39f0586..074a3be 100644 (file)
@@ -349,6 +349,8 @@ void CSQC_RAPTOR_HUD();
 vector freeze_pmove_org, freeze_input_angles;
 entity nightvision_noise, nightvision_noise2;
 
+float pickup_crosshair_time, pickup_crosshair_size;
+
 void CSQC_UpdateView(float w, float h)
 {
        entity e;
@@ -356,6 +358,7 @@ void CSQC_UpdateView(float w, float h)
        float f, i, j;
        vector v, vo;
        vector vf_size, vf_min;
+       float a;
 
        vf_size = R_SetView3fv(VF_SIZE);
        vf_min = R_SetView3fv(VF_MIN);
@@ -567,7 +570,6 @@ void CSQC_UpdateView(float w, float h)
        {
                // apply night vision effect
                vector rgb, tc_00, tc_01, tc_10, tc_11;
-               float a;
 
                if(!nightvision_noise)
                {
@@ -698,6 +700,18 @@ void CSQC_UpdateView(float w, float h)
 
                // crosshair goes VERY LAST
                if(!scoreboard_active && !camera_active && intermission != 2) {
+                       string wcross_style;
+                       float wcross_alpha, wcross_resolution;
+                       wcross_style = cvar_string("crosshair");
+                       if (wcross_style == "0")
+                               return;
+                       wcross_resolution = cvar("crosshair_size");
+                       if (wcross_resolution == 0)
+                               return;
+                       wcross_alpha = cvar("crosshair_alpha");
+                       if (wcross_alpha == 0)
+                               return;
+
                        // TrueAim check
                        float shottype;
                        float bullets, ring_scale;
@@ -723,170 +737,183 @@ void CSQC_UpdateView(float w, float h)
                        else
                                shottype = SHOTTYPE_HITWORLD;
 
-                       string wcross_style;
-                       wcross_style = cvar_string("crosshair");
+                       vector wcross_color, wcross_size;
+                       string wcross_wep, wcross_name;
+                       float wcross_scale, wcross_blur;
 
-                       if (wcross_style != "0") {
-                               vector wcross_color, wcross_size;
-                               string wcross_wep, wcross_name;
-                               float wcross_alpha, wcross_scale, wcross_blur, wcross_resolution;
-
-                               wcross_color_x = cvar("crosshair_color_red");
-                               wcross_color_y = cvar("crosshair_color_green");
-                               wcross_color_z = cvar("crosshair_color_blue");
-                               wcross_alpha = cvar("crosshair_color_alpha");
-                               wcross_resolution = cvar("crosshair_size");
-                               if (cvar("crosshair_per_weapon")) {
-                                       e = get_weaponinfo(activeweapon);
-                                       if (e && e.netname != "")
+                       wcross_color_x = cvar("crosshair_color_red");
+                       wcross_color_y = cvar("crosshair_color_green");
+                       wcross_color_z = cvar("crosshair_color_blue");
+                       if (cvar("crosshair_per_weapon")) {
+                               e = get_weaponinfo(activeweapon);
+                               if (e && e.netname != "")
+                               {
+                                       wcross_wep = e.netname;
+                                       wcross_resolution *= cvar(strcat("crosshair_", wcross_wep, "_size"));
+                                       if (wcross_resolution == 0)
+                                               return;
+                                       wcross_alpha *= cvar(strcat("crosshair_", wcross_wep, "_alpha"));
+                                       if (wcross_alpha == 0)
+                                               return;
+
+                                       wcross_style = cvar_string(strcat("crosshair_", wcross_wep));
+                                       if(wcross_style == "")
+                                               wcross_style = e.netname;
+
+                                       if(!cvar("crosshair_color_override"))
                                        {
-                                               wcross_wep = e.netname;
-                                               wcross_style = cvar_string(strcat("crosshair_", wcross_wep));
-                                               if(wcross_style == "")
-                                                       wcross_style = e.netname;
-
-                                               if(!cvar("crosshair_color_override"))
-                                               {
-                                                       wcross_color_x = cvar(strcat("crosshair_", wcross_wep, "_color_red"));
-                                                       wcross_color_y = cvar(strcat("crosshair_", wcross_wep, "_color_green"));
-                                                       wcross_color_z = cvar(strcat("crosshair_", wcross_wep, "_color_blue"));
-                                               }
-
-                                               wcross_alpha *= cvar(strcat("crosshair_", wcross_wep, "_color_alpha"));
-                                               wcross_resolution *= cvar(strcat("crosshair_", wcross_wep, "_size"));
+                                               wcross_color_x = cvar(strcat("crosshair_", wcross_wep, "_color_red"));
+                                               wcross_color_y = cvar(strcat("crosshair_", wcross_wep, "_color_green"));
+                                               wcross_color_z = cvar(strcat("crosshair_", wcross_wep, "_color_blue"));
                                        }
                                }
+                       }
 
-                               wcross_name = strcat("gfx/crosshair", wcross_style);
+                       wcross_name = strcat("gfx/crosshair", wcross_style);
 
-                               if(cvar("crosshair_effect_scalefade"))
+                       if(cvar("crosshair_effect_scalefade"))
+                       {
+                               wcross_scale = wcross_resolution;
+                               wcross_resolution = 1;
+                       }
+                       else
+                       {
+                               wcross_scale = 1;
+                       }
+
+                       if(cvar("crosshair_pickup"))
+                       {
+                               if(pickup_crosshair_time < getstatf(STAT_LAST_PICKUP))
                                {
-                                       wcross_scale = wcross_resolution;
-                                       wcross_resolution = 1;
+                                       pickup_crosshair_size = 1;
+                                       pickup_crosshair_time = getstatf(STAT_LAST_PICKUP);
                                }
+
+                               if(pickup_crosshair_size > 0)
+                                       pickup_crosshair_size -= cvar("crosshair_pickup_speed") * frametime;
                                else
-                               {
-                                       wcross_scale = 1;
-                               }
+                                       pickup_crosshair_size = 0;
 
-                               if(shottype == SHOTTYPE_HITENEMY)
-                                       wcross_scale *= cvar("crosshair_hittest"); // is not queried if hittest is 0
-                               if(shottype == SHOTTYPE_HITTEAM)
-                                       wcross_scale /= cvar("crosshair_hittest"); // is not queried if hittest is 0
+                               wcross_scale += sin(pickup_crosshair_size) * cvar("crosshair_pickup");
+                       }
 
-                               f = cvar("crosshair_effect_speed");
-                               if(f < 0)
-                                       f *= -2 * g_weaponswitchdelay;
-                               if(wcross_scale != wcross_scale_goal_prev || wcross_alpha != wcross_alpha_goal_prev || wcross_color != wcross_color_goal_prev)
-                               {
-                                       wcross_changedonetime = time + f;
-                               }
-                               if(wcross_name != wcross_name_goal_prev || wcross_resolution != wcross_resolution_goal_prev)
-                               {
-                                       wcross_name_changestarttime = time;
-                                       wcross_name_changedonetime = time + f;
-                                       if(wcross_name_goal_prev_prev)
-                                               strunzone(wcross_name_goal_prev_prev);
-                                       wcross_name_goal_prev_prev = wcross_name_goal_prev;
-                                       wcross_name_goal_prev = strzone(wcross_name);
-                                       wcross_name_alpha_goal_prev_prev = wcross_name_alpha_goal_prev;
-                                       wcross_resolution_goal_prev_prev = wcross_resolution_goal_prev;
-                                       wcross_resolution_goal_prev = wcross_resolution;
-                               }
+                       if(shottype == SHOTTYPE_HITENEMY)
+                               wcross_scale *= cvar("crosshair_hittest"); // is not queried if hittest is 0
+                       if(shottype == SHOTTYPE_HITTEAM)
+                               wcross_scale /= cvar("crosshair_hittest"); // is not queried if hittest is 0
 
-                               wcross_scale_goal_prev = wcross_scale;
-                               wcross_alpha_goal_prev = wcross_alpha;
-                               wcross_color_goal_prev = wcross_color;
+                       f = cvar("crosshair_effect_speed");
+                       if(f < 0)
+                               f *= -2 * g_weaponswitchdelay;
+                       if(wcross_scale != wcross_scale_goal_prev || wcross_alpha != wcross_alpha_goal_prev || wcross_color != wcross_color_goal_prev)
+                       {
+                               wcross_changedonetime = time + f;
+                       }
+                       if(wcross_name != wcross_name_goal_prev || wcross_resolution != wcross_resolution_goal_prev)
+                       {
+                               wcross_name_changestarttime = time;
+                               wcross_name_changedonetime = time + f;
+                               if(wcross_name_goal_prev_prev)
+                                       strunzone(wcross_name_goal_prev_prev);
+                               wcross_name_goal_prev_prev = wcross_name_goal_prev;
+                               wcross_name_goal_prev = strzone(wcross_name);
+                               wcross_name_alpha_goal_prev_prev = wcross_name_alpha_goal_prev;
+                               wcross_resolution_goal_prev_prev = wcross_resolution_goal_prev;
+                               wcross_resolution_goal_prev = wcross_resolution;
+                       }
 
-                               if(shottype == SHOTTYPE_HITTEAM || (shottype == SHOTTYPE_HITOBSTRUCTION && cvar("crosshair_hittest_blur") && !cvar("chase_active")))
-                               {
-                                       wcross_blur = 1;
-                                       wcross_alpha *= 0.75;
-                               }
-                               else
-                                       wcross_blur = 0;
-                               // *_prev is at time-frametime
-                               // * is at wcross_changedonetime+f
-                               // what do we have at time?
-                               if(time < wcross_changedonetime)
-                               {
-                                       f = frametime / (wcross_changedonetime - time + frametime);
-                                       wcross_scale = f * wcross_scale + (1 - f) * wcross_scale_prev;
-                                       wcross_alpha = f * wcross_alpha + (1 - f) * wcross_alpha_prev;
-                                       wcross_color = f * wcross_color + (1 - f) * wcross_color_prev;
-                               }
+                       wcross_scale_goal_prev = wcross_scale;
+                       wcross_alpha_goal_prev = wcross_alpha;
+                       wcross_color_goal_prev = wcross_color;
 
-                               wcross_scale_prev = wcross_scale;
-                               wcross_alpha_prev = wcross_alpha;
-                               wcross_color_prev = wcross_color;
+                       if(shottype == SHOTTYPE_HITTEAM || (shottype == SHOTTYPE_HITOBSTRUCTION && cvar("crosshair_hittest_blur") && !cvar("chase_active")))
+                       {
+                               wcross_blur = 1;
+                               wcross_alpha *= 0.75;
+                       }
+                       else
+                               wcross_blur = 0;
+                       // *_prev is at time-frametime
+                       // * is at wcross_changedonetime+f
+                       // what do we have at time?
+                       if(time < wcross_changedonetime)
+                       {
+                               f = frametime / (wcross_changedonetime - time + frametime);
+                               wcross_scale = f * wcross_scale + (1 - f) * wcross_scale_prev;
+                               wcross_alpha = f * wcross_alpha + (1 - f) * wcross_alpha_prev;
+                               wcross_color = f * wcross_color + (1 - f) * wcross_color_prev;
+                       }
 
-                               wcross_scale *= 1 - cvar("_menu_alpha");
-                               wcross_alpha *= 1 - cvar("_menu_alpha");
+                       wcross_scale_prev = wcross_scale;
+                       wcross_alpha_prev = wcross_alpha;
+                       wcross_color_prev = wcross_color;
 
-                               ring_scale = cvar("crosshair_ring_size");
+                       wcross_scale *= 1 - cvar("_menu_alpha");
+                       wcross_alpha *= 1 - cvar("_menu_alpha");
 
-                               wcross_size = drawgetimagesize(wcross_name) * wcross_scale;
+                       ring_scale = cvar("crosshair_ring_size");
 
-                               float nex_charge;
-                               nex_charge = getstatf(STAT_NEX_CHARGE);
+                       wcross_size = drawgetimagesize(wcross_name) * wcross_scale;
 
-                               // ring around crosshair representing bullets left in camping rifle clip
-                               if (activeweapon == WEP_CAMPINGRIFLE && cr_maxbullets)
-                               {
-                                       bullets = getstati(STAT_BULLETS_LOADED);
-                                       f = bound(0, bullets / cr_maxbullets, 1);
+                       float nex_charge;
+                       nex_charge = getstatf(STAT_NEX_CHARGE);
 
-                                       a = cvar("crosshair_campingrifle_bulletcounter_alpha");
-                                       DrawCircleClippedPic(wcross_origin, wcross_size_x * ring_scale, "gfx/crosshair_ring.tga", f, wcross_color, wcross_alpha * a, DRAWFLAG_ADDITIVE);
-                               }
-                               else if (activeweapon == WEP_NEX && nex_charge) // ring around crosshair representing velocity-dependent damage for the nex
-                               {
-                                       a = cvar("crosshair_nexvelocity_alpha");
-                                       DrawCircleClippedPic(wcross_origin, wcross_size_x * ring_scale, "gfx/crosshair_ring.tga", nex_charge, wcross_color, wcross_alpha * a, DRAWFLAG_ADDITIVE);
-                               }
+                       // ring around crosshair representing bullets left in camping rifle clip
+                       if (activeweapon == WEP_CAMPINGRIFLE && cr_maxbullets)
+                       {
+                               bullets = getstati(STAT_BULLETS_LOADED);
+                               f = bound(0, bullets / cr_maxbullets, 1);
+
+                               a = cvar("crosshair_campingrifle_bulletcounter_alpha");
+                               DrawCircleClippedPic(wcross_origin, wcross_size_x * ring_scale, "gfx/crosshair_ring.tga", f, wcross_color, wcross_alpha * a, DRAWFLAG_ADDITIVE);
+                       }
+                       else if (activeweapon == WEP_NEX && nex_charge) // ring around crosshair representing velocity-dependent damage for the nex
+                       {
+                               a = cvar("crosshair_nexvelocity_alpha");
+                               DrawCircleClippedPic(wcross_origin, wcross_size_x * ring_scale, "gfx/crosshair_ring.tga", nex_charge, wcross_color, wcross_alpha * a, DRAWFLAG_ADDITIVE);
+                       }
 
 #define CROSSHAIR_DO_BLUR(M,sz,wcross_name,wcross_alpha) \
-                               do \
+                       do \
+                       { \
+                               if(wcross_blur > 0) \
+                               { \
+                                       for(i = -2; i <= 2; ++i) \
+                                               for(j = -2; j <= 2; ++j) \
+                                                       M(i,j,sz,wcross_name,wcross_alpha*0.04); \
+                               } \
+                               else \
                                { \
-                                       if(wcross_blur > 0) \
-                                       { \
-                                               for(i = -2; i <= 2; ++i) \
-                                                       for(j = -2; j <= 2; ++j) \
-                                                               M(i,j,sz,wcross_name,wcross_alpha*0.04); \
-                                       } \
-                                       else \
-                                       { \
-                                               M(0,0,sz,wcross_name,wcross_alpha); \
-                                       } \
+                                       M(0,0,sz,wcross_name,wcross_alpha); \
                                } \
-                               while(0)
+                       } \
+                       while(0)
 
 #define CROSSHAIR_DRAW_SINGLE(i,j,sz,wcross_name,wcross_alpha) \
-                               drawpic(wcross_origin - ('0.5 0 0' * (sz * wcross_size_x + i * wcross_blur) + '0 0.5 0' * (sz * wcross_size_y + j * wcross_blur)), wcross_name, sz * wcross_size, wcross_color, wcross_alpha, DRAWFLAG_NORMAL)
+                       drawpic(wcross_origin - ('0.5 0 0' * (sz * wcross_size_x + i * wcross_blur) + '0 0.5 0' * (sz * wcross_size_y + j * wcross_blur)), wcross_name, sz * wcross_size, wcross_color, wcross_alpha, DRAWFLAG_NORMAL)
 
 #define CROSSHAIR_DRAW(sz,wcross_name,wcross_alpha) \
-                               CROSSHAIR_DO_BLUR(CROSSHAIR_DRAW_SINGLE,sz,wcross_name,wcross_alpha)
+                       CROSSHAIR_DO_BLUR(CROSSHAIR_DRAW_SINGLE,sz,wcross_name,wcross_alpha)
 
-                               if(time < wcross_name_changedonetime && wcross_name != wcross_name_goal_prev_prev && wcross_name_goal_prev_prev)
-                               {
-                                       f = (wcross_name_changedonetime - time) / (wcross_name_changedonetime - wcross_name_changestarttime);
-                                       wcross_size = drawgetimagesize(wcross_name_goal_prev_prev) * wcross_scale;
-                                       CROSSHAIR_DRAW(wcross_resolution_goal_prev_prev, wcross_name_goal_prev_prev, wcross_alpha * f * wcross_name_alpha_goal_prev_prev);
-                                       f = 1 - f;
-                               }
-                               else
-                               {
-                                       f = 1;
-                               }
+                       if(time < wcross_name_changedonetime && wcross_name != wcross_name_goal_prev_prev && wcross_name_goal_prev_prev)
+                       {
+                               f = (wcross_name_changedonetime - time) / (wcross_name_changedonetime - wcross_name_changestarttime);
+                               wcross_size = drawgetimagesize(wcross_name_goal_prev_prev) * wcross_scale;
+                               CROSSHAIR_DRAW(wcross_resolution_goal_prev_prev, wcross_name_goal_prev_prev, wcross_alpha * f * wcross_name_alpha_goal_prev_prev);
+                               f = 1 - f;
+                       }
+                       else
+                       {
+                               f = 1;
+                       }
 
-                               wcross_size = drawgetimagesize(wcross_name) * wcross_scale;
-                               CROSSHAIR_DRAW(wcross_resolution, wcross_name, wcross_alpha * f);
+                       wcross_size = drawgetimagesize(wcross_name) * wcross_scale;
+                       CROSSHAIR_DRAW(wcross_resolution, wcross_name, wcross_alpha * f);
 
-                               if(cvar("crosshair_dot"))
-                                       CROSSHAIR_DRAW(wcross_resolution * cvar("crosshair_dot_size"), "gfx/crosshairdot.tga", wcross_alpha * f * cvar("crosshair_dot_alpha"));
+                       if(cvar("crosshair_dot"))
+                               CROSSHAIR_DRAW(wcross_resolution * cvar("crosshair_dot_size"), "gfx/crosshairdot.tga", wcross_alpha * f * cvar("crosshair_dot_alpha"));
 
-                               wcross_name_alpha_goal_prev = f;
-                       }
+                       wcross_name_alpha_goal_prev = f;
                }
                else
                {
index ac721ed..ea0fcec 100644 (file)
@@ -235,3 +235,5 @@ var string autocvar_hud_panel_infomessages_bg_padding;
 var float autocvar_hud_panel_infomessages_flip;
 
 var float autocvar_scoreboard_border_thickness;
+
+var float autocvar_cl_allow_uid2name;
index cb2d7f3..a995970 100644 (file)
@@ -189,8 +189,16 @@ void Draw_GrapplingHook()
        {
                default:
                case ENT_CLIENT_HOOK:
-                       setorigin(self, trace_endpos); // hook endpoint!
-                       self.angles = vectoangles(trace_endpos - atrans);
+                       if(vlen(trace_endpos - atrans) > 0.5)
+                       {
+                               setorigin(self, trace_endpos); // hook endpoint!
+                               self.angles = vectoangles(trace_endpos - atrans);
+                               self.drawmask = MASK_NORMAL;
+                       }
+                       else
+                       {
+                               self.drawmask = 0;
+                       }
                        break;
                case ENT_CLIENT_LGBEAM:
                case ENT_CLIENT_GAUNTLET:
index 8ddcd25..971a791 100644 (file)
@@ -1470,7 +1470,6 @@ float GetAmmoTypeForWep(float i)
        {
                case WEP_SHOTGUN: return 0;
                case WEP_UZI: return 1;
-               case WEP_CAMPINGRIFLE: return 1;
                case WEP_GRENADE_LAUNCHER: return 2;
                case WEP_MINE_LAYER: return 2;
                case WEP_ELECTRO: return 3;
@@ -1478,6 +1477,7 @@ float GetAmmoTypeForWep(float i)
                case WEP_HLAC: return 3;
                case WEP_MINSTANEX: return 3;
                case WEP_NEX: return 3;
+               case WEP_CAMPINGRIFLE: return 1;
                case WEP_HAGAR: return 2;
                case WEP_ROCKET_LAUNCHER: return 2;
                case WEP_SEEKER: return 2;
@@ -2595,6 +2595,9 @@ void HUD_KillNotify(string s1, string s2, string s3, float type, float msg) // s
        alsoprint = (autocvar_hud_panel_notify_print || !panel_enabled); // print message to console if: notify panel disabled, or cvar to do so enabled
        gentle = (autocvar_cl_gentle || autocvar_cl_gentle_messages);
        
+       if ((msg == MSG_SUICIDE || msg == MSG_KILL || msg == MSG_KILL_ACTION) && gametype == GAME_CTS) // selfkill isn't interesting in CTS and only spams up the notify panel
+               return;
+
        if(msg == MSG_SUICIDE) {
                w = DEATH_WEAPONOF(type);
                if(WEP_VALID(w)) {
@@ -2921,6 +2924,19 @@ void HUD_KillNotify(string s1, string s2, string s3, float type, float msg) // s
                        HUD_KillNotify_Push(s1, s2, 0, INFO_CAPTUREFLAG);
                        print(s1, "^7 captured the ", s2, s3, "\n");
                }
+       } else if(msg == MSG_RACE) {
+               if(type == RACE_SERVER_RECORD) {
+                       HUD_KillNotify_Push(s1, s2, 1, RACE_SERVER_RECORD);
+               }
+               else if(type == RACE_NEW_RANK) {
+                       HUD_KillNotify_Push(s1, s2, 1, RACE_NEW_RANK);
+               }
+               else if(type == RACE_NEW_TIME) {
+                       HUD_KillNotify_Push(s1, s2, 1, RACE_NEW_TIME);
+               }
+               else if(type == RACE_FAIL) {
+                       HUD_KillNotify_Push(s1, s2, 1, RACE_FAIL);
+               }
        }
 }
 
@@ -3257,6 +3273,22 @@ void HUD_Notify (void)
                        {
                                s = "notify_void";
                        }
+                       else if(killnotify_deathtype[j] == RACE_SERVER_RECORD)
+                       {
+                               s = "race_newrecordserver";
+                       }
+                       else if(killnotify_deathtype[j] == RACE_NEW_RANK)
+                       {
+                               s = "race_newrankyellow";
+                       }
+                       else if(killnotify_deathtype[j] == RACE_NEW_TIME)
+                       {
+                               s = "race_newtime";
+                       }
+                       else if(killnotify_deathtype[j] == RACE_FAIL)
+                       {
+                               s = "race_newfail";
+                       }
                        if(s != "" && a)
                        {
                                drawpic_aspect_skin(weap_pos, s, '2 1 0' * height, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
@@ -3485,6 +3517,7 @@ void HUD_Score(void)
        }
 
        float score, distribution, leader;
+       string sign;
        vector distribution_color;
        entity tm, pl, me;
        me = (spectatee_status > 0) ? playerslots[spectatee_status - 1] : playerslots[player_localentnum - 1];
@@ -3506,15 +3539,17 @@ void HUD_Score(void)
                        // distribution display
                        distribution = me.(scores[ps_primary]) - pl.(scores[ps_primary]);
 
-                       distrtimer = ftos(distribution/pow(10, TIME_DECIMALS));
+                       distrtimer = ftos_decimals(fabs(distribution/pow(10, TIME_DECIMALS)), TIME_DECIMALS);
 
                        if (distribution <= 0) {
                                distribution_color = '0 1 0';
+                               sign = "-";
                        }
                        else {
                                distribution_color = '1 0 0';
+                               sign = "+";
                        }
-                       drawstring_aspect(pos + eX * 0.75 * mySize_x, distrtimer, eX * 0.25 * mySize_x + eY * (1/3) * mySize_y, distribution_color, panel_fg_alpha, DRAWFLAG_NORMAL);
+                       drawstring_aspect(pos + eX * 0.75 * mySize_x, strcat(sign, distrtimer), eX * 0.25 * mySize_x + eY * (1/3) * mySize_y, distribution_color, panel_fg_alpha, DRAWFLAG_NORMAL);
                }
                // race record display
                if (distribution <= 0)
@@ -3747,11 +3782,22 @@ float vote_change; // "time" when vote_active changed
 
 void HUD_VoteWindow(void) 
 {
+       if(autocvar_cl_allow_uid2name == -1 && (gametype == GAME_CTS || gametype == GAME_RACE))
+       {
+               vote_active = 1;
+               vote_called_vote = strzone(strcat("^2Name ^7instead of \"^1Unregistered player\"", " ^7in stats"));
+       }
+
        if(!autocvar_hud_panel_vote && !autocvar__hud_configure)
                return;
 
        active_panel = HUD_PANEL_VOTE;
        HUD_Panel_UpdateCvars(vote);
+       if(autocvar_cl_allow_uid2name == -1 && (gametype == GAME_CTS || gametype == GAME_RACE))
+       {
+               panel_pos = eX * 0.3 * vid_conwidth + eY * 0.1 * vid_conheight;
+               panel_size = eX * 0.4 * vid_conwidth + eY * 0.3 * vid_conheight;
+       }
        vector pos, mySize;
        pos = panel_pos;
        mySize = panel_size;
@@ -3817,16 +3863,22 @@ void HUD_VoteWindow(void)
        mySize = newSize;
 
        s = "A vote has been called for:";
+       if(autocvar_cl_allow_uid2name == -1 && (gametype == GAME_CTS || gametype == GAME_RACE))
+               s = "Allow servers to store and display your name?";
        drawstring_aspect(pos, s, eX * mySize_x + eY * (2/8) * mySize_y, '1 1 1', a, DRAWFLAG_NORMAL);
-       s = textShortenToWidth(vote_called_vote, mySize_x, '1 1 0' * mySize_y * (1.75/8), stringwidth_colors);
+       s = textShortenToWidth(vote_called_vote, mySize_x, '1 1 0' * mySize_y * (1/8), stringwidth_colors);
        if(autocvar__hud_configure)
                s = "^1Configure the HUD";
        drawcolorcodedstring_aspect(pos + eY * (2/8) * mySize_y, s, eX * mySize_x + eY * (1.75/8) * mySize_y, a, DRAWFLAG_NORMAL);
 
        // print the yes/no counts
        s = strcat("Yes (", getcommandkey("vyes", "vyes"), "): ", ftos(vote_yescount));
+       if(autocvar_cl_allow_uid2name == -1 && (gametype == GAME_CTS || gametype == GAME_RACE))
+               s = strcat("Yes: (press y)");
        drawstring_aspect(pos + eY * (4/8) * mySize_y, s, eX * 0.5 * mySize_x + eY * (1.5/8) * mySize_y, '0 1 0', a, DRAWFLAG_NORMAL);
        s = strcat("No (", getcommandkey("vno", "vno"), "): ", ftos(vote_nocount));
+       if(autocvar_cl_allow_uid2name == -1 && (gametype == GAME_CTS || gametype == GAME_RACE))
+               s = strcat("No: (press n)");
        drawstring_aspect(pos + eX * 0.5 * mySize_x + eY * (4/8) * mySize_y, s, eX * 0.5 * mySize_x + eY * (1.5/8) * mySize_y, '1 0 0', a, DRAWFLAG_NORMAL);
 
        // draw the progress bar backgrounds
@@ -4948,6 +5000,8 @@ switch (id) {\
 
 void HUD_Main (void)
 {
+       float i;
+
        hud_skin_path = strcat("gfx/hud/", autocvar_hud_skin);
 
        // global hud alpha fade
@@ -4974,7 +5028,6 @@ void HUD_Main (void)
        // HUD configure visible grid
        if(autocvar__hud_configure && autocvar_hud_configure_grid && autocvar_hud_configure_grid_alpha)
        {
-               float i;
                // x-axis
                for(i = 0; i < 1/bound(0.005, autocvar_hud_configure_grid_xsize, 0.2); ++i)
                {
index 2fdf0d2..b61568a 100644 (file)
@@ -1043,7 +1043,7 @@ vector HUD_DrawScoreboardRankings(vector pos, entity pl,  vector rgb, vector bg_
        pos_y += hud_fontsize_y;
        vector tmp;
        tmp_x = sbwidth;
-       tmp_y = hud_fontsize_y * RANKINGS_RECEIVED_CNT;
+       tmp_y = 1.25 * hud_fontsize_y * RANKINGS_RECEIVED_CNT;
 
        if (teamplay)
                drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb * autocvar_scoreboard_color_bg_team, scoreboard_alpha_bg, DRAWFLAG_NORMAL);
@@ -1062,12 +1062,12 @@ vector HUD_DrawScoreboardRankings(vector pos, entity pl,  vector rgb, vector bg_
                n = grecordholder[i];
                p = race_PlaceName(i+1);
                if(grecordholder[i] == GetPlayerName(player_localentnum - 1))
-                       drawfill(pos, '1 0 0' * sbwidth + '0 1 0' * hud_fontsize_y, hl_rgb, scoreboard_highlight_alpha_self, DRAWFLAG_NORMAL);
+                       drawfill(pos, '1 0 0' * sbwidth + '0 1.25 0' * hud_fontsize_y, hl_rgb, scoreboard_highlight_alpha_self, DRAWFLAG_NORMAL);
                else if(!mod(i, 2) && scoreboard_highlight)
-                       drawfill(pos, '1 0 0' * sbwidth + '0 1 0' * hud_fontsize_y, hl_rgb, scoreboard_highlight_alpha, DRAWFLAG_NORMAL);
-               drawstring(pos, p, hud_fontsize, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL);
-               drawstring(pos + '3 0 0' * hud_fontsize_x, TIME_ENCODED_TOSTRING(t), hud_fontsize, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL);
-               drawcolorcodedstring(pos + '8 0 0' * hud_fontsize_x, n, hud_fontsize, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+                       drawfill(pos, '1 0 0' * sbwidth + '0 1.25 0' * hud_fontsize_y, hl_rgb, scoreboard_highlight_alpha, DRAWFLAG_NORMAL);
+               drawstring(pos, p, '1 1 0' * hud_fontsize_y, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+               drawstring(pos + '3 0 0' * hud_fontsize_y, TIME_ENCODED_TOSTRING(t), '1 1 0' * hud_fontsize_y, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+               drawcolorcodedstring(pos + '8 0 0' * hud_fontsize_y, n, '1 1 0' * hud_fontsize_y, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
                pos_y += 1.25 * hud_fontsize_y;
        }
 
@@ -1176,11 +1176,11 @@ void HUD_DrawScoreboard()
 
        if(gametype == GAME_CTS || gametype == GAME_RACE) {
                if(race_speedaward) {
-                       drawcolorcodedstring(pos, strcat("Speed award: ", ftos(race_speedaward), " (", race_speedaward_holder, ")"), hud_fontsize, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+                       drawcolorcodedstring(pos, strcat("Speed award: ", ftos(race_speedaward), " ^7(", race_speedaward_holder, "^7)"), hud_fontsize, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
                        pos_y += 1.25 * hud_fontsize_y;
                }
                if(race_speedaward_alltimebest) {
-                       drawcolorcodedstring(pos, strcat("All-time fastest: ", ftos(race_speedaward_alltimebest), " (", race_speedaward_alltimebest_holder, ")"), hud_fontsize, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+                       drawcolorcodedstring(pos, strcat("All-time fastest: ", ftos(race_speedaward_alltimebest), " ^7(", race_speedaward_alltimebest_holder, "^7)"), hud_fontsize, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
                        pos_y += 1.25 * hud_fontsize_y;
                }
                pos = HUD_DrawScoreboardRankings(pos, pl, rgb, bg_size);
index 5265cb1..cf33b01 100644 (file)
@@ -1,5 +1,6 @@
 #define TUBA_STARTNOTE(n) strcat((checkextension("DP_SND_SETPARAMS") ? "weapons/tuba_loopnote" : "weapons/tuba_note"), ftos(n), ".wav")
 .float cnt; // note
+.float attenuate; // if set, attenuate it
 
 void Ent_TubaNote_Think()
 {
@@ -16,14 +17,14 @@ void Ent_TubaNote_Think()
                remove(self);
        }
        else
-               sound(self, CHAN_PROJECTILE, "", self.cnt, cvar("g_balance_tuba_attenuation"));
+               sound(self, CHAN_PROJECTILE, "", self.cnt, self.attenuate * cvar("g_balance_tuba_attenuation"));
 }
 
 void Ent_TubaNote_UpdateSound()
 {
        self.enemy.cnt = bound(0, VOL_BASE * cvar("g_balance_tuba_volume"), 1);
        self.enemy.count = self.enemy.cnt;
-       sound(self.enemy, CHAN_PROJECTILE, TUBA_STARTNOTE(self.cnt), self.enemy.cnt, cvar("g_balance_tuba_attenuation"));
+       sound(self.enemy, CHAN_PROJECTILE, TUBA_STARTNOTE(self.cnt), self.enemy.cnt, self.enemy.attenuate * cvar("g_balance_tuba_attenuation"));
 }
 
 void Ent_TubaNote_StopSound()
@@ -52,6 +53,7 @@ void Ent_TubaNote(float bIsNew)
                self.enemy.origin_y = ReadCoord();
                self.enemy.origin_z = ReadCoord();
                setorigin(self.enemy, self.enemy.origin);
+               self.enemy.attenuate = ReadByte();
        }
        self.think = Ent_TubaNote_StopSound;
        self.entremove = Ent_TubaNote_StopSound;
index b4b92ff..29029f6 100644 (file)
@@ -310,7 +310,8 @@ const float STAT_SHOTORG = 46; // compressShotOrigin
 const float STAT_LEADLIMIT = 47;
 const float STAT_BULLETS_LOADED = 48;
 const float STAT_NEX_CHARGE = 49;
-const float STAT_HUD = 50;
+const float    STAT_LAST_PICKUP = 50;
+const float STAT_HUD = 51;
 
 // see DP source, quakedef.h
 const float STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW = 222;
@@ -564,6 +565,8 @@ float MSG_KILL_ACTION = 3;
 float MSG_KILL_ACTION_SPREE = 4;
 float MSG_INFO = 5;
 
+float MSG_RACE = 10;
+
 float KILL_TEAM_RED = 10301;
 float KILL_TEAM_BLUE = 10302;
 float KILL_TEAM_SPREE = 10303;
@@ -589,6 +592,11 @@ float INFO_LOSTFLAG = 10321;
 float INFO_RETURNFLAG = 10322;
 float INFO_CAPTUREFLAG = 10323;
 
+float RACE_SERVER_RECORD = 10400;
+float RACE_NEW_TIME = 10401;
+float RACE_NEW_RANK = 10402;
+float RACE_FAIL = 10403;
+
 // weapon requests
 float WR_SETUP         = 1; // (SVQC) setup weapon data
 float WR_THINK         = 2; // (SVQC) logic to run every frame
index be2f5e7..f6b54f1 100644 (file)
@@ -831,6 +831,10 @@ float GameCommand_Generic(string command)
                print(records_reply);
                return TRUE;
        }
+       else if(argv(0) == "ladder") {
+               print(ladder_reply);
+               return TRUE;
+       }
        else if(argv(0) == "rankings") {
                print(rankings_reply);
                return TRUE;
index 43a05b1..3388982 100644 (file)
@@ -231,7 +231,7 @@ float _MapInfo_Generate(string pFilename) // 0: failure, 1: ok ent, 2: ok bsp
        }
        if(fh < 0)
                return 0;
-       print("Analyzing ", fn, " to generate initial mapinfo; please edit that file later\n");
+       print("Analyzing ", fn, " to generate initial mapinfo\n");
 
        inWorldspawn = 2;
        MapInfo_Map_flags = 0;
@@ -804,69 +804,76 @@ float MapInfo_Get_ByName(string pFilename, float pAllowGenerate, float pGametype
        fh = fopen(fn, FILE_READ);
        if(fh < 0)
        {
-               if(!pAllowGenerate)
-                       return 0;
-               _MapInfo_Map_Reset();
-               r = _MapInfo_Generate(pFilename);
-               if(!r)
-                       return 0;
-               fh = fopen(fn, FILE_WRITE);
-               fputs(fh, strcat("title ", MapInfo_Map_title, "\n"));
-               fputs(fh, strcat("description ", MapInfo_Map_description, "\n"));
-               fputs(fh, strcat("author ", MapInfo_Map_author, "\n"));
-               if(_MapInfo_Map_worldspawn_music != "")
+               fn = strcat("maps/autogenerated/", pFilename, ".mapinfo");
+               fh = fopen(fn, FILE_READ);
+               if(fh < 0)
                {
-                       if(
-                               substring(_MapInfo_Map_worldspawn_music, strlen(_MapInfo_Map_worldspawn_music) - 4, 4) == ".wav"
-                               ||
-                               substring(_MapInfo_Map_worldspawn_music, strlen(_MapInfo_Map_worldspawn_music) - 4, 4) == ".ogg"
-                       )
-                               fputs(fh, strcat("cdtrack ", substring(_MapInfo_Map_worldspawn_music, 0, strlen(_MapInfo_Map_worldspawn_music) - 4), "\n"));
+                       if(!pAllowGenerate)
+                               return 0;
+                       _MapInfo_Map_Reset();
+                       r = _MapInfo_Generate(pFilename);
+                       if(!r)
+                               return 0;
+                       fh = fopen(fn, FILE_WRITE);
+                       fputs(fh, strcat("title ", MapInfo_Map_title, "\n"));
+                       fputs(fh, strcat("description ", MapInfo_Map_description, "\n"));
+                       fputs(fh, strcat("author ", MapInfo_Map_author, "\n"));
+                       if(_MapInfo_Map_worldspawn_music != "")
+                       {
+                               if(
+                                       substring(_MapInfo_Map_worldspawn_music, strlen(_MapInfo_Map_worldspawn_music) - 4, 4) == ".wav"
+                                       ||
+                                       substring(_MapInfo_Map_worldspawn_music, strlen(_MapInfo_Map_worldspawn_music) - 4, 4) == ".ogg"
+                               )
+                                       fputs(fh, strcat("cdtrack ", substring(_MapInfo_Map_worldspawn_music, 0, strlen(_MapInfo_Map_worldspawn_music) - 4), "\n"));
+                               else
+                                       fputs(fh, strcat("cdtrack ", _MapInfo_Map_worldspawn_music, "\n"));
+                       }
                        else
-                               fputs(fh, strcat("cdtrack ", _MapInfo_Map_worldspawn_music, "\n"));
-               }
-               else
-               {
-                       n = tokenize_console(cvar_string("g_cdtracks_remaplist"));
-                       s = strcat(" ", cvar_string("g_cdtracks_dontusebydefault"), " ");
-                       for(;;)
                        {
-                               i = floor(random() * n);
-                               if(strstrofs(s, strcat(" ", argv(i), " "), 0) < 0)
-                                       break;
+                               n = tokenize_console(cvar_string("g_cdtracks_remaplist"));
+                               s = strcat(" ", cvar_string("g_cdtracks_dontusebydefault"), " ");
+                               for(;;)
+                               {
+                                       i = floor(random() * n);
+                                       if(strstrofs(s, strcat(" ", argv(i), " "), 0) < 0)
+                                               break;
+                               }
+                               fputs(fh, strcat("cdtrack ", ftos(i + 1), "\n"));
                        }
-                       fputs(fh, strcat("cdtrack ", ftos(i + 1), "\n"));
-               }
-               if(MapInfo_Map_supportedFeatures & MAPINFO_FEATURE_WEAPONS)
-                       fputs(fh, "has weapons\n");
-               else
-                       fputs(fh, "// uncomment this if you added weapon pickups: has weapons\n");
-               if(MapInfo_Map_flags & MAPINFO_FLAG_FRUSTRATING)
-                       fputs(fh, "frustrating\n");
+                       if(MapInfo_Map_supportedFeatures & MAPINFO_FEATURE_WEAPONS)
+                               fputs(fh, "has weapons\n");
+                       else
+                               fputs(fh, "// uncomment this if you added weapon pickups: has weapons\n");
+                       if(MapInfo_Map_flags & MAPINFO_FLAG_FRUSTRATING)
+                               fputs(fh, "frustrating\n");
 
-               for(i = 1; i <= MapInfo_Map_supportedGametypes; i *= 2)
-                       if(MapInfo_Map_supportedGametypes & i)
-                               fputs(fh, sprintf("gametype %s // defaults: %s\n", MapInfo_Type_ToString(i), _MapInfo_GetDefaultEx(i)));
+                       for(i = 1; i <= MapInfo_Map_supportedGametypes; i *= 2)
+                               if(MapInfo_Map_supportedGametypes & i)
+                                       fputs(fh, sprintf("gametype %s // defaults: %s\n", MapInfo_Type_ToString(i), _MapInfo_GetDefaultEx(i)));
 
-               fh2 = fopen(strcat("scripts/", pFilename, ".arena"), FILE_READ);
-               if(fh2 >= 0)
-               {
-                       fclose(fh2);
-                       fputs(fh, "settemp_for_type all sv_q3acompat_machineshotgunswap 1\n");
-               }
+                       fh2 = fopen(strcat("scripts/", pFilename, ".arena"), FILE_READ);
+                       if(fh2 >= 0)
+                       {
+                               fclose(fh2);
+                               fputs(fh, "settemp_for_type all sv_q3acompat_machineshotgunswap 1\n");
+                       }
 
-               fputs(fh, "// optional: fog density red green blue alpha mindist maxdist\n");
-               fputs(fh, "// optional: settemp_for_type (all|gametypename) cvarname value\n");
-               fputs(fh, "// optional: clientsettemp_for_type (all|gametypename) cvarname value\n");
-               fputs(fh, "// optional: size mins_x mins_y mins_z maxs_x maxs_y maxs_z\n");
-               fputs(fh, "// optional: hidden\n");
+                       fputs(fh, "// optional: fog density red green blue alpha mindist maxdist\n");
+                       fputs(fh, "// optional: settemp_for_type (all|gametypename) cvarname value\n");
+                       fputs(fh, "// optional: clientsettemp_for_type (all|gametypename) cvarname value\n");
+                       fputs(fh, "// optional: size mins_x mins_y mins_z maxs_x maxs_y maxs_z\n");
+                       fputs(fh, "// optional: hidden\n");
 
-               fclose(fh);
-               r = 2;
-               // return r;
-               fh = fopen(fn, FILE_READ);
-               if(fh < 0)
-                       error("... but I just wrote it!");
+                       fclose(fh);
+                       r = 2;
+                       // return r;
+                       fh = fopen(fn, FILE_READ);
+                       if(fh < 0)
+                               error("... but I just wrote it!");
+               }
+
+               print("WARNING: autogenerated mapinfo file ", fn, " has been loaded; please edit that file and move it to maps/", pFilename, ".mapinfo\n");
        }
 
        _MapInfo_Map_Reset();
index 2472374..e7d6739 100644 (file)
@@ -1,3 +1,6 @@
+#pragma flag enable subscope
+#pragma flag enable lo
+
 //float log(float x);
 #define log log_builtin \
        #undef log \
index f1d2832..2de439f 100644 (file)
@@ -165,7 +165,7 @@ void check_unacceptable_compiler_bugs();
 float compressShotOrigin(vector v);
 vector decompressShotOrigin(float f);
 
-string rankings_reply, lsmaps_reply, lsnewmaps_reply, maplist_reply; // cached replies
+string rankings_reply, ladder_reply, lsmaps_reply, lsnewmaps_reply, maplist_reply; // cached replies
 string records_reply[10];
 
 float RandomSelection_totalweight;
index b93ecaa..afea3e7 100644 (file)
@@ -222,6 +222,7 @@ SKINBEGIN
        SKINVECTOR(COLOR_SERVERLIST_FAVORITE, '1 1 1');
        SKINFLOAT(ALPHA_SERVERLIST_IMPOSSIBLE, 0.7);
        SKINVECTOR(COLOR_SERVERLIST_IMPOSSIBLE, '0.3 0.3 0.3');
+       SKINSTRING(GFX_SERVERLIST_ICON, "icon");
 
        // item: server info
        SKINVECTOR(COLOR_SERVERINFO_NAME, '1 1 1');
index 058bfd7..645b932 100644 (file)
@@ -66,7 +66,7 @@ void XonoticCrosshairButton_draw(entity me)
        float a;
 
        rgb = eX * cvar("crosshair_color_red") + eY * cvar("crosshair_color_green") + eZ * cvar("crosshair_color_blue");
-       a = cvar("crosshair_color_alpha");
+       a = cvar("crosshair_alpha");
 
        if(!me.checked && !me.focused)
        {
index 2d75d43..a49e352 100644 (file)
@@ -6,7 +6,7 @@ CLASS(XonoticAdvancedDialog) EXTENDS(XonoticDialog)
        ATTRIB(XonoticAdvancedDialog, title, string, "Advanced server settings")
        ATTRIB(XonoticAdvancedDialog, color, vector, SKINCOLOR_DIALOG_ADVANCED)
        ATTRIB(XonoticAdvancedDialog, intendedWidth, float, 0.5)
-       ATTRIB(XonoticAdvancedDialog, rows, float, 14)
+       ATTRIB(XonoticAdvancedDialog, rows, float, 13)
        ATTRIB(XonoticAdvancedDialog, columns, float, 3)
        ATTRIB(XonoticAdvancedDialog, refilterEntity, entity, NULL)
 ENDCLASS(XonoticAdvancedDialog)
@@ -31,10 +31,6 @@ void XonoticAdvancedDialog_fill(entity me)
                me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, "Spawn shield:"));
                me.TD(me, 1, 1.7, e = makeXonoticSlider(0, 15, 0.5, "g_spawnshieldtime"));
        me.TR(me);
-               me.TDempty(me, 0.2);
-               me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, "Start delay:"));
-               me.TD(me, 1, 1.7, e = makeXonoticSlider(0, 30, 0.5, "g_start_delay"));
-       me.TR(me);
        me.TR(me);
                me.TDempty(me, 0.2);
                me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, "Game speed:"));
index 21eefea..ec006bd 100644 (file)
@@ -5,7 +5,7 @@ CLASS(XonoticServerInfoDialog) EXTENDS(XonoticDialog)
        ATTRIB(XonoticServerInfoDialog, title, string, "Server Information")
        ATTRIB(XonoticServerInfoDialog, color, vector, SKINCOLOR_DIALOG_SERVERINFO)
        ATTRIB(XonoticServerInfoDialog, intendedWidth, float, 0.68)
-       ATTRIB(XonoticServerInfoDialog, rows, float, 14)
+       ATTRIB(XonoticServerInfoDialog, rows, float, 15)
        ATTRIB(XonoticServerInfoDialog, columns, float, 12)
 
        ATTRIB(XonoticServerInfoDialog, currentServerName, string, string_null)
@@ -21,7 +21,7 @@ CLASS(XonoticServerInfoDialog) EXTENDS(XonoticDialog)
        ATTRIB(XonoticServerInfoDialog, currentServerKey, string, string_null)
        ATTRIB(XonoticServerInfoDialog, currentServerID, string, string_null)
        ATTRIB(XonoticServerInfoDialog, currentServerEncrypt, string, string_null)
-       ATTRIB(XonoticServerInfoDialog, currentServerCanConnect, string, string_null)
+       ATTRIB(XonoticServerInfoDialog, currentServerPure, string, string_null)
 
        ATTRIB(XonoticServerInfoDialog, nameLabel, entity, NULL)
        ATTRIB(XonoticServerInfoDialog, cnameLabel, entity, NULL)
@@ -37,6 +37,7 @@ CLASS(XonoticServerInfoDialog) EXTENDS(XonoticDialog)
        ATTRIB(XonoticServerInfoDialog, idLabel, entity, NULL)
        ATTRIB(XonoticServerInfoDialog, encryptLabel, entity, NULL)
        ATTRIB(XonoticServerInfoDialog, canConnectLabel, entity, NULL)
+       ATTRIB(XonoticServerInfoDialog, pureLabel, entity, NULL)
 ENDCLASS(XonoticServerInfoDialog)
 
 float SLIST_FIELD_NAME;
@@ -55,8 +56,52 @@ void Join_Click(entity btn, entity me);
 #ifdef IMPLEMENTATION
 void XonoticServerInfoDialog_loadServerInfo(entity me, float i)
 {
-       float m;
-       string s, typestr, versionstr, numh, maxp;
+       float m, pure, j;
+       string s, typestr, versionstr, numh, maxp, k, v;
+
+       if(me.currentServerName)
+               strunzone(me.currentServerName);
+       me.currentServerName = string_null;
+       if(me.currentServerCName)
+               strunzone(me.currentServerCName);
+       me.currentServerCName = string_null;
+       if(me.currentServerType)
+               strunzone(me.currentServerType);
+       me.currentServerType = string_null;
+       if(me.currentServerMap)
+               strunzone(me.currentServerMap);
+       me.currentServerMap = string_null;
+       if(me.currentServerPlayers)
+               strunzone(me.currentServerPlayers);
+       me.currentServerPlayers = string_null;
+       if(me.currentServerNumPlayers)
+               strunzone(me.currentServerNumPlayers);
+       me.currentServerNumPlayers = string_null;
+       if(me.currentServerNumBots)
+               strunzone(me.currentServerNumBots);
+       me.currentServerNumBots = string_null;
+       if(me.currentServerMod)
+               strunzone(me.currentServerMod);
+       me.currentServerMod = string_null;
+       if(me.currentServerVersion)
+               strunzone(me.currentServerVersion);
+       me.currentServerVersion = string_null;
+       if(me.currentServerPing)
+               strunzone(me.currentServerPing);
+       me.currentServerPing = string_null;
+       if(me.currentServerKey)
+               strunzone(me.currentServerKey);
+       me.currentServerKey = string_null;
+       if(me.currentServerID)
+               strunzone(me.currentServerID);
+       me.currentServerID = string_null;
+       // not zoned!
+       //if(me.currentServerEncrypt)
+       //      strunzone(me.currentServerEncrypt);
+       //me.currentServerEncrypt = string_null;
+       if(me.currentServerPure)
+               strunzone(me.currentServerPure);
+       me.currentServerPure = string_null;
 
        SLIST_FIELD_NAME = gethostcacheindexforkey("name");
        me.currentServerName = strzone(gethostcachestring(SLIST_FIELD_NAME, i));
@@ -66,19 +111,28 @@ void XonoticServerInfoDialog_loadServerInfo(entity me, float i)
        me.currentServerCName = strzone(gethostcachestring(SLIST_FIELD_CNAME, i));
        me.cnameLabel.setText(me.cnameLabel, me.currentServerCName);
 
+       pure = -1;
+       typestr = "N/A";
+       versionstr = "N/A";
+
        SLIST_FIELD_QCSTATUS = gethostcacheindexforkey("qcstatus");
        s = gethostcachestring(SLIST_FIELD_QCSTATUS, i);
        m = tokenizebyseparator(s, ":");
-       if(m > 1)
+       if(m >= 2)
        {
-               typestr = argv (0);
+               typestr = argv(0);
                versionstr = argv(1);
        }
-       else
+       for(j = 2; j < m; ++j)
        {
-               typestr = "N/A";
-               versionstr = "N/A";
+               if(argv(j) == "")
+                       break;
+               k = substring(argv(j), 0, 1);
+               v = substring(argv(j), 1, -1);
+               if(k == "P")
+                       pure = stof(v);
        }
+
        me.currentServerType = strzone(typestr);
        me.typeLabel.setText(me.typeLabel, me.currentServerType);
 
@@ -109,6 +163,10 @@ void XonoticServerInfoDialog_loadServerInfo(entity me, float i)
        me.currentServerVersion = strzone(versionstr);
        me.versionLabel.setText(me.versionLabel, me.currentServerVersion);
 
+       me.currentServerPure = ((pure < 0) ? "N/A" : (pure == 0) ? "Official settings" : sprintf("%d modified settings", pure));
+       me.currentServerPure = strzone(me.currentServerPure);
+       me.pureLabel.setText(me.pureLabel, me.currentServerPure);
+
        SLIST_FIELD_PING = gethostcacheindexforkey("ping");
        s = ftos(gethostcachenumber(SLIST_FIELD_PING, i));
        me.currentServerPing = strzone(s);
@@ -193,6 +251,11 @@ void XonoticServerInfoDialog_fill(entity me)
                        e.allowCut = 1;
                        me.mapLabel = e;
        me.TR(me);
+               me.TD(me, 1, 1.75, e = makeXonoticTextLabel(0, "Gameplay:"));
+               me.TD(me, 1, 4.0, e = makeXonoticTextLabel(0, ""));
+                       e.allowCut = 1;
+                       me.pureLabel = e;
+       me.TR(me);
                me.TD(me, 1, 1.75, e = makeXonoticTextLabel(0, "Players:"));
                me.TD(me, 1, 4.0, e = makeXonoticTextLabel(0, ""));
                        e.allowCut = 1;
index 751c555..2a075f4 100644 (file)
@@ -92,7 +92,8 @@ void XonoticPlayerSettingsTab_fill(entity me)
        me.TR(me);
                sl = makeXonoticSlider(0.45, 0.75, 0.01, "cl_bobcycle");
                me.TD(me, 1, 1, e = makeXonoticSliderCheckBox(0, 1, sl, "View bobbing:"));
-               me.TD(me, 1, 2, sl);    
+               makeMulti(sl, "cl_bob2cycle");
+               me.TD(me, 1, 2, sl);
        me.TR(me);
                me.TD(me, 1, 1, e = makeXonoticTextLabel(0, "Zoom factor:"));
                me.TD(me, 1, 2, e = makeXonoticSlider(2, 16, 0.5, "cl_zoomfactor"));
@@ -131,7 +132,7 @@ void XonoticPlayerSettingsTab_fill(entity me)
        me.TR(me);
                me.TDempty(me, 0.2);
                me.TD(me, 1, 1, e = makeXonoticTextLabel(0, "Crosshair alpha:"));
-               me.TD(me, 1, 1.8, e = makeXonoticSlider(0, 1, 0.1, "crosshair_color_alpha"));
+               me.TD(me, 1, 1.8, e = makeXonoticSlider(0, 1, 0.1, "crosshair_alpha"));
        me.TR(me);
                me.TDempty(me, 0.2);
                me.TD(me, 1, 1, e = makeXonoticTextLabel(0, "Crosshair red:"));
index 95e1f80..ce9676f 100644 (file)
@@ -10,6 +10,8 @@ CLASS(XonoticServerList) EXTENDS(XonoticListBox)
 
        ATTRIB(XonoticServerList, realFontSize, vector, '0 0 0')
        ATTRIB(XonoticServerList, realUpperMargin, float, 0)
+       ATTRIB(XonoticServerList, columnIconsOrigin, float, 0)
+       ATTRIB(XonoticServerList, columnIconsSize, float, 0)
        ATTRIB(XonoticServerList, columnPingOrigin, float, 0)
        ATTRIB(XonoticServerList, columnPingSize, float, 0)
        ATTRIB(XonoticServerList, columnNameOrigin, float, 0)
@@ -490,12 +492,14 @@ void XonoticServerList_resizeNotify(entity me, vector relOrigin, vector relSize,
        me.realFontSize_x = me.fontSize / (absSize_x * (1 - me.controlWidth));
        me.realUpperMargin = 0.5 * (1 - me.realFontSize_y);
 
-       me.columnPingOrigin = 0;
+       me.columnIconsOrigin = 0;
+       me.columnIconsSize = me.realFontSize_x * 2;
        me.columnPingSize = me.realFontSize_x * 4;
        me.columnMapSize = me.realFontSize_x * 12;
        me.columnTypeSize = me.realFontSize_x * 4;
        me.columnPlayersSize = me.realFontSize_x * 6;
-       me.columnNameSize = 1 - me.columnPlayersSize - me.columnMapSize - me.columnPingSize - me.columnTypeSize - 4 * me.realFontSize_x;
+       me.columnNameSize = 1 - me.columnPlayersSize - me.columnMapSize - me.columnPingSize - me.columnIconsSize - me.columnTypeSize - 5 * me.realFontSize_x;
+       me.columnPingOrigin = me.columnIconsOrigin + me.columnIconsSize + me.realFontSize_x;
        me.columnNameOrigin = me.columnPingOrigin + me.columnPingSize + me.realFontSize_x;
        me.columnMapOrigin = me.columnNameOrigin + me.columnNameSize + me.realFontSize_x;
        me.columnTypeOrigin = me.columnMapOrigin + me.columnMapSize + me.realFontSize_x;
@@ -598,7 +602,44 @@ void XonoticServerList_drawListBoxItem(entity me, float i, vector absSize, float
                theColor = SKINCOLOR_SERVERLIST_IMPOSSIBLE;
                theAlpha = SKINALPHA_SERVERLIST_IMPOSSIBLE;
        }
-       // TODO show an icon for encryption status
+
+       if(q == 1)
+       {
+               if(cvar("crypto_aeslevel") >= 2)
+                       q |= 4;
+       }
+       if(q == 2)
+       {
+               if(cvar("crypto_aeslevel") >= 1)
+                       q |= 4;
+       }
+       if(q == 3)
+               q = 5;
+       if(q >= 3)
+               q -= 2;
+       // possible status:
+       // 0: crypto off
+       // 1: AES possible
+       // 2: AES recommended but not available
+       // 3: AES possible and will be used
+       // 4: AES recommended and will be used
+       // 5: AES required
+
+       s = gethostcachestring(SLIST_FIELD_QCSTATUS, i);
+       {
+               vector iconSize;
+               iconSize_y = 1;
+               iconSize_x = iconSize_y * (absSize_y / absSize_x);
+
+               vector iconPos;
+               iconPos_x = (me.columnIconsSize - 2 * iconSize_x) * 0.5;
+               iconPos_y = (1 - iconSize_y) * 0.5;
+
+               draw_Picture(iconPos, strcat(SKINGFX_SERVERLIST_ICON, "_pure", ftos(strstrofs(s, ":P0:", 0) >= 0)), iconSize, '1 1 1', 1);
+
+               iconPos_x += iconSize_x;
+               draw_Picture(iconPos, strcat(SKINGFX_SERVERLIST_ICON, "_aeslevel", ftos(q)), iconSize, '1 1 1', 1);
+       }
 
        s = ftos(p);
        draw_Text(me.realUpperMargin * eY + (me.columnPingSize - draw_TextWidth(s, 0, me.realFontSize)) * eX, s, me.realFontSize, theColor, theAlpha, 0);
index 4d150fc..196e3d7 100644 (file)
@@ -101,7 +101,7 @@ entity bot_getplace(string placename)
        {
                e = find(world, targetname, placename);
                if(!e)
-                       print("invalid place ", s, "\n");
+                       print("invalid place ", placename, "\n");
                return e;
        }
 }
index 955c0a4..66a838a 100644 (file)
@@ -1313,6 +1313,22 @@ void ClientKill (void)
                ClientKill_TeamChange(0);
 }
 
+void CTS_ClientKill_Think (void)
+{
+       self = self.owner; // set self to the player to be killed
+       sprint(self, "^1You were killed in order to prevent cheating!");
+       ClientKill_Now();
+}
+
+void CTS_ClientKill (float t) // silent version of ClientKill
+{
+       entity e;
+       e = spawn();
+       e.owner = self;
+       e.think = CTS_ClientKill_Think;
+       e.nextthink = t;
+}
+
 void DoTeamChange(float destteam)
 {
        float t, c0;
@@ -1587,11 +1603,12 @@ void ClientConnect (void)
                        rr = RACE_RECORD;
                t = stof(db_get(ServerProgsDB, strcat(GetMapname(), rr, "time")));
 
+               msg_entity = self;
                race_send_recordtime(MSG_ONE);
                race_send_speedaward(MSG_ONE);
 
                speedaward_alltimebest = stof(db_get(ServerProgsDB, strcat(GetMapname(), rr, "speed/speed")));
-               speedaward_alltimebest_holder = db_get(ServerProgsDB, strcat(GetMapname(), rr, "speed/netname"));
+               speedaward_alltimebest_holder = uid2name(db_get(ServerProgsDB, strcat(GetMapname(), rr, "speed/crypto_idfp")));
                race_send_speedaward_alltimebest(MSG_ONE);
 
                float i;
@@ -2225,6 +2242,7 @@ void SpectateCopy(entity spectatee) {
        self.health = spectatee.health;
        self.impulse = 0;
        self.items = spectatee.items;
+       self.last_pickup = spectatee.last_pickup;
        self.metertime = spectatee.metertime;
        self.strength_finished = spectatee.strength_finished;
        self.invincible_finished = spectatee.invincible_finished;
@@ -3016,6 +3034,18 @@ void PlayerPostThink (void)
 
        playerdemo_write();
 
+       if((g_cts || g_race) && self.cvar_cl_allow_uid2name)
+       {
+               if(!self.stored_netname)
+                       self.stored_netname = strzone(uid2name(self.crypto_idfp));
+               if(self.stored_netname != self.netname)
+               {
+                       db_put(ServerProgsDB, strcat("uid2name", self.crypto_idfp), self.netname);
+                       strunzone(self.stored_netname);
+                       self.stored_netname = strzone(self.netname);
+               }
+       }
+
        /*
        if(g_race)
                dprint(sprintf("%f %.6f\n", time, race_GetFractionalLapCount(self)));
index b587c16..e211275 100644 (file)
@@ -266,7 +266,7 @@ void RaceCarPhysics()
        // using this move type for "big rigs"
        // the engine does not push the entity!
 
-       float accel, steer, f;
+       float accel, steer, f, myspeed, steerfactor;
        vector angles_save, rigvel;
 
        angles_save = self.angles;
@@ -292,7 +292,7 @@ void RaceCarPhysics()
 
        if(self.flags & FL_ONGROUND || g_bugrigs_air_steering)
        {
-               float myspeed, upspeed, steerfactor, accelfactor;
+               float upspeed, accelfactor;
 
                myspeed = self.velocity * v_forward;
                upspeed = self.velocity * v_up;
@@ -671,6 +671,7 @@ void SpecialCommand()
 
 float speedaward_speed;
 string speedaward_holder;
+string speedaward_uid;
 void race_send_speedaward(float msg)
 {
        // send the best speed of the round
@@ -683,6 +684,7 @@ void race_send_speedaward(float msg)
 
 float speedaward_alltimebest;
 string speedaward_alltimebest_holder;
+string speedaward_alltimebest_uid;
 void race_send_speedaward_alltimebest(float msg)
 {
        // send the best speed
@@ -1304,6 +1306,7 @@ void SV_PlayerPhysics()
                if(vlen(self.velocity - self.velocity_z * '0 0 1') > speedaward_speed) {
                        speedaward_speed = vlen(self.velocity - self.velocity_z * '0 0 1');
                        speedaward_holder = self.netname;
+                       speedaward_uid = self.crypto_idfp;
                        speedaward_lastupdate = time;
                }
                if(speedaward_speed > speedaward_lastsent && time - speedaward_lastupdate > 1) {
@@ -1317,8 +1320,9 @@ void SV_PlayerPhysics()
                        if (speedaward_speed > speedaward_alltimebest) {
                                speedaward_alltimebest = speedaward_speed;
                                speedaward_alltimebest_holder = speedaward_holder;
+                               speedaward_alltimebest_uid = speedaward_uid;
                                db_put(ServerProgsDB, strcat(GetMapname(), rr, "speed/speed"), ftos(speedaward_alltimebest));
-                               db_put(ServerProgsDB, strcat(GetMapname(), rr, "speed/netname"), speedaward_alltimebest_holder);
+                               db_put(ServerProgsDB, strcat(GetMapname(), rr, "speed/crypto_idfp"), speedaward_alltimebest_uid);
                                race_send_speedaward_alltimebest(MSG_ALL);
                        }
                }
index db8bc4b..d890f5d 100644 (file)
@@ -488,15 +488,18 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht
 
                                        if(sound_allowed(MSG_BROADCAST, attacker))
                                        if(!DEATH_ISWEAPON(deathtype, WEP_LASER) || attacker != self || self.health < 2 * cvar("g_balance_laser_primary_damage") * cvar("g_balance_selfdamagepercent") + 1)
+                                       if(self.health > 1)
                                        // exclude pain sounds for laserjumps as long as you aren't REALLY low on health and would die of the next two
                                        {
-                                               if(self.health > 75) // TODO make a "gentle" version?
+                                               if(deathtype == DEATH_FALL)
+                                                       PlayerSound(playersound_fall, CHAN_PAIN, VOICETYPE_PLAYERSOUND);
+                                               else if(self.health > 75) // TODO make a "gentle" version?
                                                        PlayerSound(playersound_pain100, CHAN_PAIN, VOICETYPE_PLAYERSOUND);
                                                else if(self.health > 50)
                                                        PlayerSound(playersound_pain75, CHAN_PAIN, VOICETYPE_PLAYERSOUND);
                                                else if(self.health > 25)
                                                        PlayerSound(playersound_pain50, CHAN_PAIN, VOICETYPE_PLAYERSOUND);
-                                               else if(self.health > 1)
+                                               else
                                                        PlayerSound(playersound_pain25, CHAN_PAIN, VOICETYPE_PLAYERSOUND);
                                        }
                                }
@@ -855,6 +858,7 @@ float Say(entity source, float teamsay, entity privatesay, string msgin, float f
 {
        string msgstr, colorstr, cmsgstr, namestr, fullmsgstr, sourcemsgstr, fullcmsgstr, sourcecmsgstr, privatemsgprefix;
        float flood, privatemsgprefixlen;
+       var .float flood_field;
        entity head;
        float ret;
 
@@ -936,7 +940,6 @@ float Say(entity source, float teamsay, entity privatesay, string msgin, float f
                float flood_spl;
                float flood_burst;
                float flood_lmax;
-               var .float flood_field;
                float lines;
                if(privatesay)
                {
@@ -998,10 +1001,10 @@ float Say(entity source, float teamsay, entity privatesay, string msgin, float f
                        else
                                flood = 1;
                }
-       }
 
-       if (timeoutStatus == 2) //when game is paused, no flood protection
-               source.flood_field = flood = 0;
+               if (timeoutStatus == 2) //when game is paused, no flood protection
+                       source.flood_field = flood = 0;
+       }
 
        if(flood == 2) // cannot happen for empty msgstr
        {
index b705e9c..df19ab5 100644 (file)
@@ -303,6 +303,8 @@ void SV_ParseClientCommand(string s) {
        } else if(cmd == "records") {
                for(i = 0; i < 10; ++i)
                        sprint(self, records_reply[i]);
+       } else if(cmd == "ladder") {
+               sprint(self, ladder_reply);
        } else if(cmd == "rankings") {
                sprint(self, rankings_reply);
        } else if(cmd == "voice") {
@@ -362,6 +364,8 @@ void SV_ParseClientCommand(string s) {
                Score_NicePrint(self);
        } else if(cmd == "cvar_changes") {
                sprint(self, cvar_changes);
+       } else if(cmd == "cvar_purechanges") {
+               sprint(self, cvar_purechanges);
        } else if(CheatCommand(tokens)) {
        } else {
                //if(ctf_clientcommand())
index 5be0414..45394eb 100644 (file)
@@ -329,6 +329,9 @@ float sv_loddistance2;
 
 .string weaponorder_byimpulse;
 
+.float cvar_cl_allow_uid2name;
+.string stored_netname;
+
 void Announce(string snd);
 void AnnounceTo(entity e, string snd);
 
@@ -523,6 +526,8 @@ string clientstuff;
 .string fog;
 
 string cvar_changes;
+string cvar_purechanges;
+float cvar_purechanges_count;
 
 float game_starttime; //point in time when the countdown is over
 .float stat_game_starttime;
@@ -603,6 +608,8 @@ string matchid;
 .float stats_hit[WEP_MAXCOUNT];  // for hitscan bullets hit
 .float stats_fired[WEP_MAXCOUNT];  // for hitscan bullets fired
 
+.float last_pickup;
+
 FTEQCC_YOU_SUCK_THIS_IS_NOT_UNREFERENCED(stats_hit);
 FTEQCC_YOU_SUCK_THIS_IS_NOT_UNREFERENCED(stats_fired);
 
index ce3d9b7..88e1ced 100644 (file)
@@ -268,7 +268,7 @@ void GrapplingHookThink()
        }
 
        makevectors(self.angles_x * '-1 0 0' + self.angles_y * '0 1 0');
-       myorg = WarpZone_RefSys_TransformOrigin(self, self.owner, self.origin) + v_forward * (-9);
+       myorg = WarpZone_RefSys_TransformOrigin(self, self.owner, self.origin); // + v_forward * (-9);
 
        if(myorg != self.hook_start)
        {
@@ -343,6 +343,10 @@ void FireGrapplingHook (void)
        // UGLY WORKAROUND: play this on CHAN_WEAPON2 so it can't cut off fire sounds
        sound (self, CHAN_WEAPON2, "weapons/hook_fire.wav", VOL_BASE, ATTN_NORM);
        org = self.origin + self.view_ofs + v_forward * vs_x + v_right * -vs_y + v_up * vs_z;
+
+       tracebox(self.origin + self.view_ofs, '-3 -3 -3', '3 3 3', org, MOVE_NORMAL, self);
+       org = trace_endpos;
+
        pointparticles(particleeffectnum("grapple_muzzleflash"), org, '0 0 0', 1);
 
        missile = WarpZone_RefSys_SpawnSameRefSys(self);
index a6e73ba..f5def6a 100644 (file)
@@ -13,6 +13,9 @@ float Violence_GibSplash_SendEntity(entity to, float sf)
 // TODO maybe convert this to a TE?
 void Violence_GibSplash_At(vector org, vector dir, float type, float amount, entity gibowner, entity attacker)
 {
+       if(g_cts) // no gibs in CTS
+               return;
+
        entity e;
 
        e = spawn();
index 73ae560..acfbb8a 100644 (file)
@@ -213,16 +213,23 @@ void cvar_changes_init()
 {
        float h;
        string k, v, d;
-       float n, i;
+       float n, i, adding, pureadding;
 
        if(cvar_changes)
                strunzone(cvar_changes);
        cvar_changes = string_null;
+       if(cvar_purechanges)
+               strunzone(cvar_purechanges);
+       cvar_purechanges = string_null;
+       cvar_purechanges_count = 0;
 
        h = buf_create();
        buf_cvarlist(h, "", "_"); // exclude all _ cvars as they are temporary
        n = buf_getsize(h);
 
+       adding = TRUE;
+       pureadding = TRUE;
+
        for(i = 0; i < n; ++i)
        {
                k = bufstr_get(h, i);
@@ -239,22 +246,30 @@ void cvar_changes_init()
                BADPREFIX("sv_world");
 
                // client
+               BADPREFIX("chase_");
                BADPREFIX("cl_");
                BADPREFIX("con_");
+               BADPREFIX("scoreboard_");
                BADPREFIX("g_campaign");
                BADPREFIX("gl_");
                BADPREFIX("joy");
+               BADPREFIX("hud_");
                BADPREFIX("menu_");
                BADPREFIX("net_slist_");
                BADPREFIX("r_");
                BADPREFIX("sbar_");
                BADPREFIX("scr_");
+               BADPREFIX("snd_");
                BADPREFIX("userbind");
                BADPREFIX("v_");
                BADPREFIX("vid_");
                BADPREFIX("crosshair");
                BADCVAR("mod_q3bsp_lightmapmergepower");
                BADCVAR("mod_q3bsp_nolightmaps");
+               BADCVAR("fov");
+               BADCVAR("mastervolume");
+               BADCVAR("volume");
+               BADCVAR("bgmvolume");
 
                // private
                BADCVAR("serverconfig");
@@ -282,10 +297,19 @@ void cvar_changes_init()
                BADCVAR("timestamps");
                BADCVAR("net_address");
                BADCVAR("net_address_ipv6");
+               BADPREFIX("sv_weaponstats_");
+               BADCVAR("developer");
+               BADPREFIX("developer_");
 
                // mapinfo
                BADCVAR("timelimit");
                BADCVAR("fraglimit");
+               BADCVAR("leadlimit");
+               BADCVAR("g_tdm_teams");
+               BADCVAR("g_keyhunt_teams");
+               BADCVAR("g_domination_default_teams");
+               BADCVAR("g_race_qualifying_timelimit");
+               BADCVAR("g_lms");
                BADCVAR("g_arena");
                BADCVAR("g_ca");
                BADCVAR("g_assault");
@@ -307,27 +331,135 @@ void cvar_changes_init()
                BADCVAR("g_maplist");
                BADCVAR("g_maplist_mostrecent");
                BADCVAR("sv_motd");
-#undef BADPREFIX
-#undef BADCVAR
 
                v = cvar_string(k);
                d = cvar_defstring(k);
-               if(v != d)
+               if(v == d)
+                       continue;
+
+               if(adding)
                {
                        cvar_changes = strcat(cvar_changes, k, " \"", v, "\" // \"", d, "\"\n");
                        if(strlen(cvar_changes) > 16384)
                        {
                                cvar_changes = "// too many settings have been changed to show them here\n";
-                               break;
+                               adding = 0;
+                       }
+               }
+
+               // now check if the changes are actually gameplay relevant
+
+               // does nothing visible
+               BADCVAR("captureleadlimit_override");
+               BADCVAR("g_arena_point_leadlimit");
+               BADCVAR("g_ca_point_leadlimit");
+               BADCVAR("g_ctf_capture_leadlimit");
+               BADCVAR("g_domination_point_leadlimit");
+               BADCVAR("g_keyhunt_point_leadlimit");
+               BADCVAR("g_nexball_goalleadlimit");
+               BADCVAR("g_runematch_point_leadlimit");
+               BADCVAR("leadlimit_and_fraglimit");
+               BADCVAR("leadlimit_override");
+               BADPREFIX("crypto_");
+               BADPREFIX("g_chat_");
+               BADPREFIX("prvm_");
+               BADPREFIX("sv_fragmessage_");
+               BADPREFIX("sv_vote_");
+               BADPREFIX("timelimit_");
+
+               // allowed changes to server admins (please sync this to server.cfg)
+               // vi commands:
+               //   :/"impure"/,$d
+               //   :g!,^\/\/[^ /],d
+               //   :%s,//\([^ ]*\).*,BADCVAR("\1");,
+               //   :%!sort
+               // yes, this does contain some redundant stuff, don't really care
+               BADCVAR("bot_number");
+               BADCVAR("bot_prefix");
+               BADCVAR("bot_suffix");
+               BADCVAR("capturelimit_override");
+               BADCVAR("fraglimit_override");
+               BADCVAR("gametype");
+               BADCVAR("g_antilag");
+               BADCVAR("g_balance_teams");
+               BADCVAR("g_balance_teams_force");
+               BADCVAR("g_ban_sync_trusted_servers");
+               BADCVAR("g_ban_sync_uri");
+               BADCVAR("g_ctf_capture_limit");
+               BADCVAR("g_ctf_ignore_frags");
+               BADCVAR("g_ctf_win_mode");
+               BADCVAR("g_domination_point_limit");
+               BADCVAR("g_fullbrightitems");
+               BADCVAR("g_fullbrightplayers");
+               BADCVAR("g_keyhunt_point_limit");
+               BADCVAR("g_keyhunt_teams_override");
+               BADCVAR("g_lms_lives_override");
+               BADCVAR("g_maplist");
+               BADCVAR("g_maplist_check_waypoints");
+               BADCVAR("g_maplist_mostrecent_count");
+               BADCVAR("g_maplist_shuffle");
+               BADCVAR("g_maplist_votable");
+               BADCVAR("g_maplist_votable_abstain");
+               BADCVAR("g_maplist_votable_nodetail");
+               BADCVAR("g_maplist_votable_suggestions");
+               BADCVAR("g_nexball_goallimit");
+               BADCVAR("g_runematch_point_limit");
+               BADCVAR("g_start_delay");
+               BADCVAR("hostname");
+               BADCVAR("log_file");
+               BADCVAR("maxplayers");
+               BADCVAR("minplayers");
+               BADCVAR("net_address");
+               BADCVAR("port");
+               BADCVAR("rcon_password");
+               BADCVAR("rcon_restricted_commands");
+               BADCVAR("rcon_restricted_password");
+               BADCVAR("skill");
+               BADCVAR("sv_adminnick");
+               BADCVAR("sv_autoscreenshot");
+               BADCVAR("sv_curl_defaulturl");
+               BADCVAR("sv_defaultcharacter");
+               BADCVAR("sv_defaultplayermodel");
+               BADCVAR("sv_defaultplayerskin");
+               BADCVAR("sv_maxidle");
+               BADCVAR("sv_maxrate");
+               BADCVAR("sv_motd");
+               BADCVAR("sv_public");
+               BADCVAR("sv_ready_restart");
+               BADCVAR("sv_status_privacy");
+               BADCVAR("sv_vote_call");
+               BADCVAR("sv_vote_commands");
+               BADCVAR("sv_vote_majority_factor");
+               BADCVAR("sv_vote_master");
+               BADCVAR("sv_vote_master_commands");
+               BADCVAR("sv_vote_master_password");
+               BADCVAR("sv_vote_simple_majority_factor");
+               BADCVAR("timelimit_override");
+#undef BADPREFIX
+#undef BADCVAR
+
+               if(pureadding)
+               {
+                       cvar_purechanges = strcat(cvar_purechanges, k, " \"", v, "\" // \"", d, "\"\n");
+                       if(strlen(cvar_purechanges) > 16384)
+                       {
+                               cvar_purechanges = "// too many settings have been changed to show them here\n";
+                               pureadding = 0;
                        }
                }
+               ++cvar_purechanges_count;
        }
        buf_del(h);
        if(cvar_changes == "")
-               cvar_changes = "// this server runs at default settings\n";
+               cvar_changes = "// this server runs at default server settings\n";
        else
-               cvar_changes = strcat("// this server runs at modified settings:\n", cvar_changes);
+               cvar_changes = strcat("// this server runs at modified server settings:\n", cvar_changes);
        cvar_changes = strzone(cvar_changes);
+       if(cvar_purechanges == "")
+               cvar_purechanges = "// this server runs at default gameplay settings\n";
+       else
+               cvar_purechanges = strcat("// this server runs at modified gameplay settings:\n", cvar_purechanges);
+       cvar_purechanges = strzone(cvar_purechanges);
 }
 
 void detect_maptype()
@@ -438,6 +570,8 @@ void spawnfunc_worldspawn (void)
 
        check_unacceptable_compiler_bugs();
 
+       cvar_changes_init(); // do this very early now so it REALLY matches the server config
+
        compressShortVector_init();
 
        allowed_to_spawn = TRUE;
@@ -641,6 +775,7 @@ void spawnfunc_worldspawn (void)
        addstat(STAT_SHOTORG, AS_INT, stat_shotorg);
        addstat(STAT_LEADLIMIT, AS_FLOAT, stat_leadlimit);
        addstat(STAT_BULLETS_LOADED, AS_INT, campingrifle_bulletcounter);
+       addstat(STAT_LAST_PICKUP, AS_FLOAT, last_pickup);
 
        addstat(STAT_NEX_CHARGE, AS_FLOAT, nex_charge);
 
@@ -655,7 +790,6 @@ void spawnfunc_worldspawn (void)
        addstat(STAT_MOVEVARS_AIRSTRAFEACCEL_QW, AS_FLOAT, stat_sv_airstrafeaccel_qw);
 
        next_pingtime = time + 5;
-       InitializeEntity(self, cvar_changes_init, INITPRIO_CVARS);
 
        detect_maptype();
 
@@ -704,6 +838,8 @@ void spawnfunc_worldspawn (void)
        {
                records_reply[i] = strzone(getrecords(i));
        }
+       if(g_cts)
+               ladder_reply = strzone(getladder());
 
        rankings_reply = strzone(getrankings());
 
index b5c68ca..90b06a5 100644 (file)
@@ -1,5 +1,5 @@
 string GotoMap(string m);
-void race_DeleteTime(float pos);
+void race_deleteTime(string map, float pos);
 
 float FullTraceFraction(vector a, vector mi, vector ma, vector b)
 {
@@ -651,6 +651,7 @@ void GameCommand(string command)
                print("  radarmap [--force] [--quit | --loop] [sharpness]\n");
                print("  bbox\n");
                print("  cvar_changes\n");
+               print("  cvar_purechanges\n");
                print("  find classname\n");
                GameCommand_Vote("help", world);
                GameCommand_Ban("help");
@@ -912,6 +913,11 @@ void GameCommand(string command)
                print(cvar_changes);
                return;
        }
+       if (argv(0) == "cvar_purechanges")
+       {
+               print(cvar_purechanges);
+               return;
+       }
        if (argv(0) == "find") if(argc == 2)
        {
                for(client = world; (client = find(client, classname, argv(1))); )
@@ -924,6 +930,11 @@ void GameCommand(string command)
                        print(records_reply[i]);
                return;
        }
+       if (argv(0) == "ladder")
+       {
+               print(ladder_reply);
+               return;
+       }
        if (argv(0) == "rankings")
        {
                strunzone(rankings_reply);
@@ -1340,7 +1351,11 @@ void GameCommand(string command)
        }
        if(argv(0) == "delrec")
        {
-               race_DeleteTime(stof(argv(1)));
+               if(argv(2) != "")
+                       race_deleteTime(argv(2), stof(argv(1)));
+               else
+                       race_deleteTime(GetMapname(), stof(argv(1)));
+
                return;
        }
 
index f8f5ebe..5485cc1 100644 (file)
@@ -16,9 +16,6 @@ void WarpZone_crosshair_trace(entity pl)
 
 void() spawnfunc_info_player_deathmatch; // needed for the other spawnpoints
 void() spawnpoint_use;
-float race_GetTime(float pos);
-string race_GetName(float pos);
-string race_PlaceName(float pos);
 string GetMapname();
 string ColoredTeamName(float t);
 
@@ -638,6 +635,7 @@ void GetCvars(float f)
        GetCvars_handleFloat(s, f, cvar_cl_forceplayermodelsfromxonotic, "cl_forceplayermodelsfromxonotic");
 #endif
        GetCvars_handleFloatOnce(s, f, cvar_cl_gunalign, "cl_gunalign");
+       GetCvars_handleFloat(s, f, cvar_cl_allow_uid2name, "cl_allow_uid2name");
 
        // fixup of switchweapon (needed for LMS or when spectating is disabled, as PutClientInServer comes too early)
        if (f > 0)
@@ -1732,7 +1730,6 @@ void precache()
 #define INITPRIO_FIRST              0
 #define INITPRIO_GAMETYPE           0
 #define INITPRIO_GAMETYPE_FALLBACK  1
-#define INITPRIO_CVARS              5
 #define INITPRIO_FINDTARGET        10
 #define INITPRIO_DROPTOFLOOR       20
 #define INITPRIO_SETLOCATION       90
@@ -2079,6 +2076,106 @@ void print_to(entity e, string s)
         print(s, "\n");
 }
 
+string uid2name(string myuid) {
+       string s;
+       s = db_get(ServerProgsDB, strcat("uid2name", myuid));
+       
+       if(s == "")
+               s = "^1Unregistered Player";
+       return s;
+}
+
+float race_readTime(string map, float pos)
+{
+       string rr;
+       if(g_cts)
+               rr = CTS_RECORD;
+       else
+               rr = RACE_RECORD;
+
+       return stof(db_get(ServerProgsDB, strcat(map, rr, "time", ftos(pos))));
+}
+
+string race_readUID(string map, float pos)
+{
+       string rr;
+       if(g_cts)
+               rr = CTS_RECORD;
+       else
+               rr = RACE_RECORD;
+
+       return db_get(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(pos)));
+}
+
+float race_readPos(string map, float t) {
+       float i;
+       for (i = 1; i <= RANKINGS_CNT; ++i)
+               if (race_readTime(map, i) == 0 || race_readTime(map, i) > t)
+                       return i;
+
+       return 0; // pos is zero if unranked
+}
+
+void race_writeTime(string map, float t, string myuid)
+{
+       string rr;
+       if(g_cts)
+               rr = CTS_RECORD;
+       else
+               rr = RACE_RECORD;
+
+       float newpos;
+       newpos = race_readPos(map, t);
+
+       float i, prevpos;
+       for(i = 1; i <= RANKINGS_CNT; ++i)
+       {
+               if(race_readUID(map, i) == myuid)
+                       prevpos = i;
+       }
+       if (prevpos) { // player improved his existing record, only have to iterate on ranks between new and old recs
+               for (i = prevpos; i > newpos; --i) {
+                       db_put(ServerProgsDB, strcat(map, rr, "time", ftos(i)), ftos(race_readTime(map, i - 1)));
+                       db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(i)), race_readUID(map, i - 1));
+               }
+       } else { // player has no ranked record yet
+               for (i = RANKINGS_CNT; i > newpos; --i) {
+                       db_put(ServerProgsDB, strcat(map, rr, "time", ftos(i)), ftos(race_readTime(map, i - 1)));
+                       db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(i)), race_readUID(map, i - 1));
+               }
+       }
+
+       // store new time itself
+       db_put(ServerProgsDB, strcat(map, rr, "time", ftos(newpos)), ftos(t));
+       db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(newpos)), myuid);
+}
+
+string race_readName(string map, float pos)
+{
+       string rr;
+       if(g_cts)
+               rr = CTS_RECORD;
+       else
+               rr = RACE_RECORD;
+
+       return uid2name(db_get(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(pos))));
+}
+
+string race_placeName(float pos) {
+       if(floor((mod(pos, 100))/10) * 10 != 10) // examples: 12th, 111th, 213th will not execute this block
+       {
+               if(mod(pos, 10) == 1)
+                       return strcat(ftos(pos), "st");
+               else if(mod(pos, 10) == 2)
+                       return strcat(ftos(pos), "nd");
+               else if(mod(pos, 10) == 3)
+                       return strcat(ftos(pos), "rd");
+               else
+                       return strcat(ftos(pos), "th");
+       }
+       else
+               return strcat(ftos(pos), "th");
+}
 string getrecords(float page) // 50 records per page
 {
     float rec;
@@ -2100,6 +2197,7 @@ string getrecords(float page) // 50 records per page
                 r = stof(db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, "/captimerecord/time")));
                 if (r == 0)
                     continue;
+               // TODO: uid2name
                 h = db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, "/captimerecord/netname"));
                 s = strcat(s, strpad(32, MapInfo_Map_bspname), " ", strpad(-6, ftos_decimals(r, 2)), " ", h, "\n");
                 ++rec;
@@ -2113,10 +2211,10 @@ string getrecords(float page) // 50 records per page
         {
             if (MapInfo_Get_ByID(i))
             {
-                r = stof(db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, RACE_RECORD, "time")));
+               r = race_readTime(MapInfo_Map_bspname, 1);
                 if (r == 0)
                     continue;
-                h = db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, RACE_RECORD, "netname"));
+               h = race_readName(MapInfo_Map_bspname, 1);
                 s = strcat(s, strpad(32, MapInfo_Map_bspname), " ", strpad(-8, TIME_ENCODED_TOSTRING(r)), " ", h, "\n");
                 ++rec;
             }
@@ -2129,10 +2227,10 @@ string getrecords(float page) // 50 records per page
         {
             if (MapInfo_Get_ByID(i))
             {
-                r = stof(db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, CTS_RECORD, "time")));
+               r = race_readTime(MapInfo_Map_bspname, 1);
                 if (r == 0)
                     continue;
-                h = db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, CTS_RECORD, "netname"));
+               h = race_readName(MapInfo_Map_bspname, 1);
                 s = strcat(s, strpad(32, MapInfo_Map_bspname), " ", strpad(-8, TIME_ENCODED_TOSTRING(r)), " ", h, "\n");
                 ++rec;
             }
@@ -2162,11 +2260,11 @@ string getrankings()
 
     for (i = 1; i <= RANKINGS_CNT; ++i)
     {
-        t = race_GetTime(i);
+        t = race_readTime(map, i);
        if (t == 0)
            continue;
-       n = race_GetName(i);
-       p = race_PlaceName(i);
+       n = race_readName(map, i);
+       p = race_placeName(i);
         s = strcat(s, strpad(8, p), " ", strpad(-8, TIME_ENCODED_TOSTRING(t)), " ", n, "\n");
     }
 
@@ -2178,6 +2276,193 @@ string getrankings()
         return strcat("Records for ", map, ":\n", s);
 }
 
+#define LADDER_FIRSTPOINT 100
+#define LADDER_CNT 10
+       // position X still gives LADDER_FIRSTPOINT/X points
+#define LADDER_SIZE 30
+       // ladder shows the top X players
+string top_uids[LADDER_SIZE];
+float top_scores[LADDER_SIZE];
+string getladder()
+{
+    float i, j, k, uidcnt;
+    string s, temp_s;
+
+    s = "";
+    temp_s = "";
+
+    string rr;
+    if(g_cts)
+       rr = CTS_RECORD;
+    else
+       rr = RACE_RECORD;
+
+    string myuid;
+
+    for (k = 0; k < MapInfo_count; ++k)
+    {
+        if (MapInfo_Get_ByID(k))
+       {
+               for (i = 0; i <= LADDER_CNT; ++i) { // i = 0 because it is the speed award
+                       if(i == 0) // speed award
+                       {
+                               if(stof(db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, rr, "speed/speed"))) == 0)
+                                       continue;
+
+                               myuid = db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, rr, "speed/crypto_idfp"));
+                       }
+                       else // normal record, if it exists (else break)
+                       {
+                               if(race_readTime(MapInfo_Map_bspname, i) == 0)
+                                       continue;
+
+                               myuid = race_readUID(MapInfo_Map_bspname, i);
+                       }
+
+                       // string s contains:
+                       // arg 0 = # of speed recs
+                       // arg 1 = # of 1st place recs
+                       // arg 2 = # of 2nd place recs
+                       // ... etc
+                       // LADDER_CNT+1 = total points
+
+                       temp_s = db_get(TemporaryDB, strcat("ladder", myuid));
+                       if (temp_s == "")
+                       {
+                           db_put(TemporaryDB, strcat("uid", ftos(uidcnt)), myuid);
+                           ++uidcnt;
+                           for (j = 0; j <= LADDER_CNT + 1; ++j)
+                           {
+                               if(j != LADDER_CNT + 1)
+                                   temp_s = strcat(temp_s, "0 ");
+                               else
+                                   temp_s = strcat(temp_s, "0");
+                           }
+                       }
+
+                       tokenize_console(temp_s);
+                       s = "";
+
+                       if(i == 0) // speed award
+                           for (j = 0; j <= LADDER_CNT; ++j) // loop over each arg in the string
+                           {
+                               if(j == 0) // speed award
+                                   s = strcat(s, ftos(stof(argv(j)) +1)); // add 1 to speed rec count and write
+                               else
+                                   s = strcat(s, " ", argv(j)); // just copy over everything else
+                           }
+                       else // record
+                           for (j = 0; j <= LADDER_CNT; ++j) // loop over each arg in the string
+                           {
+                               if(j == 0)
+                                   s = strcat(s, argv(j)); // speed award, dont prefix with " "
+                               else if(j == i) // wanted rec!
+                                   s = strcat(s, " ", ftos(stof(argv(j)) +1)); // update argv(j)
+                               else
+                                   s = strcat(s, " ", argv(j)); // just copy over everything else
+                           }
+
+                       // total points are (by default) calculated like this:
+                       // speedrec = floor(100 / 10) = 10 points
+                       // 1st place = floor(100 / 1) = 100 points
+                       // 2nd place = floor(100 / 2) = 50 points
+                       // 3rd place = floor(100 / 3) = 33 points
+                       // 4th place = floor(100 / 4) = 25 points
+                       // 5th place = floor(100 / 5) = 20 points
+                       // ... etc
+
+                       if(i == 0)
+                           s = strcat(s, " ", ftos(stof(argv(LADDER_CNT+1)) + LADDER_FIRSTPOINT / 10)); // speed award, add LADDER_FIRSTPOINT / 10 points
+                       else
+                           s = strcat(s, " ", ftos(stof(argv(LADDER_CNT+1)) + floor(LADDER_FIRSTPOINT / i))); // record, add LADDER_FIRSTPOINT / i points
+
+                       db_put(TemporaryDB, strcat("ladder", myuid), s);
+               }
+       }
+    }
+
+    float thiscnt;
+    string thisuid;
+    for (i = 0; i <= uidcnt; ++i) // for each known uid
+    {
+       thisuid = db_get(TemporaryDB, strcat("uid", ftos(i)));
+       temp_s = db_get(TemporaryDB, strcat("ladder", thisuid));
+       tokenize_console(temp_s);
+        thiscnt = stof(argv(LADDER_CNT+1));
+
+       if(thiscnt > top_scores[LADDER_SIZE-1])
+       for (j = 0; j < LADDER_SIZE; ++j) // for each place in ladder
+       {
+           if(thiscnt > top_scores[j])
+           {
+               for (k = LADDER_SIZE-1; k >= j; --k)
+               {
+                   top_uids[k] = top_uids[k-1];
+                   top_scores[k] = top_scores[k-1];
+               }
+               top_uids[j] = thisuid;
+               top_scores[j] = thiscnt;
+               break;
+           }
+       }
+    }
+
+    s = "^3-----------------------\n\n";
+
+    s = strcat(s, "Pos ^3|");
+    s = strcat(s, " ^7Total  ^3|");
+    for (i = 1; i <= LADDER_CNT; ++i)
+    {
+       s = strcat(s, " ^7", race_placeName(i), " ^3|");
+    }
+    s = strcat(s, " ^7Speed awards ^3| ^7Name");
+
+    s = strcat(s, "\n^3----+--------");
+    for (i = 1; i <= min(9, LADDER_CNT); ++i)
+    {
+       s = strcat(s, "+-----");
+    }
+#if LADDER_CNT > 9
+    for (i = 1; i <= LADDER_CNT - 9; ++i)
+    {
+       s = strcat(s, "+------");
+    }
+#endif
+
+    s = strcat(s, "+--------------+--------------------\n");
+
+    for (i = 0; i < LADDER_SIZE; ++i)
+    {
+       temp_s = db_get(TemporaryDB, strcat("ladder", top_uids[i]));
+       tokenize_console(temp_s);
+       if (argv(LADDER_CNT+1) == "") // total is 0, skip
+           continue;
+       s = strcat(s, strpad(4, race_placeName(i+1)), "^3| ^7"); // pos
+       s = strcat(s, strpad(7, argv(LADDER_CNT+1)), "^3| ^7"); // total
+       for (j = 1; j <= min(9, LADDER_CNT); ++j)
+       {
+           s = strcat(s, strpad(4, argv(j)), "^3| ^7"); // 1st, 2nd, 3rd etc cnt
+       }
+#if LADDER_CNT > 9
+       for (j = 10; j <= LADDER_CNT; ++j)
+       {
+           s = strcat(s, strpad(4, argv(j)), " ^3| ^7"); // 1st, 2nd, 3rd etc cnt
+       }
+#endif
+
+       s = strcat(s, strpad(13, argv(0)), "^3| ^7"); // speed award cnt
+       s = strcat(s, uid2name(top_uids[i]), "\n"); // name
+    }
+
+    MapInfo_ClearTemps();
+
+    if (s == "")
+       return "No ladder on this server!\n";
+    else
+        return strcat("Top ", ftos(LADDER_SIZE), " ladder rankings:\n", s);
+}
+
+
 float MoveToRandomMapLocation(entity e, float goodcontents, float badcontents, float badsurfaceflags, float attempts, float maxaboveground, float minviewdistance)
 {
     float m, i;
index 2f15889..3786edb 100644 (file)
@@ -98,75 +98,13 @@ void race_InitSpectator()
                        race_SendNextCheckpoint(msg_entity.enemy, 1);
 }
 
-string rr;
-float grecordtime[RANKINGS_CNT];
-string grecordholder[RANKINGS_CNT];
-string grecorduid[RANKINGS_CNT];
-float worst_time; // last ranked time
-float have_recs; // have we already read the records from the database before?
-float race_GetTime(float pos) {
-       if(g_cts)
-               rr = CTS_RECORD;
-       else
-               rr = RACE_RECORD;
-
-       if (!have_recs) { // I guess this is better than checking if the first array item is empty, rumor has it that arrays are slow
-               float i;
-               for(i=0;i<RANKINGS_CNT;++i) {
-                       grecordtime[i] = stof(db_get(ServerProgsDB, strcat(GetMapname(), rr, "time", ftos(i))));
-                       grecordholder[i] = strzone(db_get(ServerProgsDB, strcat(GetMapname(), rr, "netname", ftos(i))));
-                       grecorduid[i] = strzone(db_get(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp", ftos(i))));
-               }
-               grecordtime[0] = stof(db_get(ServerProgsDB, strcat(GetMapname(), rr, "time")));
-               grecordholder[0] = strzone(db_get(ServerProgsDB, strcat(GetMapname(), rr, "netname")));
-               grecorduid[0] = strzone(db_get(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp")));
-               worst_time = stof(db_get(ServerProgsDB, strcat(GetMapname(), rr, strcat("time", ftos(RANKINGS_CNT-1)))));
-               have_recs = 1;
-       }
-
-       return grecordtime[pos-1];
-}
-
-string race_GetName(float pos) { // these other functions assume that race_GetTime has been called >= once before
-       return grecordholder[pos-1];
-}
-
-float race_CheckUID(string myuid, string net_name) { // return existing UID or player name ranking pos, else 0
-       float i;
-       if(myuid)
-       {
-               for (i=RANKINGS_CNT-1;i>=0;--i)
-                       if(grecorduid[i] == myuid)
-                               return i+1;
-       }
-       for (i=RANKINGS_CNT-1;i>=0;--i)
-               if(!grecorduid[i])
-                       if(grecordholder[i] == net_name)
-                               return i+1;
-       return 0;
-}
-
-float race_GetPos(float t) {
-       float i;
-
-       if(worst_time == 0)
-       for (i=0;i<RANKINGS_CNT;++i)
-               if (grecordtime[i] == 0 || grecordtime[i] > t)
-                       return i+1;
-
-       for (i=0;i<RANKINGS_CNT;++i)
-               if (grecordtime[i] > t)
-                       return i+1;
-       return 0;
-}
-
 void race_send_recordtime(float msg)
 {
        // send the server best time
        WriteByte(msg, SVC_TEMPENTITY);
        WriteByte(msg, TE_CSQC_RACE);
        WriteByte(msg, RACE_NET_SERVER_RECORD);
-       WriteInt24_t(msg, race_GetTime(1));
+       WriteInt24_t(msg, race_readTime(GetMapname(), 1));
 }
 
 void race_SendRankings(float pos, float prevpos, float del, float msg)
@@ -177,8 +115,8 @@ void race_SendRankings(float pos, float prevpos, float del, float msg)
        WriteShort(msg, pos);
        WriteShort(msg, prevpos);
        WriteShort(msg, del);
-       WriteString(msg, race_GetName(pos));
-       WriteInt24_t(msg, race_GetTime(pos));
+       WriteString(msg, race_readName(GetMapname(), pos));
+       WriteInt24_t(msg, race_readTime(GetMapname(), pos));
 }
 
 void race_SendStatus(float id, entity e)
@@ -198,179 +136,99 @@ void race_SendStatus(float id, entity e)
        });
 }
 
-string race_PlaceName(float pos) {
-       if(pos == 1)
-               return "1st";
-       else if(pos == 2)
-               return "2nd";
-       else if(pos == 3)
-               return "3rd";
-       else
-               return strcat(ftos(pos), "th");
-}
+void race_setTime(string map, float t, string myuid, string mynetname, entity e) { // netname only used TEMPORARILY for printing
+       float newpos, player_prevpos;
+       newpos = race_readPos(map, t);
 
-void race_SetTime(entity e, float t, float match_rec) {
-       float pos, prevpos;
-       pos = race_GetPos(t);
-       prevpos = race_CheckUID(e.crypto_idfp, e.netname);
+       float i;
+       for(i = 1; i <= RANKINGS_CNT; ++i)
+       {
+               if(race_readUID(map, i) == myuid)
+                       player_prevpos = i;
+       }
 
        float oldrec;
-       string recorddifference;
-       if (prevpos && (prevpos < pos || !pos))
+       string recorddifference, oldrec_holder;
+       if (player_prevpos && (player_prevpos < newpos || !newpos))
        {
-               oldrec = race_GetTime(prevpos);
+               oldrec = race_readTime(GetMapname(), player_prevpos);
                recorddifference = strcat(" ^1[+", TIME_ENCODED_TOSTRING(t - oldrec), "]");
-               bprint(e.netname, "^7 couldn't break their ", race_PlaceName(prevpos), " place record of ", TIME_ENCODED_TOSTRING(oldrec), recorddifference, "\n");
+               bprint(mynetname, "^7 couldn't break their ", race_placeName(player_prevpos), " place record of ", TIME_ENCODED_TOSTRING(oldrec), recorddifference, "\n");
                race_SendStatus(0, e); // "fail"
+               Send_KillNotification(e.netname, TIME_ENCODED_TOSTRING(t), "", RACE_FAIL, MSG_RACE);
                return;
-       } else if (!pos) { // no ranking, time worse than the worst ranked
-               recorddifference = strcat(" ^1[+", TIME_ENCODED_TOSTRING(t - grecordtime[RANKINGS_CNT-1]), "]");
-               bprint(e.netname, "^7 couldn't break the ", race_PlaceName(RANKINGS_CNT), " place record of ", TIME_ENCODED_TOSTRING(grecordtime[RANKINGS_CNT-1]), recorddifference, "\n");
+       } else if (!newpos) { // no ranking, time worse than the worst ranked
+               recorddifference = strcat(" ^1[+", TIME_ENCODED_TOSTRING(t - race_readTime(GetMapname(), RANKINGS_CNT)), "]");
+               bprint(mynetname, "^7 couldn't break the ", race_placeName(RANKINGS_CNT), " place record of ", TIME_ENCODED_TOSTRING(race_readTime(GetMapname(), RANKINGS_CNT)), recorddifference, "\n");
                race_SendStatus(0, e); // "fail"
+               Send_KillNotification(e.netname, TIME_ENCODED_TOSTRING(t), "", RACE_FAIL, MSG_RACE);
                return;
        }
 
-       oldrec = grecordtime[pos-1];
+       // if we didn't hit a return yet, we have a new record!
 
-       // move other rankings out of the way
-       float i;
-       if (prevpos) { // player improved his existing record
-               for (i=prevpos-1;i>pos-1;--i) {
-                       db_put(ServerProgsDB, strcat(GetMapname(), rr, "time", ftos(i)), ftos(grecordtime[i-1]));
-                       db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname", ftos(i)), grecordholder[i-1]);
-                       db_put(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp", ftos(i)), grecorduid[i-1]);
-                       grecordtime[i] = grecordtime[i-1];
-
-                       if (grecordholder[i])
-                               strunzone(grecordholder[i]);
-                       grecordholder[i] = strzone(grecordholder[i-1]);
-                       if (grecorduid[i])
-                               strunzone(grecorduid[i]);
-                       grecorduid[i] = strzone(grecorduid[i-1]);
-               }
-       } else { // player has no ranked record yet
-               for (i=RANKINGS_CNT-1;i>pos-1;--i) {
-                       db_put(ServerProgsDB, strcat(GetMapname(), rr, "time", ftos(i)), ftos(grecordtime[i-1]));
-                       db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname", ftos(i)), grecordholder[i-1]);
-                       db_put(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp", ftos(i)), grecorduid[i-1]);
-                       grecordtime[i] = grecordtime[i-1];
-
-                       if (grecordholder[i])
-                               strunzone(grecordholder[i]);
-                       grecordholder[i] = strzone(grecordholder[i-1]);
-                       if (grecorduid[i])
-                               strunzone(grecorduid[i]);
-                       grecorduid[i] = strzone(grecorduid[i-1]);
-               }
-       }
+       oldrec = race_readTime(GetMapname(), newpos);
+       oldrec_holder = race_readName(GetMapname(), newpos);
        
        // store new ranking
-       if (pos == 1) {
-               db_put(ServerProgsDB, strcat(GetMapname(), rr, "time"), ftos(t));
-               db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname"), e.netname);
-               db_put(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp"), e.crypto_idfp);
-
-               grecordtime[0] = t;
-
-               if (grecordholder[0])
-                       strunzone(grecordholder[0]);
-               grecordholder[0] = strzone(e.netname);
-               if (grecorduid[0])
-                       strunzone(grecorduid[0]);
-               grecorduid[0] = strzone(e.crypto_idfp);
+       race_writeTime(GetMapname(), t, myuid);
+
+       if (newpos == 1) {
                write_recordmarker(e, time - TIME_DECODE(t), TIME_DECODE(t));
                race_send_recordtime(MSG_ALL);
-       } else {
-               db_put(ServerProgsDB, strcat(GetMapname(), rr, "time", ftos(pos-1)), ftos(t));
-               db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname", ftos(pos-1)), e.netname);
-               db_put(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp", ftos(pos-1)), e.crypto_idfp);
-
-               grecordtime[pos-1] = t;
-
-               if (grecordholder[pos-1])
-                       strunzone(grecordholder[pos-1]);
-               grecordholder[pos-1] = strzone(e.netname);
-               if (grecorduid[pos-1])
-                       strunzone(grecorduid[pos-1]);
-               grecorduid[pos-1] = strzone(e.crypto_idfp);
        }
 
-       if (pos == RANKINGS_CNT)
-               worst_time = t;
-
-       race_SendRankings(pos, prevpos, 0, MSG_ALL);
+       race_SendRankings(newpos, player_prevpos, 0, MSG_ALL);
        if(rankings_reply)
                strunzone(rankings_reply);
        rankings_reply = strzone(getrankings());
-       if(pos == 1) {
-               if(pos == prevpos) {
+       if(newpos == 1) {
+               if(newpos == player_prevpos) {
                        recorddifference = strcat(" ^2[-", TIME_ENCODED_TOSTRING(oldrec - t), "]");
-                       bprint(e.netname, "^1 improved their 1st place record with ", TIME_ENCODED_TOSTRING(t), recorddifference, "\n");
+                       bprint(mynetname, "^1 improved their 1st place record with ", TIME_ENCODED_TOSTRING(t), recorddifference, "\n");
                } else if (oldrec == 0) {
-                       bprint(e.netname, "^1 set the 1st place record with ", TIME_ENCODED_TOSTRING(t), "\n");
+                       bprint(mynetname, "^1 set the 1st place record with ", TIME_ENCODED_TOSTRING(t), "\n");
                } else {
                        recorddifference = strcat(" ^2[-", TIME_ENCODED_TOSTRING(oldrec - t), "]");
-                       bprint(e.netname, "^1 broke ", grecordholder[pos], "^1's 1st place record with ", strcat(TIME_ENCODED_TOSTRING(t), recorddifference, "\n"));
+                       bprint(mynetname, "^1 broke ", oldrec_holder, "^1's 1st place record with ", strcat(TIME_ENCODED_TOSTRING(t), recorddifference, "\n"));
                }
                race_SendStatus(3, e); // "new server record"
+               Send_KillNotification(e.netname, TIME_ENCODED_TOSTRING(t), "", RACE_SERVER_RECORD, MSG_RACE);
        } else {
-               if(pos == prevpos) {
+               if(newpos == player_prevpos) {
                        recorddifference = strcat(" ^2[-", TIME_ENCODED_TOSTRING(oldrec - t), "]");
-                       bprint(e.netname, "^5 improved their ", race_PlaceName(pos), " ^5place record with ", TIME_ENCODED_TOSTRING(t), recorddifference, "\n");
+                       bprint(mynetname, "^5 improved their ", race_placeName(newpos), " ^5place record with ", TIME_ENCODED_TOSTRING(t), recorddifference, "\n");
                        race_SendStatus(1, e); // "new time"
+                       Send_KillNotification(e.netname, TIME_ENCODED_TOSTRING(t), "", RACE_NEW_TIME, MSG_RACE);
                } else if (oldrec == 0) {
-                       bprint(e.netname, "^2 set the ", race_PlaceName(pos), " ^2place record with ", TIME_ENCODED_TOSTRING(t), "\n");
+                       bprint(mynetname, "^2 set the ", race_placeName(newpos), " ^2place record with ", TIME_ENCODED_TOSTRING(t), "\n");
                        race_SendStatus(2, e); // "new rank"
+                       Send_KillNotification(e.netname, TIME_ENCODED_TOSTRING(t), "", RACE_NEW_RANK, MSG_RACE);
                } else {
                        recorddifference = strcat(" ^2[-", TIME_ENCODED_TOSTRING(oldrec - t), "]");
-                       bprint(e.netname, "^2 broke ", grecordholder[pos], "^2's ", race_PlaceName(pos), " ^2place record with ", strcat(TIME_ENCODED_TOSTRING(t), recorddifference, "\n"));
+                       bprint(mynetname, "^2 broke ", oldrec_holder, "^2's ", race_placeName(newpos), " ^2place record with ", strcat(TIME_ENCODED_TOSTRING(t), recorddifference, "\n"));
                        race_SendStatus(2, e); // "new rank"
+                       Send_KillNotification(e.netname, TIME_ENCODED_TOSTRING(t), "", RACE_NEW_TIME, MSG_RACE);
                }
        }
 }
 
-void race_DeleteTime(float pos) {
-       float i;
+void race_deleteTime(string map, float pos) {
+       string rr;
+       if(g_cts)
+               rr = CTS_RECORD;
+       else
+               rr = RACE_RECORD;
 
-       for (i = pos-1; i <= RANKINGS_CNT-1; ++i) {
-               if (i == 0) {
-                       db_put(ServerProgsDB, strcat(GetMapname(), rr, "time"), ftos(grecordtime[1]));
-                       db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname"), grecordholder[1]);
-                       db_put(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp"), grecorduid[1]);
-                       grecordtime[0] = grecordtime[1];
-                       if (grecordholder[i])
-                               strunzone(grecordholder[0]);
-                       grecordholder[0] = strzone(grecordholder[1]);
-
-                       if (grecorduid[i])
-                               strunzone(grecorduid[0]);
-                       grecorduid[0] = strzone(grecorduid[1]);
-               }
-               else if (i == RANKINGS_CNT-1) {
-                       db_put(ServerProgsDB, strcat(GetMapname(), rr, "time", ftos(i)), string_null);
-                       db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname", ftos(i)), string_null);
-                       db_put(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp", ftos(i)), string_null);
-                       grecordtime[i] = 0;
-                       if (grecordholder[i])
-                               strunzone(grecordholder[i]);
-                       grecordholder[i] = string_null;
-
-                       if (grecorduid[i])
-                               strunzone(grecorduid[i]);
-                       grecorduid[i] = string_null;
+       float i;
+       for (i = pos; i <= RANKINGS_CNT; ++i) {
+               if (i == RANKINGS_CNT) {
+                       db_put(ServerProgsDB, strcat(map, rr, "time", ftos(i)), string_null);
+                       db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(i)), string_null);
                }
                else {
-                       db_put(ServerProgsDB, strcat(GetMapname(), rr, "time", ftos(i)), ftos(grecordtime[i+1]));
-                       db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname", ftos(i)), grecordholder[i+1]);
-                       db_put(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp", ftos(i)), grecorduid[i+1]);
-                       grecordtime[i] = grecordtime[i+1];
-                       if (grecordholder[i])
-                               strunzone(grecordholder[i]);
-                       grecordholder[i] = strzone(grecordholder[i+1]);
-
-                       if (grecorduid[i])
-                               strunzone(grecorduid[i]);
-                       grecorduid[i] = strzone(grecorduid[i+1]);
+                       db_put(ServerProgsDB, strcat(map, rr, "time", ftos(i)), ftos(race_readTime(GetMapname(), i+1)));
+                       db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(i)), race_readUID(GetMapname(), i+1));
                }
        }
 
@@ -381,8 +239,6 @@ void race_DeleteTime(float pos) {
        if(rankings_reply)
                strunzone(rankings_reply);
        rankings_reply = strzone(getrankings());
-
-       worst_time = 0;
 }
 
 void race_SendTime(entity e, float cp, float t, float tvalid)
@@ -441,8 +297,13 @@ void race_SendTime(entity e, float cp, float t, float tvalid)
 
                        if(t != 0) {
                                if(cp == race_timed_checkpoint)
-                                       race_SetTime(e, t, recordtime);
-
+                               {
+                                       race_setTime(GetMapname(), t, e.crypto_idfp, e.netname, e);
+                                       if(g_cts && cvar("g_cts_finish_kill_delay"))
+                                       {
+                                               CTS_ClientKill(cvar("g_cts_finish_kill_delay"));
+                                       }
+                               }
                                if(t < recordtime || recordtime == 0)
                                {
                                        race_checkpoint_records[cp] = t;
index 59480ab..fbddca7 100644 (file)
@@ -369,7 +369,8 @@ void WinningConditionHelper()
 
        s = GetGametype();
        s = strcat(s, ":", cvar_string("g_xonoticversion"));
-       s = strcat(s, "::", GetPlayerScoreString(world, 2)); // make this 1 once we can
+       s = strcat(s, ":P", ftos(cvar_purechanges_count));
+       s = strcat(s, "::", GetPlayerScoreString(world, 1)); // make this 1 once we can, note: this doesn't contain any :<letter>
 
        fullstatus = cvar("g_full_getstatus_responses");
 
index 3b7d77d..5b8ca7f 100644 (file)
@@ -75,13 +75,7 @@ void CreatureFrame (void)
                                else
                                        dm = min((dm - cvar("g_balance_falldamage_minspeed")) * cvar("g_balance_falldamage_factor"), cvar("g_balance_falldamage_maxdamage"));
                                if (dm > 0)
-                               {
                                        Damage (self, world, world, dm, DEATH_FALL, self.origin, '0 0 0');
-                                       // this must be allowed to cut the normal pain sounds (played after them and on the same channel)
-                                       // there's no way to detect falling damage and prevent the pain sounds for this to be played instead
-                                       if(self.health > 0)
-                                               PlayerSound(playersound_fall, CHAN_PAIN, VOICETYPE_PLAYERSOUND);
-                               }
                        }
 
                        maxspeed = cvar("g_maxspeed");
index ba0cb8b..9f0075a 100644 (file)
@@ -489,6 +489,8 @@ void Item_Touch (void)
        if(!Item_GiveTo(self, other))
                return;
 
+       other.last_pickup = time;
+
        pointparticles(particleeffectnum("item_pickup"), self.origin, '0 0 0', 1);
 
        if (self.classname == "droppedweapon")
index d338cf6..d92a253 100644 (file)
@@ -423,12 +423,6 @@ void func_bobbing_controller_think()
                self.owner.velocity = (v - self.owner.origin) * 10;
 };
 
-void bobbing_blocked()
-{
-       // no need to duplicate code
-       generic_plat_blocked();
-}
-
 /*QUAKED spawnfunc_func_bobbing (0 .5 .8) ? X_AXIS Y_AXIS
 Brush model that moves back and forth on one axis (default Z).
 speed : how long one cycle takes in seconds (default 4)
@@ -458,7 +452,7 @@ void spawnfunc_func_bobbing()
        self.active = ACTIVE_ACTIVE;
 
        // damage when blocked
-       self.blocked = bobbing_blocked;
+       self.blocked = generic_plat_blocked;
        if(self.dmg & (!self.message))
                self.message = " was squished";
     if(self.dmg && (!self.message2))
@@ -493,6 +487,81 @@ void spawnfunc_func_bobbing()
        // TODO make a reset function for this one
 };
 
+.float freq;
+void func_pendulum_controller_think()
+{
+       local float v;
+       self.nextthink = time + 0.1;
+
+       if not (self.owner.active == ACTIVE_ACTIVE)
+       {
+               self.owner.avelocity_x = 0;
+               return;
+       }
+
+       // calculate sinewave using makevectors
+       makevectors((self.nextthink * self.owner.freq + self.owner.phase) * '0 360 0');
+       v = self.owner.speed * v_forward_y + self.cnt;
+       if(self.owner.classname == "func_pendulum") // don't brake stuff if the func_bobbing was killtarget'ed
+       {
+               // * 10 so it will arrive in 0.1 sec
+               self.owner.avelocity_z = (remainder(v - self.owner.angles_z, 360)) * 10;
+       }
+};
+
+void spawnfunc_func_pendulum()
+{
+       local entity controller;
+       if (self.noise != "")
+       {
+               precache_sound(self.noise);
+               soundto(MSG_INIT, self, CHAN_TRIGGER, self.noise, VOL_BASE, ATTN_IDLE);
+       }
+
+       self.active = ACTIVE_ACTIVE;
+
+       // keys: angle, speed, phase, noise, freq
+
+       if(!self.speed)
+               self.speed = 30;
+       // not initializing self.dmg to 2, to allow damageless pendulum
+
+       if(self.dmg & (!self.message))
+               self.message = " was squished";
+       if(self.dmg && (!self.message2))
+               self.message2 = "was squished by";
+       if(self.dmg && (!self.dmgtime))
+               self.dmgtime = 0.25;
+       self.dmgtime2 = time;
+
+       self.blocked = generic_plat_blocked;
+
+       if not(InitMovingBrushTrigger())
+               return;
+
+       if(!self.freq)
+       {
+               // find pendulum length (same formula as Q3A)
+               self.freq = 1 / (M_PI * 2) * sqrt(cvar("sv_gravity") / (3 * max(8, fabs(self.mins_z))));
+       }
+
+       // copy initial angle
+       self.cnt = self.angles_z;
+
+       // wait for targets to spawn
+       controller = spawn();
+       controller.classname = "func_pendulum_controller";
+       controller.owner = self;
+       controller.nextthink = time + 1;
+       controller.think = func_pendulum_controller_think;
+       self.nextthink = self.ltime + 999999999;
+       self.think = SUB_Null;
+
+       //self.effects |= EF_LOWPRECISION;
+
+       // TODO make a reset function for this one
+};
+
 // button and multiple button
 
 void() button_wait;
index cffe88b..3d3f1d6 100644 (file)
@@ -39,12 +39,29 @@ void spawnfunc_item_armor_combat()   { spawnfunc_item_armor_big();      }
 void spawnfunc_item_armor_shard()    { spawnfunc_item_armor_small();    }
 void spawnfunc_item_enviro()         { spawnfunc_item_invincible();     }
 
-// weapon remove ent from defrag
+// weapon remove ent from df
+void target_init_verify()
+{
+       entity trigger, targ;
+       for(trigger = world; (trigger = find(trigger, classname, "trigger_multiple")); )
+               for(targ = world; (targ = find(targ, targetname, trigger.target)); )
+                       if (targ.classname == "target_init" || targ.classname == "target_give" || targ.classname == "target_items")
+                       {
+                               targ.wait = -2;
+                               targ.delay = 0;
+
+                               setsize(targ, trigger.mins, trigger.maxs);
+                               setorigin(targ, trigger.origin);
+                               //remove(trigger);
+                       }
+}
+
 void spawnfunc_target_init()
 {
        self.spawnflags = 0; // remove all weapons except the ones listed below
        self.netname = "laser uzi"; // keep these weapons through the remove trigger
        spawnfunc_target_items();
+       InitializeEntity(self, target_init_verify, INITPRIO_FINDTARGET);
 }
 
 // weapon give ent from defrag
@@ -85,6 +102,7 @@ void target_give_init()
        }
        self.spawnflags = 2;
        spawnfunc_target_items();
+       InitializeEntity(self, target_init_verify, INITPRIO_FINDTARGET);
 }
 
 void spawnfunc_target_give()
index 61d4af6..07268a7 100644 (file)
@@ -1,5 +1,5 @@
 #ifdef REGISTER_WEAPON
-REGISTER_WEAPON(CAMPINGRIFLE, w_campingrifle, IT_NAILS, 3, WEP_FLAG_NORMAL | WEP_TYPE_HITSCAN, BOT_PICKUP_RATING_MID, "campingrifle", "campingrifle", "Sniper Rifle");
+REGISTER_WEAPON(CAMPINGRIFLE, w_campingrifle, IT_NAILS, 7, WEP_FLAG_NORMAL | WEP_TYPE_HITSCAN, BOT_PICKUP_RATING_MID, "campingrifle", "campingrifle", "Sniper Rifle");
 #else
 #ifdef SVQC
 //Camping rifle Primary mode: manually operated bolt*, Secondary: full automatic**
index 6879061..29b8be7 100644 (file)
@@ -50,8 +50,8 @@ void W_Nex_Attack (float issecondary)
        }
        else
                charge = 1;
-       mydmg = mydmg * charge;
-       myforce = myforce * charge;
+       mydmg *= charge;
+       myforce *= charge;
 
        W_SetupShot (self, TRUE, 5, "weapons/nexfire.wav", mydmg);
 
index 08b1a67..b74f60e 100644 (file)
@@ -51,9 +51,9 @@ void Seeker_Missile_Think()
        {
                e               = self.enemy;
                eorg            = 0.5 * (e.absmin + e.absmax);
-               turnrate        = cvar("g_balance_seeker_missile_turnrate");                // how fast to turn
+               turnrate        = cvar("g_balance_seeker_missile_turnrate"); // how fast to turn
                desireddir      = normalize(eorg - self.origin);
-               olddir          = normalize(self.velocity);                                         // get my current direction
+               olddir          = normalize(self.velocity); // get my current direction
                dist            = vlen(eorg - self.origin);
 
                // Do evasive maneuvers for world objects? ( this should be a cpu hog. :P )
@@ -66,18 +66,14 @@ void Seeker_Missile_Think()
                                traceline(self.origin, eorg, FALSE, self);
 
                        // Setup adaptive tracelength
-                       self.wait = vlen(self.origin - trace_endpos);
-                       if (self.wait < cvar("g_balance_seeker_missile_smart_trace_min")) self.wait = cvar("g_balance_seeker_missile_smart_trace_min");
-                       if (self.wait > cvar("g_balance_seeker_missile_smart_trace_max")) self.wait = cvar("g_balance_seeker_missile_smart_trace_max");
+                       self.wait = bound(cvar("g_balance_seeker_missile_smart_trace_min"), vlen(self.origin - trace_endpos), self.wait = cvar("g_balance_seeker_missile_smart_trace_max"));
 
                        // Calc how important it is that we turn and add this to the desierd (enemy) dir.
                        desireddir  = normalize(((trace_plane_normal * (1 - trace_fraction)) + (desireddir * trace_fraction)) * 0.5);
                }
-
-               //newdir = normalize((olddir + desireddir * turnrate) * 0.5);// take the average of the 2 directions; not the best method but simple & easy
-               newdir = normalize(olddir + desireddir * turnrate);// take the average of the 2 directions; not the best method but simple & easy
-
-               self.velocity = newdir * self.switchweapon;                                         // make me fly in the new direction at my flight speed
+               
+               newdir = normalize(olddir + desireddir * turnrate); // take the average of the 2 directions; not the best method but simple & easy
+               self.velocity = newdir * self.switchweapon; // make me fly in the new direction at my flight speed
        }
 
        // Proxy
@@ -114,9 +110,8 @@ void Seeker_Missile_Think()
                return;
        }
 
-       self.angles = vectoangles(self.velocity);                       // turn model in the new flight direction
-       self.nextthink = time + 0.05;
-
+       //self.angles = vectoangles(self.velocity);                     // turn model in the new flight direction
+       self.nextthink = time;// + 0.05; // csqc projectiles
        UpdateCSQCProjectile(self);
 }
 
@@ -124,21 +119,19 @@ void Seeker_Missile_Think()
 
 void Seeker_Missile_Damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
 {
-       float d;
-       d = damage;
-
        if (self.health <= 0)
                return;
 
        if (self.owner == attacker)
-               d = d * 0.25;
-
-       self.health = self.health - d;
-
+               self.health = self.health - (damage * 0.25);
+       else
+               self.health = self.health - damage;
+               
        if (self.health <= 0)
                W_PrepareExplosionByDamage(attacker, Seeker_Missile_Explode);
 }
 
+/*
 void Seeker_Missile_Animate()
 {
        self.frame = self.frame +1;
@@ -161,6 +154,7 @@ void Seeker_Missile_Animate()
 
        UpdateCSQCProjectile(self);
 }
+*/
 
 void Seeker_Fire_Missile(vector f_diff)
 {
@@ -182,30 +176,25 @@ void Seeker_Fire_Missile(vector f_diff)
        missile.bot_dodge       = TRUE;
        missile.bot_dodgerating = cvar("g_balance_seeker_missile_damage");
 
-       missile.think           = Seeker_Missile_Animate;
-
-       //if (!cvar("g_balance_seeker_missile_proxy"))
+       missile.think           = Seeker_Missile_Think;
        missile.touch           = Seeker_Missile_Touch;
-
        missile.event_damage    = Seeker_Missile_Damage;
        missile.nextthink       = time;// + 0.2;// + cvar("g_balance_seeker_missile_activate_delay");
        missile.cnt             = time + cvar("g_balance_seeker_missile_lifetime");
        missile.enemy           = self.enemy;
        missile.solid           = SOLID_BBOX;
        missile.scale           = 2;
-       missile.takedamage          = DAMAGE_YES;
+       missile.takedamage      = DAMAGE_YES;
        missile.health          = cvar("g_balance_seeker_missile_health");
        missile.damageforcescale = cvar("g_balance_seeker_missile_damageforcescale");
        missile.projectiledeathtype = WEP_SEEKER;
+       //missile.think           = Seeker_Missile_Animate; // csqc projectiles.
+
 
        setorigin (missile, w_shotorg);
        setsize (missile, '-4 -4 -4', '4 4 4');
-
-
-       missile.movetype    = MOVETYPE_FLYMISSILE;// MOVETYPE_TOSS;
-
+       missile.movetype    = MOVETYPE_FLYMISSILE;
        missile.flags       = FL_PROJECTILE;
-
        W_SETUPPROJECTILEVELOCITY_UP(missile, g_balance_seeker_missile);
 
        missile.switchweapon = vlen(missile.velocity);
@@ -276,17 +265,13 @@ void Seeker_Tag_Damage (entity inflictor, entity attacker, float damage, float d
                Seeker_Tag_Explode();
 }
 
-void Seeker_Tag_Think()
-{
-       remove(self);
-       return;
-}
 
 void Seeker_Tag_Touch()
 {
        vector dir;
        vector org2;
-
+       entity e;
+       
        dir     = normalize (self.owner.origin - self.origin);
        org2    = findbetterlocation (self.origin, 8);
 
@@ -296,28 +281,19 @@ void Seeker_Tag_Touch()
        Damage_DamageInfo(self.origin, 0, 0, 0, self.velocity, WEP_SEEKER | HITTYPE_HEADSHOT, self);
 
        if (other.takedamage == DAMAGE_AIM && other.deadflag == DEAD_NO)
-       {
-               entity e;
+       {               
                e           = spawn();
                e.cnt       = cvar("g_balance_seeker_missile_count");
                e.owner     = self.owner;
                e.enemy     = other;
                e.think     = Seeker_Vollycontroler_Think;
                e.nextthink = time;
-
-               //sprint(self.owner, "^1Target lock ^3[^7 ",other.netname, " ^3]^1 acquired - autofire activated.\n");
-               //sprint(other,"^1You are targeted!\n");
-
-               // stuffcmd(other,"play2 weapons/zany-alarm4.ogg\n");
-               // stuffcmd(self.owner, "play2 weapons/zany-lock4.ogg\n");
        }
 
        remove(self);
        return;
 }
 
-
-
 void Seeker_Fire_Tag()
 {
        local entity missile;
@@ -332,7 +308,7 @@ void Seeker_Fire_Tag()
        missile.bot_dodge       = TRUE;
        missile.bot_dodgerating = 50;
        missile.touch           = Seeker_Tag_Touch;
-       missile.think           = Seeker_Tag_Think;
+       missile.think           = SUB_Remove;
        missile.nextthink       = time + cvar("g_balance_seeker_tag_lifetime");
        missile.movetype        = MOVETYPE_FLY;
        missile.solid           = SOLID_BBOX;
@@ -405,28 +381,29 @@ void Seeker_Fire_Flac()
 
        pointparticles(particleeffectnum("hagar_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
 
-       missile = spawn ();
-       missile.owner = missile.realowner = self;
-       missile.classname = "missile";
-       missile.bot_dodge = TRUE;
+       missile                                 = spawn ();
+       missile.owner                   = missile.realowner = self;
+       missile.classname               = "missile";
+       missile.bot_dodge               = TRUE;
        missile.bot_dodgerating = cvar("g_balance_seeker_flac_damage");
-       missile.touch = Seeker_Flac_Explode;
-       missile.use = Seeker_Flac_Explode;
-       missile.think = adaptor_think2use_hittype_splash;
-       missile.nextthink = time + cvar("g_balance_seeker_flac_lifetime") + cvar("g_balance_seeker_flac_lifetime_rand");
-       missile.solid = SOLID_BBOX;
-       missile.scale = 0.4; // BUG: the model is too big
+       missile.touch                   = Seeker_Flac_Explode;
+       missile.use                     = Seeker_Flac_Explode; 
+       missile.think                   = adaptor_think2use_hittype_splash;
+       missile.nextthink               = time + cvar("g_balance_seeker_flac_lifetime") + cvar("g_balance_seeker_flac_lifetime_rand");
+       missile.solid                   = SOLID_BBOX;
+       missile.movetype                = MOVETYPE_FLY; 
        missile.projectiledeathtype = WEP_SEEKER;
+       missile.projectiledeathtype = WEP_SEEKER | HITTYPE_SECONDARY;
+       missile.flags                           = FL_PROJECTILE;
+       
+       // csqc projectiles
+       //missile.angles                                = vectoangles (missile.velocity);       
+       //missile.scale = 0.4; // BUG: the model is too big 
+       
        setorigin (missile, w_shotorg);
        setsize (missile, '-2 -2 -2', '2 2 2');
-       missile.projectiledeathtype = WEP_SEEKER | HITTYPE_SECONDARY;
-
-       missile.movetype = MOVETYPE_FLY;
+               
        W_SETUPPROJECTILEVELOCITY_UP(missile, g_balance_seeker_flac);
-
-       missile.angles = vectoangles (missile.velocity);
-       missile.flags = FL_PROJECTILE;
-
        CSQCProjectile(missile, TRUE, PROJECTILE_FLAC, TRUE);
 
        other = missile; MUTATOR_CALLHOOK(EditProjectile);
index c89735e..491030f 100644 (file)
@@ -83,13 +83,14 @@ float W_Tuba_NoteSendEntity(entity to, float sf)
                WriteCoord(MSG_ENTITY, self.origin_x);
                WriteCoord(MSG_ENTITY, self.origin_y);
                WriteCoord(MSG_ENTITY, self.origin_z);
+               WriteByte(MSG_ENTITY, self.owner != to);
        }
        return TRUE;
 }
 
 void W_Tuba_NoteThink()
 {
-       float needchange, dist_mult;
+       float dist_mult;
        float vol0, vol1;
        vector dir0, dir1;
        vector v;
@@ -102,7 +103,6 @@ void W_Tuba_NoteThink()
        }
        self.nextthink = time;
        dist_mult = cvar("g_balance_tuba_attenuation") / cvar("snd_soundradius");
-       needchange = 0;
        FOR_EACH_REALCLIENT(e)
        if(e != self.owner)
        {