set g_balance_uzi_bulletconstant 115 // 13.1qu
// }}}
// {{{ mortar
-set g_balance_grenadelauncher_primary2secondary 0
-set g_balance_grenadelauncher_primary_sticky 0
+set g_balance_grenadelauncher_primary_type 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_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_primary_damageforcescale 4
+set g_balance_grenadelauncher_primary_bouncefactor 0.5
+set g_balance_grenadelauncher_primary_bouncestop 0.075
+set g_balance_grenadelauncher_primary_remote_minbouncecnt 0
+
+set g_balance_grenadelauncher_secondary_type 1
set g_balance_grenadelauncher_secondary_damage 70
set g_balance_grenadelauncher_secondary_edgedamage 38
set g_balance_grenadelauncher_secondary_force 400
set g_balance_grenadelauncher_secondary_damageforcescale 4
set g_balance_grenadelauncher_secondary_bouncefactor 0.5
set g_balance_grenadelauncher_secondary_bouncestop 0.075
+set g_balance_grenadelauncher_secondary_remote_detonateprimary 0
// }}}
// {{{ electro
set g_balance_electro_lightning 0
set g_balance_electro_primary_falloff_maxdist 850
set g_balance_electro_primary_falloff_halflifedist 425
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_nex_secondary_damagefalloff_maxdist 0
set g_balance_nex_secondary_damagefalloff_halflife 0
set g_balance_nex_secondary_damagefalloff_forcehalflife 0
+
+set g_balance_nex_velocitydependent_halflife 0
+set g_balance_nex_velocitydependent_minspeed 400
+set g_balance_nex_velocitydependent_maxspeed 1000
// }}}
// {{{ minstanex
set g_balance_minstanex_refire 1
--- /dev/null
+////2.4.2 weapons (with some tweaks) VS balanceLeeStricklin
+
+// {{{ weapon replacement
+// NOTE: this only replaces weapons on the map
+// use g_start_weapon_* to also replace the on-startup weapons!
+// example: g_weaponreplace_nex "nex minstanex", then Nexes become MinstaNexes 50% of the times
+// set the cvars to "0" to totally disable a weapon
+set sv_q3acompat_machineshotgunswap 0 "shorthand for swapping uzi and shotgun"
+// }}}
+
+// {{{ starting gear
+set g_start_weapon_laser -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_shotgun -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_uzi -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_grenadelauncher -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_electro -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_crylink -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_nex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_hagar -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_rocketlauncher -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_minstanex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_porto -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_hook -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_hlac 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 -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_tuba -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_start_weapon_fireball 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 -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default, -2 = provide the weapon in ca and lms"
+set g_balance_health_start 200
+set g_balance_armor_start 115
+set g_start_ammo_shells 45
+set g_start_ammo_nails 0
+set g_start_ammo_rockets 0
+set g_start_ammo_cells 0
+set g_start_ammo_fuel 0
+set g_warmup_start_health 200 "starting values when being in warmup-stage"
+set g_warmup_start_armor 100 "starting values when being in warmup-stage"
+set g_warmup_start_ammo_shells 50 "starting values when being in warmup-stage"
+set g_warmup_start_ammo_nails 150 "starting values when being in warmup-stage"
+set g_warmup_start_ammo_rockets 50 "starting values when being in warmup-stage"
+set g_warmup_start_ammo_cells 50 "starting values when being in warmup-stage"
+set g_warmup_start_ammo_fuel 0 "starting values when being in warmup-stage"
+set g_lms_start_health 200
+set g_lms_start_armor 100
+set g_lms_start_ammo_shells 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
+set g_balance_nix_ammo_shells 15
+set g_balance_nix_ammo_nails 45
+set g_balance_nix_ammo_rockets 15
+set g_balance_nix_ammo_cells 15
+set g_balance_nix_ammo_fuel 0
+set g_balance_nix_ammoincr_shells 2
+set g_balance_nix_ammoincr_nails 6
+set g_balance_nix_ammoincr_rockets 2
+set g_balance_nix_ammoincr_cells 2
+set g_balance_nix_ammoincr_fuel 2
+// }}}
+
+// {{{ pickup items
+// Ammo caps copied from balanceFruit
+set g_pickup_ammo_anyway 0
+set g_pickup_weapons_anyway 1
+set g_pickup_shells 20
+set g_pickup_shells_max 45
+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
+set g_pickup_fuel_jetpack 50
+set g_pickup_fuel_max 999
+set g_pickup_armorsmall 10
+set g_pickup_armorsmall_max 250
+set g_pickup_armorsmall_anyway 1
+set g_pickup_armormedium 25
+set g_pickup_armormedium_max 250
+set g_pickup_armormedium_anyway 0
+set g_pickup_armorbig 50
+set g_pickup_armorbig_max 250
+set g_pickup_armorbig_anyway 0
+set g_pickup_armorlarge 100
+set g_pickup_armorlarge_max 250
+set g_pickup_armorlarge_anyway 0
+set g_pickup_healthsmall 10
+set g_pickup_healthsmall_max 300
+set g_pickup_healthsmall_anyway 1
+set g_pickup_healthmedium 25
+set g_pickup_healthmedium_max 300
+set g_pickup_healthmedium_anyway 0
+set g_pickup_healthlarge 50
+set g_pickup_healthlarge_max 300
+set g_pickup_healthlarge_anyway 0
+set g_pickup_healthmega 100
+set g_pickup_healthmega_max 300
+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 120
+set g_pickup_respawntime_weapon 15
+set g_pickup_respawntime_ammo 15
+set g_pickup_respawntimejitter_short 0
+set g_pickup_respawntimejitter_medium 0
+set g_pickup_respawntimejitter_long 0
+set g_pickup_respawntimejitter_powerup 10
+set g_pickup_respawntimejitter_weapon 0
+set g_pickup_respawntimejitter_ammo 0
+// }}}
+
+// {{{ regen/rot
+set g_balance_health_regen 0
+set g_balance_health_regenlinear 5
+set g_balance_pause_health_regen 5
+set g_balance_pause_health_regen_spawn 0
+set g_balance_health_rot 0
+set g_balance_health_rotlinear 5
+set g_balance_pause_health_rot 3
+set g_balance_pause_health_rot_spawn 1
+set g_balance_health_regenstable 100
+set g_balance_health_rotstable 100
+set g_balance_health_limit 300
+set g_balance_armor_regen 0
+set g_balance_armor_regenlinear 0
+set g_balance_armor_rot 0
+set g_balance_armor_rotlinear 4.86
+set g_balance_pause_armor_rot 1
+set g_balance_pause_armor_rot_spawn 1
+set g_balance_armor_regenstable 100
+set g_balance_armor_rotstable 200
+set g_balance_armor_limit 250
+set g_balance_armor_blockpercent 0.6
+set g_balance_fuel_regen 0.1 "fuel regeneration (only applies if the player owns IT_FUEL_REGEN)"
+set g_balance_fuel_regenlinear 0
+set g_balance_pause_fuel_regen 2 // other than this, fuel uses the health regen counter
+set g_balance_fuel_rot 0.05
+set g_balance_fuel_rotlinear 0
+set g_balance_pause_fuel_rot 5
+set g_balance_pause_fuel_rot_spawn 10
+set g_balance_fuel_regenstable 100
+set g_balance_fuel_rotstable 999
+set g_balance_fuel_limit 999
+// }}}
+
+// {{{ misc
+set g_balance_selfdamagepercent 0.6
+set g_balance_weaponswitchdelay 0.15
+set g_weaponspeedfactor 1 "weapon projectile speed multiplier"
+set g_weaponratefactor 1 "weapon fire rate multiplier"
+set g_weapondamagefactor 1 "weapon damage multiplier"
+set g_weaponforcefactor 1 "weapon force multiplier"
+set g_weaponspreadfactor 1 "weapon spread multiplier"
+set g_balance_firetransfer_time 0.9
+set g_balance_firetransfer_damage 0.8
+set g_throughfloor_damage 0.4
+set g_throughfloor_force 0.7
+set g_projectiles_newton_style 2
+// possible values:
+// 0: absolute velocity projectiles (like Quake)
+// 1: relative velocity projectiles, "Newtonian" (like Tribes 2)
+// 2: relative velocity projectiles, but aim is precorrected so projectiles hit the crosshair (note: strafe rockets then are SLOWER than ones shot while standing, happens in 1 too when aiming correctly which is hard)
+// 3: absolute velocity + player velocity component in shot direction (note: does NOT yield the right relative velocity, but may be good enough, but it is somewhat prone to sniper rockets)
+// 4: just add the player velocity length to the absolute velocity (tZork's sniper rockets)
+set g_projectiles_newton_style_2_minfactor 0.8
+set g_projectiles_newton_style_2_maxfactor 1.5
+set g_projectiles_spread_style 0
+// possible values:
+// 0: forward + solid sphere (like Quake) - varies velocity
+// 1: forward + flattened solid sphere
+// 2: forward + solid circle
+// 3: forward + normal distribution 3D - varies velocity
+// 4: forward + normal distribution on a plane
+// 5: forward + circle with 1-r falloff
+// 6: forward + circle with 1-r^2 falloff
+// 7: forward + circle with (1-r)(2-r) falloff
+set g_balance_falldamage_deadminspeed 150
+set g_balance_falldamage_minspeed 1400
+set g_balance_falldamage_factor 0.15
+set g_balance_falldamage_maxdamage 25
+// }}}
+
+// {{{ powerups
+set g_balance_powerup_invincible_takedamage 0.2
+set g_balance_powerup_invincible_time 30
+set g_balance_powerup_strength_damage 3
+set g_balance_powerup_strength_force 3
+set g_balance_powerup_strength_time 30
+set g_balance_powerup_strength_selfdamage 1.5
+set g_balance_powerup_strength_selfforce 1.5
+// }}}
+
+// {{{ jetpack/hook
+set g_jetpack_antigravity 0.8 "factor of gravity compensation of the jetpack"
+set g_jetpack_acceleration_side 1200 "acceleration of the jetpack in xy direction"
+set g_jetpack_acceleration_up 600 "acceleration of the jetpack in z direction (note: you have to factor in gravity here, if antigravity is not 1)"
+set g_jetpack_maxspeed_side 1200 "max speed of the jetpack in xy direction"
+set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
+set g_jetpack_fuel 8 "fuel per second for jetpack"
+set g_jetpack_attenuation 2 "jetpack sound attenuation"
+
+set g_grappling_hook_tarzan 2 // 2: can also pull players
+set g_balance_grapplehook_speed_fly 1800
+set g_balance_grapplehook_speed_pull 2000
+set g_balance_grapplehook_force_rubber 2000
+set g_balance_grapplehook_force_rubber_overstretch 1000
+set g_balance_grapplehook_length_min 50
+set g_balance_grapplehook_stretch 50
+set g_balance_grapplehook_airfriction 0.2
+set g_balance_grapplehook_health 130
+// }}}
+
+// {{{ weapon properties
+// {{{ laser
+set g_balance_laser_primary_damage 25
+set g_balance_laser_primary_edgedamage 10
+set g_balance_laser_primary_force 258
+set g_balance_laser_primary_radius 70
+set g_balance_laser_primary_speed 12000
+set g_balance_laser_primary_spread 0
+set g_balance_laser_primary_refire 0.7
+set g_balance_laser_primary_animtime 0.3
+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_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_force 375
+set g_balance_laser_secondary_radius 70
+set g_balance_laser_secondary_speed 12000
+set g_balance_laser_secondary_spread 0
+set g_balance_laser_secondary_refire 0.7
+set g_balance_laser_secondary_animtime 0.3
+set g_balance_laser_secondary_lifetime 30
+set g_balance_laser_secondary_shotangle -90
+set g_balance_laser_secondary_delay 0
+set g_balance_laser_secondary_gauntlet 0
+// }}}
+// {{{ shotgun
+set g_balance_shotgun_primary_bullets 5
+set g_balance_shotgun_primary_damage 12
+set g_balance_shotgun_primary_force 40
+set g_balance_shotgun_primary_spread 0.08
+set g_balance_shotgun_primary_refire 0.5
+set g_balance_shotgun_primary_animtime 0.2
+set g_balance_shotgun_primary_ammo 1
+set g_balance_shotgun_primary_speed 12000
+set g_balance_shotgun_primary_bulletconstant 75 // 3.8qu
+set g_balance_shotgun_secondary 1
+set g_balance_shotgun_secondary_melee_delay 0.35 // match the anim
+set g_balance_shotgun_secondary_melee_range 85
+set g_balance_shotgun_secondary_melee_swing 50
+set g_balance_shotgun_secondary_melee_time 0.1
+set g_balance_shotgun_secondary_damage 84
+set g_balance_shotgun_secondary_force 147
+set g_balance_shotgun_secondary_refire 1.1
+set g_balance_shotgun_secondary_animtime 1
+// }}}
+// {{{ uzi
+set g_balance_uzi_first 1
+set g_balance_uzi_first_damage 26
+set g_balance_uzi_first_force -30
+set g_balance_uzi_first_spread 0.01
+set g_balance_uzi_first_refire 0.2
+set g_balance_uzi_first_ammo 1
+set g_balance_uzi_sustained_damage 17
+set g_balance_uzi_sustained_force 27
+set g_balance_uzi_sustained_spread 0.05
+set g_balance_uzi_sustained_refire 0.1
+set g_balance_uzi_sustained_ammo 1
+set g_balance_uzi_speed 18000
+set g_balance_uzi_bulletconstant 300 // 13.1qu
+// }}}
+// {{{ mortar
+set g_balance_grenadelauncher_primary_type 0
+set g_balance_grenadelauncher_primary_damage 65
+set g_balance_grenadelauncher_primary_edgedamage 35
+set g_balance_grenadelauncher_primary_force 310
+set g_balance_grenadelauncher_primary_radius 140
+set g_balance_grenadelauncher_primary_speed 2000
+set g_balance_grenadelauncher_primary_speed_up 200
+set g_balance_grenadelauncher_primary_speed_z 0
+set g_balance_grenadelauncher_primary_spread 0
+set g_balance_grenadelauncher_primary_lifetime 30
+set g_balance_grenadelauncher_primary_lifetime2 0.65
+set g_balance_grenadelauncher_primary_refire 0.7
+set g_balance_grenadelauncher_primary_animtime 0.3
+set g_balance_grenadelauncher_primary_ammo 2
+set g_balance_grenadelauncher_primary_health 72
+set g_balance_grenadelauncher_primary_damageforcescale 0
+set g_balance_grenadelauncher_primary_bouncefactor 0.7
+set g_balance_grenadelauncher_primary_bouncestop 0.12
+set g_balance_grenadelauncher_primary_remote_minbouncecnt 0
+
+set g_balance_grenadelauncher_secondary_type 1
+set g_balance_grenadelauncher_secondary_damage 65
+set g_balance_grenadelauncher_secondary_edgedamage 35
+set g_balance_grenadelauncher_secondary_force 320
+set g_balance_grenadelauncher_secondary_radius 140
+set g_balance_grenadelauncher_secondary_speed 1400
+set g_balance_grenadelauncher_secondary_speed_up 200
+set g_balance_grenadelauncher_secondary_speed_z 0
+set g_balance_grenadelauncher_secondary_spread 0
+set g_balance_grenadelauncher_secondary_lifetime 2.5
+set g_balance_grenadelauncher_secondary_lifetime2 1
+set g_balance_grenadelauncher_secondary_refire 0.6
+set g_balance_grenadelauncher_secondary_animtime 0.3
+set g_balance_grenadelauncher_secondary_ammo 2
+set g_balance_grenadelauncher_secondary_health 40
+set g_balance_grenadelauncher_secondary_damageforcescale 0
+set g_balance_grenadelauncher_secondary_bouncefactor 0.7
+set g_balance_grenadelauncher_secondary_bouncestop 0.12
+set g_balance_grenadelauncher_secondary_remote_detonateprimary 0
+// }}}
+// {{{ electro
+set g_balance_electro_lightning 0
+set g_balance_electro_primary_damage 55
+set g_balance_electro_primary_edgedamage 5
+set g_balance_electro_primary_force 267
+set g_balance_electro_primary_force_up 125
+set g_balance_electro_primary_radius 150
+set g_balance_electro_primary_comboradius 75
+set g_balance_electro_primary_speed 2000
+set g_balance_electro_primary_spread 0
+set g_balance_electro_primary_lifetime 30
+set g_balance_electro_primary_refire 0.78
+set g_balance_electro_primary_animtime 0.4
+set g_balance_electro_primary_ammo 2
+set g_balance_electro_primary_range 800
+set g_balance_electro_primary_falloff_mindist 255
+set g_balance_electro_primary_falloff_maxdist 850
+set g_balance_electro_primary_falloff_halflifedist 0
+set g_balance_electro_secondary_damage 60
+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_lifetime 3
+set g_balance_electro_secondary_spread 0.05
+set g_balance_electro_secondary_refire 0.2
+set g_balance_electro_secondary_refire2 1
+set g_balance_electro_secondary_animtime 0.3
+set g_balance_electro_secondary_ammo 2
+set g_balance_electro_secondary_health 10
+set g_balance_electro_secondary_damageforcescale 4
+set g_balance_electro_secondary_count 3
+set g_balance_electro_combo_damage 70
+set g_balance_electro_combo_edgedamage 0
+set g_balance_electro_combo_force 200
+set g_balance_electro_combo_radius 250
+set g_balance_electro_combo_comboradius 70
+set g_balance_electro_combo_speed 400
+// }}}
+// {{{ crylink
+set g_balance_crylink_primary_damage 23
+set g_balance_crylink_primary_edgedamage 0
+set g_balance_crylink_primary_force -55
+set g_balance_crylink_primary_radius 80
+set g_balance_crylink_primary_speed 6950
+set g_balance_crylink_primary_spread 0.03
+set g_balance_crylink_primary_shots 4
+set g_balance_crylink_primary_bounces 2
+set g_balance_crylink_primary_refire 0.4
+set g_balance_crylink_primary_animtime 0.30008
+set g_balance_crylink_primary_ammo 3
+set g_balance_crylink_primary_bouncedamagefactor 0.2
+
+set g_balance_crylink_primary_middle_lifetime 5 // range: 10000 full, fades to 20000
+set g_balance_crylink_primary_middle_fadetime 5
+set g_balance_crylink_primary_star_lifetime 2 // range: 800 full, fades to 1300
+set g_balance_crylink_primary_star_fadetime 0.25
+set g_balance_crylink_primary_other_lifetime 2 // range: 800 full, fades to 1300
+set g_balance_crylink_primary_other_fadetime 0.25
+
+set g_balance_crylink_secondary 1
+set g_balance_crylink_secondary_damage 19
+set g_balance_crylink_secondary_edgedamage 0
+set g_balance_crylink_secondary_force -55
+set g_balance_crylink_secondary_radius 3
+set g_balance_crylink_secondary_speed 6950
+set g_balance_crylink_secondary_spread 0.08
+set g_balance_crylink_secondary_shots 7
+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 3
+set g_balance_crylink_secondary_bouncedamagefactor 0.5
+
+set g_balance_crylink_secondary_middle_lifetime 5 // range: 10000 full, fades to 10000
+set g_balance_crylink_secondary_middle_fadetime 5
+set g_balance_crylink_secondary_line_lifetime 2 // range: 4000 full, fades to 8000
+set g_balance_crylink_secondary_line_fadetime 2
+// }}}
+// {{{ nex
+set g_balance_nex_primary_ammo 13
+set g_balance_nex_primary_animtime 0.3
+set g_balance_nex_primary_damage 78
+set g_balance_nex_primary_force 600
+set g_balance_nex_primary_refire 1.505
+set g_balance_nex_primary_damagefalloff_mindist 9999999
+set g_balance_nex_primary_damagefalloff_maxdist 9999999
+set g_balance_nex_primary_damagefalloff_halflife 9999999
+set g_balance_nex_primary_damagefalloff_forcehalflife 9999999
+
+set g_balance_nex_secondary 0
+set g_balance_nex_secondary_damage 80
+set g_balance_nex_secondary_force -500
+set g_balance_nex_secondary_refire 1.25
+set g_balance_nex_secondary_animtime 0.75
+set g_balance_nex_secondary_ammo 5
+set g_balance_nex_secondary_damagefalloff_mindist 9999999
+set g_balance_nex_secondary_damagefalloff_maxdist 9999999
+set g_balance_nex_secondary_damagefalloff_halflife 9999999
+set g_balance_nex_secondary_damagefalloff_forcehalflife 9999999
+
+set g_balance_nex_velocitydependent_halflife 0
+set g_balance_nex_velocitydependent_minspeed 400
+set g_balance_nex_velocitydependent_maxspeed 1000
+// }}}
+// {{{ minstanex
+set g_balance_minstanex_refire 1
+set g_balance_minstanex_animtime 0.278
+set g_balance_minstanex_ammo 10
+// }}}
+// {{{ hagar
+set g_balance_hagar_primary_damage 43
+set g_balance_hagar_primary_edgedamage 15
+set g_balance_hagar_primary_force 94
+set g_balance_hagar_primary_radius 70
+set g_balance_hagar_primary_spread 0.010
+set g_balance_hagar_primary_speed 3000
+set g_balance_hagar_primary_lifetime 30
+set g_balance_hagar_primary_refire 0.15
+set g_balance_hagar_primary_ammo 2
+set g_balance_hagar_secondary 1
+set g_balance_hagar_secondary_damage 43
+set g_balance_hagar_secondary_edgedamage 15
+set g_balance_hagar_secondary_force 100
+set g_balance_hagar_secondary_radius 70
+set g_balance_hagar_secondary_spread 0.015
+set g_balance_hagar_secondary_speed 1400
+set g_balance_hagar_secondary_lifetime_min 5
+set g_balance_hagar_secondary_lifetime_rand 0
+set g_balance_hagar_secondary_refire 0.15
+set g_balance_hagar_secondary_ammo 2
+// }}}
+// {{{ rocketlauncher
+set g_balance_rocketlauncher_damage 65
+set g_balance_rocketlauncher_edgedamage 25
+set g_balance_rocketlauncher_force 360
+set g_balance_rocketlauncher_radius 185
+set g_balance_rocketlauncher_speed 900
+set g_balance_rocketlauncher_speedaccel 0
+set g_balance_rocketlauncher_speedstart 850
+set g_balance_rocketlauncher_lifetime 30
+set g_balance_rocketlauncher_refire 1
+set g_balance_rocketlauncher_animtime 0.3
+set g_balance_rocketlauncher_ammo 7
+set g_balance_rocketlauncher_health 40
+set g_balance_rocketlauncher_damageforcescale 4
+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 65 // max degrees per second
+set g_balance_rocketlauncher_guideratedelay 0.01 // immediate
+set g_balance_rocketlauncher_guidegoal 512 // goal distance for (non-laser) guiding (higher = less control, lower = erratic)
+set g_balance_rocketlauncher_guidedelay 0.15 // delay before guiding kicks in
+set g_balance_rocketlauncher_guidestop 0 // stop guiding when firing again
+set g_balance_rocketlauncher_laserguided_speed 1000 //650
+set g_balance_rocketlauncher_laserguided_speedaccel 0
+set g_balance_rocketlauncher_laserguided_speedstart 1000
+set g_balance_rocketlauncher_laserguided_turnrate 0.60 //0.5
+set g_balance_rocketlauncher_laserguided_allow_steal 1
+set g_balance_rocketlauncher_remote_damage 120
+set g_balance_rocketlauncher_remote_edgedamage 46
+set g_balance_rocketlauncher_remote_radius 185
+set g_balance_rocketlauncher_remote_force 590
+// }}}
+// {{{ 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_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_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_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 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...
+set g_balance_hook_secondary_animtime 0.3 // good shoot anim
+set g_balance_hook_secondary_power 3 // effect behaves like a square function
+set g_balance_hook_secondary_duration 1.5 // effect runs for three seconds
+// }}}
+// {{{ hlac
+set g_balance_hlac_primary_spread_min 0.01
+set g_balance_hlac_primary_spread_max 0.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 17
+set g_balance_hlac_primary_edgedamage 10
+set g_balance_hlac_primary_force 45
+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.1
+set g_balance_hlac_primary_animtime 0.3
+set g_balance_hlac_primary_ammo 3
+
+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 18
+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_lifetime 5
+
+set g_balance_hlac_secondary_refire 1
+set g_balance_hlac_secondary_animtime 0.3
+set g_balance_hlac_secondary_ammo 11
+set g_balance_hlac_secondary_shots 6
+// }}}
+// {{{ campingrifle
+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_tracer 1
+set g_balance_campingrifle_primary_damage 75
+set g_balance_campingrifle_primary_headshotaddeddamage 90
+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.7
+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 // require same cooldown as secondary, note it's smaller than primary refire time
+set g_balance_campingrifle_primary_bullethail 0 // empty magazine on shot
+set g_balance_campingrifle_secondary 1
+set g_balance_campingrifle_secondary_damage 40
+set g_balance_campingrifle_secondary_headshotaddeddamage 20
+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.0006
+set g_balance_campingrifle_secondary_animtime 0.1
+set g_balance_campingrifle_secondary_ammo 10
+set g_balance_campingrifle_secondary_bulletconstant 130 // 18.3qu
+set g_balance_campingrifle_secondary_burstcost 0
+set g_balance_campingrifle_secondary_bullethail 0
+// }}}
+// {{{ tuba
+set g_balance_tuba_refire 0.05
+set g_balance_tuba_animtime 0.05
+set g_balance_tuba_attenuation 0.5
+set g_balance_tuba_volume 1
+set g_balance_tuba_fadetime 0.25
+set g_balance_tuba_damage 5
+set g_balance_tuba_edgedamage 0
+set g_balance_tuba_radius 200
+set g_balance_tuba_force 40
+// }}}
+// {{{ fireball
+set g_balance_fireball_primary_ammo 5
+set g_balance_fireball_primary_animtime 0.3
+set g_balance_fireball_primary_bfgdamage 0
+set g_balance_fireball_primary_bfgforce 0
+set g_balance_fireball_primary_bfgradius 0
+set g_balance_fireball_primary_damage 40
+set g_balance_fireball_primary_damageforcescale 4
+set g_balance_fireball_primary_edgedamage 0
+set g_balance_fireball_primary_force 100
+set g_balance_fireball_primary_health 9999
+set g_balance_fireball_primary_laserburntime 0.5
+set g_balance_fireball_primary_laserdamage 30
+set g_balance_fireball_primary_laseredgedamage 20
+set g_balance_fireball_primary_laserradius 110
+set g_balance_fireball_primary_lifetime 7
+set g_balance_fireball_primary_radius 20
+set g_balance_fireball_primary_refire 2
+set g_balance_fireball_primary_refire2 1.5
+set g_balance_fireball_primary_speed 900
+set g_balance_fireball_primary_spread 0
+set g_balance_fireball_secondary_ammo 25
+set g_balance_fireball_secondary_animtime 0.15
+set g_balance_fireball_secondary_damage 150
+set g_balance_fireball_secondary_damageforcescale 4
+set g_balance_fireball_secondary_damagetime 3
+set g_balance_fireball_secondary_force 700
+set g_balance_fireball_secondary_laserburntime 0.5
+set g_balance_fireball_secondary_laserdamage 30
+set g_balance_fireball_secondary_laseredgedamage 20
+set g_balance_fireball_secondary_laserradius 256
+set g_balance_fireball_secondary_lifetime 15
+set g_balance_fireball_secondary_refire 0
+set g_balance_fireball_secondary_speed 650
+set g_balance_fireball_secondary_speed_up 0
+set g_balance_fireball_secondary_speed_z 0
+set g_balance_fireball_secondary_spread 0
+// }}}
+// {{{ seeker
+set g_balance_seeker_flac_ammo 0.5
+set g_balance_seeker_flac_animtime 0.1
+set g_balance_seeker_flac_damage 15
+set g_balance_seeker_flac_edgedamage 10
+set g_balance_seeker_flac_force 50
+set g_balance_seeker_flac_lifetime 0.1
+set g_balance_seeker_flac_lifetime_rand 0.05
+set g_balance_seeker_flac_radius 100
+set g_balance_seeker_flac_refire 0.1
+set g_balance_seeker_flac_speed 3000
+set g_balance_seeker_flac_speed_up 1000
+set g_balance_seeker_flac_speed_z 0
+set g_balance_seeker_flac_spread 0.4
+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 8
+set g_balance_seeker_missile_damage 15
+set g_balance_seeker_missile_damageforcescale 4
+set g_balance_seeker_missile_decel 0.9
+set g_balance_seeker_missile_delay 0.25
+set g_balance_seeker_missile_edgedamage 10
+set g_balance_seeker_missile_force 250
+set g_balance_seeker_missile_health 5
+set g_balance_seeker_missile_lifetime 15
+set g_balance_seeker_missile_proxy 0
+set g_balance_seeker_missile_proxy_delay 0.2
+set g_balance_seeker_missile_proxy_maxrange 45
+set g_balance_seeker_missile_radius 80
+set g_balance_seeker_missile_refire 0.5
+set g_balance_seeker_missile_smart 1
+set g_balance_seeker_missile_smart_mindist 800
+set g_balance_seeker_missile_smart_trace_max 2500
+set g_balance_seeker_missile_smart_trace_min 1000
+set g_balance_seeker_missile_speed 700
+set g_balance_seeker_missile_speed_accel 0
+set g_balance_seeker_missile_speed_up 300
+set g_balance_seeker_missile_speed_z 0
+set g_balance_seeker_missile_speed_max 1250
+set g_balance_seeker_missile_spread 0
+set g_balance_seeker_missile_turnrate 0.65
+set g_balance_seeker_tag_ammo 1
+set g_balance_seeker_tag_animtime 0.3
+set g_balance_seeker_tag_damageforcescale 4
+set g_balance_seeker_tag_health 5
+set g_balance_seeker_tag_lifetime 15
+set g_balance_seeker_tag_refire 0.7
+set g_balance_seeker_tag_speed 9000
+set g_balance_seeker_tag_spread 0
+// End new seeker
set g_balance_uzi_bulletconstant 115 // 13.1qu
// }}}
// {{{ mortar
-set g_balance_grenadelauncher_primary2secondary 0
-set g_balance_grenadelauncher_primary_sticky 0
+set g_balance_grenadelauncher_primary_type 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_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_primary_damageforcescale 4
+set g_balance_grenadelauncher_primary_bouncefactor 0.5
+set g_balance_grenadelauncher_primary_bouncestop 0.075
+set g_balance_grenadelauncher_primary_remote_minbouncecnt 0
+set g_balance_grenadelauncher_secondary_type 1
set g_balance_grenadelauncher_secondary_damage 70
set g_balance_grenadelauncher_secondary_edgedamage 38
set g_balance_grenadelauncher_secondary_force 400
set g_balance_grenadelauncher_secondary_damageforcescale 4
set g_balance_grenadelauncher_secondary_bouncefactor 0.5
set g_balance_grenadelauncher_secondary_bouncestop 0.075
+set g_balance_grenadelauncher_secondary_remote_detonateprimary 0
// }}}
// {{{ electro
set g_balance_electro_lightning 0
set g_balance_electro_primary_falloff_maxdist 850
set g_balance_electro_primary_falloff_halflifedist 425
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_nex_secondary_damagefalloff_maxdist 3000
set g_balance_nex_secondary_damagefalloff_halflife 1500
set g_balance_nex_secondary_damagefalloff_forcehalflife 1500
+
+set g_balance_nex_velocitydependent_halflife 0
+set g_balance_nex_velocitydependent_minspeed 400
+set g_balance_nex_velocitydependent_maxspeed 1000
// }}}
// {{{ minstanex
set g_balance_minstanex_refire 1
set g_balance_uzi_bulletconstant 115 // 13.1qu
// }}}
// {{{ mortar
-set g_balance_grenadelauncher_primary2secondary 0
-set g_balance_grenadelauncher_primary_sticky 0
+set g_balance_grenadelauncher_primary_type 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_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_primary_damageforcescale 4
+set g_balance_grenadelauncher_primary_bouncefactor 0.5
+set g_balance_grenadelauncher_primary_bouncestop 0.075
+set g_balance_grenadelauncher_primary_remote_minbouncecnt 0
+
+set g_balance_grenadelauncher_secondary_type 1
set g_balance_grenadelauncher_secondary_damage 60
set g_balance_grenadelauncher_secondary_edgedamage 38
set g_balance_grenadelauncher_secondary_force 400
set g_balance_grenadelauncher_secondary_damageforcescale 4
set g_balance_grenadelauncher_secondary_bouncefactor 0.5
set g_balance_grenadelauncher_secondary_bouncestop 0.075
+set g_balance_grenadelauncher_secondary_remote_detonateprimary 1
// }}}
// {{{ electro
set g_balance_electro_lightning 0
set g_balance_electro_primary_falloff_maxdist 850
set g_balance_electro_primary_falloff_halflifedist 425
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_nex_secondary_damagefalloff_maxdist 3000
set g_balance_nex_secondary_damagefalloff_halflife 1500
set g_balance_nex_secondary_damagefalloff_forcehalflife 1500
+
+set g_balance_nex_velocitydependent_halflife 0
+set g_balance_nex_velocitydependent_minspeed 400
+set g_balance_nex_velocitydependent_maxspeed 1000
// }}}
// {{{ minstanex
set g_balance_minstanex_refire 1
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 9
+set g_balance_uzi_sustained_damage 12
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_refire 0.1
set g_balance_uzi_sustained_ammo 1
set g_balance_uzi_speed 18000
set g_balance_uzi_bulletconstant 115 // 13.1qu
// }}}
// {{{ mortar // TODO
-set g_balance_grenadelauncher_primary2secondary 0
-set g_balance_grenadelauncher_primary_sticky 0
+set g_balance_grenadelauncher_primary_type 1
set g_balance_grenadelauncher_primary_damage 60
set g_balance_grenadelauncher_primary_edgedamage 25
set g_balance_grenadelauncher_primary_force 300
set g_balance_grenadelauncher_primary_radius 100
-set g_balance_grenadelauncher_primary_speed 1400
+set g_balance_grenadelauncher_primary_speed 1000
set g_balance_grenadelauncher_primary_speed_up 225
set g_balance_grenadelauncher_primary_speed_z 0
set g_balance_grenadelauncher_primary_spread 0
set g_balance_grenadelauncher_primary_animtime 0.4
set g_balance_grenadelauncher_primary_ammo 2
set g_balance_grenadelauncher_primary_health 72
-set g_balance_grenadelauncher_secondary_sticky 1
+set g_balance_grenadelauncher_primary_damageforcescale 0
+set g_balance_grenadelauncher_primary_bouncefactor 0.5
+set g_balance_grenadelauncher_primary_bouncestop 0.12
+set g_balance_grenadelauncher_primary_remote_minbouncecnt 1
+
+set g_balance_grenadelauncher_secondary_type 0
set g_balance_grenadelauncher_secondary_damage 90
set g_balance_grenadelauncher_secondary_edgedamage 32
set g_balance_grenadelauncher_secondary_force 300
set g_balance_grenadelauncher_secondary_ammo 2
set g_balance_grenadelauncher_secondary_health 40
set g_balance_grenadelauncher_secondary_damageforcescale 0
-set g_balance_grenadelauncher_secondary_bouncefactor 0.7
+set g_balance_grenadelauncher_secondary_bouncefactor 0.5
set g_balance_grenadelauncher_secondary_bouncestop 0.12
+set g_balance_grenadelauncher_secondary_remote_detonateprimary 1
// }}}
// {{{ electro // TODO
set g_balance_electro_lightning 1
-set g_balance_electro_primary_damage 90
+set g_balance_electro_primary_damage 85
set g_balance_electro_primary_edgedamage 0
-set g_balance_electro_primary_force 550
+set g_balance_electro_primary_force 425
set g_balance_electro_primary_force_up 125
set g_balance_electro_primary_radius 850
set g_balance_electro_primary_comboradius 75
set g_balance_electro_primary_falloff_maxdist 850
set g_balance_electro_primary_falloff_halflifedist 425
set g_balance_electro_secondary_damage 25
-set g_balance_electro_secondary_spread 0
set g_balance_electro_secondary_edgedamage 0
set g_balance_electro_secondary_force 100
set g_balance_electro_secondary_radius 100
set g_balance_crylink_secondary_line_fadetime 2
// }}}
// {{{ nex
-set g_balance_nex_primary_damage 80
-set g_balance_nex_primary_force 400
-set g_balance_nex_primary_refire 1.25
+set g_balance_nex_primary_damage 125
+set g_balance_nex_primary_force 500
+set g_balance_nex_primary_refire 1
set g_balance_nex_primary_animtime 0.75
set g_balance_nex_primary_ammo 5
-set g_balance_nex_primary_damagefalloff_mindist 0
-set g_balance_nex_primary_damagefalloff_maxdist 4000
+set g_balance_nex_primary_damagefalloff_mindist 500
+set g_balance_nex_primary_damagefalloff_maxdist 4500
set g_balance_nex_primary_damagefalloff_halflife 2000
set g_balance_nex_primary_damagefalloff_forcehalflife 2000
set g_balance_nex_secondary 1
-set g_balance_nex_secondary_damage 80
-set g_balance_nex_secondary_force -500
-set g_balance_nex_secondary_refire 1.25
+set g_balance_nex_secondary_damage 125
+set g_balance_nex_secondary_force -700
+set g_balance_nex_secondary_refire 1
set g_balance_nex_secondary_animtime 0.75
set g_balance_nex_secondary_ammo 5
-set g_balance_nex_secondary_damagefalloff_mindist 0
-set g_balance_nex_secondary_damagefalloff_maxdist 4000
+set g_balance_nex_secondary_damagefalloff_mindist 500
+set g_balance_nex_secondary_damagefalloff_maxdist 4500
set g_balance_nex_secondary_damagefalloff_halflife 2000
set g_balance_nex_secondary_damagefalloff_forcehalflife 2000
+
+set g_balance_nex_velocitydependent_halflife -500
+set g_balance_nex_velocitydependent_minspeed 400
+set g_balance_nex_velocitydependent_maxspeed 1000
// }}}
// {{{ minstanex
set g_balance_minstanex_refire 1.25
set g_balance_campingrifle_auto_reload_after_changing_weapons 0
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 50
+set g_balance_campingrifle_primary_damage 75
+set g_balance_campingrifle_primary_headshotaddeddamage 75
set g_balance_campingrifle_primary_spread 0
set g_balance_campingrifle_primary_force 2
set g_balance_campingrifle_primary_speed 35000
set g_balance_campingrifle_primary_lifetime 5
-set g_balance_campingrifle_primary_refire 0.8
-set g_balance_campingrifle_primary_animtime 0.8
+set g_balance_campingrifle_primary_refire 1.5
+set g_balance_campingrifle_primary_animtime 1.4
set g_balance_campingrifle_primary_ammo 10
set g_balance_campingrifle_primary_bulletconstant 130 // 56.3qu
set g_balance_campingrifle_primary_burstcost 0
seta crosshair_fireball_color_blue 0.2 "crosshair color blue component to display when wielding the fireball"
seta crosshair_fireball_color_alpha 1 "crosshair alpha value to display when wielding the fireball"
seta crosshair_fireball_size 1 "crosshair size when wielding the fireball"
+seta crosshair_nexvelocity_color_red 0.8
+seta crosshair_nexvelocity_color_green 0
+seta crosshair_nexvelocity_color_blue 0
+seta crosshair_nexvelocity_alpha 0.25
seta cl_reticle_stretch 0 "whether to stretch reticles so they fit the screen (brakes image proportions)"
seta cl_reticle_item_nex 1 "draw aiming recticle for the nex weapon's zoom, 0 disables and values between 0 and 1 change alpha"
seta cl_reticle_item_normal 1 "draw recticle when zooming with the zoom button, 0 disables and values between 0 and 1 change alpha"
seta cl_zoomsensitivity 0 "how zoom changes sensitivity (0 = weakest, 1 = strongest)"
freelook 1
sensitivity 6
-v_gamma 1.125000
+v_gamma 1
viewsize 100
bgmvolume 1
volume 0.5
seta g_balance_cloaked_alpha 0.25
set g_playerclip_collisions 1 "0 = disable collision testing against playerclips, might be useful on some defrag maps"
+set g_botclip_collisions 1 "0 = disable collision testing against botclips, might be useful on some defrag maps"
set welcome_message_time 8
// singleplayer campaign
set g_campaign 0
+set g_campaign_forceteam 0 "Forces the player to a given team in campaign mode, 1 = red, 2 = blue, 3 = yellow, 4 = pink"
seta g_campaign_name "xonotic25"
set g_campaign_skill 0
set g_campaignxonotic20_index 0
set cl_gravity 800 "but ignored anyway"
set g_ban_default_bantime 5400 "90 minutes"
-set g_ban_default_masksize 3 "whole 255.255.255.0 networks (set to 4 for single IPs); when UID support is compiled in, masksize 0 means banning by UID"
+set g_ban_default_masksize 3 "masksize 0 means banning by UID only, 1 means banning by /8 (IPv6: /32) network, 2 means banning by /16 (IPv6: /48) network, 3 means banning by /24 (IPv6: /56) network, 4 means banning by single IP (IPv6: /64 network)"
set g_banned_list "" "format: IP remainingtime IP remainingtime ..."
alias bans "sv_cmd bans"
alias ban "sv_cmd ban $*" // usage: ban address(maybe incomplete, like 1.2.3) bantime(seconds)
// exact gloss looks better, e.g. on g-23
r_shadow_glossexact 1
+
+// use fake light if map has no lightmaps
+r_fakelight 1
-// These have been modified from Nexuiz 2.4.2's physicsQBR.cfg file
-sv_gravity 800
-sv_gravity 802
-sv_maxspeed 417
-sv_maxairspeed 202
+// These have been modified from Nexuiz 2.4.2's physicsQBR.cfg file and a bunch of other crap div0 threw on here :P
+// DO NOT SCREW WITH friction on land, edge friction, step height, or sv_airaccel_qw
+sv_gravity 819
+sv_maxspeed 420
+sv_maxairspeed 283
+
sv_stopspeed 100
-sv_accelerate 5.8
-sv_airaccelerate 5.5
-sv_friction 4.1
-edgefriction 1
-sv_stepheight 34
-sv_jumpvelocity 307
+sv_accelerate 13
+sv_airaccelerate 6
+sv_friction 9.6 // higher values make you slide less
+edgefriction 1 // div0 says no! lol
+sv_stepheight 26
+sv_jumpvelocity 304
sv_wateraccelerate -1
sv_waterfriction -1
-sv_airaccel_sideways_friction 0.207
-sv_airaccel_qw -0.93
+sv_airaccel_sideways_friction 0 // pain in the ass to tweak without screwing up the strafing
+sv_airaccel_qw -0.93 //given a negative value to combat potential cheats, was told by divVerent not to mess with it
+
sv_airstopaccelerate 0
sv_airstrafeaccelerate 0
sv_maxairstrafespeed 0
sv_friction_on_land 0
sv_doublejump 0
sv_jumpspeedcap_min ""
-sv_jumpspeedcap_max ""
+sv_jumpspeedcap_max 0.38
sv_jumpspeedcap_max_disable_on_ramps 0
float campingrifle_scope;
float nex_scope;
+
+float nex_minvelocity;
+float nex_maxvelocity;
Net_WeaponComplain();
bHandled = true;
break;
+ case TE_CSQC_NEX_VELOCITY:
+ nex_minvelocity = ReadShort();
+ nex_maxvelocity = ReadShort();
+ bHandled = true;
+ break;
default:
// No special logic for this temporary entity; return 0 so the engine can handle it
bHandled = false;
void CSQC_RAPTOR_HUD();
vector freeze_pmove_org, freeze_input_angles;
+entity nightvision_noise, nightvision_noise2;
void CSQC_UpdateView(float w, float h)
{
// next R_RenderScene call
drawstring('0 0 0', "", '1 1 0', '1 1 1', 0, 0);
+ if(cvar("r_fakelight") >= 2 || cvar("r_fullbright"))
+ {
+ // apply night vision effect
+ vector rgb, tc_00, tc_01, tc_10, tc_11;
+ float a;
+
+ if(!nightvision_noise)
+ {
+ nightvision_noise = spawn();
+ nightvision_noise.classname = "nightvision_noise";
+ }
+ if(!nightvision_noise2)
+ {
+ nightvision_noise2 = spawn();
+ nightvision_noise2.classname = "nightvision_noise2";
+ }
+
+ // color tint in yellow
+ drawfill('0 0 0', cvar("vid_conwidth") * '1 0 0' + cvar("vid_conheight") * '0 1 0', '0.5 1 0.3', 1, DRAWFLAG_MODULATE);
+
+ // draw BG
+ a = Noise_Pink(nightvision_noise, frametime * 1.5) * 0.05 + 0.15;
+ rgb = '1 1 1';
+ tc_00 = '0 0 0' + '0.2 0 0' * sin(time * 0.3) + '0 0.3 0' * cos(time * 0.7);
+ tc_01 = '0 2.25 0' + '0.6 0 0' * cos(time * 1.2) - '0 0.3 0' * sin(time * 2.2);
+ tc_10 = '1.5 0 0' - '0.2 0 0' * sin(time * 0.5) + '0 0.5 0' * cos(time * 1.7);
+ //tc_11 = '1 1 0' + '0.6 0 0' * sin(time * 0.6) + '0 0.3 0' * cos(time * 0.1);
+ tc_11 = tc_01 + tc_10 - tc_00;
+ R_BeginPolygon("gfx/nightvision-bg.tga", DRAWFLAG_ADDITIVE);
+ R_PolygonVertex('0 0 0', tc_00, rgb, a);
+ R_PolygonVertex(cvar("vid_conwidth") * '1 0 0', tc_10, rgb, a);
+ R_PolygonVertex(cvar("vid_conwidth") * '1 0 0' + cvar("vid_conheight") * '0 1 0', tc_11, rgb, a);
+ R_PolygonVertex(cvar("vid_conheight") * '0 1 0', tc_01, rgb, a);
+ R_EndPolygon();
+
+ // draw FG
+ a = Noise_Pink(nightvision_noise2, frametime * 0.1) * 0.05 + 0.12;
+ rgb = '0.3 0.6 0.4' + '0.1 0.4 0.2' * Noise_White(nightvision_noise2, frametime);
+ tc_00 = '0 0 0' + '1 0 0' * Noise_White(nightvision_noise2, frametime) + '0 1 0' * Noise_White(nightvision_noise2, frametime);
+ tc_01 = tc_00 + '0 3 0' * (1 + Noise_White(nightvision_noise2, frametime) * 0.2);
+ tc_10 = tc_00 + '2 0 0' * (1 + Noise_White(nightvision_noise2, frametime) * 0.3);
+ tc_11 = tc_01 + tc_10 - tc_00;
+ R_BeginPolygon("gfx/nightvision-fg.tga", DRAWFLAG_ADDITIVE);
+ R_PolygonVertex('0 0 0', tc_00, rgb, a);
+ R_PolygonVertex(cvar("vid_conwidth") * '1 0 0', tc_10, rgb, a);
+ R_PolygonVertex(cvar("vid_conwidth") * '1 0 0' + cvar("vid_conheight") * '0 1 0', tc_11, rgb, a);
+ R_PolygonVertex(cvar("vid_conheight") * '0 1 0', tc_01, rgb, a);
+ R_EndPolygon();
+ }
+
// Draw the aiming reticle for weapons that use it
// reticle_type is changed to the item we are zooming / aiming with, to decide which reticle to use
// It must be a persisted float for fading out to work properly (you let go of the zoom button for
if(cvar("viewsize") < 120)
CSQC_common_hud();
+
+ // ring around crosshair representing velocity-dependent damage for the nex
+ if (activeweapon == WEP_NEX)
+ {
+ float f, a, curvel;
+ vector rgb;
+
+ rgb_x = cvar("crosshair_nexvelocity_color_red");
+ rgb_y = cvar("crosshair_nexvelocity_color_green");
+ rgb_z = cvar("crosshair_nexvelocity_color_blue");
+ a = cvar("crosshair_nexvelocity_alpha");
+
+ curvel = vlen('1 0 0' * pmove_vel_x + '0 1 0' * pmove_vel_y);
+ f = bound(0, (curvel - nex_minvelocity) / (nex_maxvelocity - nex_minvelocity), 1);
+
+ DrawCircleClippedPic('0.5 0 0' * vid_conwidth + '0 0.5 0' * vid_conheight, 0.1 * vid_conheight, "gfx/nex_ring.tga", f, rgb, a, DRAWFLAG_ADDITIVE);
+ }
+
// crosshair goes VERY LAST
if(!scoreboard_active && !camera_active && intermission != 2) {
// TrueAim check
}
}
}
+
+void DrawCircleClippedPic(vector centre, float radius, string pic, float f, vector rgb, float a, float drawflag)
+{
+ float x, y, q, d;
+ vector ringsize, v, t;
+ ringsize = radius * '1 1 0';
+
+ x = cos(f * 2 * M_PI);
+ y = sin(f * 2 * M_PI);
+ q = fabs(x) + fabs(y);
+ x /= q;
+ y /= q;
+
+ if(f >= 1)
+ {
+ // draw full rectangle
+ R_BeginPolygon(pic, drawflag);
+ v = centre; t = '0.5 0.5 0';
+ v_x += 0.5 * ringsize_x; t += '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ v = centre; t = '0.5 0.5 0';
+ v_y += 0.5 * ringsize_y; t += '0.5 -0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ v = centre; t = '0.5 0.5 0';
+ v_x -= 0.5 * ringsize_x; t -= '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ v = centre; t = '0.5 0.5 0';
+ v_y -= 0.5 * ringsize_y; t -= '0.5 -0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+ R_EndPolygon();
+
+ d = q - 1;
+ if(d > 0)
+ {
+ R_BeginPolygon(pic, drawflag);
+ v = centre; t = '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ v = centre; t = '0.5 0.5 0';
+ v_x += 0.5 * ringsize_x; t += '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+ }
+ }
+ else if(f > 0.75)
+ {
+ // draw upper and first triangle
+ R_BeginPolygon(pic, drawflag);
+ v = centre; t = '0.5 0.5 0';
+ v_x += 0.5 * ringsize_x; t += '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ v = centre; t = '0.5 0.5 0';
+ v_y += 0.5 * ringsize_y; t += '0.5 -0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ v = centre; t = '0.5 0.5 0';
+ v_x -= 0.5 * ringsize_x; t -= '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+ R_EndPolygon();
+ R_BeginPolygon(pic, drawflag);
+ v = centre; t = '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ v = centre; t = '0.5 0.5 0';
+ v_x -= 0.5 * ringsize_x; t -= '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ v = centre; t = '0.5 0.5 0';
+ v_y -= 0.5 * ringsize_y; t -= '0.5 -0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ d = q - 0.75;
+ if(d <= 0)
+ R_EndPolygon();
+ }
+ else if(f > 0.5)
+ {
+ // draw upper triangle
+ R_BeginPolygon(pic, drawflag);
+ v = centre; t = '0.5 0.5 0';
+ v_x += 0.5 * ringsize_x; t += '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ v = centre; t = '0.5 0.5 0';
+ v_y += 0.5 * ringsize_y; t += '0.5 -0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ v = centre; t = '0.5 0.5 0';
+ v_x -= 0.5 * ringsize_x; t -= '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+ R_EndPolygon();
+
+ d = q - 0.5;
+ if(d > 0)
+ {
+ R_BeginPolygon(pic, drawflag);
+ v = centre; t = '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ v = centre; t = '0.5 0.5 0';
+ v_x -= 0.5 * ringsize_x; t -= '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+ }
+ }
+ else if(f > 0.25)
+ {
+ // draw first triangle
+ R_BeginPolygon(pic, drawflag);
+ v = centre; t = '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ v = centre; t = '0.5 0.5 0';
+ v_x += 0.5 * ringsize_x; t += '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ v = centre; t = '0.5 0.5 0';
+ v_y += 0.5 * ringsize_y; t += '0.5 -0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ d = q - 0.25;
+ if(d <= 0)
+ R_EndPolygon();
+ }
+ else
+ {
+ d = q;
+ if(d > 0)
+ {
+ R_BeginPolygon(pic, drawflag);
+ v = centre; t = '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+
+ v = centre; t = '0.5 0.5 0';
+ v_x += 0.5 * ringsize_x; t += '0.5 0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+ }
+ }
+
+ if(d > 0)
+ {
+ v = centre; t = '0.5 0.5 0';
+ v_x += x * 0.5 * ringsize_x; t += x * '0.5 0.5 0';
+ v_y += y * 0.5 * ringsize_y; t += y * '0.5 -0.5 0';
+ R_PolygonVertex(v, t, rgb, a);
+ R_EndPolygon();
+ }
+}
{
self.modelindex = ReadShort();
self.solid = ReadByte();
- self.scale = ReadByte() / 16.0;
+ self.scale = ReadShort() / 256.0;
if(f & 0x20)
{
self.mins_x = ReadCoord();
const float TE_CSQC_WEAPONCOMPLAIN = 113;
const float TE_CSQC_CAMPINGRIFLE_SCOPE = 115;
const float TE_CSQC_NEX_SCOPE = 116;
+const float TE_CSQC_NEX_VELOCITY = 117;
const float RACE_NET_CHECKPOINT_HIT_QUALIFYING = 0; // byte checkpoint, short time, short recordtime, string recordholder
const float RACE_NET_CHECKPOINT_CLEAR = 1;
//self.bot_painintensity = self.bot_painintensity + self.bot_oldhealth - self.health;
//self.bot_painintensity = bound(0, self.bot_painintensity, 100);
- if(time < game_starttime || ((cvar("g_campaign") && !campaign_bots_may_start)))
+ if (cvar("g_campaign") && !campaign_bots_may_start)
{
self.nextthink = time + 0.5;
return;
self.BUTTON_CHAT = 0;
self.BUTTON_USE = 0;
+ if (time < game_starttime)
+ {
+ // block the bot during the countdown to game start
+ self.movement = '0 0 0';
+ self.nextthink = game_starttime;
+ return;
+ }
+
// if dead, just wait until we can respawn
if (self.deadflag)
{
// But don't remove bots immediately on level change, as the real players
// usually haven't rejoined yet
bots_would_leave = FALSE;
- if ((realplayers || cvar("bot_join_empty") || (currentbots > 0 && time < 5)))
+ if (teamplay && cvar("bot_vs_human") && (c3==-1 && c4==-1))
+ bots = min(ceil(fabs(cvar("bot_vs_human")) * activerealplayers), maxclients - realplayers);
+ else if ((realplayers || cvar("bot_join_empty") || (currentbots > 0 && time < 5)))
{
float realminplayers, minplayers;
realminplayers = cvar("minplayers");
minplayers = max(0, floor(realminplayers));
float realminbots, minbots;
- if(teamplay && cvar("bot_vs_human"))
- realminbots = ceil(fabs(cvar("bot_vs_human")) * activerealplayers);
- else
- realminbots = cvar("bot_number");
+ realminbots = cvar("bot_number");
minbots = max(0, floor(realminbots));
bots = min(max(minbots, minplayers - activerealplayers), maxclients - realplayers);
}
w = spawn();
- w.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP;
+ w.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
w.classname = "waypoint";
w.wpflags = f;
setorigin(w, (m1 + m2) * 0.5);
WriteByte(0, TE_CSQC_TEAMNAGGER);
}
+void send_CSQC_nexvelocity(entity e) {
+ msg_entity = e;
+ WriteByte(MSG_ONE, SVC_TEMPENTITY);
+ WriteByte(MSG_ONE, TE_CSQC_NEX_VELOCITY);
+ WriteShort(MSG_ONE, cvar("g_balance_nex_velocitydependent_minspeed"));
+ WriteShort(MSG_ONE, cvar("g_balance_nex_velocitydependent_maxspeed"));
+}
+
void Announce(string snd) {
WriteByte(MSG_ALL, SVC_TEMPENTITY);
WriteByte(MSG_ALL, TE_CSQC_ANNOUNCE);
self.iscreature = TRUE;
self.movetype = MOVETYPE_WALK;
self.solid = SOLID_SLIDEBOX;
+ self.dphitcontentsmask = DPCONTENTS_BODY | DPCONTENTS_SOLID;
if(cvar("g_playerclip_collisions"))
- self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP;
- else
- self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY;
+ self.dphitcontentsmask |= DPCONTENTS_PLAYERCLIP;
+ if(clienttype(self) == CLIENTTYPE_BOT && cvar("g_botclip_collisions"))
+ self.dphitcontentsmask |= DPCONTENTS_BOTCLIP;
self.frags = FRAGS_PLAYER;
if(independent_players)
MAKE_INDEPENDENT_PLAYER(self);
if(g_race || g_cts)
stuffcmd(e, "cl_cmd settemp cl_movecliptokeyboard 2\n");
if(cvar("g_antilag") == 3) // client side hitscan
- //stuffcmd(e, "cl_cmd settemp cl_prydoncursor -1\ncl_cmd settemp cl_prydoncursor_notrace 0\n");
stuffcmd(e, "cl_cmd settemp cl_prydoncursor_notrace 0\n");
+ if(sv_gentle)
+ stuffcmd(e, "cl_cmd settemp cl_gentle 1\n");
/*
* we no longer need to stuff this. Remove this comment block if you feel
* 2.3 and higher (or was it 2.2.3?) don't need these any more
race_SendRankings(i, 0, 0, MSG_ONE);
}
}
- else if(cvar("sv_teamnagger") && !g_ca) // teamnagger is currently bad for ca
+ else if(cvar("sv_teamnagger") && !(cvar("bot_vs_human") && (c3==-1 && c4==-1)) && !g_ca) // teamnagger is currently bad for ca
send_CSQC_teamnagger();
+ send_CSQC_nexvelocity(self);
+
CheatInitClient();
}
self.nextthink = time + 0.1;
self.cnt = FLAG_BASE;
self.mangle = self.angles;
- self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP;
+ self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
//self.effects = self.effects | EF_DIMLIGHT;
if(self.noalign)
{
.float ballistics_density; // wall piercing factor, larger = bullet can pass through more
+#define ACTIVE_NOT 0
+#define ACTIVE_ACTIVE 1
+#define ACTIVE_IDLE 2
+#define ACTIVE_BUSY 2
+#define ACTIVE_TOGGLE 3
+.float active;
+.float (float act_state) setactive;
.entity realowner;
{
WriteShort(MSG_ENTITY, self.modelindex);
WriteByte(MSG_ENTITY, self.solid);
- WriteByte(MSG_ENTITY, floor(self.scale * 16));
+ WriteShort(MSG_ENTITY, floor(self.scale * 256));
if(sf & 0x20)
{
WriteCoord(MSG_ENTITY, self.mins_x);
.float triggerhurttime;
void trigger_hurt_touch()
{
+ if (self.active != ACTIVE_ACTIVE)
+ return;
+
// only do the EXACTTRIGGER_TOUCH checks when really needed (saves some cpu)
if (other.iscreature)
{
void spawnfunc_trigger_hurt()
{
EXACTTRIGGER_INIT;
+ self.active = ACTIVE_ACTIVE;
self.touch = trigger_hurt_touch;
if (!self.dmg)
self.dmg = 1000;
.float triggerhealtime;
void trigger_heal_touch()
{
+ if (self.active != ACTIVE_ACTIVE)
+ return;
+
// only do the EXACTTRIGGER_TOUCH checks when really needed (saves some cpu)
if (other.iscreature)
{
void spawnfunc_trigger_heal()
{
+ self.active = ACTIVE_ACTIVE;
+
EXACTTRIGGER_INIT;
self.touch = trigger_heal_touch;
if (!self.health)
float pushdeltatime;
float str;
+ if (self.active != ACTIVE_ACTIVE)
+ return;
+
// FIXME: Better checking for what to push and not.
if not(other.iscreature)
if (other.classname != "corpse")
{
float pushdeltatime;
+ if (self.active != ACTIVE_ACTIVE)
+ return;
+
// FIXME: Better checking for what to push and not.
if not(other.iscreature)
if (other.classname != "corpse")
float pushdeltatime;
float str;
+ if (self.active != ACTIVE_ACTIVE)
+ return;
+
// FIXME: Better checking for what to push and not.
if not(other.iscreature)
if (other.classname != "corpse")
void spawnfunc_trigger_impulse()
{
+ self.active = ACTIVE_ACTIVE;
+
EXACTTRIGGER_INIT;
if(self.radius)
{
// target:
// what to trigger
}
+
+void relay_activators_use()
+{
+ entity trg, os;
+
+ os = self;
+
+ for(trg = world; (trg = find(trg, targetname, os.target)); )
+ {
+ self = trg;
+ if (trg.setactive)
+ trg.setactive(os.cnt);
+ else
+ {
+ //bprint("Not using setactive\n");
+ if(os.cnt == ACTIVE_TOGGLE)
+ if(trg.active == ACTIVE_ACTIVE)
+ trg.active = ACTIVE_NOT;
+ else
+ trg.active = ACTIVE_ACTIVE;
+ else
+ trg.active = os.cnt;
+ }
+ }
+ self = os;
+}
+
+void spawnfunc_relay_activate()
+{
+ self.cnt = ACTIVE_ACTIVE;
+ self.use = relay_activators_use;
+}
+
+void spawnfunc_relay_deactivate()
+{
+ self.cnt = ACTIVE_NOT;
+ self.use = relay_activators_use;
+}
+
+void spawnfunc_relay_activatetoggle()
+{
+ self.cnt = ACTIVE_TOGGLE;
+ self.use = relay_activators_use;
+}
e.classname = "gibsplash";
e.cnt = amount;
e.state = type; // should stay smaller than 15
- if(sv_gentle)
- e.state |= 0x80; // "force gentle" bit
if(!sound_allowed(MSG_BROADCAST, gibowner) || !sound_allowed(MSG_BROADCAST, attacker))
e.state |= 0x40; // "silence" bit
e.state |= 8 * self.species; // gib type, ranges from 0 to 15
float i1, i2, i3, i4;
string s;
+#ifdef UID
+ ban_uid = client.uid;
+#endif
+
s = client.netaddress;
-
+
i1 = strstrofs(s, ".", 0);
if(i1 < 0)
- return FALSE;
+ goto ipv6;
i2 = strstrofs(s, ".", i1 + 1);
if(i2 < 0)
return FALSE;
return FALSE;
i4 = strstrofs(s, ".", i3 + 1);
if(i4 >= 0)
- return FALSE;
+ s = substring(s, 0, i4);
- ban_ip1 = substring(s, 0, i1);
- ban_ip2 = substring(s, 0, i2);
- ban_ip3 = substring(s, 0, i3);
- ban_ip4 = strcat1(s);
-#ifdef UID
- ban_uid = client.uid;
-#endif
+ ban_ip1 = substring(s, 0, i1); // 8
+ ban_ip2 = substring(s, 0, i2); // 16
+ ban_ip3 = substring(s, 0, i3); // 24
+ ban_ip4 = strcat1(s); // 32
+ return TRUE;
+
+:ipv6
+ i1 = strstrofs(s, ":", 0);
+ if(i1 < 0)
+ return FALSE;
+ i1 = strstrofs(s, ":", i1 + 1);
+ if(i1 < 0)
+ return FALSE;
+ i2 = strstrofs(s, ":", i1 + 1);
+ if(i2 < 0)
+ return FALSE;
+ i3 = strstrofs(s, ":", i2 + 1);
+ if(i3 < 0)
+ return FALSE;
+
+ ban_ip1 = strcat(substring(s, 0, i1), "::/32"); // 32
+ ban_ip2 = strcat(substring(s, 0, i2), "::/48"); // 48
+ ban_ip4 = strcat(substring(s, 0, i3), "::/64"); // 64
+
+ if(i3 - i2 > 3) // means there is more than 2 digits and a : in the range
+ ban_ip3 = strcat(substring(s, 0, i2), ":", substring(s, i2 + 1, i3 - i2 - 3), "00::/56");
+ else
+ ban_ip3 = strcat(substring(s, 0, i2), ":0::/56");
return TRUE;
}
key.modelindex = kh_key_dropped;
key.model = "key";
key.kh_dropperteam = 0;
- key.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP;
+ key.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
setsize(key, KH_KEY_MIN, KH_KEY_MAX);
key.colormod = TeamColor(initial_owner.team) * KH_KEY_BRIGHTNESS;
key.reset = key_reset;
self.max_armorvalue = g_pickup_armorsmall_max;
if(!self.pickup_anyway)
self.pickup_anyway = g_pickup_armorsmall_anyway;
- StartItem ("models/items/g_a1.md3", "misc/armor1.wav", g_pickup_respawntime_short, g_pickup_respawntimejitter_short, "5 Armor", IT_ARMOR_SHARD, 0, 0, commodity_pickupevalfunc, BOT_PICKUP_RATING_LOW);
+ StartItem ("models/items/item_armor_small.md3", "misc/armor1.wav", g_pickup_respawntime_short, g_pickup_respawntimejitter_short, "5 Armor", IT_ARMOR_SHARD, 0, 0, commodity_pickupevalfunc, BOT_PICKUP_RATING_LOW);
}
void spawnfunc_item_armor_medium (void) {
self.max_armorvalue = g_pickup_armormedium_max;
if(!self.pickup_anyway)
self.pickup_anyway = g_pickup_armormedium_anyway;
- StartItem ("models/items/g_armormedium.md3", "misc/armor10.wav", g_pickup_respawntime_medium, g_pickup_respawntimejitter_medium, "25 Armor", IT_ARMOR, 0, 0, commodity_pickupevalfunc, BOT_PICKUP_RATING_MID);
+ StartItem ("models/items/item_armor_medium.md3", "misc/armor10.wav", g_pickup_respawntime_medium, g_pickup_respawntimejitter_medium, "25 Armor", IT_ARMOR, 0, 0, commodity_pickupevalfunc, BOT_PICKUP_RATING_MID);
}
void spawnfunc_item_armor_big (void) {
self.max_armorvalue = g_pickup_armorbig_max;
if(!self.pickup_anyway)
self.pickup_anyway = g_pickup_armorbig_anyway;
- StartItem ("models/items/g_a50.md3", "misc/armor17_5.wav", g_pickup_respawntime_long, g_pickup_respawntimejitter_long, "50 Armor", IT_ARMOR, 0, 0, commodity_pickupevalfunc, 20000);
+ StartItem ("models/items/item_armor_big.md3", "misc/armor17_5.wav", g_pickup_respawntime_long, g_pickup_respawntimejitter_long, "50 Armor", IT_ARMOR, 0, 0, commodity_pickupevalfunc, 20000);
}
void spawnfunc_item_armor_large (void) {
self.max_armorvalue = g_pickup_armorlarge_max;
if(!self.pickup_anyway)
self.pickup_anyway = g_pickup_armorlarge_anyway;
- StartItem ("models/items/g_a25.md3", "misc/armor25.wav", g_pickup_respawntime_long, g_pickup_respawntimejitter_long, "100 Armor", IT_ARMOR, 0, 0, commodity_pickupevalfunc, BOT_PICKUP_RATING_HIGH);
+ StartItem ("models/items/item_armor_large.md3", "misc/armor25.wav", g_pickup_respawntime_long, g_pickup_respawntimejitter_long, "100 Armor", IT_ARMOR, 0, 0, commodity_pickupevalfunc, BOT_PICKUP_RATING_HIGH);
}
void spawnfunc_item_health_small (void) {
void trigger_push_touch()
{
+ if (self.active == ACTIVE_NOT)
+ return;
+
// FIXME: add a .float for whether an entity should be tossed by jumppads
if (!other.iscreature)
if (other.classname != "corpse")
};
.vector dest;
-
void trigger_push_findtarget()
{
local entity e;
SetMovedir ();
EXACTTRIGGER_INIT;
-
+
+ self.active = ACTIVE_ACTIVE;
self.use = trigger_push_use;
self.touch = trigger_push_touch;
// TODO make a reset function for this one
};
+void func_rotating_setactive(float astate)
+{
+
+ if (astate == ACTIVE_TOGGLE)
+ {
+ if(self.active == ACTIVE_ACTIVE)
+ self.active = ACTIVE_NOT;
+ else
+ self.active = ACTIVE_ACTIVE;
+ }
+ else
+ self.active = astate;
+
+ if(self.active == ACTIVE_NOT)
+ self.avelocity = '0 0 0';
+ else
+ self.avelocity = self.pos1;
+}
+
/*QUAKED spawnfunc_func_rotating (0 .5 .8) ? - - X_AXIS Y_AXIS
Brush model that spins in place on one axis (default Z).
speed : speed to rotate (in degrees per second)
precache_sound(self.noise);
ambientsound(self.origin, self.noise, VOL_BASE, ATTN_IDLE);
}
+
+ self.active = ACTIVE_ACTIVE;
+ self.setactive = func_rotating_setactive;
+
if (!self.speed)
self.speed = 100;
// FIXME: test if this turns the right way, then remove this comment (negate as needed)
// FIXME: test if this turns the right way, then remove this comment (negate as needed)
else // Z
self.avelocity = '0 1 0' * self.speed;
-
+
+ self.pos1 = self.avelocity;
+
if(self.dmg & (!self.message))
self.message = " was squished";
if(self.dmg && (!self.message2))
{
local vector v;
self.nextthink = time + 0.1;
+
+ if not (self.owner.active == ACTIVE_ACTIVE)
+ {
+ self.owner.velocity = '0 0 0';
+ return;
+ }
+
// calculate sinewave using makevectors
makevectors((self.nextthink * self.owner.cnt + self.owner.phase * 360) * '0 1 0');
v = self.owner.destvec + self.owner.movedir * v_forward_y;
// time scale to get degrees
self.cnt = 360 / self.speed;
+ self.active = ACTIVE_ACTIVE;
+
// damage when blocked
self.blocked = bobbing_blocked;
if(self.dmg & (!self.message))
// dprint(activator.classname);
// dprint(" triggered a button\n");
// }
+
+ if not (self.active == ACTIVE_ACTIVE)
+ return;
+
self.enemy = activator;
button_fire ();
};
if(self.noise != "")
precache_sound(self.noise);
+ self.active = ACTIVE_ACTIVE;
+
self.pos1 = self.origin;
self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip);
self.flags |= FL_NOTARGET;
float n, i, t;
self.nextthink = time + 0.1;
+ if not (self.owner.active == ACTIVE_ACTIVE)
+ {
+ self.owner.velocity = '0 0 0';
+ return;
+ }
+
n = floor((tokenize_console(self.owner.netname)) / 5);
t = self.nextthink * self.owner.cnt + self.owner.phase * 360;
if not(InitMovingBrushTrigger())
return;
+ self.active = ACTIVE_ACTIVE;
+
// wait for targets to spawn
controller = spawn();
controller.classname = "func_fourier_controller";
void func_vectormamamam_controller_think()
{
self.nextthink = time + 0.1;
+
+ if not (self.owner.active == ACTIVE_ACTIVE)
+ {
+ self.owner.velocity = '0 0 0';
+ return;
+ }
+
self.owner.velocity = (self.owner.destvec + func_vectormamamam_origin(self.owner, 0.1) - self.owner.origin) * 10;
}
// Savage: Reduce bandwith, critical on e.g. nexdm02
self.effects |= EF_LOWPRECISION;
+ self.active = ACTIVE_ACTIVE;
+
InitializeEntity(self, func_vectormamamam_findtarget, INITPRIO_FINDTARGET);
}
entity oldself, e;
vector o;
float p;
+ string s;
+ if (self.active != ACTIVE_ACTIVE)
+ return;
+
if (other.health < 1)
return;
if not(other.flags & FL_CLIENT) // FIXME: Make missiles firable through the teleport too
o = e.origin + '0 0 1' * (1 - other.mins_z - 24);
TeleportPlayer(self, other, o, e.mangle, v_forward * vlen(other.velocity), '0 0 0', '0 0 0', TELEPORT_FLAGS_TELEPORTER);
- if(e.target)
- {
- oldself = self;
- activator = other;
- self = e;
- SUB_UseTargets();
- self = oldself;
- }
+ activator = other;
+ s = self.target; self.target = string_null;
+ SUB_UseTargets();
+ if not(self.target) self.target = s;
+
+ oldself = self;
+ self = e;
+ SUB_UseTargets();
+ self = oldself;
}
void spawnfunc_info_teleport_destination (void)
self.angles = '0 0 0';
EXACTTRIGGER_INIT;
-
+
+ self.active = ACTIVE_ACTIVE;
+
self.use = trigger_teleport_use;
// this must be called to spawn the teleport waypoints for bots
return 0;
if(cvar("g_campaign"))
return 0;
+ if(cvar("bot_vs_human") && (c3==-1 && c4==-1))
+ return 0;
if(!cvar("g_balance_teams_force"))
return -1;
return 1;
modifications = strcat(modifications, ", Low gravity");
if(g_cloaked)
modifications = strcat(modifications, ", Cloaked");
- if(g_footsteps)
- modifications = strcat(modifications, ", Steps");
if(g_grappling_hook)
modifications = strcat(modifications, ", Hook");
if(g_laserguided_missile)
}
// TODO: Balance quantity of bots across > 2 teams when bot_vs_human is set (and remove next line)
- if(c3==-1&&c4==-1)
+ if(c3==-1 && c4==-1)
if(cvar("bot_vs_human") && for_whom)
{
if(cvar("bot_vs_human") > 0)
if(IsTeamBalanceForced() == 1)
return 1;
return 1;
+ // FIXME: it always returns 1...
}
// c1...c4 should be set to -1 (not allowed) or 0 (allowed).
if(c4 >= 0)
totalteams = totalteams + 1;
- if(cvar("bot_vs_human"))
+ if(cvar("bot_vs_human") && totalteams == 1)
totalteams += 1;
if(totalteams <= 1)
// find out what teams are available
CheckAllowedTeams(pl);
+ // if we want the player in a certain team for campaign, force him there
+ if(cvar("g_campaign"))
+ if(clienttype(pl) == CLIENTTYPE_REAL) // only players, not bots
+ {
+ switch(cvar("g_campaign_forceteam"))
+ {
+ case 1:
+ SetPlayerColors(pl, COLOR_TEAM1 - 1);
+ LogTeamchange(pl.playerid, pl.team, 2);
+ return COLOR_TEAM1;
+ case 2:
+ SetPlayerColors(pl, COLOR_TEAM2 - 1);
+ LogTeamchange(pl.playerid, pl.team, 2);
+ return COLOR_TEAM2;
+ case 3:
+ SetPlayerColors(pl, COLOR_TEAM3 - 1);
+ LogTeamchange(pl.playerid, pl.team, 2);
+ return COLOR_TEAM3;
+ case 4:
+ SetPlayerColors(pl, COLOR_TEAM4 - 1);
+ LogTeamchange(pl.playerid, pl.team, 2);
+ return COLOR_TEAM4;
+ default:
+ break;
+ }
+ }
+
// if we don't care what team he ends up on, put him on whatever team he entered as.
// if he's not on a valid team, then let other code put him on the smallest team
if(!forcebestteam)
smallest = FindSmallestTeam(pl, TRUE);
- if(!only_return_best)
+ if(!only_return_best && !pl.bot_forced_team)
{
TeamchangeFrags(self);
if(smallest == 1)
REGISTER_WEAPON(GRENADE_LAUNCHER, w_glauncher, IT_ROCKETS, 4, WEP_FLAG_NORMAL | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_MID, "gl", "grenadelauncher", "Mortar");
#else
#ifdef SVQC
+.float gl_detonate_later;
+.float gl_bouncecnt;
+
void W_Grenade_Explode (void)
{
if(other.takedamage == DAMAGE_AIM)
}
}
+void W_Grenade_Think1 (void)
+{
+ self.nextthink = time;
+ if (time > self.cnt)
+ {
+ other = world;
+ self.projectiledeathtype |= HITTYPE_BOUNCE;
+ W_Grenade_Explode ();
+ return;
+ }
+ if(self.gl_detonate_later && self.gl_bouncecnt >= cvar("g_balance_grenadelauncher_primary_remote_minbouncecnt"))
+ W_Grenade_Explode();
+}
+
void W_Grenade_Touch1 (void)
{
PROJECTILE_TOUCH;
- if(cvar("g_balance_grenadelauncher_primary_sticky") && (!other || (other.takedamage != DAMAGE_AIM && other.movetype == MOVETYPE_NONE)))
+ if (other.takedamage == DAMAGE_AIM || cvar("g_balance_grenadelauncher_primary_type") == 0) // always explode when hitting a player, or if normal mortar projectile
+ {
+ self.use ();
+ }
+ else if (cvar("g_balance_grenadelauncher_primary_type") == 1) // bounce
+ {
+ 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;
+ self.gl_bouncecnt += 1;
+ }
+ else if(cvar("g_balance_grenadelauncher_primary_type") == 2 && (!other || (other.takedamage != DAMAGE_AIM && other.movetype == MOVETYPE_NONE))) // stick
{
spamsound (self, CHAN_PROJECTILE, "weapons/grenade_stick.wav", VOL_BASE, ATTN_NORM);
self.nextthink = min(self.nextthink, time + cvar("g_balance_grenadelauncher_primary_lifetime2"));
}
- else
- W_Grenade_Explode ();
}
void W_Grenade_Touch2 (void)
{
PROJECTILE_TOUCH;
- if(cvar("g_balance_grenadelauncher_secondary_sticky") && (!other || (other.takedamage != DAMAGE_AIM && other.movetype == MOVETYPE_NONE)))
+ if (other.takedamage == DAMAGE_AIM || cvar("g_balance_grenadelauncher_secondary_type") == 0) // always explode when hitting a player, or if normal mortar projectile
+ {
+ self.use ();
+ }
+ else if (cvar("g_balance_grenadelauncher_secondary_type") == 1) // bounce
+ {
+ 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;
+ self.gl_bouncecnt += 1;
+ }
+ else if(cvar("g_balance_grenadelauncher_secondary_type") == 2 && (!other || (other.takedamage != DAMAGE_AIM && other.movetype == MOVETYPE_NONE))) // stick
{
spamsound (self, CHAN_PROJECTILE, "weapons/grenade_stick.wav", VOL_BASE, ATTN_NORM);
self.nextthink = min(self.nextthink, time + cvar("g_balance_grenadelauncher_secondary_lifetime2"));
}
- else
- {
- if (cvar("g_balance_grenadelauncher_secondary_sticky") || other.takedamage == DAMAGE_AIM)
- {
- self.use ();
- }
- 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);
- else
- spamsound (self, CHAN_PROJECTILE, "weapons/grenade_bounce6.wav", VOL_BASE, ATTN_NORM);
- self.projectiledeathtype |= HITTYPE_BOUNCE;
- }
- }
}
void W_Grenade_Attack (void)
gren.bot_dodge = TRUE;
gren.bot_dodgerating = cvar("g_balance_grenadelauncher_primary_damage");
gren.movetype = MOVETYPE_BOUNCE;
+ gren.bouncefactor = cvar("g_balance_grenadelauncher_primary_bouncefactor");
+ gren.bouncestop = cvar("g_balance_grenadelauncher_primary_bouncestop");
PROJECTILE_MAKETRIGGER(gren);
gren.projectiledeathtype = WEP_GRENADE_LAUNCHER;
setorigin(gren, w_shotorg);
setsize(gren, '-3 -3 -3', '3 3 3');
- gren.nextthink = time + cvar("g_balance_grenadelauncher_primary_lifetime");
- gren.think = adaptor_think2use_hittype_splash;
+ gren.cnt = time + cvar("g_balance_grenadelauncher_primary_lifetime");
+ gren.nextthink = time;
+ gren.think = W_Grenade_Think1;
gren.use = W_Grenade_Explode;
gren.touch = W_Grenade_Touch1;
gren.takedamage = DAMAGE_YES;
gren.health = cvar("g_balance_grenadelauncher_primary_health");
+ gren.damageforcescale = cvar("g_balance_grenadelauncher_primary_damageforcescale");
gren.event_damage = W_Grenade_Damage;
W_SETUPPROJECTILEVELOCITY_UP(gren, g_balance_grenadelauncher_primary);
gren.angles = vectoangles (gren.velocity);
gren.flags = FL_PROJECTILE;
- CSQCProjectile(gren, TRUE, PROJECTILE_GRENADE, TRUE);
+ if(cvar("g_balance_grenadelauncher_primary_type") == 0 || cvar("g_balance_grenadelauncher_primary_type") == 2)
+ CSQCProjectile(gren, TRUE, PROJECTILE_GRENADE, TRUE);
+ else
+ CSQCProjectile(gren, TRUE, PROJECTILE_GRENADE_BOUNCING, TRUE);
}
void W_Grenade_Attack2 (void)
gren.angles = vectoangles (gren.velocity);
gren.flags = FL_PROJECTILE;
- if(cvar("g_balance_grenadelauncher_secondary_sticky"))
+ if(cvar("g_balance_grenadelauncher_secondary_type") == 0 || cvar("g_balance_grenadelauncher_secondary_type") == 2)
CSQCProjectile(gren, TRUE, PROJECTILE_GRENADE, TRUE);
else
CSQCProjectile(gren, TRUE, PROJECTILE_GRENADE_BOUNCING, TRUE);
.float bot_secondary_grenademooth;
float w_glauncher(float req)
{
+ entity nade;
+ float nadefound;
+
if (req == WR_AIM)
{
self.BUTTON_ATCK = FALSE;
if (self.BUTTON_ATCK)
if (weapon_prepareattack(0, cvar("g_balance_grenadelauncher_primary_refire")))
{
- if(cvar("g_balance_grenadelauncher_primary2secondary"))
- W_Grenade_Attack2();
- else
- W_Grenade_Attack();
+ W_Grenade_Attack();
weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_grenadelauncher_primary_animtime"), w_ready);
}
- if (self.BUTTON_ATCK2 && !cvar("g_balance_grenadelauncher_primary2secondary"))
- if (weapon_prepareattack(1, cvar("g_balance_grenadelauncher_secondary_refire")))
+ if (self.BUTTON_ATCK2)
{
- W_Grenade_Attack2();
- weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_grenadelauncher_secondary_animtime"), w_ready);
+ if (cvar("g_balance_grenadelauncher_secondary_remote_detonateprimary"))
+ {
+ nadefound = 0;
+ for(nade = world; (nade = find(nade, classname, "grenade")); ) if(nade.owner == self)
+ {
+ if(!nade.gl_detonate_later)
+ {
+ nade.gl_detonate_later = TRUE;
+ nadefound = 1;
+ }
+ }
+ if(nadefound)
+ sound (self, CHAN_WEAPON2, "weapons/rocket_det.wav", VOL_BASE, ATTN_NORM);
+ }
+ else if (weapon_prepareattack(1, cvar("g_balance_grenadelauncher_secondary_refire")))
+ {
+ W_Grenade_Attack2();
+ weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_grenadelauncher_secondary_animtime"), w_ready);
+ }
}
}
else if (req == WR_PRECACHE)
void W_Nex_Attack (float issecondary)
{
- float mydmg, myforce, mymindist, mymaxdist, myhalflife, myforcehalflife, myammo;
+ float mydmg, myforce, mymindist, mymaxdist, myhalflife, myforcehalflife, myammo, f;
if(issecondary)
{
mydmg = cvar("g_balance_nex_secondary_damage");
float flying;
flying = IsFlying(self); // do this BEFORE to make the trace values from FireRailgunBullet last
+ f = ExponentialFalloff(cvar("g_balance_nex_velocitydependent_minspeed"), cvar("g_balance_nex_velocitydependent_maxspeed"), cvar("g_balance_nex_velocitydependent_halflife"), vlen('1 0 0' * self.velocity_x + '0 1 0' * self.velocity_y));
+
+ // TODO: make it more obvious (through effects, indicator on weapon) that damage increases when speed increases
+ mydmg *= f;
+ myforce *= f;
+
W_SetupShot (self, TRUE, 5, "weapons/nexfire.wav", mydmg);
yoda = 0;
+void WarpZone_Fade_PreDraw()
+{
+ if(self.warpzone_fadestart)
+ self.alpha = bound(0, (self.warpzone_fadeend - vlen(view_origin - self.origin - 0.5 * (self.mins + self.maxs))) / (self.warpzone_fadeend - self.warpzone_fadestart), 1);
+ else
+ self.alpha = 1;
+ //print(sprintf("%v <-> %v\n", view_origin, self.origin + 0.5 * (self.mins + self.maxs)));
+ if(self.alpha <= 0)
+ self.drawmask = 0;
+ else
+ self.drawmask = MASK_NORMAL;
+}
+
void WarpZone_Read(float isnew)
{
+ float f;
+
++warpzone_warpzones_exist;
if not(self.enemy)
{
}
self.classname = "trigger_warpzone";
- self.warpzone_isboxy = ReadByte();
- self.origin_x = ReadCoord();
- self.origin_y = ReadCoord();
- self.origin_z = ReadCoord();
+ f = ReadByte();
+ self.warpzone_isboxy = (f & 1);
+ if(f & 4)
+ {
+ self.origin_x = ReadCoord();
+ self.origin_y = ReadCoord();
+ self.origin_z = ReadCoord();
+ }
+ else
+ self.origin = '0 0 0';
self.modelindex = ReadShort();
self.mins_x = ReadCoord();
self.mins_y = ReadCoord();
self.avelocity_y = ReadCoord();
self.avelocity_z = ReadCoord();
+ if(f & 2)
+ {
+ self.warpzone_fadestart = ReadShort();
+ self.warpzone_fadeend = max(self.warpzone_fadestart + 1, ReadShort());
+ }
+ else
+ {
+ self.warpzone_fadestart = 0;
+ self.warpzone_fadeend = 0;
+ }
+
// common stuff
WarpZone_SetUp(self, self.enemy.oldorigin, self.enemy.avelocity, self.oldorigin, self.avelocity);
- // engine currently wants this
- self.drawmask = MASK_NORMAL;
-
// link me
//setmodel(self, self.model);
setorigin(self, self.origin);
setsize(self, self.mins, self.maxs);
+
+ // how to draw
+ // engine currently wants this
+ if(self.warpzone_fadestart)
+ self.predraw = WarpZone_Fade_PreDraw;
+ else
+ self.drawmask = MASK_NORMAL;
}
void WarpZone_Camera_Read(float isnew)
{
+ float f;
++warpzone_cameras_exist;
self.classname = "func_warpzone_camera";
- self.origin_x = ReadCoord();
- self.origin_y = ReadCoord();
- self.origin_z = ReadCoord();
+
+ f = ReadByte();
+ if(f & 4)
+ {
+ self.origin_x = ReadCoord();
+ self.origin_y = ReadCoord();
+ self.origin_z = ReadCoord();
+ }
+ else
+ self.origin = '0 0 0';
self.modelindex = ReadShort();
self.mins_x = ReadCoord();
self.mins_y = ReadCoord();
self.avelocity_y = ReadCoord();
self.avelocity_z = ReadCoord();
+ if(f & 2)
+ {
+ self.warpzone_fadestart = ReadShort();
+ self.warpzone_fadeend = max(self.warpzone_fadestart + 1, ReadShort());
+ }
+ else
+ {
+ self.warpzone_fadestart = 0;
+ self.warpzone_fadeend = 0;
+ }
+
// common stuff
WarpZone_Camera_SetUp(self, self.oldorigin, self.avelocity);
//setmodel(self, self.model);
setorigin(self, self.origin);
setsize(self, self.mins, self.maxs);
+
+ // how to draw
+ // engine currently wants this
+ if(self.warpzone_fadestart)
+ self.predraw = WarpZone_Fade_PreDraw;
+ else
+ self.drawmask = MASK_NORMAL;
}
float warpzone_fixingview;
vector WarpZone_camera_transform(vector org, vector ang)
{
vector vf, vr, vu;
+ if(self.warpzone_fadestart)
+ if(vlen(org - self.origin - 0.5 * (self.mins + self.maxs)) > self.warpzone_fadeend + 400)
+ return org;
+ // don't transform if zone faded out (plus 400qu safety margin for typical speeds and latencies)
+ // unneeded on client, on server this helps a lot
vf = v_forward;
vr = v_right;
vu = v_up;
vector WarpZone_Camera_camera_transform(vector org, vector ang)
{
// a fixed camera view
+ if(self.warpzone_fadestart)
+ if(vlen(org - self.origin - 0.5 * (self.mins + self.maxs)) > self.warpzone_fadeend + 400)
+ return org;
+ // don't transform if zone faded out (plus 400qu safety margin for typical speeds and latencies)
+ // unneeded on client, on server this helps a lot
trace_endpos = self.warpzone_origin;
makevectors(self.warpzone_angles);
return self.warpzone_origin;
goto fail;
}
WarpZone_Trace_AddTransform(wz);
- org = WarpZone_TransformOrigin(wz, trace_endpos);
+ org = WarpZone_TransformOrigin(wz, org);
end = WarpZone_TransformOrigin(wz, end);
}
WarpZone_MakeAllSolid();
.vector warpzone_targetangles;
.vector warpzone_targetforward;
.vector warpzone_transform;
+.float warpzone_fadestart;
+.float warpzone_fadeend;
void WarpZone_SetUp(entity e, vector my_org, vector my_ang, vector other_org, vector other_ang);
float WarpZoneLib_BoxTouchesBrush(vector mi, vector ma, entity e, entity ig);
e = self.enemy;
if(WarpZone_Teleport(other))
{
- if(self.aiment.target)
- {
- oldself = self;
- activator = other;
- self = self.aiment;
- SUB_UseTargets();
- self = oldself;
- }
+ string save1, save2;
+ activator = other;
+
+ save1 = self.target; self.target = string_null;
+ save2 = self.target3; self.target3 = string_null;
+ SUB_UseTargets();
+ if not(self.target) self.target = save1;
+ if not(self.target3) self.target3 = save2;
+
+ oldself = self;
+ self = self.enemy;
+ save1 = self.target; self.target = string_null;
+ save2 = self.target2; self.target2 = string_null;
+ SUB_UseTargets();
+ if not(self.target) self.target = save1;
+ if not(self.target2) self.target2 = save2;
+ self = oldself;
}
else
{
float WarpZone_Send(entity to, float sendflags)
{
+ float f;
WriteByte(MSG_ENTITY, ENT_CLIENT_WARPZONE);
// we must send this flag for clientside to match properly too
- WriteByte(MSG_ENTITY, self.warpzone_isboxy);
+ f = 0;
+ if(self.warpzone_isboxy)
+ f |= 1;
+ if(self.warpzone_fadestart)
+ f |= 2;
+ if(self.origin != '0 0 0')
+ f |= 4;
+ WriteByte(MSG_ENTITY, f);
// we need THESE to render the warpzone (and cull properly)...
- WriteCoord(MSG_ENTITY, self.origin_x);
- WriteCoord(MSG_ENTITY, self.origin_y);
- WriteCoord(MSG_ENTITY, self.origin_z);
+ if(f & 4)
+ {
+ WriteCoord(MSG_ENTITY, self.origin_x);
+ WriteCoord(MSG_ENTITY, self.origin_y);
+ WriteCoord(MSG_ENTITY, self.origin_z);
+ }
WriteShort(MSG_ENTITY, self.modelindex);
WriteCoord(MSG_ENTITY, self.mins_x);
WriteCoord(MSG_ENTITY, self.warpzone_targetangles_y);
WriteCoord(MSG_ENTITY, self.warpzone_targetangles_z);
+ if(f & 2)
+ {
+ WriteShort(MSG_ENTITY, self.warpzone_fadestart);
+ WriteShort(MSG_ENTITY, self.warpzone_fadeend);
+ }
+
return TRUE;
}
float WarpZone_Camera_Send(entity to, float sendflags)
{
+ float f;
WriteByte(MSG_ENTITY, ENT_CLIENT_WARPZONE_CAMERA);
+ if(self.warpzone_fadestart)
+ f |= 2;
+ if(self.origin != '0 0 0')
+ f |= 4;
+ WriteByte(MSG_ENTITY, f);
+
// we need THESE to render the warpzone (and cull properly)...
- WriteCoord(MSG_ENTITY, self.origin_x);
- WriteCoord(MSG_ENTITY, self.origin_y);
- WriteCoord(MSG_ENTITY, self.origin_z);
+ if(f & 4)
+ {
+ WriteCoord(MSG_ENTITY, self.origin_x);
+ WriteCoord(MSG_ENTITY, self.origin_y);
+ WriteCoord(MSG_ENTITY, self.origin_z);
+ }
WriteShort(MSG_ENTITY, self.modelindex);
WriteCoord(MSG_ENTITY, self.mins_x);
WriteCoord(MSG_ENTITY, self.enemy.angles_y);
WriteCoord(MSG_ENTITY, self.enemy.angles_z);
+ if(f & 2)
+ {
+ WriteShort(MSG_ENTITY, self.warpzone_fadestart);
+ WriteShort(MSG_ENTITY, self.warpzone_fadeend);
+ }
+
return TRUE;
}
WarpZone_TraceBox_ThroughZone(self.warpzone_oldorigin, self.mins, self.maxs, self.warpzone_oldorigin + self.warpzone_oldvelocity * frametime, MOVE_NORMAL, self, wz, WarpZone_trace_callback_t_null); // this will get us through the warpzone
setorigin(self, trace_endpos);
self.angles = WarpZone_TransformAngles(WarpZone_trace_transform, self.angles);
- self.velocity = WarpZone_TransformVelocity(WarpZone_trace_transform, self.velocity);
+ self.velocity = WarpZone_TransformVelocity(WarpZone_trace_transform, self.warpzone_oldvelocity);
// in case we are in our warp zone post-teleport, shift the projectile forward a bit
mpd = max(vlen(self.mins), vlen(self.maxs));
error("Warp zone with nonexisting killtarget");
return;
}
+ self.killtarget = string_null;
}
}
countb=`awk '/^seta? g_/ { print $2; }' "$b" | sort -u | tr -d '\r' | git hash-object --stdin | cut -c 1-32`
if [ "$countw" != "$countb" ]; then
echo "Mismatch between balanceXonotic.cfg and $b. Aborting."
+ echo "Differences are:"
+ A=`mktemp`
+ B=`mktemp`
+ awk '/^seta? g_/ { print $2; }' balanceXonotic.cfg | sort -u | tr -d '\r' > "$A"
+ awk '/^seta? g_/ { print $2; }' "$b" | sort -u | tr -d '\r' > "$B"
+ echo "< missing in $b"
+ echo "> must get removed from $b"
+ diff "$A" "$B" | grep '^[<>]' | sort
+ rm -f "$A" "$B"
exit 1
fi
done