set g_balance_laser_primary_lifetime 30
set g_balance_laser_primary_shotangle 0
set g_balance_laser_primary_delay 0.03
-set g_balance_laser_gauntlet 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_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 6
set g_balance_shotgun_primary_damage 9
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 0 // ew, bad! Still uses the melee anim!
+set g_balance_shotgun_secondary_melee_delay 0.35 // match the anim
+set g_balance_shotgun_secondary_melee_range 60
+set g_balance_shotgun_secondary_melee_swing 50
+set g_balance_shotgun_secondary_melee_time 0.4
set g_balance_shotgun_secondary_bullets 6
set g_balance_shotgun_secondary_damage 9
set g_balance_shotgun_secondary_force 60
// }}}
// {{{ mortar
set g_balance_grenadelauncher_primary2secondary 0
+set g_balance_grenadelauncher_primary_sticky 0
set g_balance_grenadelauncher_primary_damage 70
set g_balance_grenadelauncher_primary_edgedamage 38
set g_balance_grenadelauncher_primary_force 400
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_secondary_sticky 0
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_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_electro_primary_damage 65
set g_balance_electro_primary_edgedamage 0
set g_balance_electro_primary_force 200
+set g_balance_electro_primary_force_up 0
set g_balance_electro_primary_radius 150
set g_balance_electro_primary_comboradius 0
set g_balance_electro_primary_speed 2000
set g_balance_electro_primary_refire 0.6
set g_balance_electro_primary_animtime 0.3
set g_balance_electro_primary_ammo 2
+set g_balance_electro_primary_range 0
set g_balance_electro_secondary_damage 50
set g_balance_electro_secondary_spread 0.05
set g_balance_electro_secondary_edgedamage 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 105
+set g_balance_rocketlauncher_remote_edgedamage 40
+set g_balance_rocketlauncher_remote_radius 150
+set g_balance_rocketlauncher_remote_force 600
// }}}
// {{{ porto
set g_balance_porto_primary_refire 1.5
set g_balance_campingrifle_primary_bulletconstant 130 // 56.3qu
set g_balance_campingrifle_primary_burstcost 0.35 // require same cooldown as secondary, note it's smaller than primary refire time
set g_balance_campingrifle_primary_bullethail 0
+set g_balance_campingrifle_secondary 1
set g_balance_campingrifle_secondary_damage 15
set g_balance_campingrifle_secondary_headshotaddeddamage 25
set g_balance_campingrifle_secondary_spread 0.02
set g_balance_laser_primary_lifetime 30
set g_balance_laser_primary_shotangle 0
set g_balance_laser_primary_delay 0
-set g_balance_laser_gauntlet 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_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 6
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 0 // ew, bad! Still uses the melee anim!
+set g_balance_shotgun_secondary_melee_delay 0.35 // match the anim
+set g_balance_shotgun_secondary_melee_range 60
+set g_balance_shotgun_secondary_melee_swing 50
+set g_balance_shotgun_secondary_melee_time 0.4
set g_balance_shotgun_secondary_bullets 6
set g_balance_shotgun_secondary_damage 9
set g_balance_shotgun_secondary_force 60
// }}}
// {{{ mortar
set g_balance_grenadelauncher_primary2secondary 0
+set g_balance_grenadelauncher_primary_sticky 0
set g_balance_grenadelauncher_primary_damage 70
set g_balance_grenadelauncher_primary_edgedamage 38
set g_balance_grenadelauncher_primary_force 400
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_secondary_sticky 0
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_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_electro_primary_damage 65
set g_balance_electro_primary_edgedamage 0
set g_balance_electro_primary_force 200
+set g_balance_electro_primary_force_up 0
set g_balance_electro_primary_radius 150
set g_balance_electro_primary_comboradius 0
set g_balance_electro_primary_speed 2000
set g_balance_electro_primary_refire 0.6
set g_balance_electro_primary_animtime 0.3
set g_balance_electro_primary_ammo 2
+set g_balance_electro_primary_range 0
set g_balance_electro_secondary_damage 50
set g_balance_electro_secondary_spread 0.05
set g_balance_electro_secondary_edgedamage 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 105
+set g_balance_rocketlauncher_remote_edgedamage 40
+set g_balance_rocketlauncher_remote_radius 150
+set g_balance_rocketlauncher_remote_force 600
// }}}
// {{{ porto
set g_balance_porto_primary_refire 1.5
set g_balance_campingrifle_primary_bulletconstant 130 // 56.3qu
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_damage 35
set g_balance_campingrifle_secondary_headshotaddeddamage 15 // 50 damage only on head
set g_balance_campingrifle_secondary_spread 0.008
// {{{ 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 -2 "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_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_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_seeker 0 "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 0
-set g_start_ammo_nails 90
+set g_start_ammo_shells 14
+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_ammo_fuel 0 "starting values when being in warmup-stage"
set g_lms_start_health 250
set g_lms_start_armor 100
-set g_lms_start_ammo_shells 50
-set g_lms_start_ammo_nails 150
-set g_lms_start_ammo_rockets 50
-set g_lms_start_ammo_cells 50
+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
// {{{ pickup items
set g_pickup_ammo_anyway 1
set g_pickup_weapons_anyway 1
-set g_pickup_shells 15
-set g_pickup_shells_max 100
-set g_pickup_nails 80
-set g_pickup_nails_max 400
-set g_pickup_rockets 15
-set g_pickup_rockets_max 200
+set g_pickup_shells 10
+set g_pickup_shells_max 30
+set g_pickup_nails 120
+set g_pickup_nails_max 300
+set g_pickup_rockets 25
+set g_pickup_rockets_max 150
set g_pickup_cells 25
set g_pickup_cells_max 200
set g_pickup_fuel 25
// {{{ misc
set g_balance_selfdamagepercent 0.65
-set g_balance_weaponswitchdelay 0.15
+set g_balance_weaponswitchdelay 0.1
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_balance_firetransfer_damage 0.8
set g_throughfloor_damage 0.5
set g_throughfloor_force 0.7
-set g_projectiles_newton_style 2
+set g_projectiles_newton_style 0
// possible values:
// 0: absolute velocity projectiles (like Quake)
// 1: relative velocity projectiles, "Newtonian" (like Tribes 2)
// {{{ weapon properties
// {{{ laser
-set g_balance_laser_primary_damage 22
-set g_balance_laser_primary_edgedamage 0
-set g_balance_laser_primary_force 200
+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_radius 60
-set g_balance_laser_primary_speed 0
+set g_balance_laser_primary_speed 4000
set g_balance_laser_primary_spread 0
-set g_balance_laser_primary_refire 0.1
-set g_balance_laser_primary_animtime 0.1
-set g_balance_laser_primary_lifetime 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_gauntlet 1
-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_primary_gauntlet 0
+set g_balance_laser_secondary 1 // when 1, a secondary laser mode exists
+set g_balance_laser_secondary_damage 110 // dps
+set g_balance_laser_secondary_edgedamage 0
+set g_balance_laser_secondary_force 500
+set g_balance_laser_secondary_radius 45
+set g_balance_laser_secondary_speed 0
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_refire 0.066
+set g_balance_laser_secondary_animtime 0.066
+set g_balance_laser_secondary_lifetime 0
set g_balance_laser_secondary_shotangle 0
set g_balance_laser_secondary_delay 0
+set g_balance_laser_secondary_gauntlet 1
// }}}
// {{{ shotgun
-set g_balance_shotgun_primary_bullets 15
-set g_balance_shotgun_primary_damage 7
+set g_balance_shotgun_primary_bullets 16
+set g_balance_shotgun_primary_damage 4
set g_balance_shotgun_primary_force 20
set g_balance_shotgun_primary_spread 0.16
set g_balance_shotgun_primary_refire 1
-set g_balance_shotgun_primary_animtime 0.7
+set g_balance_shotgun_primary_animtime 0.4
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 1
+set g_balance_shotgun_secondary_melee_delay 0.35 // match the anim
+set g_balance_shotgun_secondary_melee_range 60
+set g_balance_shotgun_secondary_melee_swing 50
+set g_balance_shotgun_secondary_melee_time 0.1
set g_balance_shotgun_secondary_bullets 6 // one more per shot than 15/3 (primary bullets/amount of shots = 3)
-set g_balance_shotgun_secondary_damage 7
-set g_balance_shotgun_secondary_force 20
-set g_balance_shotgun_secondary_spread 0.20
-set g_balance_shotgun_secondary_refire 1.35
-set g_balance_shotgun_secondary_animtime 0.33
-set g_balance_shotgun_secondary_ammo 1
+set g_balance_shotgun_secondary_damage 115
+set g_balance_shotgun_secondary_force 150
+set g_balance_shotgun_secondary_spread 0
+set g_balance_shotgun_secondary_refire 1.1
+set g_balance_shotgun_secondary_animtime 1
+set g_balance_shotgun_secondary_ammo 0
set g_balance_shotgun_secondary_speed 12000
set g_balance_shotgun_secondary_bulletconstant 75 // 3.8qu
// }}}
// {{{ uzi
set g_balance_uzi_first 1
-set g_balance_uzi_first_damage 24
-set g_balance_uzi_first_force 30
-set g_balance_uzi_first_spread 0.0125
+set g_balance_uzi_first_damage 17
+set g_balance_uzi_first_force 35
+set g_balance_uzi_first_spread 0.03
set g_balance_uzi_first_refire 0.2
-set g_balance_uzi_first_ammo 1
-set g_balance_uzi_sustained_damage 12
-set g_balance_uzi_sustained_force 20
-set g_balance_uzi_sustained_spread 0.0125
-set g_balance_uzi_sustained_refire 0.1
+set g_balance_uzi_first_ammo 2
+set g_balance_uzi_sustained_damage 7
+set g_balance_uzi_sustained_force 7.5
+set g_balance_uzi_sustained_spread 0.1
+set g_balance_uzi_sustained_refire 0.075
set g_balance_uzi_sustained_ammo 1
set g_balance_uzi_speed 18000
set g_balance_uzi_bulletconstant 115 // 13.1qu
// }}}
// {{{ mortar // TODO
set g_balance_grenadelauncher_primary2secondary 0
+set g_balance_grenadelauncher_primary_sticky 0
set g_balance_grenadelauncher_primary_damage 60
-set g_balance_grenadelauncher_primary_edgedamage 28
-set g_balance_grenadelauncher_primary_force 200
-set g_balance_grenadelauncher_primary_radius 140
-set g_balance_grenadelauncher_primary_speed 1200
+set g_balance_grenadelauncher_primary_edgedamage 35
+set g_balance_grenadelauncher_primary_force 300
+set g_balance_grenadelauncher_primary_radius 100
+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 10
+set g_balance_grenadelauncher_primary_lifetime 5
+set g_balance_grenadelauncher_primary_lifetime2 0.65
set g_balance_grenadelauncher_primary_refire 0.8
-set g_balance_grenadelauncher_primary_animtime 0.5
+set g_balance_grenadelauncher_primary_animtime 0.2
set g_balance_grenadelauncher_primary_ammo 2
-set g_balance_grenadelauncher_secondary_damage 65
+set g_balance_grenadelauncher_primary_health 72
+set g_balance_grenadelauncher_secondary_sticky 1
+set g_balance_grenadelauncher_secondary_damage 100
set g_balance_grenadelauncher_secondary_edgedamage 30
set g_balance_grenadelauncher_secondary_force 300
-set g_balance_grenadelauncher_secondary_radius 200
-set g_balance_grenadelauncher_secondary_speed 800
-set g_balance_grenadelauncher_secondary_speed_up 0
-set g_balance_grenadelauncher_secondary_speed_z 200
+set g_balance_grenadelauncher_secondary_radius 150
+set g_balance_grenadelauncher_secondary_speed 1000
+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
+set g_balance_grenadelauncher_secondary_lifetime 5
+set g_balance_grenadelauncher_secondary_lifetime2 1
set g_balance_grenadelauncher_secondary_refire 0.8
-set g_balance_grenadelauncher_secondary_animtime 0.5
+set g_balance_grenadelauncher_secondary_animtime 0.2
set g_balance_grenadelauncher_secondary_ammo 2
-set g_balance_grenadelauncher_secondary_health 0
+set g_balance_grenadelauncher_secondary_health 72
set g_balance_grenadelauncher_secondary_damageforcescale 0
-set g_balance_grenadelauncher_secondary_bouncefactor 0.5
-set g_balance_grenadelauncher_secondary_bouncestop 0.075
+set g_balance_grenadelauncher_secondary_bouncefactor 0.7
+set g_balance_grenadelauncher_secondary_bouncestop 0.12
// }}}
// {{{ electro // TODO
-set g_balance_electro_lightning 0
-set g_balance_electro_primary_damage 65
+set g_balance_electro_lightning 1
+set g_balance_electro_primary_damage 100
set g_balance_electro_primary_edgedamage 0
-set g_balance_electro_primary_force 200
-set g_balance_electro_primary_radius 150
-set g_balance_electro_primary_comboradius 0
-set g_balance_electro_primary_speed 2000
+set g_balance_electro_primary_force 600
+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_speed 0
set g_balance_electro_primary_spread 0
-set g_balance_electro_primary_lifetime 30
-set g_balance_electro_primary_refire 0.6
-set g_balance_electro_primary_animtime 0.3
-set g_balance_electro_primary_ammo 2
-set g_balance_electro_secondary_damage 50
-set g_balance_electro_secondary_spread 0.05
+set g_balance_electro_primary_lifetime 0
+set g_balance_electro_primary_refire 0.03333333
+set g_balance_electro_primary_animtime 0.03333333
+set g_balance_electro_primary_ammo 6
+set g_balance_electro_primary_range 800
+set g_balance_electro_secondary_damage 40
+set g_balance_electro_secondary_spread 0
set g_balance_electro_secondary_edgedamage 0
-set g_balance_electro_secondary_force 200
-set g_balance_electro_secondary_radius 150
-set g_balance_electro_secondary_speed 900
+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 200
set g_balance_electro_secondary_speed_z 0
-set g_balance_electro_secondary_spread 0
-set g_balance_electro_secondary_lifetime 5
-set g_balance_electro_secondary_refire 0.3
+set g_balance_electro_secondary_spread 0.08
+set g_balance_electro_secondary_lifetime 3.5
+set g_balance_electro_secondary_refire 0.5
set g_balance_electro_secondary_refire2 0
-set g_balance_electro_secondary_animtime 0.3
+set g_balance_electro_secondary_animtime 0.5
set g_balance_electro_secondary_ammo 2
-set g_balance_electro_secondary_health 5
+set g_balance_electro_secondary_health 10
set g_balance_electro_secondary_damageforcescale 4
set g_balance_electro_secondary_count 1
-set g_balance_electro_combo_damage 80
+set g_balance_electro_combo_damage 40
set g_balance_electro_combo_edgedamage 0
-set g_balance_electro_combo_force 200
+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 2000
+set g_balance_electro_combo_speed 400
// }}}
// {{{ crylink
-set g_balance_crylink_primary_damage 18
-set g_balance_crylink_primary_edgedamage 0
-set g_balance_crylink_primary_force -80
+set g_balance_crylink_primary_damage 10
+set g_balance_crylink_primary_edgedamage 8
+set g_balance_crylink_primary_force 25
set g_balance_crylink_primary_radius 100
-set g_balance_crylink_primary_speed 2000
-set g_balance_crylink_primary_spread 0.03
-set g_balance_crylink_primary_shots 4
+set g_balance_crylink_primary_speed 1100
+set g_balance_crylink_primary_spread 0.1
+set g_balance_crylink_primary_shots 7
set g_balance_crylink_primary_bounces 1
-set g_balance_crylink_primary_refire 0.4
-set g_balance_crylink_primary_animtime 0.3
+set g_balance_crylink_primary_refire 0.8
+set g_balance_crylink_primary_animtime 0.4
set g_balance_crylink_primary_ammo 2
-set g_balance_crylink_primary_bouncedamagefactor 0.5
+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 0.4 // range: 800 full, fades to 1300
+set g_balance_crylink_primary_star_lifetime 0.8 // range: 800 full, fades to 1300
set g_balance_crylink_primary_star_fadetime 0.25
-set g_balance_crylink_primary_other_lifetime 0.4 // range: 800 full, fades to 1300
+set g_balance_crylink_primary_other_lifetime 0.8 // 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 18
+set g_balance_crylink_secondary_damage 4
set g_balance_crylink_secondary_edgedamage 0
-set g_balance_crylink_secondary_force -80
-set g_balance_crylink_secondary_radius 5
-set g_balance_crylink_secondary_speed 2000
-set g_balance_crylink_secondary_spread 0.04
-set g_balance_crylink_secondary_shots 7
+set g_balance_crylink_secondary_force 16
+set g_balance_crylink_secondary_radius 15
+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.5
-set g_balance_crylink_secondary_animtime 0.3
-set g_balance_crylink_secondary_ammo 2
+set g_balance_crylink_secondary_refire 0.1
+set g_balance_crylink_secondary_animtime 0.1
+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_minstanex_ammo 10
// }}}
// {{{ hagar
-set g_balance_hagar_primary_damage 30
-set g_balance_hagar_primary_edgedamage 15
+set g_balance_hagar_primary_damage 12
+set g_balance_hagar_primary_edgedamage 12
set g_balance_hagar_primary_force 70
-set g_balance_hagar_primary_radius 50
-set g_balance_hagar_primary_spread 0.005
-set g_balance_hagar_primary_speed 2000
-set g_balance_hagar_primary_lifetime 30
-set g_balance_hagar_primary_refire 0.13
+set g_balance_hagar_primary_radius 70
+set g_balance_hagar_primary_spread 0.1
+set g_balance_hagar_primary_speed 1800
+set g_balance_hagar_primary_lifetime 5
+set g_balance_hagar_primary_refire 0.12
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_damage 12
+set g_balance_hagar_secondary_edgedamage 12
set g_balance_hagar_secondary_force 70
set g_balance_hagar_secondary_radius 50
-set g_balance_hagar_secondary_spread 0.01
-set g_balance_hagar_secondary_speed 1400
-set g_balance_hagar_secondary_lifetime_min 30
+set g_balance_hagar_secondary_spread 0.15
+set g_balance_hagar_secondary_speed 1800
+set g_balance_hagar_secondary_lifetime_min 5
set g_balance_hagar_secondary_lifetime_rand 0
-set g_balance_hagar_secondary_refire 0.13
+set g_balance_hagar_secondary_refire 0.12
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_force 350
-set g_balance_rocketlauncher_radius 120
+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 30
+set g_balance_rocketlauncher_lifetime 5
set g_balance_rocketlauncher_refire 1
-set g_balance_rocketlauncher_animtime 0.3
+set g_balance_rocketlauncher_animtime 0.2
set g_balance_rocketlauncher_ammo 3
set g_balance_rocketlauncher_health 0
set g_balance_rocketlauncher_damageforcescale 0
-set g_balance_rocketlauncher_detonatedelay 9999 // 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_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_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 50
+set g_balance_rocketlauncher_remote_edgedamage 16.5
+set g_balance_rocketlauncher_remote_radius 120
+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_porto_primary_lifetime 5
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
// }}}
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 30 // infinite
+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_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.25
-set g_balance_hlac_primary_spread_add 0.0045
-set g_balance_hlac_primary_spread_crouchmod 0.25
+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_damage 23
-set g_balance_hlac_primary_edgedamage 10
-set g_balance_hlac_primary_force 100
-set g_balance_hlac_primary_radius 70
-set g_balance_hlac_primary_speed 9000
+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_refire 0.1
set g_balance_hlac_secondary_spread 0.15
set g_balance_hlac_secondary_spread_crouchmod 0.5
-set g_balance_hlac_secondary_damage 23
-set g_balance_hlac_secondary_edgedamage 10
-set g_balance_hlac_secondary_force 100
-set g_balance_hlac_secondary_radius 70
-set g_balance_hlac_secondary_speed 9000
+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_refire 1
-set g_balance_hlac_secondary_animtime 0.3
+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
+set g_balance_campingrifle_magazinecapacity 0
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_tracer 0
-set g_balance_campingrifle_primary_damage 60
-set g_balance_campingrifle_primary_headshotaddeddamage 100
+set g_balance_campingrifle_tracer 1
+set g_balance_campingrifle_primary_damage 50
+set g_balance_campingrifle_primary_headshotaddeddamage 35
set g_balance_campingrifle_primary_spread 0
set g_balance_campingrifle_primary_force 2
set g_balance_campingrifle_primary_speed 35000
set g_balance_campingrifle_primary_lifetime 5
set g_balance_campingrifle_primary_refire 0.8
-set g_balance_campingrifle_primary_animtime 0.3
+set g_balance_campingrifle_primary_animtime 0.8
set g_balance_campingrifle_primary_ammo 10
set g_balance_campingrifle_primary_bulletconstant 130 // 56.3qu
set g_balance_campingrifle_primary_burstcost 0
set g_balance_campingrifle_primary_bullethail 0 // empty magazine on shot
-set g_balance_campingrifle_secondary_damage 35
-set g_balance_campingrifle_secondary_headshotaddeddamage 15 // 50 damage only on head
+set g_balance_campingrifle_secondary 0
+set g_balance_campingrifle_secondary_damage 15
+set g_balance_campingrifle_secondary_headshotaddeddamage 25 // 50 damage only on head
set g_balance_campingrifle_secondary_spread 0.008
set g_balance_campingrifle_secondary_force 1
set g_balance_campingrifle_secondary_speed 20000
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_count 3
+set g_balance_seeker_missile_damage 33
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_laser_primary_lifetime 30
set g_balance_laser_primary_shotangle 0
set g_balance_laser_primary_delay 0.03
-set g_balance_laser_gauntlet 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 25
set g_balance_laser_secondary_edgedamage 10
set g_balance_laser_secondary_lifetime 30
set g_balance_laser_secondary_shotangle -90
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_speed 8000
set g_balance_shotgun_primary_bulletconstant 75 // 3.8qu
set g_balance_shotgun_secondary 1
+set g_balance_shotgun_secondary_melee 0 // ew, bad! Still uses the melee anim!
+set g_balance_shotgun_secondary_melee_delay 0.35 // match the anim
+set g_balance_shotgun_secondary_melee_range 60
+set g_balance_shotgun_secondary_melee_swing 50
+set g_balance_shotgun_secondary_melee_time 0.4
set g_balance_shotgun_secondary_bullets 6
set g_balance_shotgun_secondary_damage 8
set g_balance_shotgun_secondary_force 15
// }}}
// {{{ mortar
set g_balance_grenadelauncher_primary2secondary 0
+set g_balance_grenadelauncher_primary_sticky 0
set g_balance_grenadelauncher_primary_damage 50
set g_balance_grenadelauncher_primary_edgedamage 38
set g_balance_grenadelauncher_primary_force 400
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_secondary_sticky 0
set g_balance_grenadelauncher_secondary_damage 60
set g_balance_grenadelauncher_secondary_edgedamage 38
set g_balance_grenadelauncher_secondary_force 400
set g_balance_grenadelauncher_secondary_speed_z 0
set g_balance_grenadelauncher_secondary_spread 0
set g_balance_grenadelauncher_secondary_lifetime 1
+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_electro_primary_damage 65
set g_balance_electro_primary_edgedamage 0
set g_balance_electro_primary_force 200
+set g_balance_electro_primary_force_up 0
set g_balance_electro_primary_radius 150
set g_balance_electro_primary_comboradius 0
set g_balance_electro_primary_speed 2000
set g_balance_electro_primary_refire 0.6
set g_balance_electro_primary_animtime 0.3
set g_balance_electro_primary_ammo 2
+set g_balance_electro_primary_range 0
set g_balance_electro_secondary_damage 50
set g_balance_electro_secondary_spread 0.05
set g_balance_electro_secondary_edgedamage 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 80
+set g_balance_rocketlauncher_remote_edgedamage 40
+set g_balance_rocketlauncher_remote_radius 100
+set g_balance_rocketlauncher_remote_force 600
// }}}
// {{{ porto
set g_balance_porto_primary_refire 1.5
set g_balance_campingrifle_primary_bulletconstant 130 // 56.3qu
set g_balance_campingrifle_primary_burstcost 0.35 // require same cooldown as secondary, note it's smaller than primary refire time
set g_balance_campingrifle_primary_bullethail 0
+set g_balance_campingrifle_secondary 1
set g_balance_campingrifle_secondary_damage 15
set g_balance_campingrifle_secondary_headshotaddeddamage 25
set g_balance_campingrifle_secondary_spread 0.02
// {{{ 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 -2 "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_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_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_minstanex 0 "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 0 "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 0 "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 0 "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 0 "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_tuba 0 "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 0 "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 0 "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 0
-set g_start_ammo_nails 100
+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_health 250 "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_health 250
set g_lms_start_armor 100
-set g_lms_start_ammo_shells 30
-set g_lms_start_ammo_nails 210
-set g_lms_start_ammo_rockets 150
-set g_lms_start_ammo_cells 150
+set g_lms_start_ammo_shells 50
+set g_lms_start_ammo_nails 150
+set g_lms_start_ammo_rockets 50
+set g_lms_start_ammo_cells 50
set g_lms_start_ammo_fuel 0
set g_balance_nix_roundtime 25
set g_balance_nix_incrtime 1.6
// }}}
// {{{ pickup items
-set g_pickup_ammo_anyway 0
-set g_pickup_weapons_anyway 0
-set g_pickup_shells 10
-set g_pickup_shells_max 30
-set g_pickup_nails 30
-set g_pickup_nails_max 210
-set g_pickup_rockets 20
-set g_pickup_rockets_max 150
-set g_pickup_cells 50
-set g_pickup_cells_max 150
+set g_pickup_ammo_anyway 1
+set g_pickup_weapons_anyway 1
+set g_pickup_shells 15
+set g_pickup_shells_max 100
+set g_pickup_nails 150
+set g_pickup_nails_max 300
+set g_pickup_rockets 15
+set g_pickup_rockets_max 200
+set g_pickup_cells 25
+set g_pickup_cells_max 200
set g_pickup_fuel 25
set g_pickup_fuel_jetpack 50
-set g_pickup_fuel_max 999
+set g_pickup_fuel_max 100
set g_pickup_armorsmall 5
set g_pickup_armorsmall_max 200
-set g_pickup_armorsmall_anyway 0
+set g_pickup_armorsmall_anyway 1
set g_pickup_armormedium 25
set g_pickup_armormedium_max 200
-set g_pickup_armormedium_anyway 0
+set g_pickup_armormedium_anyway 1
set g_pickup_armorbig 50
set g_pickup_armorbig_max 200
-set g_pickup_armorbig_anyway 0
+set g_pickup_armorbig_anyway 1
set g_pickup_armorlarge 100
set g_pickup_armorlarge_max 200
-set g_pickup_armorlarge_anyway 0
+set g_pickup_armorlarge_anyway 1
set g_pickup_healthsmall 5
set g_pickup_healthsmall_max 200
-set g_pickup_healthsmall_anyway 0
+set g_pickup_healthsmall_anyway 1
set g_pickup_healthmedium 25
set g_pickup_healthmedium_max 100
set g_pickup_healthmedium_anyway 0
set g_pickup_healthlarge_anyway 0
set g_pickup_healthmega 100
set g_pickup_healthmega_max 200
-set g_pickup_healthmega_anyway 0
-set g_pickup_respawntime_short 30
-set g_pickup_respawntime_medium 30
+set g_pickup_healthmega_anyway 1
+set g_pickup_respawntime_short 15
+set g_pickup_respawntime_medium 20
set g_pickup_respawntime_long 30
-set g_pickup_respawntime_powerup 90
+set g_pickup_respawntime_powerup 120
set g_pickup_respawntime_weapon 5
-set g_pickup_respawntime_ammo 30
+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 15
+set g_pickup_respawntimejitter_powerup 10
set g_pickup_respawntimejitter_weapon 0
set g_pickup_respawntimejitter_ammo 0
// }}}
set g_balance_pause_health_rot_spawn 0
set g_balance_health_regenstable 100
set g_balance_health_rotstable 100
-set g_balance_health_limit 999
+set g_balance_health_limit 200
set g_balance_armor_regen 0
set g_balance_armor_regenlinear 0
set g_balance_armor_rot 0
set g_balance_pause_armor_rot_spawn 0
set g_balance_armor_regenstable 100
set g_balance_armor_rotstable 100
-set g_balance_armor_limit 999
-set g_balance_armor_blockpercent 0.66
-
+set g_balance_armor_limit 200
+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
// }}}
// {{{ misc
-set g_balance_selfdamagepercent 0.75
-set g_balance_weaponswitchdelay 0.05
+set g_balance_selfdamagepercent 0.65
+set g_balance_weaponswitchdelay 0.1
set g_weaponspeedfactor 1 "weapon projectile speed multiplier"
set g_weaponratefactor 1 "weapon fire rate multiplier"
set g_weapondamagefactor 1 "weapon damage multiplier"
// 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 675
-set g_balance_falldamage_factor 0.25
-set g_balance_falldamage_maxdamage 10
+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.25
+set g_balance_powerup_invincible_takedamage 0.3
set g_balance_powerup_invincible_time 30
-set g_balance_powerup_strength_damage 4
+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 2
-set g_balance_powerup_strength_selfforce 2
+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 1200 "max speed of the jetpack in xy direction"
+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"
// {{{ weapon properties
// {{{ laser
-set g_balance_laser_primary_damage 22
+set g_balance_laser_primary_damage 10
set g_balance_laser_primary_edgedamage 0
-set g_balance_laser_primary_force 200
-set g_balance_laser_primary_radius 52
+set g_balance_laser_primary_force 75
+set g_balance_laser_primary_radius 10
set g_balance_laser_primary_speed 0
set g_balance_laser_primary_spread 0
-set g_balance_laser_primary_refire 0.1
-set g_balance_laser_primary_animtime 0.1
+set g_balance_laser_primary_refire 0.066
+set g_balance_laser_primary_animtime 0.066
set g_balance_laser_primary_lifetime 0
set g_balance_laser_primary_shotangle 0
set g_balance_laser_primary_delay 0
-set g_balance_laser_gauntlet 1
+set g_balance_laser_primary_gauntlet 1
set g_balance_laser_secondary 0 // when 1, a secondary laser mode exists
-set g_balance_laser_secondary_damage 30
-set g_balance_laser_secondary_edgedamage 0
-set g_balance_laser_secondary_force 100
-set g_balance_laser_secondary_radius 3
-set g_balance_laser_secondary_speed 1500
+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
-set g_balance_laser_secondary_animtime 0.15
-set g_balance_laser_secondary_lifetime 0.066
+set g_balance_laser_secondary_refire 0.7
+set g_balance_laser_secondary_animtime 0
+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 25
+set g_balance_shotgun_primary_bullets 16
set g_balance_shotgun_primary_damage 4
-set g_balance_shotgun_primary_force 10
-set g_balance_shotgun_primary_spread 0.18
+set g_balance_shotgun_primary_force 20
+set g_balance_shotgun_primary_spread 0.16
set g_balance_shotgun_primary_refire 1
-set g_balance_shotgun_primary_animtime 0.7
+set g_balance_shotgun_primary_animtime 0.4
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 0
-set g_balance_shotgun_secondary_bullets 22
-set g_balance_shotgun_secondary_damage 2
-set g_balance_shotgun_secondary_force 12
-set g_balance_shotgun_secondary_spread 0.25
-set g_balance_shotgun_secondary_refire 1.5
-set g_balance_shotgun_secondary_animtime 0.2
-set g_balance_shotgun_secondary_ammo 0.5
+set g_balance_shotgun_secondary_melee 0 // ew, bad! Still uses the melee anim!
+set g_balance_shotgun_secondary_melee_delay 0.35 // match the anim
+set g_balance_shotgun_secondary_melee_range 60
+set g_balance_shotgun_secondary_melee_swing 50
+set g_balance_shotgun_secondary_melee_time 0.4
+set g_balance_shotgun_secondary_bullets 6 // one more per shot than 15/3 (primary bullets/amount of shots = 3)
+set g_balance_shotgun_secondary_damage 7
+set g_balance_shotgun_secondary_force 20
+set g_balance_shotgun_secondary_spread 0.20
+set g_balance_shotgun_secondary_refire 1.35
+set g_balance_shotgun_secondary_animtime 0.33
+set g_balance_shotgun_secondary_ammo 1
set g_balance_shotgun_secondary_speed 12000
set g_balance_shotgun_secondary_bulletconstant 75 // 3.8qu
// }}}
// {{{ uzi
-set g_balance_uzi_first 0
-set g_balance_uzi_first_damage 10
-set g_balance_uzi_first_force 50
-set g_balance_uzi_first_spread 0.007
-set g_balance_uzi_first_refire 0.15
-set g_balance_uzi_first_ammo 1
-set g_balance_uzi_sustained_damage 5
-set g_balance_uzi_sustained_force 10
-set g_balance_uzi_sustained_spread 0.02
-set g_balance_uzi_sustained_refire 0.1
+set g_balance_uzi_first 1
+set g_balance_uzi_first_damage 18
+set g_balance_uzi_first_force 35
+set g_balance_uzi_first_spread 0.03
+set g_balance_uzi_first_refire 0.2
+set g_balance_uzi_first_ammo 2
+set g_balance_uzi_sustained_damage 8
+set g_balance_uzi_sustained_force 7.5
+set g_balance_uzi_sustained_spread 0.1
+set g_balance_uzi_sustained_refire 0.075
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_primary2secondary 1
-set g_balance_grenadelauncher_primary_damage 60
-set g_balance_grenadelauncher_primary_edgedamage 10
-set g_balance_grenadelauncher_primary_force 250
-set g_balance_grenadelauncher_primary_radius 100
-set g_balance_grenadelauncher_primary_speed 2000
-set g_balance_grenadelauncher_primary_speed_up 200
-set g_balance_grenadelauncher_primary_speed_z 0
+// {{{ mortar // TODO
+set g_balance_grenadelauncher_primary2secondary 0
+set g_balance_grenadelauncher_primary_sticky 1
+set g_balance_grenadelauncher_primary_damage 100
+set g_balance_grenadelauncher_primary_edgedamage 30
+set g_balance_grenadelauncher_primary_force 300
+set g_balance_grenadelauncher_primary_radius 200
+set g_balance_grenadelauncher_primary_speed 1000
+set g_balance_grenadelauncher_primary_speed_up 0
+set g_balance_grenadelauncher_primary_speed_z 200
set g_balance_grenadelauncher_primary_spread 0
set g_balance_grenadelauncher_primary_lifetime 5
-set g_balance_grenadelauncher_primary_refire 0.7
-set g_balance_grenadelauncher_primary_animtime 0.3
+set g_balance_grenadelauncher_primary_lifetime2 0.8
+set g_balance_grenadelauncher_primary_refire 0.8
+set g_balance_grenadelauncher_primary_animtime 0.2
set g_balance_grenadelauncher_primary_ammo 2
-set g_balance_grenadelauncher_secondary_damage 65
-set g_balance_grenadelauncher_secondary_edgedamage 10
+set g_balance_grenadelauncher_primary_health 25
+set g_balance_grenadelauncher_secondary_sticky 0
+set g_balance_grenadelauncher_secondary_damage 100
+set g_balance_grenadelauncher_secondary_edgedamage 30
set g_balance_grenadelauncher_secondary_force 300
set g_balance_grenadelauncher_secondary_radius 200
-set g_balance_grenadelauncher_secondary_speed 800
+set g_balance_grenadelauncher_secondary_speed 600
set g_balance_grenadelauncher_secondary_speed_up 0
set g_balance_grenadelauncher_secondary_speed_z 200
set g_balance_grenadelauncher_secondary_spread 0
-set g_balance_grenadelauncher_secondary_lifetime 2
+set g_balance_grenadelauncher_secondary_lifetime 1.5
+set g_balance_grenadelauncher_secondary_lifetime2 0
set g_balance_grenadelauncher_secondary_refire 0.8
-set g_balance_grenadelauncher_secondary_animtime 0.5
+set g_balance_grenadelauncher_secondary_animtime 0.2
set g_balance_grenadelauncher_secondary_ammo 2
set g_balance_grenadelauncher_secondary_health 0
set g_balance_grenadelauncher_secondary_damageforcescale 0
set g_balance_grenadelauncher_secondary_bouncefactor 0.5
set g_balance_grenadelauncher_secondary_bouncestop 0.075
// }}}
-// {{{ electro
+// {{{ electro // TODO
set g_balance_electro_lightning 1
-set g_balance_electro_primary_damage 6
+set g_balance_electro_primary_damage 120
set g_balance_electro_primary_edgedamage 0
-set g_balance_electro_primary_force 60 // todo: probaby needs movement nerfing code when hit?
+set g_balance_electro_primary_force 780
+set g_balance_electro_primary_force_up 6000
set g_balance_electro_primary_radius 850
set g_balance_electro_primary_comboradius 0
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.066
-set g_balance_electro_primary_animtime 0.066
-set g_balance_electro_primary_ammo 0.66
-set g_balance_electro_secondary_damage 45
-set g_balance_electro_secondary_spread 0.10
-set g_balance_electro_secondary_edgedamage 10
-set g_balance_electro_secondary_force 100
+set g_balance_electro_primary_refire 0
+set g_balance_electro_primary_animtime 0.05
+set g_balance_electro_primary_ammo 40
+set g_balance_electro_primary_range 800
+set g_balance_electro_secondary_damage 50
+set g_balance_electro_secondary_spread 0.05
+set g_balance_electro_secondary_edgedamage 0
+set g_balance_electro_secondary_force 200
set g_balance_electro_secondary_radius 150
set g_balance_electro_secondary_speed 900
set g_balance_electro_secondary_speed_up 200
set g_balance_electro_secondary_speed_z 0
-set g_balance_electro_secondary_spread 0.05
-set g_balance_electro_secondary_lifetime 2.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_spread 0
+set g_balance_electro_secondary_lifetime 5
+set g_balance_electro_secondary_refire 0.3
+set g_balance_electro_secondary_refire2 0
+set g_balance_electro_secondary_animtime 0.3
set g_balance_electro_secondary_ammo 2
set g_balance_electro_secondary_health 5
set g_balance_electro_secondary_damageforcescale 4
-set g_balance_electro_secondary_count 3
-set g_balance_electro_combo_damage 50
+set g_balance_electro_secondary_count 1
+set g_balance_electro_combo_damage 80
set g_balance_electro_combo_edgedamage 0
-set g_balance_electro_combo_force 100
+set g_balance_electro_combo_force 200
set g_balance_electro_combo_radius 250
set g_balance_electro_combo_comboradius 0
set g_balance_electro_combo_speed 2000
// }}}
// {{{ crylink
-set g_balance_crylink_primary_damage 18
-set g_balance_crylink_primary_edgedamage 18
-set g_balance_crylink_primary_force 50
+set g_balance_crylink_primary_damage 12
+set g_balance_crylink_primary_edgedamage 10
+set g_balance_crylink_primary_force 25
set g_balance_crylink_primary_radius 100
set g_balance_crylink_primary_speed 1100
-set g_balance_crylink_primary_spread 0.01
-set g_balance_crylink_primary_shots 4
-set g_balance_crylink_primary_bounces 0
-set g_balance_crylink_primary_refire 0.4
+set g_balance_crylink_primary_spread 0.1
+set g_balance_crylink_primary_shots 7
+set g_balance_crylink_primary_bounces 1
+set g_balance_crylink_primary_refire 0.8
set g_balance_crylink_primary_animtime 0.4
set g_balance_crylink_primary_ammo 2
set g_balance_crylink_primary_bouncedamagefactor 0.5
-set g_balance_crylink_primary_middle_lifetime 5 // range: 35000 full, fades to 70000
+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 3 // range: 700 full, fades to 2450
-set g_balance_crylink_primary_star_fadetime 5
-set g_balance_crylink_primary_other_lifetime 3 // range: 700 full, fades to 2450
-set g_balance_crylink_primary_other_fadetime 5
+set g_balance_crylink_primary_star_lifetime 0.8 // range: 800 full, fades to 1300
+set g_balance_crylink_primary_star_fadetime 0.25
+set g_balance_crylink_primary_other_lifetime 0.8 // range: 800 full, fades to 1300
+set g_balance_crylink_primary_other_fadetime 0.25
-set g_balance_crylink_secondary 0
-set g_balance_crylink_secondary_damage 8
-set g_balance_crylink_secondary_edgedamage 8
-set g_balance_crylink_secondary_force -40
-set g_balance_crylink_secondary_radius 10
-set g_balance_crylink_secondary_speed 4000
-set g_balance_crylink_secondary_spread 0.01
+set g_balance_crylink_secondary 1
+set g_balance_crylink_secondary_damage 4
+set g_balance_crylink_secondary_edgedamage 0
+set g_balance_crylink_secondary_force 16
+set g_balance_crylink_secondary_radius 15
+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.1
set g_balance_crylink_secondary_ammo 1
set g_balance_crylink_secondary_bouncedamagefactor 0.5
-set g_balance_crylink_secondary_middle_lifetime 5 // range: 35000 full, fades to 70000
+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: 35000 full, fades to 70000
+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_damage 80
+set g_balance_nex_damage 100
set g_balance_nex_force 200
set g_balance_nex_refire 1.25
-set g_balance_nex_animtime 1.25
+set g_balance_nex_animtime 1
set g_balance_nex_ammo 5
set g_balance_nex_damagefalloff_mindist 1000
set g_balance_nex_damagefalloff_maxdist 3000
-set g_balance_nex_damagefalloff_halflife 1500
-set g_balance_nex_damagefalloff_forcehalflife 1500
+set g_balance_nex_damagefalloff_halflife 2000
+set g_balance_nex_damagefalloff_forcehalflife 2000
// }}}
// {{{ minstanex
-set g_balance_minstanex_refire 1
+set g_balance_minstanex_refire 1.25
set g_balance_minstanex_animtime 1
set g_balance_minstanex_ammo 10
// }}}
// {{{ hagar
set g_balance_hagar_primary_damage 12
-set g_balance_hagar_primary_edgedamage 5
+set g_balance_hagar_primary_edgedamage 12
set g_balance_hagar_primary_force 70
-set g_balance_hagar_primary_radius 50
-set g_balance_hagar_primary_spread 0
+set g_balance_hagar_primary_radius 70
+set g_balance_hagar_primary_spread 0.1
set g_balance_hagar_primary_speed 1800
-set g_balance_hagar_primary_lifetime 5
-set g_balance_hagar_primary_refire 0.1
+set g_balance_hagar_primary_lifetime 30
+set g_balance_hagar_primary_refire 0.12
set g_balance_hagar_primary_ammo 1
-set g_balance_hagar_secondary 0
-set g_balance_hagar_secondary_damage 11
-set g_balance_hagar_secondary_edgedamage 4
-set g_balance_hagar_secondary_force 60
-set g_balance_hagar_secondary_radius 70
-set g_balance_hagar_secondary_spread 0.05
+set g_balance_hagar_secondary 1
+set g_balance_hagar_secondary_damage 12
+set g_balance_hagar_secondary_edgedamage 12
+set g_balance_hagar_secondary_force 70
+set g_balance_hagar_secondary_radius 50
+set g_balance_hagar_secondary_spread 0.15
set g_balance_hagar_secondary_speed 1800
-set g_balance_hagar_secondary_lifetime_min 5
+set g_balance_hagar_secondary_lifetime_min 30
set g_balance_hagar_secondary_lifetime_rand 0
-set g_balance_hagar_secondary_refire 0.1
+set g_balance_hagar_secondary_refire 0.12
set g_balance_hagar_secondary_ammo 1
// }}}
-// {{{ rocketlauncher
-set g_balance_rocketlauncher_damage 90
-set g_balance_rocketlauncher_edgedamage 30
+// {{{ rocketlauncher // TODO
+set g_balance_rocketlauncher_damage 100
+set g_balance_rocketlauncher_edgedamage 33
set g_balance_rocketlauncher_force 350
-set g_balance_rocketlauncher_radius 110
+set g_balance_rocketlauncher_radius 100
set g_balance_rocketlauncher_speed 1000
set g_balance_rocketlauncher_speedaccel 0
set g_balance_rocketlauncher_speedstart 1000
-set g_balance_rocketlauncher_lifetime 10
-set g_balance_rocketlauncher_refire 0.9
-set g_balance_rocketlauncher_animtime 0.7
+set g_balance_rocketlauncher_lifetime 30
+set g_balance_rocketlauncher_refire 1
+set g_balance_rocketlauncher_animtime 0.2
set g_balance_rocketlauncher_ammo 3
set g_balance_rocketlauncher_health 0
set g_balance_rocketlauncher_damageforcescale 0
-set g_balance_rocketlauncher_detonatedelay 9999 // 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 0 // max degrees per second
+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 1 // stop guiding when firing again
+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 50
+set g_balance_rocketlauncher_remote_edgedamage 16.5
+set g_balance_rocketlauncher_remote_radius 120
+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 5000
+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 2 // hook monkeys set 0
+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 3 // fuel per second hooked
+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 10 // infinite
+set g_balance_hook_secondary_lifetime 30 // 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...
// }}}
// {{{ hlac
set g_balance_hlac_primary_spread_min 0.01
-set g_balance_hlac_primary_spread_max 0.03
-set g_balance_hlac_primary_spread_add 0.002
-set g_balance_hlac_primary_spread_crouchmod 0.5
+set g_balance_hlac_primary_spread_max 0.25
+set g_balance_hlac_primary_spread_add 0.0045
+set g_balance_hlac_primary_spread_crouchmod 0.25
-set g_balance_hlac_primary_damage 6
-set g_balance_hlac_primary_edgedamage 0
-set g_balance_hlac_primary_force 60 // todo: probably needs movement nerfing code when hit
-set g_balance_hlac_primary_radius 850
-set g_balance_hlac_primary_speed 0
-set g_balance_hlac_primary_lifetime 0
+set g_balance_hlac_primary_damage 23
+set g_balance_hlac_primary_edgedamage 10
+set g_balance_hlac_primary_force 100
+set g_balance_hlac_primary_radius 70
+set g_balance_hlac_primary_speed 9000
+set g_balance_hlac_primary_lifetime 5
-set g_balance_hlac_primary_refire 0.066
-set g_balance_hlac_primary_animtime 0.066
-set g_balance_hlac_primary_ammo 0.066
+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 0
-set g_balance_hlac_secondary_spread 0.06
+set g_balance_hlac_secondary 1
+set g_balance_hlac_secondary_spread 0.15
set g_balance_hlac_secondary_spread_crouchmod 0.5
-set g_balance_hlac_secondary_damage 11
+set g_balance_hlac_secondary_damage 23
set g_balance_hlac_secondary_edgedamage 10
-set g_balance_hlac_secondary_force 60
+set g_balance_hlac_secondary_force 100
set g_balance_hlac_secondary_radius 70
-set g_balance_hlac_secondary_speed 20000
+set g_balance_hlac_secondary_speed 9000
set g_balance_hlac_secondary_lifetime 5
-set g_balance_hlac_secondary_refire 0.6
-set g_balance_hlac_secondary_animtime 0.6
+set g_balance_hlac_secondary_refire 1
+set g_balance_hlac_secondary_animtime 0.3
set g_balance_hlac_secondary_ammo 10
-set g_balance_hlac_secondary_shots 5
+set g_balance_hlac_secondary_shots 6
// }}}
// {{{ campingrifle
-set g_balance_campingrifle_magazinecapacity 0
+set g_balance_campingrifle_magazinecapacity 8
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.85 // 0.35 - 0.1 + 0.35 - 0.1 + 0.35 = three secondaries
+set g_balance_campingrifle_bursttime 0
set g_balance_campingrifle_tracer 1
-set g_balance_campingrifle_primary_damage 50
-set g_balance_campingrifle_primary_headshotaddeddamage 80
+set g_balance_campingrifle_primary_damage 60
+set g_balance_campingrifle_primary_headshotaddeddamage 100
set g_balance_campingrifle_primary_spread 0
-set g_balance_campingrifle_primary_force 0
+set g_balance_campingrifle_primary_force 2
set g_balance_campingrifle_primary_speed 35000
set g_balance_campingrifle_primary_lifetime 5
-set g_balance_campingrifle_primary_refire 0.7
-set g_balance_campingrifle_primary_animtime 0.7
+set g_balance_campingrifle_primary_refire 0.8
+set g_balance_campingrifle_primary_animtime 0.3
set g_balance_campingrifle_primary_ammo 10
set g_balance_campingrifle_primary_bulletconstant 130 // 56.3qu
-set g_balance_campingrifle_primary_burstcost 0.35 // require same cooldown as secondary, note it's smaller than primary refire time
-set g_balance_campingrifle_primary_bullethail 0
-set g_balance_campingrifle_secondary_damage 15
-set g_balance_campingrifle_secondary_headshotaddeddamage 25
-set g_balance_campingrifle_secondary_spread 0.02
-set g_balance_campingrifle_secondary_force 0
+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_damage 35
+set g_balance_campingrifle_secondary_headshotaddeddamage 15 // 50 damage only on head
+set g_balance_campingrifle_secondary_spread 0.008
+set g_balance_campingrifle_secondary_force 1
set g_balance_campingrifle_secondary_speed 20000
set g_balance_campingrifle_secondary_lifetime 5
-set g_balance_campingrifle_secondary_refire 0.1
+set g_balance_campingrifle_secondary_refire 0.15
set g_balance_campingrifle_secondary_animtime 0.1
-set g_balance_campingrifle_secondary_ammo 4
+set g_balance_campingrifle_secondary_ammo 10
set g_balance_campingrifle_secondary_bulletconstant 130 // 18.3qu
-set g_balance_campingrifle_secondary_burstcost 0.35
-set g_balance_campingrifle_secondary_bullethail 0
+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_weaponreplace_seeker 0
set sv_q3acompat_machineshotgunswap 0
+// other options
+set sv_fragmessage_information_ping 1
+set sv_fragmessage_information_handicap 2
+set sv_fragmessage_information_stats 1
+set sv_fragmessage_information_typefrag 1
+
+set sv_defaultcharacter 1
+set sv_defaultplayermodel "models/player/nyx.iqm"
+set sv_defaultplayercolors 60 // force some visible color for now
+
+set g_jump_grunt 1
+set g_footsteps 1
+set g_shootfromcenter 1
+set g_fullbrightplayers 1 // until all models are visible with this set to 0
+set g_forced_respawn 1
+set g_mirrordamage 0
+set g_friendlyfire 1
+
+set timelimit_overtimes 1
+set timelimit_override 15 // for now, maybe not in future
+
exec physicsXPM.cfg
-exec balanceXPM.cfg
+exec balanceFruit.cfg
set sv_ready_restart_after_countdown 0 "if set to 1 the players and map items are reset after the countdown ended, otherwise they're reset already at the beginning of the countdown"
set sv_ready_restart_repeatable 0 "allows the players to restart the game as often as needed"
+set sv_hitsound_antispam_time 0.05 "don't play the hitsound more often than this for the electro lightning gun or the laser gauntlet"
+
//nifreks lockonrestart feature, used in team-based game modes, if set to 1 and all players readied up no other player can then join the game anymore, useful to block spectators from joining
set teamplay_lockonrestart 0 "it set to 1 in a team-based game, the teams are locked once all players readied up and the game restarted (no new players can join after restart unless using the server-command unlockteams)"
// based off morphed's cl_gentle
// used in qcsrc/server/w_laser.qc
effect laser_gauntlet
+count 3
+type spark
+color 0xb44215 0x880000
tex 43 43
-count 1.5
+size 7 10
+alpha 128 512 6280
+airfriction 10
+originjitter 2 2 2
+velocityjitter 150 150 150
+velocitymultiplier 0.2
+sizeincrease -100
+stretchfactor 2.3
+rotate -180 180 4000 -4000
+
+effect laser_gauntlet
+count 6
type spark
-color 0xff00ff 0xff0000
-size 4 8
-sizeincrease 34
-alpha 128 128 292
-gravity 0
-airfriction 5
-liquidfriction 10
-velocityjitter 50 50 50
+color 0xff4200 0xff0000
+tex 8 15
+size 7 9
+alpha 256 512 6280
+airfriction 12
+originjitter 2 2 2
+velocityjitter 100 100 100
+velocitymultiplier 0.2
+sizeincrease -100
+stretchfactor 2
+
+
+// muzzle flash
+effect laser_gauntletmuzzleflash
+// glow and light
+countabsolute 1
+type smoke
+color 0x220000 0x880000
+tex 65 65
+size 10 15
+alpha 256 512 6280
+airfriction 10
+sizeincrease -100
+stretchfactor 2
+lightradius 150
+lightradiusfade 500
+lightcolor 3 0.1 0.1
+// electricity
+effect laser_gauntletmuzzleflash
+count 3
+type spark
+color 0xb44215 0x880000
+tex 43 43
+size 7 10
+alpha 128 512 6280
+airfriction 10
+originjitter 2 2 2
+velocityjitter 150 150 150
+velocitymultiplier 0.2
+sizeincrease -100
+stretchfactor 2.3
+rotate -180 180 4000 -4000
+// fire
+effect laser_gauntletmuzzleflash
+count 6
+type spark
+color 0xff4200 0xff0000
+tex 8 15
+size 7 9
+alpha 256 512 6280
+airfriction 12
+originjitter 2 2 2
+velocityjitter 100 100 100
+velocitymultiplier 0.2
+sizeincrease -100
+stretchfactor 2
+
//torch flame, spawn it as fast as you can 20 times per second or more, supports direction but not required
//fast fire
// used nowhere in code, meant for maps
airfriction 5
liquidfriction 10
velocityjitter 156 156 156
+
+
+
+// used in qcsrc/server/w_electro.qc: pointparticles(particleeffectnum("electro_muzzleflash"), w_shotorg, w_shotdir * 1000, 1)
+// used in qcsrc/server/w_electro.qc: pointparticles(particleeffectnum("electro_muzzleflash"), w_shotorg, w_shotdir * 1000, 1)
+effect electro_lightning
+countabsolute 1
+type smoke
+color 0x283880 0x283880 // 0x202020 0x404040
+tex 65 65
+size 10 10
+alpha 256 256 1500
+originjitter 1.5 1.5 1.5
+velocityjitter 6 6 6
+sizeincrease -20
+velocitymultiplier 0.01
+
+effect electro_lightning
+count 3
+type spark
+tex 8 15
+color 0xD9FDFF 0xD9FDFF
+size 3 7
+alpha 110 228 2024
+originjitter 1 1 1
+velocityjitter 150 150 150
+velocitymultiplier 0.5
+airfriction 2
+stretchfactor 1.5
+
+effect electro_lightning
+count 5
+type spark
+tex 41 41
+color 0xD9FDFF 0xD9FDFF
+size 3 4
+alpha 110 228 1500
+originjitter 1 1 1
+velocityjitter 350 350 350
+velocitymultiplier 2.5
+airfriction 8
+gravity 1.3
+stretchfactor 0.1
1 8 20 0 // fire
-9 5 20 0 // fire2
-15 200 20 1 // idle
-215 40 20 0 // reload
+9 23 20 0 // fire2
+32 200 20 1 // idle
+232 40 20 0 // reload
+// compile opts used in the iqm exporter (apparently needed to prevent insane ram usage):
+// fire:1:8, fire2:1:23, idle:1:200, reload:1:40
// database for misc stuff
float tempdb;
float ClientProgsDB;
-vector hook_shotorigin;
+vector hook_shotorigin[4];
+vector electro_shotorigin[4];
+vector gauntlet_shotorigin[4];
#ifdef BLURTEST
float blurtest_time0, blurtest_time1, blurtest_radius, blurtest_power;
string w_deathtypestring;
vector w_org, w_backoff;
+float campingrifle_scope;
// precaches
Projectile_Precache();
+ Hook_Precache();
GibSplash_Precache();
Casings_Precache();
DamageInfo_Precache();
case ENT_CLIENT_WARPZONE: WarpZone_Read(bIsNewEntity); break;
case ENT_CLIENT_WARPZONE_CAMERA: WarpZone_Camera_Read(bIsNewEntity); break;
case ENT_CLIENT_TRIGGER_MUSIC: Ent_ReadTriggerMusic(); break;
+ case ENT_CLIENT_HOOK: Ent_ReadHook(bIsNewEntity, ENT_CLIENT_HOOK); break;
+ case ENT_CLIENT_LGBEAM: Ent_ReadHook(bIsNewEntity, ENT_CLIENT_LGBEAM); break;
+ case ENT_CLIENT_GAUNTLET: Ent_ReadHook(bIsNewEntity, ENT_CLIENT_GAUNTLET); break;
default:
error(strcat("unknown entity type in CSQC_Ent_Update: ", ftos(self.enttype), "\n"));
break;
nb_pb_period = ReadByte() / 32; //Accuracy of 1/32th
- hook_shotorigin_x = ReadCoord();
- hook_shotorigin_y = ReadCoord();
- hook_shotorigin_z = ReadCoord();
+ hook_shotorigin[0] = decompressShotOrigin(ReadInt24_t());
+ hook_shotorigin[1] = decompressShotOrigin(ReadInt24_t());
+ hook_shotorigin[2] = decompressShotOrigin(ReadInt24_t());
+ hook_shotorigin[3] = decompressShotOrigin(ReadInt24_t());
+ electro_shotorigin[0] = decompressShotOrigin(ReadInt24_t());
+ electro_shotorigin[1] = decompressShotOrigin(ReadInt24_t());
+ electro_shotorigin[2] = decompressShotOrigin(ReadInt24_t());
+ electro_shotorigin[3] = decompressShotOrigin(ReadInt24_t());
+ gauntlet_shotorigin[0] = decompressShotOrigin(ReadInt24_t());
+ gauntlet_shotorigin[1] = decompressShotOrigin(ReadInt24_t());
+ gauntlet_shotorigin[2] = decompressShotOrigin(ReadInt24_t());
+ gauntlet_shotorigin[3] = decompressShotOrigin(ReadInt24_t());
if(forcefog)
strunzone(forcefog);
complain_weapon_time = time;
}
+void Net_CampingrifleScope() {
+ campingrifle_scope = TRUE;
+}
+
// CSQC_Parse_TempEntity : Handles all temporary entity network data in the CSQC layer.
// You must ALWAYS first acquire the temporary ID, which is sent as a byte.
// Return value should be 1 if CSQC handled the temporary entity, otherwise return 0 to have the engine process the event.
Net_ReadRace();
bHandled = true;
break;
- case 13: // TE_BEAM
- Net_GrapplingHook();
- bHandled = true;
- break;
case TE_CSQC_SPAWN:
Net_ReadSpawn();
bHandled = true;
Net_WeaponComplain();
bHandled = true;
break;
+ case TE_CSQC_CAMPINGRIFLE_SCOPE:
+ Net_CampingrifleScope();
+ bHandled = true;
+ break;
default:
// No special logic for this temporary entity; return 0 so the engine can handle it
bHandled = false;
zoomspeed = 3.5;
zoomdir = button_zoom;
- if(getstati(STAT_ACTIVEWEAPON) == WEP_NEX) // do NOT use switchweapon here
+ if(getstati(STAT_ACTIVEWEAPON) == WEP_NEX || (getstati(STAT_ACTIVEWEAPON) == WEP_CAMPINGRIFLE && campingrifle_scope)) // do NOT use switchweapon here
zoomdir += button_attack2;
if(spectatee_status > 0 || isdemo())
{
reticle_type = 0; // prevent reticle from showing during the respawn zoom effect or for spectators
else if(button_zoom)
reticle_type = 1; // normal zoom
- else if(activeweapon == WEP_NEX && button_attack2)
+ else if(activeweapon == WEP_NEX && button_attack2 || activeweapon == WEP_CAMPINGRIFLE && button_attack2)
reticle_type = 2; // nex zoom
if(cvar("cl_reticle_stretch"))
-.vector HookStart;
-.vector HookEnd;
-.float HookKillTime;
+.float HookType; // ENT_CLIENT_*
+.vector origin;
+.vector velocity;
+.float HookSound;
+.float HookSilent;
void Draw_CylindricLine(vector from, vector to, float thickness, string texture, float aspect, float shift, vector rgb, float alpha, float drawflag)
{
void Draw_GrapplingHook()
{
vector a, b;
- string tex;
+ string tex, snd;
vector rgb;
float t;
+ float s;
+ vector vs;
- if(time >= self.HookKillTime)
- return;
- if(self.sv_entnum == player_localentnum - 1)
- a = view_origin + view_forward * hook_shotorigin_x + view_right * hook_shotorigin_y + view_up * hook_shotorigin_z;
+ InterpolateOrigin_Do();
+
+ s = cvar("cl_gunalign");
+ if(s != 1 && s != 2 && s != 4)
+ s = 3; // default value
+ --s;
+ switch(self.HookType)
+ {
+ default:
+ case ENT_CLIENT_HOOK:
+ vs = hook_shotorigin[s];
+ break;
+ case ENT_CLIENT_LGBEAM:
+ vs = electro_shotorigin[s];
+ break;
+ case ENT_CLIENT_GAUNTLET:
+ vs = gauntlet_shotorigin[s];
+ break;
+ }
+
+ if((self.owner.sv_entnum == player_localentnum - 1))
+ {
+ switch(self.HookType)
+ {
+ default:
+ case ENT_CLIENT_HOOK:
+ a = view_origin + view_forward * vs_x + view_right * -vs_y + view_up * vs_z;
+ b = self.origin;
+ break;
+ case ENT_CLIENT_LGBEAM:
+ case ENT_CLIENT_GAUNTLET:
+ b = view_origin + view_forward * vlen(self.velocity - self.origin); // honor original length of beam!
+ WarpZone_TraceLine(view_origin, b, MOVE_NORMAL, world);
+ b = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
+ a = view_origin + view_forward * vs_x + view_right * -vs_y + view_up * vs_z;
+ break;
+ }
+ }
else
- a = self.HookStart;
- b = self.HookEnd;
+ {
+ switch(self.HookType)
+ {
+ default:
+ case ENT_CLIENT_HOOK:
+ a = self.velocity;
+ b = self.origin;
+ break;
+ case ENT_CLIENT_LGBEAM:
+ case ENT_CLIENT_GAUNTLET:
+ a = self.origin;
+ b = self.velocity;
+ break;
+ }
+ }
- t = GetPlayerColorForce(self.sv_entnum);
+ t = GetPlayerColorForce(self.owner.sv_entnum);
- if(t == COLOR_TEAM1)
+ switch(self.HookType)
{
- tex = "particles/hook_red";
- rgb = '1 .3 .3';
+ default:
+ case ENT_CLIENT_HOOK:
+ if(t == COLOR_TEAM1)
+ {
+ tex = "particles/hook_red";
+ rgb = '1 .3 .3';
+ }
+ else if(t == COLOR_TEAM2)
+ {
+ tex = "particles/hook_blue";
+ rgb = '.3 .3 1';
+ }
+ else if(t == COLOR_TEAM3)
+ {
+ tex = "particles/hook_yellow";
+ rgb = '1 1 .3';
+ }
+ else if(t == COLOR_TEAM4)
+ {
+ tex = "particles/hook_pink";
+ rgb = '1 .3 1';
+ }
+ else
+ {
+ tex = "particles/hook_green";
+ rgb = '.3 1 .3';
+ }
+ break;
+ case ENT_CLIENT_LGBEAM:
+ tex = "particles/lgbeam";
+ rgb = '1 1 1';
+ break;
+ case ENT_CLIENT_GAUNTLET:
+ tex = "particles/gauntletbeam";
+ rgb = '1 1 1';
+ break;
}
- else if(t == COLOR_TEAM2)
+
+ Draw_GrapplingHook_trace_callback_tex = tex;
+ Draw_GrapplingHook_trace_callback_rnd = random();
+ WarpZone_TraceBox_ThroughZone(a, '0 0 0', '0 0 0', b, ((self.HookType == ENT_CLIENT_HOOK) ? MOVE_NOTHING : MOVE_NORMAL), world, world, Draw_GrapplingHook_trace_callback);
+ Draw_GrapplingHook_trace_callback_tex = string_null;
+
+ switch(self.HookType)
{
- tex = "particles/hook_blue";
- rgb = '.3 .3 1';
+ default:
+ case ENT_CLIENT_HOOK:
+ setorigin(self, trace_endpos); // hook endpoint!
+ self.angles = vectoangles(trace_endpos - WarpZone_TransformOrigin(WarpZone_trace_transform, a));
+ break;
+ case ENT_CLIENT_LGBEAM:
+ case ENT_CLIENT_GAUNTLET:
+ setorigin(self, a); // beam origin!
+ break;
}
- else if(t == COLOR_TEAM3)
+}
+
+void Remove_GrapplingHook()
+{
+ sound (self, CHAN_PROJECTILE, "misc/null.wav", VOL_BASE, ATTN_NORM);
+}
+
+void Ent_ReadHook(float bIsNew, float type)
+{
+ self.HookType = type;
+
+ float sf;
+ sf = ReadByte();
+
+ self.HookSilent = (sf & 0x80);
+ self.iflags = IFLAG_VELOCITY;
+
+ InterpolateOrigin_Undo();
+
+ if(sf & 1)
{
- tex = "particles/hook_yellow";
- rgb = '1 1 .3';
+ self.owner = playerslots[ReadByte() - 1];
}
- else if(t == COLOR_TEAM4)
+ if(sf & 2)
{
- tex = "particles/hook_pink";
- rgb = '1 .3 1';
+ self.origin_x = ReadCoord();
+ self.origin_y = ReadCoord();
+ self.origin_z = ReadCoord();
+ setorigin(self, self.origin);
}
- else
+ if(sf & 4)
{
- tex = "particles/hook_green";
- rgb = '.3 1 .3';
+ self.velocity_x = ReadCoord();
+ self.velocity_y = ReadCoord();
+ self.velocity_z = ReadCoord();
}
- Draw_GrapplingHook_trace_callback_tex = tex;
- Draw_GrapplingHook_trace_callback_rnd = random();
- WarpZone_TraceBox_ThroughZone(a, '0 0 0', '0 0 0', b, MOVE_NOMONSTERS, world, world, Draw_GrapplingHook_trace_callback);
- Draw_GrapplingHook_trace_callback_tex = string_null;
+ InterpolateOrigin_Note();
+
+ if(bIsNew)
+ {
+ self.draw = Draw_GrapplingHook;
+ self.entremove = Remove_GrapplingHook;
+
+ switch(self.HookType)
+ {
+ default:
+ case ENT_CLIENT_HOOK:
+ // for the model
+ setmodel(self, "models/hook.md3");
+ self.drawmask = MASK_NORMAL;
+ break;
+ case ENT_CLIENT_LGBEAM:
+ sound (self, CHAN_PROJECTILE, "weapons/lgbeam_fly.wav", VOL_BASE, ATTN_NORM);
+ break;
+ case ENT_CLIENT_GAUNTLET:
+ sound (self, CHAN_PROJECTILE, "weapons/gauntletbeam_fly.wav", VOL_BASE, ATTN_NORM);
+ break;
+ }
+ }
}
-void Net_GrapplingHook()
+void Hook_Precache()
{
- float i;
- vector start, end;
- entity p;
-
- i = ReadShort();
- end_x = ReadCoord();
- end_y = ReadCoord();
- end_z = ReadCoord();
- start_x = ReadCoord();
- start_y = ReadCoord();
- start_z = ReadCoord();
-
- if(i <= 0 || i >= 256) // not owned by a client
- return;
- --i;
-
- p = playerslots[i];
- if(!p)
- return;
-
- p.HookKillTime = time + 0.1;
- p.HookStart = start;
- p.HookEnd = end;
- p.draw = Draw_GrapplingHook;
+ precache_sound("weapons/lgbeam_fly.wav");
+ precache_sound("weapons/gauntletbeam_fly.wav");
+ precache_model("models/hook.md3");
}
+
+// TODO: hook: temporarily transform self.origin for drawing the model along warpzones!
case PROJECTILE_ELECTRO:
// only new engines support sound moving with object
loopsound(self, CHAN_PROJECTILE, "weapons/electro_fly.wav", VOL_BASE, ATTN_NORM);
- self.mins = '0 0 -3';
- self.maxs = '0 0 -3';
+ self.mins = '0 0 -4';
+ self.maxs = '0 0 -4';
self.move_movetype = MOVETYPE_BOUNCE;
self.move_touch = SUB_Null;
break;
const float TE_CSQC_TARGET_MUSIC = 111;
const float TE_CSQC_NOTIFY = 112;
const float TE_CSQC_WEAPONCOMPLAIN = 113;
+const float TE_CSQC_CAMPINGRIFLE_SCOPE = 115;
const float RACE_NET_CHECKPOINT_HIT_QUALIFYING = 0; // byte checkpoint, short time, short recordtime, string recordholder
const float RACE_NET_CHECKPOINT_CLEAR = 1;
const float ENT_CLIENT_WARPZONE = 24;
const float ENT_CLIENT_WARPZONE_CAMERA = 25;
const float ENT_CLIENT_TRIGGER_MUSIC = 26;
+const float ENT_CLIENT_HOOK = 27;
+const float ENT_CLIENT_LGBEAM = 28;
+const float ENT_CLIENT_GAUNTLET = 29;
const float ENT_CLIENT_TURRET = 40;
float autocvar_sv_cheats;
float autocvar_g_bastet;
var float autocvar_g_movement_highspeed = 1;
+var float autocvar_sys_ticrate;
{
WriteByte(MSG_ENTITY, ENT_CLIENT_INIT);
WriteByte(MSG_ENTITY, g_nexball_meter_period * 32);
- WriteCoord(MSG_ENTITY, hook_shotorigin_x);
- WriteCoord(MSG_ENTITY, hook_shotorigin_y);
- WriteCoord(MSG_ENTITY, hook_shotorigin_z);
+ WriteInt24_t(MSG_ENTITY, compressShotOrigin(hook_shotorigin[0]));
+ WriteInt24_t(MSG_ENTITY, compressShotOrigin(hook_shotorigin[1]));
+ WriteInt24_t(MSG_ENTITY, compressShotOrigin(hook_shotorigin[2]));
+ WriteInt24_t(MSG_ENTITY, compressShotOrigin(hook_shotorigin[3]));
+ WriteInt24_t(MSG_ENTITY, compressShotOrigin(electro_shotorigin[0]));
+ WriteInt24_t(MSG_ENTITY, compressShotOrigin(electro_shotorigin[1]));
+ WriteInt24_t(MSG_ENTITY, compressShotOrigin(electro_shotorigin[2]));
+ WriteInt24_t(MSG_ENTITY, compressShotOrigin(electro_shotorigin[3]));
+ WriteInt24_t(MSG_ENTITY, compressShotOrigin(gauntlet_shotorigin[0]));
+ WriteInt24_t(MSG_ENTITY, compressShotOrigin(gauntlet_shotorigin[1]));
+ WriteInt24_t(MSG_ENTITY, compressShotOrigin(gauntlet_shotorigin[2]));
+ WriteInt24_t(MSG_ENTITY, compressShotOrigin(gauntlet_shotorigin[3]));
if(sv_foginterval && world.fog != "")
WriteString(MSG_ENTITY, world.fog);
else
}
if(!zoomstate_set)
- SetZoomState(self.BUTTON_ZOOM || (self.BUTTON_ATCK2 && self.weapon == WEP_NEX));
+ SetZoomState(self.BUTTON_ZOOM || (self.BUTTON_ATCK2 && self.weapon == WEP_NEX) || (self.BUTTON_ATCK2 && self.weapon == WEP_CAMPINGRIFLE && cvar("g_balance_campingrifle_secondary") == 0));
float oldspectatee_status;
oldspectatee_status = self.spectatee_status;
vector w_shotorg;
vector w_shotdir;
+vector w_shotend;
// this function calculates w_shotorg and w_shotdir based on the weapon model
// offset, trueaim and antilag, and won't put w_shotorg inside a wall.
// make sure you call makevectors first (FIXME?)
-void W_SetupShot_Dir_ProjectileSize(entity ent, vector s_forward, vector mi, vector ma, float antilag, float recoil, string snd, float maxdamage)
+void W_SetupShot_Dir_ProjectileSize_Range(entity ent, vector s_forward, vector mi, vector ma, float antilag, float recoil, string snd, float maxdamage, float range)
{
float nudge = 1; // added to traceline target and subtracted from result
- local vector trueaimpoint;
local float oldsolid;
vector vecs, dv;
oldsolid = ent.dphitcontentsmask;
else
ent.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
if(antilag)
- WarpZone_traceline_antilag(world, ent.origin + ent.view_ofs, ent.origin + ent.view_ofs + s_forward * MAX_SHOT_DISTANCE, MOVE_NORMAL, ent, ANTILAG_LATENCY(ent));
+ WarpZone_traceline_antilag(world, ent.origin + ent.view_ofs, ent.origin + ent.view_ofs + s_forward * range, MOVE_NORMAL, ent, ANTILAG_LATENCY(ent));
// passing world, because we do NOT want it to touch dphitcontentsmask
else
- WarpZone_TraceLine(ent.origin + ent.view_ofs, ent.origin + ent.view_ofs + s_forward * MAX_SHOT_DISTANCE, MOVE_NOMONSTERS, ent);
+ WarpZone_TraceLine(ent.origin + ent.view_ofs, ent.origin + ent.view_ofs + s_forward * range, MOVE_NOMONSTERS, ent);
ent.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
vector vf, vr, vu;
vf = v_forward;
vr = v_right;
vu = v_up;
- trueaimpoint = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos); // warpzone support
+ w_shotend = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos); // warpzone support
v_forward = vf;
v_right = vr;
v_up = vu;
W_HitPlotAnalysis(ent, v_forward, v_right, v_up);
if(ent.weaponentity.movedir_x > 0)
- {
vecs = ent.weaponentity.movedir;
- vecs_y = -vecs_y;
- }
else
vecs = '0 0 0';
-
if(debug_shotorg != '0 0 0')
vecs = debug_shotorg;
- dv = v_right * vecs_y + v_up * vecs_z;
+ dv = v_right * -vecs_y + v_up * vecs_z;
w_shotorg = ent.origin + ent.view_ofs + dv;
// now move the shotorg forward as much as requested if possible
tracebox(w_shotorg, mi, ma, w_shotorg + v_forward * (vecs_x + nudge), MOVE_NORMAL, ent);
w_shotorg = trace_endpos - v_forward * nudge;
// calculate the shotdir from the chosen shotorg
- w_shotdir = normalize(trueaimpoint - w_shotorg);
+ w_shotdir = normalize(w_shotend - w_shotorg);
if (antilag)
if (!ent.cvar_cl_noantilag)
{
if (cvar("g_antilag") == 1) // switch to "ghost" if not hitting original
{
- traceline(w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, MOVE_NORMAL, ent);
+ traceline(w_shotorg, w_shotorg + w_shotdir * range, MOVE_NORMAL, ent);
if (!trace_ent.takedamage)
{
- traceline_antilag_force (ent, w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, MOVE_NORMAL, ent, ANTILAG_LATENCY(ent));
+ traceline_antilag_force (ent, w_shotorg, w_shotorg + w_shotdir * range, MOVE_NORMAL, ent, ANTILAG_LATENCY(ent));
if (trace_ent.takedamage && trace_ent.classname == "player")
{
entity e;
{
// verify that the shot would miss without antilag
// (avoids an issue where guns would always shoot at their origin)
- traceline(w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, MOVE_NORMAL, ent);
+ traceline(w_shotorg, w_shotorg + w_shotdir * range, MOVE_NORMAL, ent);
if (!trace_ent.takedamage)
{
// verify that the shot would hit if altered
if (ent.items & IT_STRENGTH)
if (!g_minstagib)
sound (ent, CHAN_AUTO, "weapons/strength_fire.wav", VOL_BASE, ATTN_NORM);
+
+ // nudge w_shotend so a trace to w_shotend hits
+ w_shotend = w_shotend + normalize(w_shotend - w_shotorg) * nudge;
};
+#define W_SetupShot_Dir_ProjectileSize(ent,s_forward,mi,ma,antilag,recoil,snd,maxdamage) W_SetupShot_Dir_ProjectileSize_Range(ent, s_forward, mi, ma, antilag, recoil, snd, maxdamage, MAX_SHOT_DISTANCE)
#define W_SetupShot_ProjectileSize(ent,mi,ma,antilag,recoil,snd,maxdamage) W_SetupShot_Dir_ProjectileSize(ent, v_forward, mi, ma, antilag, recoil, snd, maxdamage)
#define W_SetupShot_Dir(ent,s_forward,antilag,recoil,snd,maxdamage) W_SetupShot_Dir_ProjectileSize(ent, s_forward, '0 0 0', '0 0 0', antilag, recoil, snd, maxdamage)
#define W_SetupShot(ent,antilag,recoil,snd,maxdamage) W_SetupShot_ProjectileSize(ent, '0 0 0', '0 0 0', antilag, recoil, snd, maxdamage)
+#define W_SetupShot_Range(ent,antilag,recoil,snd,maxdamage,range) W_SetupShot_Dir_ProjectileSize_Range(ent, v_forward, '0 0 0', '0 0 0', antilag, recoil, snd, maxdamage, range)
void LaserTarget_Think()
{
* g_tuba.md3 - pickup model
*/
-void CL_Weaponentity_Think()
+// writes:
+// self.origin, self.angles
+// self.weaponentity
+// self.movedir, self.view_ofs
+// attachment stuff
+// anim stuff
+// to free:
+// call again with ""
+// remove the ent
+void CL_WeaponEntity_SetModel(string name)
{
- float tb, v_shot_idx;
- self.nextthink = time;
- if (intermission_running)
- self.frame = self.anim_idle_x;
- if (self.owner.weaponentity != self)
+ string animfilename;
+ float animfile;
+ float v_shot_idx;
+ if (name != "")
{
- if (self.weaponentity)
- remove(self.weaponentity);
- remove(self);
- return;
- }
- if (self.owner.deadflag != DEAD_NO)
- {
- self.model = "";
+ // if there is a child entity, hide it until we're sure we use it
if (self.weaponentity)
self.weaponentity.model = "";
- return;
- }
- if (self.cnt != self.owner.weapon || self.dmg != self.owner.modelindex || self.deadflag != self.owner.deadflag)
- {
- self.cnt = self.owner.weapon;
- self.dmg = self.owner.modelindex;
- self.deadflag = self.owner.deadflag;
+ setmodel(self, strcat("models/weapons/v_", name, ".md3")); // precision set below
+ v_shot_idx = gettagindex(self, "shot"); // used later
+ if(!v_shot_idx)
+ v_shot_idx = gettagindex(self, "tag_shot");
- string animfilename;
- float animfile;
- if (self.owner.weaponname != "")
+ if(qcweaponanimation)
{
- // if there is a child entity, hide it until we're sure we use it
- if (self.weaponentity)
- self.weaponentity.model = "";
- setmodel(self, strcat("models/weapons/v_", self.owner.weaponname, ".md3")); // precision set below
- v_shot_idx = gettagindex(self, "shot"); // used later
- if(!v_shot_idx)
- v_shot_idx = gettagindex(self, "tag_shot");
+ self.angles = '0 0 0';
+ makevectors(self.angles_x * '-1 0 0' + self.angles_y * '0 1 0' + self.angles_z * '0 0 1');
+ self.movedir = weapon_offset_x * v_forward - weapon_offset_y * v_right + weapon_offset_z * v_up + weapon_adjust;
+ self.movedir_x += 32;
+ self.spawnorigin = self.movedir;
+ // oldorigin - not calculated here
+ }
+ else
+ {
+ setmodel(self, strcat("models/weapons/h_", name, ".iqm")); // precision set below
+ animfilename = strcat("models/weapons/h_", name, ".iqm.animinfo");
+ animfile = fopen(animfilename, FILE_READ);
+ // preset some defaults that work great for renamed zym files (which don't need an animinfo)
+ self.anim_fire1 = '0 1 0.01';
+ self.anim_fire2 = '1 1 0.01';
+ self.anim_idle = '2 1 0.01';
+ self.anim_reload = '3 1 0.01';
+ if (animfile >= 0)
+ {
+ animparseerror = FALSE;
+ self.anim_fire1 = animparseline(animfile);
+ self.anim_fire2 = animparseline(animfile);
+ self.anim_idle = animparseline(animfile);
+ self.anim_reload = animparseline(animfile);
+ fclose(animfile);
+ if (animparseerror)
+ print("Parse error in ", animfilename, ", some player animations are broken\n");
+ }
- if(qcweaponanimation)
+ // if we have a "weapon" tag, let's attach the v_ model to it ("invisible hand" style model)
+ // if we don't, this is a "real" animated model
+ if(gettagindex(self, "weapon"))
{
- self.angles = '0 0 0';
- makevectors(self.angles_x * '-1 0 0' + self.angles_y * '0 1 0' + self.angles_z * '0 0 1');
- self.movedir = weapon_offset_x * v_forward - weapon_offset_y * v_right + weapon_offset_z * v_up + weapon_adjust;
- self.movedir_x += 32;
- self.spawnorigin = self.movedir;
- // oldorigin - not calculated here
+ if (!self.weaponentity)
+ self.weaponentity = spawn();
+ setmodel(self.weaponentity, strcat("models/weapons/v_", name, ".md3")); // precision does not matter
+ setattachment(self.weaponentity, self, "weapon");
+ }
+ else if(gettagindex(self, "tag_weapon"))
+ {
+ if (!self.weaponentity)
+ self.weaponentity = spawn();
+ setmodel(self.weaponentity, strcat("models/weapons/v_", name, ".md3")); // precision does not matter
+ setattachment(self.weaponentity, self, "tag_weapon");
}
else
{
- setmodel(self, strcat("models/weapons/h_", self.owner.weaponname, ".iqm")); // precision set below
- animfilename = strcat("models/weapons/h_", self.owner.weaponname, ".iqm.animinfo");
- animfile = fopen(animfilename, FILE_READ);
- // preset some defaults that work great for renamed zym files (which don't need an animinfo)
- self.anim_fire1 = '0 1 0.01';
- self.anim_fire2 = '1 1 0.01';
- self.anim_idle = '2 1 0.01';
- self.anim_reload = '3 1 0.01';
- if (animfile >= 0)
- {
- animparseerror = FALSE;
- self.anim_fire1 = animparseline(animfile);
- self.anim_fire2 = animparseline(animfile);
- self.anim_idle = animparseline(animfile);
- self.anim_reload = animparseline(animfile);
- fclose(animfile);
- if (animparseerror)
- print("Parse error in ", animfilename, ", some player animations are broken\n");
- }
-
- // if we have a "weapon" tag, let's attach the v_ model to it ("invisible hand" style model)
- // if we don't, this is a "real" animated model
- if(gettagindex(self, "weapon"))
- {
- if (!self.weaponentity)
- self.weaponentity = spawn();
- setmodel(self.weaponentity, strcat("models/weapons/v_", self.owner.weaponname, ".md3")); // precision does not matter
- setattachment(self.weaponentity, self, "weapon");
- }
- else if(gettagindex(self, "tag_weapon"))
- {
- if (!self.weaponentity)
- self.weaponentity = spawn();
- setmodel(self.weaponentity, strcat("models/weapons/v_", self.owner.weaponname, ".md3")); // precision does not matter
- setattachment(self.weaponentity, self, "tag_weapon");
- }
- else
- {
- if(self.weaponentity)
- remove(self.weaponentity);
- self.weaponentity = world;
- }
+ if(self.weaponentity)
+ remove(self.weaponentity);
+ self.weaponentity = world;
+ }
- setorigin(self,'0 0 0');
- self.angles = '0 0 0';
- self.frame = 0;
- self.viewmodelforclient = world;
+ setorigin(self,'0 0 0');
+ self.angles = '0 0 0';
+ self.frame = 0;
+ self.viewmodelforclient = world;
- float idx;
+ float idx;
- if(v_shot_idx) // v_ model attached to invisible h_ model
+ if(v_shot_idx) // v_ model attached to invisible h_ model
+ {
+ self.movedir = gettaginfo(self.weaponentity, v_shot_idx);
+ }
+ else
+ {
+ idx = gettagindex(self, "shot");
+ if(!idx)
+ idx = gettagindex(self, "tag_shot");
+ if(idx)
+ self.movedir = gettaginfo(self, idx);
+ else
{
- self.movedir = gettaginfo(self.weaponentity, v_shot_idx);
+ print("WARNING: weapon model ", self.model, " does not support the 'shot' tag, will display shots TOTALLY wrong\n");
+ self.movedir = '0 0 0';
}
+ }
+
+ if(self.weaponentity) // v_ model attached to invisible h_ model
+ {
+ idx = gettagindex(self.weaponentity, "shell");
+ if(!idx)
+ idx = gettagindex(self.weaponentity, "tag_shell");
+ if(idx)
+ self.spawnorigin = gettaginfo(self.weaponentity, idx);
+ }
+ else
+ idx = 0;
+ if(!idx)
+ {
+ idx = gettagindex(self, "shell");
+ if(!idx)
+ idx = gettagindex(self, "tag_shell");
+ if(idx)
+ self.spawnorigin = gettaginfo(self, idx);
else
{
- idx = gettagindex(self, "shot");
- if(!idx)
- idx = gettagindex(self, "tag_shot");
- if(idx)
- self.movedir = gettaginfo(self, idx);
- else
- {
- print("WARNING: weapon model ", self.model, " does not support the 'shot' tag, will display shots TOTALLY wrong\n");
- self.movedir = '0 0 0';
- }
+ print("WARNING: weapon model ", self.model, " does not support the 'shell' tag, will display casings wrong\n");
+ self.spawnorigin = self.movedir;
}
+ }
- if(self.weaponentity) // v_ model attached to invisible h_ model
+ if(v_shot_idx)
+ {
+ self.oldorigin = '0 0 0'; // use regular attachment
+ }
+ else
+ {
+ if(self.weaponentity)
{
- idx = gettagindex(self.weaponentity, "shell");
+ idx = gettagindex(self, "weapon");
if(!idx)
- idx = gettagindex(self.weaponentity, "tag_shell");
- if(idx)
- self.spawnorigin = gettaginfo(self.weaponentity, idx);
+ idx = gettagindex(self, "tag_weapon");
}
else
- idx = 0;
- if(!idx)
{
- idx = gettagindex(self, "shell");
+ idx = gettagindex(self, "handle");
if(!idx)
- idx = gettagindex(self, "tag_shell");
- if(idx)
- self.spawnorigin = gettaginfo(self, idx);
- else
- {
- print("WARNING: weapon model ", self.model, " does not support the 'shell' tag, will display casings wrong\n");
- self.spawnorigin = self.movedir;
- }
+ idx = gettagindex(self, "tag_handle");
}
-
- if(v_shot_idx)
+ if(idx)
{
- self.oldorigin = '0 0 0'; // use regular attachment
+ self.oldorigin = self.movedir - gettaginfo(self, idx);
}
else
{
- if(self.weaponentity)
- {
- idx = gettagindex(self, "weapon");
- if(!idx)
- idx = gettagindex(self, "tag_weapon");
- }
- else
- {
- idx = gettagindex(self, "handle");
- if(!idx)
- idx = gettagindex(self, "tag_handle");
- }
- if(idx)
- {
- self.oldorigin = self.movedir - gettaginfo(self, idx);
- }
- else
- {
- print("WARNING: weapon model ", self.model, " does not support the 'handle' tag and neither does the v_ model support the 'shot' tag, will display muzzle flashes TOTALLY wrong\n");
- self.oldorigin = '0 0 0'; // there is no way to recover from this
- }
+ print("WARNING: weapon model ", self.model, " does not support the 'handle' tag and neither does the v_ model support the 'shot' tag, will display muzzle flashes TOTALLY wrong\n");
+ self.oldorigin = '0 0 0'; // there is no way to recover from this
}
-
- self.viewmodelforclient = self.owner;
}
+
+ self.viewmodelforclient = self.owner;
}
- else
- {
- self.model = "";
- if(self.weaponentity)
- remove(self.weaponentity);
- self.weaponentity = world;
- self.movedir = '0 0 0';
- self.spawnorigin = '0 0 0';
- self.oldorigin = '0 0 0';
- self.anim_fire1 = '0 1 0.01';
- self.anim_fire2 = '0 1 0.01';
- self.anim_idle = '0 1 0.01';
- self.anim_reload = '0 1 0.01';
- }
+ }
+ else
+ {
+ self.model = "";
+ if(self.weaponentity)
+ remove(self.weaponentity);
+ self.weaponentity = world;
+ self.movedir = '0 0 0';
+ self.spawnorigin = '0 0 0';
+ self.oldorigin = '0 0 0';
+ self.anim_fire1 = '0 1 0.01';
+ self.anim_fire2 = '0 1 0.01';
+ self.anim_idle = '0 1 0.01';
+ self.anim_reload = '0 1 0.01';
+ }
- self.view_ofs = '0 0 0';
+ self.view_ofs = '0 0 0';
- if(self.movedir_x >= 0)
- {
- vector v0;
- v0 = self.movedir;
- self.movedir = shotorg_adjust(v0, FALSE, FALSE);
- self.view_ofs = shotorg_adjust(v0, FALSE, TRUE) - v0;
- }
- self.owner.stat_shotorg = compressShotOrigin(self.movedir);
- self.movedir = decompressShotOrigin(self.owner.stat_shotorg); // make them match perfectly
+ if(self.movedir_x >= 0)
+ {
+ vector v0;
+ v0 = self.movedir;
+ self.movedir = shotorg_adjust(v0, FALSE, FALSE);
+ self.view_ofs = shotorg_adjust(v0, FALSE, TRUE) - v0;
+ }
+ self.owner.stat_shotorg = compressShotOrigin(self.movedir);
+ self.movedir = decompressShotOrigin(self.owner.stat_shotorg); // make them match perfectly
- self.spawnorigin += self.view_ofs; // offset the casings origin by the same amount
+ self.spawnorigin += self.view_ofs; // offset the casings origin by the same amount
- // check if an instant weapon switch occurred
- if (qcweaponanimation)
+ // check if an instant weapon switch occurred
+ if (qcweaponanimation)
+ {
+ if (self.state == WS_READY)
{
- if (self.state == WS_READY)
- {
- self.angles = '0 0 0';
- makevectors(self.angles_x * '-1 0 0' + self.angles_y * '0 1 0' + self.angles_z * '0 0 1');
- setorigin(self, QCWEAPONANIMATION_ORIGIN(self));
- }
+ self.angles = '0 0 0';
+ makevectors(self.angles_x * '-1 0 0' + self.angles_y * '0 1 0' + self.angles_z * '0 0 1');
+ setorigin(self, QCWEAPONANIMATION_ORIGIN(self));
}
- else
- setorigin(self, self.view_ofs);
- // reset animstate now
- self.wframe = WFRAME_IDLE;
- self.weapon_morph0time = 0;
- self.weapon_morph1time = 0;
- self.weapon_morph2time = 0;
- self.weapon_morph3time = 0;
- self.weapon_morph4time = 0;
- setanim(self, self.anim_idle, TRUE, FALSE, TRUE);
+ }
+ else
+ setorigin(self, self.view_ofs);
+ // reset animstate now
+ self.wframe = WFRAME_IDLE;
+ self.weapon_morph0time = 0;
+ self.weapon_morph1time = 0;
+ self.weapon_morph2time = 0;
+ self.weapon_morph3time = 0;
+ self.weapon_morph4time = 0;
+ setanim(self, self.anim_idle, TRUE, FALSE, TRUE);
+}
+
+vector CL_Weapon_GetShotOrg(float wpn)
+{
+ entity wi, oldself;
+ vector ret;
+ wi = get_weaponinfo(wpn);
+ oldself = self;
+ self = spawn();
+ CL_WeaponEntity_SetModel(wi.mdl);
+ ret = self.movedir;
+ CL_WeaponEntity_SetModel("");
+ remove(self);
+ self = oldself;
+ return ret;
+}
+
+void CL_Weaponentity_Think()
+{
+ float tb;
+ self.nextthink = time;
+ if (intermission_running)
+ self.frame = self.anim_idle_x;
+ if (self.owner.weaponentity != self)
+ {
+ if (self.weaponentity)
+ remove(self.weaponentity);
+ remove(self);
+ return;
+ }
+ if (self.owner.deadflag != DEAD_NO)
+ {
+ self.model = "";
+ if (self.weaponentity)
+ self.weaponentity.model = "";
+ return;
+ }
+ if (self.cnt != self.owner.weapon || self.dmg != self.owner.modelindex || self.deadflag != self.owner.deadflag)
+ {
+ self.cnt = self.owner.weapon;
+ self.dmg = self.owner.modelindex;
+ self.deadflag = self.owner.deadflag;
+
+ CL_WeaponEntity_SetModel(self.owner.weaponname);
}
tb = (self.effects & (EF_TELEPORT_BIT | EF_RESTARTANIM_BIT));
}
else
{
- setattachment(flash, self.weaponentity, "shot");
+ if(gettagindex(self.weaponentity, "shot"))
+ setattachment(flash, self.weaponentity, "shot");
+ else
+ setattachment(flash, self.weaponentity, "tag_shot");
setorigin(flash, offset);
xflash = spawn();
}
else
{
- setattachment(xflash, self.exteriorweaponentity, "shot");
+ if(gettagindex(self.exteriorweaponentity, "shot"))
+ setattachment(xflash, self.exteriorweaponentity, "shot");
+ else
+ setattachment(xflash, self.exteriorweaponentity, "tag_shot");
+ setorigin(xflash, offset);
}
}
}
entity damage_targ;
entity damage_inflictor;
entity damage_attacker;
+.float prevhitsound;
void Damage (entity targ, entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
{
{
if(damage > 0)
{
- if(targ.BUTTON_CHAT)
- attacker.typehitsound += 1;
- else
- attacker.hitsound += 1;
+ if(attacker.weapon != WEP_ELECTRO && attacker.weapon != WEP_LASER || ((attacker.weapon == WEP_ELECTRO && cvar("g_balance_electro_lightning") || attacker.weapon == WEP_LASER) && attacker.prevhitsound + cvar("sv_hitsound_antispam_time") < time))
+ {
+ if(targ.BUTTON_CHAT)
+ attacker.typehitsound += 1;
+ else
+ attacker.hitsound += 1;
+ attacker.prevhitsound = time;
+ }
damage_goodhits += 1;
damage_gooddamage += damage;
self.hook_length = -1;
}
+.vector hook_start, hook_end;
+float GrapplingHookSend(entity to, float sf)
+{
+ WriteByte(MSG_ENTITY, ENT_CLIENT_HOOK);
+ sf = sf & 0x7F;
+ if(sound_allowed(MSG_BROADCAST, self.owner))
+ sf |= 0x80;
+ WriteByte(MSG_ENTITY, sf);
+ if(sf & 1)
+ {
+ WriteByte(MSG_ENTITY, num_for_edict(self.owner));
+ }
+ if(sf & 2)
+ {
+ WriteCoord(MSG_ENTITY, self.hook_start_x);
+ WriteCoord(MSG_ENTITY, self.hook_start_y);
+ WriteCoord(MSG_ENTITY, self.hook_start_z);
+ }
+ if(sf & 4)
+ {
+ WriteCoord(MSG_ENTITY, self.hook_end_x);
+ WriteCoord(MSG_ENTITY, self.hook_end_y);
+ WriteCoord(MSG_ENTITY, self.hook_end_z);
+ }
+ return TRUE;
+}
+
void GrapplingHookThink()
{
- float spd, dist, minlength, pullspeed, ropestretch, ropeairfriction, rubberforce, newlength, rubberforce_overstretch;
- vector dir, org, end, v0, dv, v, myorg;
+ float spd, dist, minlength, pullspeed, ropestretch, ropeairfriction, rubberforce, newlength, rubberforce_overstretch, s;
+ vector dir, org, end, v0, dv, v, myorg, vs;
if(self.owner.health <= 0 || self.owner.hook != self) // how did that happen?
{ // well, better fix it anyway
remove(self);
self.nextthink = time;
+ s = self.owner.cvar_cl_gunalign;
+ if(s != 1 && s != 2 && s != 4)
+ s = 3; // default value
+ --s;
+ vs = hook_shotorigin[s];
+
makevectors(self.owner.v_angle);
- org = self.owner.origin + self.owner.view_ofs + v_forward * hook_shotorigin_x + v_right * hook_shotorigin_y + v_up * hook_shotorigin_z;
+ org = self.owner.origin + self.owner.view_ofs + v_forward * vs_x + v_right * -vs_y + v_up * vs_z;
myorg = WarpZone_RefSys_TransformOrigin(self.owner, self, org);
if(self.hook_length < 0)
}
makevectors(self.angles_x * '-1 0 0' + self.angles_y * '0 1 0');
- te_beam(self.owner, WarpZone_RefSys_TransformOrigin(self, self.owner, self.origin) + v_forward * (-9), org);
+ myorg = WarpZone_RefSys_TransformOrigin(self, self.owner, self.origin) + v_forward * (-9);
+
+ if(myorg != self.hook_start)
+ {
+ self.SendFlags |= 2;
+ self.hook_start = myorg;
+ }
+ if(org != self.hook_end)
+ {
+ self.SendFlags |= 4;
+ self.hook_end = org;
+ }
}
void GrapplingHookTouch (void)
{
local entity missile;
local vector org;
+ float s;
+ vector vs;
if((arena_roundbased && time < warmup) || (time < game_starttime))
return;
makevectors(self.v_angle);
+ s = self.cvar_cl_gunalign;
+ if(s != 1 && s != 2 && s != 4)
+ s = 3; // default value
+ --s;
+ vs = hook_shotorigin[s];
+
// 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 * hook_shotorigin_x + v_right * hook_shotorigin_y + v_up * hook_shotorigin_z;
+ org = self.origin + self.view_ofs + v_forward * vs_x + v_right * -vs_y + v_up * vs_z;
pointparticles(particleeffectnum("grapple_muzzleflash"), org, '0 0 0', 1);
missile = WarpZone_RefSys_SpawnSameRefSys(self);
missile.movetype = MOVETYPE_FLY;
PROJECTILE_MAKETRIGGER(missile);
- setmodel (missile, "models/hook.md3"); // precision set below
+ //setmodel (missile, "models/hook.md3"); // precision set below
setsize (missile, '-3 -3 -3', '3 3 3');
setorigin (missile, org);
missile.event_damage = GrapplingHook_Damage;
missile.takedamage = DAMAGE_AIM;
missile.damageforcescale = 0;
+
+ missile.hook_start = missile.hook_end = missile.origin;
+
+ Net_LinkEntity(missile, FALSE, 0, GrapplingHookSend);
}
// void GrapplingHookFrame()
void GrappleHookInit()
{
if(g_grappling_hook)
- hook_shotorigin = '8 -8 -12';
+ {
+ hook_shotorigin[0] = '8 8 -12';
+ hook_shotorigin[1] = '8 8 -12';
+ hook_shotorigin[2] = '8 8 -12';
+ hook_shotorigin[3] = '8 8 -12';
+ }
else
- hook_shotorigin = shotorg_adjust('26.2148 9.2059 -15.9772', TRUE, FALSE);
+ {
+ weapon_action(WEP_HOOK, WR_PRECACHE);
+ hook_shotorigin[0] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_HOOK), FALSE, FALSE, 1);
+ hook_shotorigin[1] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_HOOK), FALSE, FALSE, 2);
+ hook_shotorigin[2] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_HOOK), FALSE, FALSE, 3);
+ hook_shotorigin[3] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_HOOK), FALSE, FALSE, 4);
+ }
}
void SetGrappleHookBindings()
.float hook_state;
void GrappleHookInit();
-vector hook_shotorigin;
+vector hook_shotorigin[4];
e.animstate_looping = looping;
e.animstate_override = override;
e.frame = e.animstate_startframe;
+ e.frame1time = servertime;
};
void updateanim(entity e)
InitGameplayMode();
readlevelcvars();
GrappleHookInit();
+ ElectroInit();
+ LaserInit();
player_count = 0;
bot_waypoints_for_items = cvar("g_waypoints_for_items");
if(argv(0) == "debug_shotorg")
{
debug_shotorg = stov(argv(1));
+ debug_shotorg_y = -debug_shotorg_y;
return;
}
" ", ftos(tstart), " ", ftos(dt), "\n"));
}
-vector shotorg_adjustfromclient(vector vecs, float y_is_right, float allowcenter)
+vector shotorg_adjustfromclient(vector vecs, float y_is_right, float allowcenter, float algn)
{
- switch(self.owner.cvar_cl_gunalign)
+ switch(algn)
{
case 1: // right
break;
return vecs;
}
-vector shotorg_adjust(vector vecs, float y_is_right, float visual)
+vector shotorg_adjust_values(vector vecs, float y_is_right, float visual, float algn)
{
string s;
vector v;
{
if (visual)
{
- vecs = shotorg_adjustfromclient(vecs, y_is_right, TRUE);
+ vecs = shotorg_adjustfromclient(vecs, y_is_right, TRUE, algn);
}
else
{
{
if (visual)
{
- vecs = shotorg_adjustfromclient(vecs, y_is_right, TRUE);
+ vecs = shotorg_adjustfromclient(vecs, y_is_right, TRUE, algn);
}
else
{
}
else if (cvar("g_shootfromclient"))
{
- vecs = shotorg_adjustfromclient(vecs, y_is_right, (cvar("g_shootfromclient") >= 2));
+ vecs = shotorg_adjustfromclient(vecs, y_is_right, (cvar("g_shootfromclient") >= 2), algn);
}
return vecs;
}
+vector shotorg_adjust(vector vecs, float y_is_right, float visual)
+{
+ return shotorg_adjust_values(vecs, y_is_right, visual, self.owner.cvar_cl_gunalign);
+}
void attach_sameorigin(entity e, entity to, string tag)
portals.qh
g_hook.qh
+w_electro.qh
+w_laser.qh
scores.qh
}
.float bot_secondary_campingriflemooth;
+.float sent_campingrifle_scope;
float w_campingrifle(float req)
{
float full;
self.campingrifle_accumulator += cvar("g_balance_campingrifle_primary_burstcost");
}
if (self.BUTTON_ATCK2)
- if (weapon_prepareattack_check(1, cvar("g_balance_campingrifle_secondary_refire")))
- if (time >= self.campingrifle_accumulator + cvar("g_balance_campingrifle_secondary_burstcost"))
- {
- weapon_prepareattack_do(1, cvar("g_balance_campingrifle_secondary_refire"));
- W_CampingRifle_BulletHail(cvar("g_balance_campingrifle_secondary_bullethail"), W_CampingRifle_Attack2, WFRAME_FIRE2, cvar("g_balance_campingrifle_secondary_animtime"), cvar("g_balance_campingrifle_primary_refire"));
- self.campingrifle_accumulator += cvar("g_balance_campingrifle_secondary_burstcost");
+ {
+ if (cvar("g_balance_campingrifle_secondary"))
+ {
+ if (weapon_prepareattack_check(1, cvar("g_balance_campingrifle_secondary_refire")))
+ if (time >= self.campingrifle_accumulator + cvar("g_balance_campingrifle_secondary_burstcost"))
+ {
+ weapon_prepareattack_do(1, cvar("g_balance_campingrifle_secondary_refire"));
+ W_CampingRifle_BulletHail(cvar("g_balance_campingrifle_secondary_bullethail"), W_CampingRifle_Attack2, WFRAME_FIRE2, cvar("g_balance_campingrifle_secondary_animtime"), cvar("g_balance_campingrifle_primary_refire"));
+ self.campingrifle_accumulator += cvar("g_balance_campingrifle_secondary_burstcost");
+ }
+ }
+ else
+ {
+ if(clienttype(self) == CLIENTTYPE_REAL)
+ if(!self.sent_campingrifle_scope)
+ {
+ msg_entity = self;
+ WriteByte(MSG_ONE, SVC_TEMPENTITY);
+ WriteByte(MSG_ONE, TE_CSQC_CAMPINGRIFLE_SCOPE);
+ self.sent_campingrifle_scope = 1;
+ }
+ }
}
}
}
else if (req == WR_PRECACHE)
- {
+ {
precache_model ("models/weapons/g_campingrifle.md3");
precache_model ("models/weapons/v_campingrifle.md3");
precache_model ("models/weapons/h_campingrifle.iqm");
{
local entity proj;
- W_SetupShot_ProjectileSize (self, '0 0 -3', '0 0 -3', FALSE, 2, "weapons/electro_fire2.wav", cvar("g_balance_electro_secondary_damage"));
+ W_SetupShot_ProjectileSize (self, '0 0 -4', '0 0 -4', FALSE, 2, "weapons/electro_fire2.wav", cvar("g_balance_electro_secondary_damage"));
w_shotdir = v_forward; // no TrueAim for grenades please
pointparticles(particleeffectnum("electro_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
proj.movetype = MOVETYPE_BOUNCE;
W_SETUPPROJECTILEVELOCITY_UP(proj, g_balance_electro_secondary);
proj.touch = W_Plasma_Touch;
- setsize(proj, '0 0 -3', '0 0 -3');
+ setsize(proj, '0 0 -4', '0 0 -4');
proj.takedamage = DAMAGE_YES;
proj.damageforcescale = cvar("g_balance_electro_secondary_damageforcescale");
proj.health = cvar("g_balance_electro_secondary_health");
CSQCProjectile(proj, TRUE, PROJECTILE_ELECTRO, FALSE); // no culling, it has sound
}
+.vector hook_start, hook_end;
+float lgbeam_send(entity to, float sf)
+{
+ WriteByte(MSG_ENTITY, ENT_CLIENT_LGBEAM);
+ sf = sf & 0x7F;
+ if(sound_allowed(MSG_BROADCAST, self.owner))
+ sf |= 0x80;
+ WriteByte(MSG_ENTITY, sf);
+ if(sf & 1)
+ {
+ WriteByte(MSG_ENTITY, num_for_edict(self.owner));
+ }
+ if(sf & 2)
+ {
+ WriteCoord(MSG_ENTITY, self.hook_start_x);
+ WriteCoord(MSG_ENTITY, self.hook_start_y);
+ WriteCoord(MSG_ENTITY, self.hook_start_z);
+ }
+ if(sf & 4)
+ {
+ WriteCoord(MSG_ENTITY, self.hook_end_x);
+ WriteCoord(MSG_ENTITY, self.hook_end_y);
+ WriteCoord(MSG_ENTITY, self.hook_end_z);
+ }
+ return TRUE;
+}
+.entity lgbeam;
+.float prevlgfire;
+void lgbeam_think()
+{
+ self.owner.prevlgfire = time;
+ if (self.owner.weaponentity.state != WS_INUSE || (self.owner.ammo_cells <= 0 && !(self.owner.items & IT_UNLIMITED_WEAPON_AMMO)) || self != self.owner.lgbeam || self.owner.deadflag != DEAD_NO || !self.owner.BUTTON_ATCK)
+ {
+ remove(self);
+ return;
+ }
+
+ self.nextthink = time;
+
+ makevectors(self.owner.v_angle);
+
+ float dt;
+ dt = frametime;
+ if not(self.owner.items & IT_UNLIMITED_WEAPON_AMMO)
+ {
+ if(cvar("g_balance_electro_primary_ammo"))
+ dt = min(frametime, self.owner.ammo_cells / cvar("g_balance_electro_primary_ammo"));
+ self.owner.ammo_cells = max(0, self.owner.ammo_cells - cvar("g_balance_electro_primary_ammo") * frametime);
+ }
+
+ W_SetupShot_Range(self.owner, TRUE, 0, "", cvar("g_balance_electro_primary_damage") * dt, cvar("g_balance_electro_primary_range"));
+ WarpZone_traceline_antilag(self.owner, w_shotorg, w_shotend, MOVE_NORMAL, self.owner, ANTILAG_LATENCY(self.owner));
+
+ // apply the damage
+ if(trace_ent)
+ {
+ vector force;
+ force = w_shotdir * cvar("g_balance_electro_primary_force") + '0 0 1' * cvar("g_balance_electro_primary_force_up");
+ Damage (trace_ent, self.owner, self.owner, cvar("g_balance_electro_primary_damage") * dt, WEP_ELECTRO, trace_endpos, force * dt);
+ }
+ W_Plasma_TriggerCombo(trace_endpos, cvar("g_balance_electro_primary_comboradius"), self.owner);
+
+ // draw effect
+ if(w_shotorg != self.hook_start)
+ {
+ self.SendFlags |= 2;
+ self.hook_start = w_shotorg;
+ }
+ if(w_shotend != self.hook_end)
+ {
+ self.SendFlags |= 4;
+ self.hook_end = w_shotend;
+ }
+}
+
// experimental lightning gun
void W_Electro_Attack3 (void)
{
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_cells = self.ammo_cells - cvar("g_balance_electro_primary_ammo");
- W_SetupShot (self, TRUE, 0, "weapons/crylink_fire2.wav", cvar("g_balance_electro_primary_damage"));
-
- traceline_antilag(self, w_shotorg, w_shotorg + w_shotdir * cvar("g_balance_electro_primary_radius"), FALSE, self, ANTILAG_LATENCY(self));
+ // only play fire sound if 0.5 sec has passed since player let go the fire button
+ if(time - self.prevlgfire > 0.5)
+ {
+ sound (self, CHAN_WEAPON, "weapons/lgbeam_fire.wav", VOL_BASE, ATTN_NORM);
+ }
- te_lightning1(self, w_shotorg, trace_endpos);
+ entity beam, oldself;
+
+ self.lgbeam = beam = spawn();
+ beam.solid = SOLID_NOT;
+ beam.think = lgbeam_think;
+ beam.owner = self;
+ beam.movetype = MOVETYPE_NONE;
+ beam.shot_spread = 0;
+ beam.bot_dodge = TRUE;
+ beam.bot_dodgerating = cvar("g_balance_electro_primary_damage");
+ Net_LinkEntity(beam, FALSE, 0, lgbeam_send);
+
+ oldself = self;
+ self = beam;
+ self.think();
+ self = oldself;
+}
- if (trace_fraction < 1)
- Damage(trace_ent, self, self, cvar("g_balance_electro_primary_damage"), WEP_ELECTRO | HITTYPE_SECONDARY, trace_endpos, cvar("g_balance_electro_primary_force") * w_shotdir);
+void ElectroInit()
+{
+ weapon_action(WEP_ELECTRO, WR_PRECACHE);
+ electro_shotorigin[0] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ELECTRO), FALSE, FALSE, 1);
+ electro_shotorigin[1] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ELECTRO), FALSE, FALSE, 2);
+ electro_shotorigin[2] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ELECTRO), FALSE, FALSE, 3);
+ electro_shotorigin[3] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ELECTRO), FALSE, FALSE, 4);
}
void spawnfunc_weapon_electro (void)
}
.float bot_secondary_electromooth;
+.float BUTTON_ATCK_prev;
float w_electro(float req)
{
if (req == WR_AIM)
else if (req == WR_THINK)
{
if (self.BUTTON_ATCK)
- if (weapon_prepareattack(0, cvar("g_balance_electro_primary_refire")))
{
- if(cvar("g_balance_electro_lightning"))
- W_Electro_Attack3();
- else
- W_Electro_Attack();
- weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_electro_primary_animtime"), w_ready);
+ if (weapon_prepareattack(0, (cvar("g_balance_electro_lightning") ? 0 : cvar("g_balance_electro_primary_refire"))))
+ {
+ if(cvar("g_balance_electro_lightning"))
+ {
+ if (self.BUTTON_ATCK_prev == 0)
+ {
+ W_Electro_Attack3();
+ }
+ self.BUTTON_ATCK_prev = 1;
+ }
+ else
+ {
+ W_Electro_Attack();
+ }
+ weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_electro_primary_animtime"), w_ready);
+ }
+ } else {
+ self.BUTTON_ATCK_prev = 0;
}
- if (self.BUTTON_ATCK2 && !cvar("g_balance_electro_lightning"))
+
+ if (self.BUTTON_ATCK2)
if (time >= self.electro_secondarytime)
if (weapon_prepareattack(1, cvar("g_balance_electro_secondary_refire")))
{
precache_sound ("weapons/electro_impact.wav");
precache_sound ("weapons/electro_impact_combo.wav");
if(cvar("g_balance_electro_lightning"))
- precache_sound ("weapons/crylink_fire2.wav");
+ {
+ precache_sound ("weapons/lgbeam_fire.wav");
+ }
}
else if (req == WR_SETUP)
weapon_setup(WEP_ELECTRO);
else if (req == WR_CHECKAMMO1)
- return self.ammo_cells >= cvar("g_balance_electro_primary_ammo");
+ {
+ if(cvar("g_balance_electro_lightning"))
+ return self.ammo_cells >= cvar("g_balance_electro_primary_ammo") * cvar("g_balance_electro_primary_refire");
+ else
+ return self.ammo_cells >= cvar("g_balance_electro_primary_ammo");
+ }
else if (req == WR_CHECKAMMO2)
return self.ammo_cells >= cvar("g_balance_electro_secondary_ammo");
else if (req == WR_RESETPLAYER)
--- /dev/null
+void ElectroInit();
+vector electro_shotorigin[4];
self.event_damage = SUB_Null;
self.takedamage = DAMAGE_NO;
+
+ if(self.movetype == MOVETYPE_NONE)
+ self.velocity = self.oldvelocity;
+
RadiusDamage (self, self.owner, cvar("g_balance_grenadelauncher_primary_damage"), cvar("g_balance_grenadelauncher_primary_edgedamage"), cvar("g_balance_grenadelauncher_primary_radius"), world, cvar("g_balance_grenadelauncher_primary_force"), self.projectiledeathtype, other);
remove (self);
remove (self);
}
+void W_Grenade_Damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
+{
+ if (self.health <= 0)
+ return;
+ self.health = self.health - damage;
+ if (self.health <= 0)
+ {
+ W_PrepareExplosionByDamage(attacker, self.think);
+ }
+}
+
void W_Grenade_Touch1 (void)
{
PROJECTILE_TOUCH;
- W_Grenade_Explode ();
+ if(cvar("g_balance_grenadelauncher_primary_sticky") && other.takedamage != DAMAGE_AIM)
+ {
+ spamsound (self, CHAN_PROJECTILE, "weapons/grenade_stick.wav", VOL_BASE, ATTN_NORM);
+
+ // let it stick whereever it is
+ self.oldvelocity = self.velocity;
+ self.velocity = '0 0 0';
+ self.movetype = MOVETYPE_NONE; // also disables gravity
+ self.gravity = 0; // nope, it does NOT! maybe a bug in CSQC code? TODO
+ UpdateCSQCProjectile(self);
+
+ // do not respond to any more touches
+ self.solid = SOLID_NOT;
+
+ self.nextthink = min(self.nextthink, time + cvar("g_balance_grenadelauncher_primary_lifetime2"));
+ }
+ else
+ W_Grenade_Explode ();
}
void W_Grenade_Touch2 (void)
{
PROJECTILE_TOUCH;
- if (other.takedamage == DAMAGE_AIM)
+ if(cvar("g_balance_grenadelauncher_secondary_sticky") && other.takedamage != DAMAGE_AIM)
{
- self.use ();
+ spamsound (self, CHAN_PROJECTILE, "weapons/grenade_stick.wav", VOL_BASE, ATTN_NORM);
+
+ // let it stick whereever it is
+ self.oldvelocity = self.velocity;
+ self.velocity = '0 0 0';
+ self.movetype = MOVETYPE_NONE; // also disables gravity
+ self.gravity = 0; // nope, it does NOT! maybe a bug in CSQC code? TODO
+ UpdateCSQCProjectile(self);
+
+ // do not respond to any more touches
+ self.solid = SOLID_NOT;
+
+ self.nextthink = min(self.nextthink, time + cvar("g_balance_grenadelauncher_secondary_lifetime2"));
}
else
{
- float r;
- r = random() * 6;
- if(r < 1)
- spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce1.wav", VOL_BASE, ATTN_NORM);
- else if(r < 2)
- spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce2.wav", VOL_BASE, ATTN_NORM);
- else if(r < 3)
- spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce3.wav", VOL_BASE, ATTN_NORM);
- else if(r < 4)
- spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce4.wav", VOL_BASE, ATTN_NORM);
- else if(r < 5)
- spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce5.wav", VOL_BASE, ATTN_NORM);
+ if (other.takedamage == DAMAGE_AIM)
+ {
+ self.use ();
+ }
else
- spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce6.wav", VOL_BASE, ATTN_NORM);
- self.projectiledeathtype |= HITTYPE_BOUNCE;
- }
-}
-
-void W_Grenade_Damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
-{
- if (self.health <= 0)
- return;
- self.health = self.health - damage;
- if (self.health <= 0)
- {
- W_PrepareExplosionByDamage(attacker, self.think);
+ {
+ float r;
+ r = random() * 6;
+ if(r < 1)
+ spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce1.wav", VOL_BASE, ATTN_NORM);
+ else if(r < 2)
+ spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce2.wav", VOL_BASE, ATTN_NORM);
+ else if(r < 3)
+ spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce3.wav", VOL_BASE, ATTN_NORM);
+ else if(r < 4)
+ spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce4.wav", VOL_BASE, ATTN_NORM);
+ else if(r < 5)
+ spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce5.wav", VOL_BASE, ATTN_NORM);
+ else
+ spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce6.wav", VOL_BASE, ATTN_NORM);
+ self.projectiledeathtype |= HITTYPE_BOUNCE;
+ }
}
}
gren.think = adaptor_think2use_hittype_splash;
gren.use = W_Grenade_Explode;
gren.touch = W_Grenade_Touch1;
+
+ gren.takedamage = DAMAGE_YES;
+ gren.health = cvar("g_balance_grenadelauncher_primary_health");
+ gren.event_damage = W_Grenade_Damage;
W_SETUPPROJECTILEVELOCITY_UP(gren, g_balance_grenadelauncher_primary);
gren.angles = vectoangles (gren.velocity);
gren.bouncestop = cvar("g_balance_grenadelauncher_secondary_bouncestop");
PROJECTILE_MAKETRIGGER(gren);
gren.projectiledeathtype = WEP_GRENADE_LAUNCHER | HITTYPE_SECONDARY;
- setsize(gren, '0 0 -3', '0 0 -3');
setorigin(gren, w_shotorg);
+ setsize(gren, '0 0 -3', '0 0 -3');
gren.nextthink = time + cvar("g_balance_grenadelauncher_secondary_lifetime");
gren.think = adaptor_think2use_hittype_splash;
gren.use = W_Grenade_Explode2;
gren.touch = W_Grenade_Touch2;
+
gren.takedamage = DAMAGE_YES;
gren.health = cvar("g_balance_grenadelauncher_secondary_health");
gren.damageforcescale = cvar("g_balance_grenadelauncher_secondary_damageforcescale");
gren.angles = vectoangles (gren.velocity);
gren.flags = FL_PROJECTILE;
- CSQCProjectile(gren, TRUE, PROJECTILE_GRENADE_BOUNCING, TRUE);
+ if(cvar("g_balance_grenadelauncher_secondary_sticky"))
+ CSQCProjectile(gren, TRUE, PROJECTILE_GRENADE, TRUE);
+ else
+ CSQCProjectile(gren, TRUE, PROJECTILE_GRENADE_BOUNCING, TRUE);
}
void spawnfunc_weapon_grenadelauncher (void)
precache_sound ("weapons/grenade_bounce4.wav");
precache_sound ("weapons/grenade_bounce5.wav");
precache_sound ("weapons/grenade_bounce6.wav");
+ precache_sound ("weapons/grenade_stick.wav");
precache_sound ("weapons/grenade_fire.wav");
}
else if (req == WR_SETUP)
}
}
-void W_Laser_Attack2 (void) // gauntlet
+.vector hook_start, hook_end;
+float gauntletbeam_send(entity to, float sf)
{
- W_SetupShot (self, TRUE, 0, "weapons/gauntlet_fire.wav", cvar("g_balance_laser_primary_damage"));
+ WriteByte(MSG_ENTITY, ENT_CLIENT_GAUNTLET);
+ sf = sf & 0x7F;
+ if(sound_allowed(MSG_BROADCAST, self.owner))
+ sf |= 0x80;
+ WriteByte(MSG_ENTITY, sf);
+ if(sf & 1)
+ {
+ WriteByte(MSG_ENTITY, num_for_edict(self.owner));
+ }
+ if(sf & 2)
+ {
+ WriteCoord(MSG_ENTITY, self.hook_start_x);
+ WriteCoord(MSG_ENTITY, self.hook_start_y);
+ WriteCoord(MSG_ENTITY, self.hook_start_z);
+ }
+ if(sf & 4)
+ {
+ WriteCoord(MSG_ENTITY, self.hook_end_x);
+ WriteCoord(MSG_ENTITY, self.hook_end_y);
+ WriteCoord(MSG_ENTITY, self.hook_end_z);
+ }
+ return TRUE;
+}
+.entity gauntletbeam;
+.float prevgauntletfire;
+void gauntletbeam_think()
+{
+ float damage, myforce, myradius;
+ if(self.cnt)
+ {
+ damage = cvar("g_balance_laser_secondary_damage");
+ myforce = cvar("g_balance_laser_secondary_force");
+ myradius = cvar("g_balance_laser_secondary_radius");
+ }
+ else
+ {
+ damage = cvar("g_balance_laser_primary_damage");
+ myforce = cvar("g_balance_laser_primary_force");
+ myradius = cvar("g_balance_laser_primary_radius");
+ }
+
+ self.owner.prevgauntletfire = time;
+ if (self.owner.weaponentity.state != WS_INUSE || self != self.owner.gauntletbeam || self.owner.deadflag != DEAD_NO || (!self.owner.BUTTON_ATCK2 && self.cnt) || (!self.owner.BUTTON_ATCK && !self.cnt))
+ {
+ remove(self);
+ return;
+ }
+
+ self.nextthink = time;
+
+ makevectors(self.owner.v_angle);
- WarpZone_traceline_antilag(self, w_shotorg, w_shotorg + w_shotdir * cvar("g_balance_laser_primary_radius"), FALSE, self, ANTILAG_LATENCY(self));
+ float dt;
+ dt = frametime;
- pointparticles(particleeffectnum("laser_gauntlet"), w_shotorg + w_shotdir * cvar("g_balance_laser_primary_radius"), '0 0 0', 1);
+ W_SetupShot_Range(self.owner, TRUE, 0, "", damage * dt, myradius);
+ WarpZone_traceline_antilag(self.owner, w_shotorg, w_shotend, MOVE_NORMAL, self.owner, ANTILAG_LATENCY(self.owner));
- if (trace_fraction < 1)
- Damage(trace_ent, self, self, cvar("g_balance_laser_primary_damage"), WEP_LASER | HITTYPE_SECONDARY, trace_endpos, cvar("g_balance_laser_primary_force") * w_shotdir);
+ // apply the damage
+ if(trace_ent)
+ {
+ vector force;
+ force = w_shotdir * myforce;
+ Damage (trace_ent, self.owner, self.owner, damage * dt, WEP_ELECTRO, trace_endpos, force * dt);
+ }
+
+ // draw effect
+ if(w_shotorg != self.hook_start)
+ {
+ self.SendFlags |= 2;
+ self.hook_start = w_shotorg;
+ }
+ if(w_shotend != self.hook_end)
+ {
+ self.SendFlags |= 4;
+ self.hook_end = w_shotend;
+ }
+}
+
+// experimental gauntlet
+void W_Laser_Attack2 (float issecondary)
+{
+ // only play fire sound if 0.5 sec has passed since player let go the fire button
+ if(time - self.prevgauntletfire > 0.5)
+ {
+ sound (self, CHAN_WEAPON, "weapons/gauntlet_fire.wav", VOL_BASE, ATTN_NORM);
+ }
+
+ entity beam, oldself;
+
+ self.gauntletbeam = beam = spawn();
+ beam.solid = SOLID_NOT;
+ beam.think = gauntletbeam_think;
+ beam.owner = self;
+ beam.movetype = MOVETYPE_NONE;
+ beam.shot_spread = 0;
+ beam.bot_dodge = TRUE;
+ beam.bot_dodgerating = cvar("g_balance_laser_primary_damage");
+ beam.cnt = issecondary;
+ Net_LinkEntity(beam, FALSE, 0, gauntletbeam_send);
+
+ oldself = self;
+ self = beam;
+ self.think();
+ self = oldself;
+}
+
+void LaserInit()
+{
+ weapon_action(WEP_LASER, WR_PRECACHE);
+ gauntlet_shotorigin[0] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_LASER), FALSE, FALSE, 1);
+ gauntlet_shotorigin[1] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_LASER), FALSE, FALSE, 2);
+ gauntlet_shotorigin[2] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_LASER), FALSE, FALSE, 3);
+ gauntlet_shotorigin[3] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_LASER), FALSE, FALSE, 4);
}
void spawnfunc_weapon_laser (void)
else if (req == WR_THINK)
{
if (self.BUTTON_ATCK)
- if (weapon_prepareattack(0, cvar("g_balance_laser_primary_refire")))
+ if (weapon_prepareattack(0, (cvar("g_balance_laser_primary_gauntlet") ? 0 : cvar("g_balance_laser_primary_refire"))))
{
- if(cvar("g_balance_laser_gauntlet"))
- W_Laser_Attack2();
+ if(cvar("g_balance_laser_primary_gauntlet"))
+ W_Laser_Attack2(0);
else
W_Laser_Attack(0);
weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_laser_primary_animtime"), w_ready);
{
if(cvar("g_balance_laser_secondary"))
{
- if (weapon_prepareattack(0, cvar("g_balance_laser_secondary_refire")))
+ if (weapon_prepareattack(0, (cvar("g_balance_laser_secondary_gauntlet") ? 0 : cvar("g_balance_laser_secondary_refire"))))
{
- W_Laser_Attack(1);
+ if(cvar("g_balance_laser_secondary_gauntlet"))
+ W_Laser_Attack2(1);
+ else
+ W_Laser_Attack(1);
weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_laser_secondary_animtime"), w_ready);
}
}
--- /dev/null
+void LaserInit();
+vector gauntlet_shotorigin[4];
}
}
-void W_Rocket_Explode (void)
+void W_Rocket_Explode ()
{
W_Rocket_Unregister();
self.event_damage = SUB_Null;
self.takedamage = DAMAGE_NO;
+
RadiusDamage (self, self.owner, cvar("g_balance_rocketlauncher_damage"), cvar("g_balance_rocketlauncher_edgedamage"), cvar("g_balance_rocketlauncher_radius"), world, cvar("g_balance_rocketlauncher_force"), self.projectiledeathtype, other);
if (self.owner.weapon == WEP_ROCKET_LAUNCHER)
remove (self);
}
+void W_Rocket_DoRemoteExplode ()
+{
+ W_Rocket_Unregister();
+
+ self.event_damage = SUB_Null;
+ self.takedamage = DAMAGE_NO;
+
+ RadiusDamage (self, self.owner, cvar("g_balance_rocketlauncher_remote_damage"), cvar("g_balance_rocketlauncher_remote_edgedamage"), cvar("g_balance_rocketlauncher_remote_radius"), world, cvar("g_balance_rocketlauncher_remote_force"), self.projectiledeathtype | HITTYPE_BOUNCE, world);
+
+ if (self.owner.weapon == WEP_ROCKET_LAUNCHER)
+ {
+ if(self.owner.ammo_rockets < cvar("g_balance_rocketlauncher_ammo"))
+ {
+ self.owner.cnt = WEP_ROCKET_LAUNCHER;
+ ATTACK_FINISHED(self.owner) = time;
+ self.owner.switchweapon = w_getbestweapon(self.owner);
+ }
+ if(g_laserguided_missile)
+ ATTACK_FINISHED(self.owner) = time + cvar("g_balance_rocketlauncher_refire") * W_WeaponRateFactor();
+ }
+ remove (self);
+}
+
entity FindLaserTarget(entity e, float dist_variance, float dot_variance)
{
entity head, selected;
: (vlen(NearestPointOnBox(self.owner, self.origin) - self.origin) > cvar("g_balance_rocketlauncher_radius")) // safety device
)
{
- other = world;
- self.projectiledeathtype |= HITTYPE_BOUNCE;
- W_Rocket_Explode ();
- }
- else
- {
+ W_Rocket_DoRemoteExplode();
}
}
}
W_AttachToShotorg(flash, '5 0 0');
}
+void shotgun_meleethink (void)
+{
+ // store time when we started swinging down inside self.cnt
+ if(!self.cnt)
+ self.cnt = time;
+
+ makevectors(self.owner.v_angle);
+ vector angle;
+ angle = v_forward;
+
+ // perform trace
+ float f;
+ f = (self.cnt + cvar("g_balance_shotgun_secondary_melee_time") - time) / cvar("g_balance_shotgun_secondary_melee_time") * 2 - 1;
+ vector targpos;
+ targpos = self.owner.origin + self.owner.view_ofs + angle * cvar("g_balance_shotgun_secondary_melee_range") + v_right * f * cvar("g_balance_shotgun_secondary_melee_swing") + v_up * f * cvar("g_balance_shotgun_secondary_melee_swing");
+ WarpZone_traceline_antilag(self.owner, self.owner.origin + self.owner.view_ofs, targpos, FALSE, self.owner, ANTILAG_LATENCY(self.owner));
+
+ // apply the damage, also remove self
+ if(trace_fraction < 1 && trace_ent.takedamage == DAMAGE_AIM && trace_ent.classname == "player")
+ {
+ vector force;
+ force = angle * cvar("g_balance_shotgun_secondary_force");
+ Damage (trace_ent, self.owner, self.owner, cvar("g_balance_shotgun_secondary_damage") * ((f + 1) / 2), WEP_SHOTGUN, self.owner.origin + self.owner.view_ofs, force);
+ remove(self);
+ }
+ else if(time >= self.cnt + cvar("g_balance_shotgun_secondary_melee_time")) // missed, remove ent
+ remove(self);
+ else // continue swinging the weapon in hope of hitting someone :)
+ self.nextthink = time;
+}
+
+void W_Shotgun_Attack3 (void)
+{
+ sound (self, CHAN_PROJECTILE, "weapons/shotgun_melee.wav", VOL_BASE, ATTN_NORM);
+ weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_shotgun_secondary_animtime"), w_ready);
+
+ entity meleetemp;
+ meleetemp = spawn();
+ meleetemp.owner = self;
+ meleetemp.think = shotgun_meleethink;
+ meleetemp.nextthink = time + cvar("g_balance_shotgun_secondary_melee_delay");
+}
+
// weapon frames
void shotgun_fire2_03()
{
if (self.BUTTON_ATCK2 && cvar("g_balance_shotgun_secondary"))
if (weapon_prepareattack(1, cvar("g_balance_shotgun_secondary_refire")))
{
- W_Shotgun_Attack2();
- weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_shotgun_secondary_animtime"), shotgun_fire2_02);
+ if(cvar("g_balance_shotgun_secondary_melee"))
+ {
+ // force playback of the anim by switching to another anim (that we never play) here...
+ weapon_thinkf(WFRAME_FIRE1, 0, W_Shotgun_Attack3);
+ }
+ else
+ {
+ W_Shotgun_Attack2();
+ weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_shotgun_secondary_animtime"), shotgun_fire2_02);
+ }
}
}
else if (req == WR_PRECACHE)
precache_model ("models/weapons/h_shotgun.iqm");
precache_sound ("misc/itempickup.wav");
precache_sound ("weapons/shotgun_fire.wav");
+ precache_sound ("weapons/shotgun_melee.wav");
}
else if (req == WR_SETUP)
weapon_setup(WEP_SHOTGUN);
else if (req == WR_CHECKAMMO1)
return self.ammo_shells >= cvar("g_balance_shotgun_primary_ammo");
else if (req == WR_CHECKAMMO2)
+ {
+ if(cvar("g_balance_shotgun_secondary_melee"))
+ return TRUE;
return self.ammo_shells >= cvar("g_balance_shotgun_secondary_ammo") * 3;
+ }
return TRUE;
};
#endif
+float trace_dphitcontents;
+.float dphitcontents;
+
void WarpZone_Accumulator_Clear(entity acc)
{
acc.warpzone_transform = '0 0 0';
void WarpZone_TraceBox_ThroughZone(vector org, vector mi, vector ma, vector end, float nomonsters, entity forent, entity zone, WarpZone_trace_callback_t cb)
{
+ float nomonsters_adjusted;
float frac, sol, i;
+ float contentshack;
vector o0, e0;
entity wz;
vector vf, vr, vu;
vu = v_up;
o0 = org;
e0 = end;
+
+ switch(nomonsters)
+ {
+ case MOVE_WORLDONLY:
+ case MOVE_NOTHING:
+ nomonsters_adjusted = MOVE_NOMONSTERS;
+ break;
+ default:
+ nomonsters_adjusted = nomonsters;
+ break;
+ }
+ if((contentshack = (forent.dphitcontentsmask && !(forent.dphitcontentsmask & DPCONTENTS_SOLID))))
+ forent.dphitcontentsmask |= DPCONTENTS_SOLID;
+
WarpZone_Trace_InitTransform();
// if starting in warpzone, first transform
wz = WarpZone_Find(org + mi, org + ma);
trace_ent = world;
break;
}
- tracebox(org, mi, ma, end, nomonsters, forent);
+ tracebox(org, mi, ma, end, nomonsters_adjusted, forent);
if(cb)
cb(org, trace_endpos, end);
if(sol < 0)
if(trace_fraction >= 1)
break;
if(trace_ent.classname != "trigger_warpzone")
+ {
+ if((nomonsters == MOVE_NOTHING) || ((nomonsters == MOVE_WORLDONLY) && trace_ent) || (contentshack && (trace_dphitcontents & forent.dphitcontentsmask) == DPCONTENTS_SOLID))
+ {
+ // continue the trace, ignoring this hit (we only care for warpzones)
+ org = trace_endpos + normalize(end - org);
+ continue;
+ // we cannot do an inverted trace here, as we do care for further warpzones inside that "solid" to be found
+ // otherwise, players could block entrances that way
+ }
break;
+ }
if(trace_ent == wz)
{
dprint("I transformed into the same zone again, wtf, aborting the trace\n");
}
WarpZone_MakeAllOther();
:fail
+ if(contentshack)
+ forent.dphitcontentsmask &~= DPCONTENTS_SOLID;
trace_startsolid = sol;
v_forward = vf;
v_right = vr;
vu = v_up;
o0 = e.origin;
v0 = e.velocity;
+
WarpZone_Trace_InitTransform();
// if starting in warpzone, first transform
wz = WarpZone_Find(e.origin + e.mins, e.origin + e.maxs);
void WarpZone_MakeAllSolid();
void WarpZone_MakeAllOther();
+#define MOVE_NOTHING -1
typedef void(vector start, vector hit, vector end) WarpZone_trace_callback_t; // called on every elementary trace
const var WarpZone_trace_callback_t WarpZone_trace_callback_t_null;
entity WarpZone_trace_transform; // transform accumulator during a trace