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
--- /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 60
+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 50
+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 15
+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_primary2secondary 0
+set g_balance_grenadelauncher_primary_sticky 0
+set g_balance_grenadelauncher_primary_damage 65
+set g_balance_grenadelauncher_primary_edgedamage 35
+set g_balance_grenadelauncher_primary_force 400
+set g_balance_grenadelauncher_primary_radius 140
+set g_balance_grenadelauncher_primary_speed 2000
+set g_balance_grenadelauncher_primary_speed_up 200
+set g_balance_grenadelauncher_primary_speed_z 0
+set g_balance_grenadelauncher_primary_spread 0
+set g_balance_grenadelauncher_primary_lifetime 30
+set g_balance_grenadelauncher_primary_lifetime2 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_secondary_sticky 0
+set g_balance_grenadelauncher_secondary_damage 65
+set g_balance_grenadelauncher_secondary_edgedamage 35
+set g_balance_grenadelauncher_secondary_force 400
+set g_balance_grenadelauncher_secondary_radius 140
+set g_balance_grenadelauncher_secondary_speed 1400
+set g_balance_grenadelauncher_secondary_speed_up 200
+set g_balance_grenadelauncher_secondary_speed_z 0
+set g_balance_grenadelauncher_secondary_spread 0
+set g_balance_grenadelauncher_secondary_lifetime 2.5
+set g_balance_grenadelauncher_secondary_lifetime2 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
+// }}}
+// {{{ electro
+set g_balance_electro_lightning 0
+set g_balance_electro_primary_damage 80
+set g_balance_electro_primary_edgedamage 0
+set g_balance_electro_primary_force 550
+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.6
+set g_balance_electro_primary_animtime 0.74
+set g_balance_electro_primary_ammo 2
+set g_balance_electro_primary_range 800
+set g_balance_electro_primary_falloff_mindist 255 // 0.3 * radius
+set g_balance_electro_primary_falloff_maxdist 850
+set g_balance_electro_primary_falloff_halflifedist 425
+set g_balance_electro_secondary_damage 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 16
+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 1
+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 12
+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 2
+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 7
+set g_balance_nex_primary_animtime 0.3
+set g_balance_nex_primary_damage 140
+set g_balance_nex_primary_force 600
+set g_balance_nex_primary_refire 1.5
+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
+// }}}
+// {{{ 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 100
+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 1
+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 1
+// }}}
+// {{{ rocketlauncher
+set g_balance_rocketlauncher_damage 130
+set g_balance_rocketlauncher_edgedamage 50
+set g_balance_rocketlauncher_force 597
+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 3
+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 140 // 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 19
+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 1
+
+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 10
+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_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_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_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
seta hud_panel_radar_zoommode 0 "zoom mode: 0 = zoomed by default, 1 = zoomed when +zoom, 2 = always zoomed, 3 = always zoomed out"
alias hud_panel_radar_rotate "toggle hud_panel_radar_rotation 0 1 2 3 4"
-seta hud_panel_engineinfo_framecounter_time 1 "time between framerate display updates, smaller values yield less accuracy"
+seta hud_panel_engineinfo_framecounter_time 0.1 "time between framerate display updates"
seta hud_panel_engineinfo_framecounter_decimals 0 "amount of decimals to show"
seta hud_panel_engineinfo_framecounter_exponentialmovingaverage 1 "use an averaging method for calculating fps instead of counting frametime like engine does"
seta hud_panel_engineinfo_framecounter_exponentialmovingaverage_new_weight 0.1 "weight of latest data point"
// exact gloss looks better, e.g. on g-23
r_shadow_glossexact 1
+
+// use fake light if map has no lightmaps
+r_fakelight 1
sv_airstrafeaccelerate 0
sv_maxairstrafespeed 0
sv_aircontrol 0
+sv_aircontrol_penalty 0
sv_aircontrol_power 2
+sv_airspeedlimit_nonqw 0
sv_warsowbunny_turnaccel 0
sv_warsowbunny_accel 0.1593
sv_warsowbunny_topspeed 925
string(float uselocaltime, string format, ...) strftime = #478;
float(float timer) gettime = #519;
+#define GETTIME_REALTIME 1
#define GETTIME_CDTRACK 4
float(string s) tokenize_console = #514;
heapsort(weapon_cnt, weaponorder_swap, weaponorder_cmp, world);
}
- HUD_Panel_DrawBg(1);
- if(panel_bg_padding)
- {
- panel_pos += '1 1 0' * panel_bg_padding;
- panel_size -= '2 2 0' * panel_bg_padding;
- }
+ HUD_Panel_DrawBg(1);
+ if(panel_bg_padding)
+ {
+ panel_pos += '1 1 0' * panel_bg_padding;
+ panel_size -= '2 2 0' * panel_bg_padding;
+ }
- // hits
- weapon_stats = getstati(STAT_DAMAGE_HITS);
- weapon_number = weapon_stats & 63;
- weapon_hits[weapon_number-WEP_FIRST] = floor(weapon_stats / 64);
- // fired
- weapon_stats = getstati(STAT_DAMAGE_FIRED);
- weapon_number = weapon_stats & 63;
- weapon_fired[weapon_number-WEP_FIRST] = floor(weapon_stats / 64);
+ // hits
+ weapon_stats = getstati(STAT_DAMAGE_HITS);
+ weapon_number = weapon_stats & 63;
+ weapon_hits[weapon_number-WEP_FIRST] = floor(weapon_stats / 64);
+ // fired
+ weapon_stats = getstati(STAT_DAMAGE_FIRED);
+ weapon_number = weapon_stats & 63;
+ weapon_fired[weapon_number-WEP_FIRST] = floor(weapon_stats / 64);
- if(cvar_or("hud_panel_weapons_fade", 1))
- {
- fade = 3.2 - 2 * (time - weapontime);
- fade = bound(0.7, fade, 1);
- }
- else
- fade = 1;
+ if(cvar_or("hud_panel_weapons_fade", 1))
+ {
+ fade = 3.2 - 2 * (time - weapontime);
+ fade = bound(0.7, fade, 1);
+ }
+ else
+ fade = 1;
- HUD_Weapons_Clear();
+ HUD_Weapons_Clear();
- float rows, columns;
- rows = panel_size_y/panel_size_x;
- rows = bound(1, floor((sqrt(4 * autocvar_hud_panel_weapons_aspect * rows * WEP_COUNT + rows * rows) + rows + 0.5) / 2), WEP_COUNT);
+ float rows, columns;
+ rows = panel_size_y/panel_size_x;
+ rows = bound(1, floor((sqrt(4 * autocvar_hud_panel_weapons_aspect * rows * WEP_COUNT + rows * rows) + rows + 0.5) / 2), WEP_COUNT);
- columns = ceil(WEP_COUNT/rows);
- float row, column;
+ columns = ceil(WEP_COUNT/rows);
+ float row, column;
- float a, type, fullammo;
- float when;
- when = autocvar_hud_panel_weapons_complainbubble_time;
- float fadetime;
- fadetime = autocvar_hud_panel_weapons_complainbubble_fadetime;
+ float a, type, fullammo;
+ float when;
+ when = autocvar_hud_panel_weapons_complainbubble_time;
+ float fadetime;
+ fadetime = autocvar_hud_panel_weapons_complainbubble_fadetime;
- vector color;
- vector wpnpos;
- vector wpnsize;
+ vector color;
+ vector wpnpos;
+ vector wpnsize;
- for(i = 0; i < weapon_cnt; ++i)
- {
- wpnpos = panel_pos + eX * column * panel_size_x*(1/columns) + eY * row * panel_size_y*(1/rows);
- wpnsize = eX * panel_size_x*(1/columns) + eY * panel_size_y*(1/rows);
+ for(i = 0; i < weapon_cnt; ++i)
+ {
+ wpnpos = panel_pos + eX * column * panel_size_x*(1/columns) + eY * row * panel_size_y*(1/rows);
+ wpnsize = eX * panel_size_x*(1/columns) + eY * panel_size_y*(1/rows);
- self = weaponorder[i];
- weapid = self.impulse;
+ self = weaponorder[i];
+ weapid = self.impulse;
- // draw background behind currently selected weapon
- if(self.weapon == activeweapon)
- drawpic_aspect_skin(wpnpos, "weapon_current_bg", wpnsize, '1 1 1', fade * panel_fg_alpha, DRAWFLAG_NORMAL);
+ // draw background behind currently selected weapon
+ if(self.weapon == activeweapon)
+ drawpic_aspect_skin(wpnpos, "weapon_current_bg", wpnsize, '1 1 1', fade * panel_fg_alpha, DRAWFLAG_NORMAL);
- // draw the weapon accuracy
- if(acc_levels)
+ // draw the weapon accuracy
+ if(acc_levels)
+ {
+ float weapon_hit, weapon_damage;
+ weapon_damage = weapon_fired[self.weapon-WEP_FIRST];
+ if(weapon_damage)
{
- float weapon_hit, weapon_damage;
- weapon_damage = weapon_fired[self.weapon-WEP_FIRST];
- if(weapon_damage)
- {
- weapon_hit = weapon_hits[self.weapon-WEP_FIRST];
- weapon_stats = floor(100 * weapon_hit / weapon_damage);
- }
+ weapon_hit = weapon_hits[self.weapon-WEP_FIRST];
+ weapon_stats = floor(100 * weapon_hit / weapon_damage);
+ }
- // find the max level lower than weapon_stats
- float j;
- j = acc_levels-1;
- while ( j && weapon_stats < acc_lev[j] )
- --j;
+ // find the max level lower than weapon_stats
+ float j;
+ j = acc_levels-1;
+ while ( j && weapon_stats < acc_lev[j] )
+ --j;
- // inject color j+1 in color j, how much depending on how much weapon_stats is higher than level j
- float factor;
- factor = (weapon_stats - acc_lev[j]) / (acc_lev[j+1] - acc_lev[j]);
- color = acc_color(j);
- color = color + factor * (acc_color(j+1) - color);
+ // inject color j+1 in color j, how much depending on how much weapon_stats is higher than level j
+ float factor;
+ factor = (weapon_stats - acc_lev[j]) / (acc_lev[j+1] - acc_lev[j]);
+ color = acc_color(j);
+ color = color + factor * (acc_color(j+1) - color);
- if(weapon_damage)
- drawpic_aspect_skin(wpnpos, "weapon_accuracy", wpnsize, color, panel_fg_alpha, DRAWFLAG_NORMAL);
- }
+ if(weapon_damage)
+ drawpic_aspect_skin(wpnpos, "weapon_accuracy", wpnsize, color, panel_fg_alpha, DRAWFLAG_NORMAL);
+ }
- // draw the weapon icon
- if((self.impulse >= 0) && (getstati(STAT_WEAPONS) & self.weapons))
- {
- drawpic_aspect_skin(wpnpos, strcat("weapon", self.netname), wpnsize, '1 1 1', fade * panel_fg_alpha, DRAWFLAG_NORMAL);
+ // draw the weapon icon
+ if((self.impulse >= 0) && (getstati(STAT_WEAPONS) & self.weapons))
+ {
+ drawpic_aspect_skin(wpnpos, strcat("weapon", self.netname), wpnsize, '1 1 1', fade * panel_fg_alpha, DRAWFLAG_NORMAL);
- if(autocvar_hud_panel_weapons_label == 1) // weapon number
- drawstring(wpnpos, ftos(weapid), '1 1 0' * 0.5 * panel_size_y*(1/rows), '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
- else if(autocvar_hud_panel_weapons_label == 2) // bind
- drawstring(wpnpos, getcommandkey(ftos(weapid), strcat("impulse ", ftos(weapid))), '1 1 0' * 0.5 * panel_size_y*(1/rows), '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ if(autocvar_hud_panel_weapons_label == 1) // weapon number
+ drawstring(wpnpos, ftos(weapid), '1 1 0' * 0.5 * panel_size_y*(1/rows), '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ else if(autocvar_hud_panel_weapons_label == 2) // bind
+ drawstring(wpnpos, getcommandkey(ftos(weapid), strcat("impulse ", ftos(weapid))), '1 1 0' * 0.5 * panel_size_y*(1/rows), '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
- // draw ammo status bar
- if(autocvar_hud_panel_weapons_ammo && weapid != WEP_TUBA && weapid != WEP_LASER && weapid != WEP_PORTO)
+ // draw ammo status bar
+ if(autocvar_hud_panel_weapons_ammo && weapid != WEP_TUBA && weapid != WEP_LASER && weapid != WEP_PORTO)
+ {
+ a = 0;
+ type = GetAmmoTypeForWep(weapid);
+ if(type != -1)
+ a = getstati(GetAmmoStat(type)); // how much ammo do we have?
+
+ if(a > 0)
{
- a = 0;
- type = GetAmmoTypeForWep(weapid);
- if(type != -1)
- a = getstati(GetAmmoStat(type)); // how much ammo do we have?
+ switch(type) {
+ case 0: fullammo = autocvar_hud_panel_weapons_ammo_full_shells; break;
+ case 1: fullammo = autocvar_hud_panel_weapons_ammo_full_nails; break;
+ case 2: fullammo = autocvar_hud_panel_weapons_ammo_full_rockets; break;
+ case 3: fullammo = autocvar_hud_panel_weapons_ammo_full_cells; break;
+ case 4: fullammo = autocvar_hud_panel_weapons_ammo_full_fuel; break;
+ default: fullammo = 60;
+ }
- if(a > 0)
+ vector barsize;
+ vector barpos;
+ if(wpnsize_x/wpnsize_y > autocvar_hud_panel_weapons_aspect)
{
- switch(type) {
- case 0: fullammo = autocvar_hud_panel_weapons_ammo_full_shells; break;
- case 1: fullammo = autocvar_hud_panel_weapons_ammo_full_nails; break;
- case 2: fullammo = autocvar_hud_panel_weapons_ammo_full_rockets; break;
- case 3: fullammo = autocvar_hud_panel_weapons_ammo_full_cells; break;
- case 4: fullammo = autocvar_hud_panel_weapons_ammo_full_fuel; break;
- default: fullammo = 60;
- }
-
- vector barsize;
- vector barpos;
- if(wpnsize_x/wpnsize_y > autocvar_hud_panel_weapons_aspect)
- {
- barsize_x = autocvar_hud_panel_weapons_aspect * wpnsize_y;
- barsize_y = wpnsize_y;
-
- barpos_x = wpnpos_x + (wpnsize_x - barsize_x) / 2;
- barpos_y = wpnpos_y;
- }
- else
- {
- barsize_y = 1/autocvar_hud_panel_weapons_aspect * wpnsize_x;
- barsize_x = wpnsize_x;
-
- barpos_y = wpnpos_y + (wpnsize_y - barsize_y) / 2;
- barpos_x = wpnpos_x;
- }
-
- drawsetcliparea(
- barpos_x,
- barpos_y,
- barsize_x * bound(0, a/fullammo, 1),
- barsize_y);
- drawpic_aspect_skin(wpnpos, "weapon_ammo", wpnsize, autocvar_hud_panel_weapons_ammo_color, panel_fg_alpha * autocvar_hud_panel_weapons_ammo_alpha, DRAWFLAG_NORMAL);
- drawresetcliparea();
+ barsize_x = autocvar_hud_panel_weapons_aspect * wpnsize_y;
+ barsize_y = wpnsize_y;
+
+ barpos_x = wpnpos_x + (wpnsize_x - barsize_x) / 2;
+ barpos_y = wpnpos_y;
}
+ else
+ {
+ barsize_y = 1/autocvar_hud_panel_weapons_aspect * wpnsize_x;
+ barsize_x = wpnsize_x;
+
+ barpos_y = wpnpos_y + (wpnsize_y - barsize_y) / 2;
+ barpos_x = wpnpos_x;
+ }
+
+ drawsetcliparea(
+ barpos_x,
+ barpos_y,
+ barsize_x * bound(0, a/fullammo, 1),
+ barsize_y);
+ drawpic_aspect_skin(wpnpos, "weapon_ammo", wpnsize, autocvar_hud_panel_weapons_ammo_color, panel_fg_alpha * autocvar_hud_panel_weapons_ammo_alpha, DRAWFLAG_NORMAL);
+ drawresetcliparea();
}
}
+ }
- // draw a "ghost weapon icon" if you don't have the weapon
- else
+ // draw a "ghost weapon icon" if you don't have the weapon
+ else
+ {
+ drawpic_aspect_skin(wpnpos, strcat("weapon", self.netname), wpnsize, '0 0 0', panel_fg_alpha * 0.5, DRAWFLAG_NORMAL);
+ }
+
+ // draw the complain message
+ if(time - complain_weapon_time < when + fadetime && self.weapon == complain_weapon && autocvar_hud_panel_weapons_complainbubble)
+ {
+ if(fadetime)
{
- drawpic_aspect_skin(wpnpos, strcat("weapon", self.netname), wpnsize, '0 0 0', panel_fg_alpha * 0.5, DRAWFLAG_NORMAL);
+ if(complain_weapon_time + when > time)
+ a = 1;
+ else
+ a = bound(0, (complain_weapon_time + when + fadetime - time) / fadetime, 1);
}
-
- // draw the complain message
- if(time - complain_weapon_time < when + fadetime && self.weapon == complain_weapon && autocvar_hud_panel_weapons_complainbubble)
+ else
{
- if(fadetime)
- {
- if(complain_weapon_time + when > time)
- a = 1;
- else
- a = bound(0, (complain_weapon_time + when + fadetime - time) / fadetime, 1);
- }
+ if(complain_weapon_time + when > time)
+ a = 1;
else
- {
- if(complain_weapon_time + when > time)
- a = 1;
- else
- a = 0;
- }
-
- string s;
- if(complain_weapon_type == 0) {
- s = "Out of ammo";
- color = autocvar_hud_panel_weapons_complainbubble_color_outofammo;
- }
- else if(complain_weapon_type == 1) {
- s = "Don't have";
- color = autocvar_hud_panel_weapons_complainbubble_color_donthave;
- }
- else {
- s = "Unavailable";
- color = autocvar_hud_panel_weapons_complainbubble_color_unavailable;
- }
- drawpic_aspect_skin(wpnpos + '1 1 0' * autocvar_hud_panel_weapons_complainbubble_padding, "weapon_complainbubble", wpnsize - '2 2 0' * autocvar_hud_panel_weapons_complainbubble_padding, color, a * panel_fg_alpha, DRAWFLAG_NORMAL);
- drawstring_aspect(wpnpos + '1 1 0' * autocvar_hud_panel_weapons_complainbubble_padding, s, wpnsize - '2 2 0' * autocvar_hud_panel_weapons_complainbubble_padding, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
+ a = 0;
}
- ++row;
- if(row >= rows)
- {
- row = 0;
- ++column;
+ string s;
+ if(complain_weapon_type == 0) {
+ s = "Out of ammo";
+ color = autocvar_hud_panel_weapons_complainbubble_color_outofammo;
+ }
+ else if(complain_weapon_type == 1) {
+ s = "Don't have";
+ color = autocvar_hud_panel_weapons_complainbubble_color_donthave;
}
+ else {
+ s = "Unavailable";
+ color = autocvar_hud_panel_weapons_complainbubble_color_unavailable;
+ }
+ drawpic_aspect_skin(wpnpos + '1 1 0' * autocvar_hud_panel_weapons_complainbubble_padding, "weapon_complainbubble", wpnsize - '2 2 0' * autocvar_hud_panel_weapons_complainbubble_padding, color, a * panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring_aspect(wpnpos + '1 1 0' * autocvar_hud_panel_weapons_complainbubble_padding, s, wpnsize - '2 2 0' * autocvar_hud_panel_weapons_complainbubble_padding, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
}
- }
-
- // Ammo (#1)
- //
- // TODO: macro
- float GetAmmoItemCode(float i)
- {
- switch(i)
+ ++row;
+ if(row >= rows)
{
- case 0: return IT_SHELLS;
- case 1: return IT_NAILS;
- case 2: return IT_ROCKETS;
- case 3: return IT_CELLS;
- case 4: return IT_FUEL;
- default: return -1;
+ row = 0;
+ ++column;
}
}
- string GetAmmoPicture(float i)
+}
+
+// Ammo (#1)
+//
+// TODO: macro
+float GetAmmoItemCode(float i)
+{
+ switch(i)
{
- switch(i)
- {
- case 0: return "ammo_shells";
- case 1: return "ammo_bullets";
- case 2: return "ammo_rockets";
- case 3: return "ammo_cells";
- case 4: return "ammo_fuel";
- default: return "";
- }
+ case 0: return IT_SHELLS;
+ case 1: return IT_NAILS;
+ case 2: return IT_ROCKETS;
+ case 3: return IT_CELLS;
+ case 4: return IT_FUEL;
+ default: return -1;
}
+}
- void DrawAmmoItem(vector myPos, vector mySize, float itemcode, float currently_selected)
+string GetAmmoPicture(float i)
+{
+ switch(i)
{
- float a;
- a = getstati(GetAmmoStat(itemcode)); // how much ammo do we have of type itemcode?
- if(autocvar__hud_configure)
- a = 100;
-
- vector color;
- if(a < 10)
- color = '0.7 0 0';
- else
- color = '1 1 1';
-
- float alpha;
- if(currently_selected)
- alpha = 1;
- else
- alpha = 0.7;
+ case 0: return "ammo_shells";
+ case 1: return "ammo_bullets";
+ case 2: return "ammo_rockets";
+ case 3: return "ammo_cells";
+ case 4: return "ammo_fuel";
+ default: return "";
+ }
+}
- vector newSize, newPos;
- if(mySize_x/mySize_y > 3)
- {
- newSize_x = 3 * mySize_y;
- newSize_y = mySize_y;
+void DrawAmmoItem(vector myPos, vector mySize, float itemcode, float currently_selected)
+{
+ float a;
+ a = getstati(GetAmmoStat(itemcode)); // how much ammo do we have of type itemcode?
+ if(autocvar__hud_configure)
+ a = 100;
- newPos_x = myPos_x + (mySize_x - newSize_x) / 2;
- newPos_y = myPos_y;
- }
- else
- {
- newSize_y = 1/3 * mySize_x;
- newSize_x = mySize_x;
+ vector color;
+ if(a < 10)
+ color = '0.7 0 0';
+ else
+ color = '1 1 1';
- newPos_y = myPos_y + (mySize_y - newSize_y) / 2;
- newPos_x = myPos_x;
- }
+ float alpha;
+ if(currently_selected)
+ alpha = 1;
+ else
+ alpha = 0.7;
- vector picpos, numpos;
- if(autocvar_hud_panel_ammo_iconalign)
- {
- numpos = newPos;
- picpos = newPos + eX * 2 * newSize_y;
- }
- else
- {
- numpos = newPos + eX * newSize_y;
- picpos = newPos;
- }
+ vector newSize, newPos;
+ if(mySize_x/mySize_y > 3)
+ {
+ newSize_x = 3 * mySize_y;
+ newSize_y = mySize_y;
- if (currently_selected)
- drawpic_aspect_skin(newPos, "ammo_current_bg", newSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ newPos_x = myPos_x + (mySize_x - newSize_x) / 2;
+ newPos_y = myPos_y;
+ }
+ else
+ {
+ newSize_y = 1/3 * mySize_x;
+ newSize_x = mySize_x;
- drawfont = hud_bigfont;
- if(a > 0)
- drawstring_aspect(numpos, ftos(a), eX * (2/3) * newSize_x + eY * newSize_y, color, panel_fg_alpha * alpha, DRAWFLAG_NORMAL);
- else // "ghost" ammo count
- drawstring_aspect(numpos, ftos(a), eX * (2/3) * newSize_x + eY * newSize_y, '0 0 0', panel_fg_alpha * alpha * 0.5, DRAWFLAG_NORMAL);
- drawfont = hud_font;
- if(a > 0)
- drawpic_aspect_skin(picpos, GetAmmoPicture(itemcode), '1 1 0' * newSize_y, '1 1 1', panel_fg_alpha * alpha, DRAWFLAG_NORMAL);
- else // "ghost" ammo icon
- drawpic_aspect_skin(picpos, GetAmmoPicture(itemcode), '1 1 0' * newSize_y, '0 0 0', panel_fg_alpha * alpha * 0.5, DRAWFLAG_NORMAL);
+ newPos_y = myPos_y + (mySize_y - newSize_y) / 2;
+ newPos_x = myPos_x;
}
- void HUD_Ammo(void)
+ vector picpos, numpos;
+ if(autocvar_hud_panel_ammo_iconalign)
{
- if(!autocvar_hud_panel_ammo && !autocvar__hud_configure)
- return;
+ numpos = newPos;
+ picpos = newPos + eX * 2 * newSize_y;
+ }
+ else
+ {
+ numpos = newPos + eX * newSize_y;
+ picpos = newPos;
+ }
- active_panel = HUD_PANEL_AMMO;
- HUD_Panel_UpdateCvars(ammo);
- float i, currently_selected;
+ if (currently_selected)
+ drawpic_aspect_skin(newPos, "ammo_current_bg", newSize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
- vector pos, mySize;
- pos = panel_pos;
- mySize = panel_size;
+ drawfont = hud_bigfont;
+ if(a > 0)
+ drawstring_aspect(numpos, ftos(a), eX * (2/3) * newSize_x + eY * newSize_y, color, panel_fg_alpha * alpha, DRAWFLAG_NORMAL);
+ else // "ghost" ammo count
+ drawstring_aspect(numpos, ftos(a), eX * (2/3) * newSize_x + eY * newSize_y, '0 0 0', panel_fg_alpha * alpha * 0.5, DRAWFLAG_NORMAL);
+ drawfont = hud_font;
+ if(a > 0)
+ drawpic_aspect_skin(picpos, GetAmmoPicture(itemcode), '1 1 0' * newSize_y, '1 1 1', panel_fg_alpha * alpha, DRAWFLAG_NORMAL);
+ else // "ghost" ammo icon
+ drawpic_aspect_skin(picpos, GetAmmoPicture(itemcode), '1 1 0' * newSize_y, '0 0 0', panel_fg_alpha * alpha * 0.5, DRAWFLAG_NORMAL);
+}
- HUD_Panel_DrawBg(1);
+void HUD_Ammo(void)
+{
+ if(!autocvar_hud_panel_ammo && !autocvar__hud_configure)
+ return;
+
+ active_panel = HUD_PANEL_AMMO;
+ HUD_Panel_UpdateCvars(ammo);
+ float i, currently_selected;
+
+ vector pos, mySize;
+ pos = panel_pos;
+ mySize = panel_size;
+
+ HUD_Panel_DrawBg(1);
if(panel_bg_padding)
{
pos += '1 1 0' * panel_bg_padding;
mySize -= '2 2 0' * panel_bg_padding;
}
+ float currentTime = gettime(GETTIME_REALTIME);
if(cvar("hud_panel_engineinfo_framecounter_exponentialmovingaverage"))
{
- frametimeavg = (frametimeavg + frametimeavg1 + frametimeavg2 + frametime)/4; // average three frametimes into framecounter for slightly more stable fps readings :P
+ float currentframetime = currentTime - prevfps_time;
+ frametimeavg = (frametimeavg + frametimeavg1 + frametimeavg2 + currentframetime)/4; // average three frametimes into framecounter for slightly more stable fps readings :P
frametimeavg2 = frametimeavg1;
frametimeavg1 = frametimeavg;
float weight;
weight = cvar("hud_panel_engineinfo_framecounter_exponentialmovingaverage_new_weight");
- if(frametime > 0.0001) // filter out insane values which sometimes seem to occur and throw off the average? If you are getting 10,000 fps or more, then you don't need a framerate counter.
+ if(currentframetime > 0.0001) // filter out insane values which sometimes seem to occur and throw off the average? If you are getting 10,000 fps or more, then you don't need a framerate counter.
{
- if(fabs(prevfps - (1/frametimeavg)) > prevfps * cvar("hud_panel_engineinfo_framecounter_exponentialmovingaverage_instantupdate_change_threshold")) // if there was a big jump in fps, just force prevfps at current (1/frametime) to make big updates instant
- prevfps = (1/frametime);
+ if(fabs(prevfps - (1/frametimeavg)) > prevfps * cvar("hud_panel_engineinfo_framecounter_exponentialmovingaverage_instantupdate_change_threshold")) // if there was a big jump in fps, just force prevfps at current (1/currentframetime) to make big updates instant
+ prevfps = (1/currentframetime);
prevfps = (1 - weight) * prevfps + weight * (1/frametimeavg); // framecounter just used so there's no need for a new variable, think of it as "frametime average"
}
+ prevfps_time = currentTime;
}
else
{
framecounter += 1;
- if(time - prevfps_time > cvar("hud_panel_engineinfo_framecounter_time"))
+ if(currentTime - prevfps_time > cvar("hud_panel_engineinfo_framecounter_time"))
{
- prevfps = framecounter/cvar("hud_panel_engineinfo_framecounter_time");
+ prevfps = framecounter/(currentTime - prevfps_time);
framecounter = 0;
- prevfps_time = time;
+ prevfps_time = currentTime;
}
}
{
self.modelindex = ReadShort();
self.solid = ReadByte();
- self.scale = ReadByte() / 16.0;
+ self.scale = ReadShort() / 256.0;
if(f & 0x20)
{
self.mins_x = ReadCoord();
//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);
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();
CheatInitClient();
.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
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);
}
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
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;
}
// 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)
smallest = FindSmallestTeam(pl, TRUE);
- if(!only_return_best)
+ if(!only_return_best && !pl.bot_forced_team)
{
TeamchangeFrags(self);
if(smallest == 1)
+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;
.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);
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));
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