set g_balance_laser_primary_force_zscale 1
set g_balance_laser_primary_force_velocitybias 0
set g_balance_laser_primary_force_other_scale 1
-set g_balance_laser_secondary 0 // when 1, a secondary laser mode exists
+
- set g_balance_laser_reload_ammo 0 //default: 6
- set g_balance_laser_reload_time 2
-
+set g_balance_laser_secondary 0 // 0 = switch away to last used weapon, 1 = projectile secondary, 2 = melee secondary
set g_balance_laser_secondary_damage 35
set g_balance_laser_secondary_edgedamage 10
set g_balance_laser_secondary_force 400
set g_balance_laser_secondary_force_zscale 1
set g_balance_laser_secondary_force_velocitybias 0
set g_balance_laser_secondary_force_other_scale 1
+
+set g_balance_laser_shockwave_damage 20
+set g_balance_laser_shockwave_distance 2000
+set g_balance_laser_shockwave_edgedamage 0
+set g_balance_laser_shockwave_force 200
+set g_balance_laser_shockwave_force_forwardbias 50
+set g_balance_laser_shockwave_force_zscale 1.5
+set g_balance_laser_shockwave_jump_damage 20
+set g_balance_laser_shockwave_jump_edgedamage 0
+set g_balance_laser_shockwave_jump_force 300
+set g_balance_laser_shockwave_jump_force_velocitybias 0
+set g_balance_laser_shockwave_jump_force_zscale 1.25
+set g_balance_laser_shockwave_jump_multiplier_accuracy 0.5
+set g_balance_laser_shockwave_jump_multiplier_distance 0.5
+set g_balance_laser_shockwave_jump_multiplier_min 0
+set g_balance_laser_shockwave_jump_radius 150
+set g_balance_laser_shockwave_multiplier_accuracy 0.5
+set g_balance_laser_shockwave_multiplier_distance 0.5
+set g_balance_laser_shockwave_multiplier_min 0
+set g_balance_laser_shockwave_splash_damage 15
+set g_balance_laser_shockwave_splash_edgedamage 0
+set g_balance_laser_shockwave_splash_force 100
+set g_balance_laser_shockwave_splash_force_forwardbias 50
+set g_balance_laser_shockwave_splash_multiplier_accuracy 0.5
+set g_balance_laser_shockwave_splash_multiplier_distance 0.5
+set g_balance_laser_shockwave_splash_multiplier_min 0
+set g_balance_laser_shockwave_splash_radius 70
+set g_balance_laser_shockwave_spread_max 100
+set g_balance_laser_shockwave_spread_min 20
++
+ set g_balance_laser_switchdelay_drop 0.15
+ set g_balance_laser_switchdelay_raise 0.15
+ set g_balance_laser_reload_ammo 0 //default: 6
+ set g_balance_laser_reload_time 2
// }}}
// {{{ shotgun
set g_balance_shotgun_primary_bullets 6
set g_balance_laser_primary_force_zscale 2 // 300 upforce
set g_balance_laser_primary_force_velocitybias 0.3
set g_balance_laser_primary_force_other_scale 2.5 // force 375 when pushing others around
-set g_balance_laser_secondary 0 // when 1, a secondary laser mode exists
+
- set g_balance_laser_reload_ammo 0 //default: 6
- set g_balance_laser_reload_time 2
-
+set g_balance_laser_secondary 0 // 0 = switch away to last used weapon, 1 = projectile secondary, 2 = melee secondary
set g_balance_laser_secondary_damage 200 // dps
set g_balance_laser_secondary_edgedamage 0
set g_balance_laser_secondary_force 1300
set g_balance_laser_secondary_force_zscale 1.25
set g_balance_laser_secondary_force_velocitybias 0
set g_balance_laser_secondary_force_other_scale 0
+
+set g_balance_laser_shockwave_damage 20
+set g_balance_laser_shockwave_distance 2000
+set g_balance_laser_shockwave_edgedamage 0
+set g_balance_laser_shockwave_force 200
+set g_balance_laser_shockwave_force_forwardbias 50
+set g_balance_laser_shockwave_force_zscale 1.5
+set g_balance_laser_shockwave_jump_damage 20
+set g_balance_laser_shockwave_jump_edgedamage 0
+set g_balance_laser_shockwave_jump_force 300
+set g_balance_laser_shockwave_jump_force_velocitybias 0
+set g_balance_laser_shockwave_jump_force_zscale 1.25
+set g_balance_laser_shockwave_jump_multiplier_accuracy 0.5
+set g_balance_laser_shockwave_jump_multiplier_distance 0.5
+set g_balance_laser_shockwave_jump_multiplier_min 0
+set g_balance_laser_shockwave_jump_radius 150
+set g_balance_laser_shockwave_multiplier_accuracy 0.5
+set g_balance_laser_shockwave_multiplier_distance 0.5
+set g_balance_laser_shockwave_multiplier_min 0
+set g_balance_laser_shockwave_splash_damage 15
+set g_balance_laser_shockwave_splash_edgedamage 0
+set g_balance_laser_shockwave_splash_force 100
+set g_balance_laser_shockwave_splash_force_forwardbias 50
+set g_balance_laser_shockwave_splash_multiplier_accuracy 0.5
+set g_balance_laser_shockwave_splash_multiplier_distance 0.5
+set g_balance_laser_shockwave_splash_multiplier_min 0
+set g_balance_laser_shockwave_splash_radius 70
+set g_balance_laser_shockwave_spread_max 100
+set g_balance_laser_shockwave_spread_min 20
++
+ set g_balance_laser_switchdelay_drop 0.15
+ set g_balance_laser_switchdelay_raise 0.15
+ set g_balance_laser_reload_ammo 0 //default: 6
+ set g_balance_laser_reload_time 2
// }}}
// {{{ shotgun
set g_balance_shotgun_primary_bullets 18
--- /dev/null
-set g_balance_laser_primary_gauntlet 0
+ g_mod_balance XDF
+
+ // {{{ starting gear
+ set g_start_weapon_laser 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_shotgun 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_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"
+ set g_start_weapon_electro -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
+ set g_start_weapon_crylink -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
+ set g_start_weapon_nex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
+ set g_start_weapon_hagar -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default" // UNTIL IT CAN BE REMOVED FROM CODE
+ set g_start_weapon_rocketlauncher -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
+ set g_start_weapon_minstanex -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
+ set g_start_weapon_porto -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
+ set g_start_weapon_hook -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
+ set g_start_weapon_tuba -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
+ set g_start_weapon_fireball -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
+ set g_balance_health_start 100
+ set g_balance_armor_start 0
+ set g_start_ammo_shells 15
+ 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 100 "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 30 "starting values when being in warmup-stage"
+ set g_warmup_start_ammo_nails 160 "starting values when being in warmup-stage"
+ set g_warmup_start_ammo_rockets 80 "starting values when being in warmup-stage"
+ set g_warmup_start_ammo_cells 90 "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 200
+ set g_lms_start_ammo_shells 60
+ set g_lms_start_ammo_nails 320
+ set g_lms_start_ammo_rockets 160
+ set g_lms_start_ammo_cells 180
+ 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 60
+ set g_balance_nix_ammo_nails 320
+ set g_balance_nix_ammo_rockets 160
+ set g_balance_nix_ammo_cells 180
+ set g_balance_nix_ammo_fuel 0
+ set g_balance_nix_ammoincr_shells 2 // eh this will need figured out later I assume
+ set g_balance_nix_ammoincr_nails 6
+ set g_balance_nix_ammoincr_rockets 2
+ set g_balance_nix_ammoincr_cells 2
+ set g_balance_nix_ammoincr_fuel 2
+ // }}}
+
+ // {{{ pickup items
+ set g_pickup_ammo_anyway 1
+ set g_pickup_weapons_anyway 1
+ set g_pickup_shells 15
+ set g_pickup_shells_weapon 15
+ set g_pickup_shells_max 60
+ set g_pickup_nails 80
+ set g_pickup_nails_weapon 80
+ set g_pickup_nails_max 320
+ set g_pickup_rockets 40
+ set g_pickup_rockets_weapon 40
+ set g_pickup_rockets_max 160
+ set g_pickup_cells 30
+ set g_pickup_cells_weapon 30
+ set g_pickup_cells_max 180
+ set g_pickup_fuel 50
+ set g_pickup_fuel_weapon 50
+ set g_pickup_fuel_jetpack 100
+ set g_pickup_fuel_max 100
+ set g_pickup_armorsmall 5
+ set g_pickup_armorsmall_max 200
+ set g_pickup_armorsmall_anyway 1
+ set g_pickup_armormedium 25
+ set g_pickup_armormedium_max 200
+ set g_pickup_armormedium_anyway 1
+ set g_pickup_armorbig 50
+ set g_pickup_armorbig_max 200
+ set g_pickup_armorbig_anyway 1
+ set g_pickup_armorlarge 100
+ set g_pickup_armorlarge_max 200
+ set g_pickup_armorlarge_anyway 1
+ set g_pickup_healthsmall 5
+ set g_pickup_healthsmall_max 200
+ set g_pickup_healthsmall_anyway 1
+ set g_pickup_healthmedium 25
+ set g_pickup_healthmedium_max 200
+ set g_pickup_healthmedium_anyway 1
+ set g_pickup_healthlarge 50
+ set g_pickup_healthlarge_max 200
+ set g_pickup_healthlarge_anyway 1
+ set g_pickup_healthmega 100
+ set g_pickup_healthmega_max 200
+ set g_pickup_healthmega_anyway 1
+ set g_pickup_respawntime_short 0.1
+ set g_pickup_respawntime_medium 0.1
+ set g_pickup_respawntime_long 0.1
+ set g_pickup_respawntime_powerup 0.1
+ set g_pickup_respawntime_weapon 0.1
+ set g_pickup_respawntime_superweapon 0.1
+ set g_pickup_respawntime_ammo 0.1
+ set g_pickup_respawntimejitter_short 0
+ set g_pickup_respawntimejitter_medium 0
+ set g_pickup_respawntimejitter_long 0
+ set g_pickup_respawntimejitter_powerup 30
+ set g_pickup_respawntimejitter_weapon 0
+ set g_pickup_respawntimejitter_superweapon 10
+ set g_pickup_respawntimejitter_ammo 0
+ // }}}
+
+ // {{{ regen/rot
+ set g_balance_health_regen 0.08
+ set g_balance_health_regenlinear 0.5
+ set g_balance_pause_health_regen 5
+ set g_balance_pause_health_regen_spawn 0
+ set g_balance_health_rot 0.04
+ set g_balance_health_rotlinear 0.75
+ set g_balance_pause_health_rot 1
+ set g_balance_pause_health_rot_spawn 5
+ set g_balance_health_regenstable 100
+ set g_balance_health_rotstable 100
+ set g_balance_health_limit 999
+ set g_balance_armor_regen 0
+ set g_balance_armor_regenlinear 0
+ set g_balance_armor_rot 0.04
+ set g_balance_armor_rotlinear 0.75
+ set g_balance_pause_armor_rot 1
+ set g_balance_pause_armor_rot_spawn 5
+ set g_balance_armor_regenstable 100
+ set g_balance_armor_rotstable 100
+ set g_balance_armor_limit 999
+ 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 50
+ set g_balance_fuel_rotstable 100
+ set g_balance_fuel_limit 999
+ // }}}
+
+ // {{{ misc
+ set g_balance_selfdamagepercent 0
+ 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_damage 2
+ // possible values:
+ // -2: absolutely no damage to projectiles (no exceptions)
+ // -1: no damage other than the exceptions (electro combo, hagar join explode, ML mines)
+ // 0: only damage from contents (lava/slime) or exceptions
+ // 1: only self damage or damage from contents or exceptions
+ // 2: allow all damage to projectiles normally
+ set g_projectiles_keep_owner 0
+ 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)
+ set g_projectiles_newton_style_2_minfactor 0.8
+ set g_projectiles_newton_style_2_maxfactor 1.5
+ set g_projectiles_spread_style 7
+ // possible values:
+ // 0: forward + solid sphere (like Quake) - varies velocity
+ // 1: forward + flattened solid sphere
+ // 2: forward + solid circle
+ // 3: forward + normal distribution 3D - varies velocity
+ // 4: forward + normal distribution on a plane
+ // 5: forward + circle with 1-r falloff
+ // 6: forward + circle with 1-r^2 falloff
+ // 7: forward + circle with (1-r)(2-r) falloff
+ set g_balance_falldamage_deadminspeed 250
+ set g_balance_falldamage_minspeed 900
+ set g_balance_falldamage_factor 0.20
+ set g_balance_falldamage_maxdamage 40
+ set g_balance_damagepush_speedfactor 2.5
+ set g_balance_contents_damagerate 0.2 // ticrate interval for applying damage with playerdamage/projectiledamage
+ set g_balance_contents_drowndelay 10 // time under water before a player begins drowning
+ set g_balance_contents_playerdamage_drowning 20 // damage per second for while player is drowning
+ set g_balance_contents_playerdamage_lava 50 // damage per second for while player is inside lava
+ set g_balance_contents_playerdamage_slime 30 // damage per second for while player is inside slime
+ set g_balance_contents_projectiledamage 10000 // instantly kill projectiles upon touching lava/slime
+ set g_maxpushtime 8.0 "timeout for kill credit when your damage knocks someone into a death trap"
+ // }}}
+
+ // {{{ powerups
+ set g_balance_powerup_invincible_takedamage 0.25 // only 1/4th damage is taken
+ set g_balance_powerup_invincible_time 999
+ set g_balance_powerup_strength_damage 3
+ set g_balance_powerup_strength_force 3
+ set g_balance_powerup_strength_time 999
+ set g_balance_powerup_strength_selfdamage 1.5
+ set g_balance_powerup_strength_selfforce 1.5
+ set g_balance_superweapons_time 30
+ // }}}
+
+ // {{{ 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
+ set g_balance_grapplehook_damagedbycontents 0
+ // }}}
+
+ // {{{ weapon properties
+ // {{{ laser
++set g_balance_laser_melee_animtime 0.3
++set g_balance_laser_melee_damage 80
++set g_balance_laser_melee_delay 0.25
++set g_balance_laser_melee_force 200
++set g_balance_laser_melee_multihit 1
++set g_balance_laser_melee_no_doubleslap 1
++set g_balance_laser_melee_nonplayerdamage 40
++set g_balance_laser_melee_range 120
++set g_balance_laser_melee_refire 1.25
++set g_balance_laser_melee_swing_side 120
++set g_balance_laser_melee_swing_up 30
++set g_balance_laser_melee_time 0.15
++set g_balance_laser_melee_traces 10
++
++set g_balance_laser_primary 1 // 0 = shockwave attack, 1 = projectile primary
+ set g_balance_laser_primary_damage 25
+ set g_balance_laser_primary_edgedamage 12.5
+ set g_balance_laser_primary_force 250
+ set g_balance_laser_primary_radius 70
+ set g_balance_laser_primary_speed 6000
+ 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 5
+ set g_balance_laser_primary_shotangle 0
+ set g_balance_laser_primary_delay 0
-set g_balance_laser_secondary 0 // when 1, a secondary laser mode exists
+ set g_balance_laser_primary_force_zscale 1.5
+ set g_balance_laser_primary_force_velocitybias 0
+ set g_balance_laser_primary_force_other_scale 1
-set g_balance_laser_secondary_animtime 0.3
++
++set g_balance_laser_secondary 0 // 0 = switch away to last used weapon, 1 = projectile secondary, 2 = melee secondary
+ set g_balance_laser_secondary_damage 25
+ set g_balance_laser_secondary_edgedamage 12.5
+ set g_balance_laser_secondary_force 400
+ 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_gauntlet 0
++set g_balance_laser_secondary_animtime 0.2
+ set g_balance_laser_secondary_lifetime 5
+ set g_balance_laser_secondary_shotangle -90
+ set g_balance_laser_secondary_delay 0
+ set g_balance_laser_secondary_force_zscale 1.25
+ set g_balance_laser_secondary_force_velocitybias 0
+ set g_balance_laser_secondary_force_other_scale 1
++
++set g_balance_laser_shockwave_damage 20
++set g_balance_laser_shockwave_distance 2000
++set g_balance_laser_shockwave_edgedamage 0
++set g_balance_laser_shockwave_force 200
++set g_balance_laser_shockwave_force_forwardbias 50
++set g_balance_laser_shockwave_force_zscale 2
++set g_balance_laser_shockwave_jump_damage 20
++set g_balance_laser_shockwave_jump_edgedamage 0
++set g_balance_laser_shockwave_jump_force 300
++set g_balance_laser_shockwave_jump_force_velocitybias 0
++set g_balance_laser_shockwave_jump_force_zscale 1.25
++set g_balance_laser_shockwave_jump_multiplier_accuracy 0.5
++set g_balance_laser_shockwave_jump_multiplier_distance 0.5
++set g_balance_laser_shockwave_jump_multiplier_min 0
++set g_balance_laser_shockwave_jump_radius 150
++set g_balance_laser_shockwave_multiplier_accuracy 0.5
++set g_balance_laser_shockwave_multiplier_distance 0.5
++set g_balance_laser_shockwave_multiplier_min 0
++set g_balance_laser_shockwave_splash_damage 15
++set g_balance_laser_shockwave_splash_edgedamage 0
++set g_balance_laser_shockwave_splash_force 100
++set g_balance_laser_shockwave_splash_force_forwardbias 50
++set g_balance_laser_shockwave_splash_multiplier_accuracy 0.5
++set g_balance_laser_shockwave_splash_multiplier_distance 0.5
++set g_balance_laser_shockwave_splash_multiplier_min 0
++set g_balance_laser_shockwave_splash_radius 70
++set g_balance_laser_shockwave_spread_max 120
++set g_balance_laser_shockwave_spread_min 25
++
+ set g_balance_laser_switchdelay_drop 0
+ set g_balance_laser_switchdelay_raise 0
+ set g_balance_laser_reload_ammo 0 //default: 6
+ set g_balance_laser_reload_time 2
+ // }}}
+ // {{{ shotgun
+ set g_balance_shotgun_primary_bullets 14
+ set g_balance_shotgun_primary_damage 4
+ set g_balance_shotgun_primary_force 15
+ set g_balance_shotgun_primary_spread 0.12
+ set g_balance_shotgun_primary_refire 0.75
+ set g_balance_shotgun_primary_animtime 0.2
+ set g_balance_shotgun_primary_ammo 1
+ set g_balance_shotgun_primary_speed 8000
+ set g_balance_shotgun_primary_bulletconstant 75 // 3.8qu
+ set g_balance_shotgun_secondary 1
+ set g_balance_shotgun_secondary_melee_delay 0.25 // 0.35 was too slow
+ set g_balance_shotgun_secondary_melee_range 120
+ set g_balance_shotgun_secondary_melee_swing_side 120
+ set g_balance_shotgun_secondary_melee_swing_up 30
+ set g_balance_shotgun_secondary_melee_time 0.15
+ set g_balance_shotgun_secondary_melee_traces 10
+ set g_balance_shotgun_secondary_melee_no_doubleslap 1
+ set g_balance_shotgun_secondary_melee_nonplayerdamage 40
+ set g_balance_shotgun_secondary_melee_multihit 1
+ set g_balance_shotgun_secondary_damage 80
+ set g_balance_shotgun_secondary_force 200
+ set g_balance_shotgun_secondary_refire 1.25
+ set g_balance_shotgun_secondary_animtime 1
+ set g_balance_shotgun_switchdelay_drop 0
+ set g_balance_shotgun_switchdelay_raise 0
+ set g_balance_shotgun_reload_ammo 0 //default: 5
+ set g_balance_shotgun_reload_time 2
+ // }}}
+ // {{{ uzi
+ set g_balance_uzi_mode 1 // Activates varible spread for sustained & burst mode secondary
+ set g_balance_uzi_spread_min 0
+ set g_balance_uzi_spread_max 0
+ set g_balance_uzi_spread_add 0
+
+ set g_balance_uzi_burst 3 // # of bullets in a burst (if set to 2 or more)
+ set g_balance_uzi_burst_animtime 0.3
+ set g_balance_uzi_burst_refire 0.06 // refire between burst bullets
+ set g_balance_uzi_burst_refire2 0.45 // refire after burst
+ set g_balance_uzi_burst_spread 0.03
+ set g_balance_uzi_burst_damage 25
+ set g_balance_uzi_burst_force 20
+ set g_balance_uzi_burst_ammo 3
+
+ set g_balance_uzi_first 1
+ set g_balance_uzi_first_damage 14
+ set g_balance_uzi_first_force 5
+ set g_balance_uzi_first_spread 0.03
+ set g_balance_uzi_first_refire 0.4
+ set g_balance_uzi_first_ammo 1
+
+ set g_balance_uzi_sustained_damage 12
+ set g_balance_uzi_sustained_force 5
+ set g_balance_uzi_sustained_spread 0
+ 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
+
+ set g_balance_uzi_switchdelay_drop 0
+ set g_balance_uzi_switchdelay_raise 0
+
+ set g_balance_uzi_reload_ammo 0 //default: 30
+ set g_balance_uzi_reload_time 2
+ // }}}
+ // {{{ mortar
+ set g_balance_grenadelauncher_primary_type 0
+ set g_balance_grenadelauncher_primary_damage 50
+ set g_balance_grenadelauncher_primary_edgedamage 25
+ set g_balance_grenadelauncher_primary_force 250
+ set g_balance_grenadelauncher_primary_radius 100
+ set g_balance_grenadelauncher_primary_speed 2000
+ set g_balance_grenadelauncher_primary_speed_up 200
+ set g_balance_grenadelauncher_primary_speed_z 0
+ set g_balance_grenadelauncher_primary_spread 0
+ set g_balance_grenadelauncher_primary_lifetime 5
+ set g_balance_grenadelauncher_primary_lifetime2 1
+ 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 0
+ set g_balance_grenadelauncher_primary_damageforcescale 0
+ 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 30
+ set g_balance_grenadelauncher_secondary_force 300
+ set g_balance_grenadelauncher_secondary_radius 200
+ set g_balance_grenadelauncher_secondary_speed 800
+ set g_balance_grenadelauncher_secondary_speed_up 0
+ set g_balance_grenadelauncher_secondary_speed_z 200
+ set g_balance_grenadelauncher_secondary_spread 0
+ set g_balance_grenadelauncher_secondary_lifetime 8
+ set g_balance_grenadelauncher_secondary_lifetime_bounce 0.5
+ set g_balance_grenadelauncher_secondary_lifetime_stick 0
+ set g_balance_grenadelauncher_secondary_refire 0.7
+ set g_balance_grenadelauncher_secondary_animtime 0.5
+ set g_balance_grenadelauncher_secondary_ammo 2
+ set g_balance_grenadelauncher_secondary_health 0
+ set g_balance_grenadelauncher_secondary_damageforcescale 0
+ set g_balance_grenadelauncher_secondary_remote_detonateprimary 0
+
+ set g_balance_grenadelauncher_bouncefactor 0.5
+ set g_balance_grenadelauncher_bouncestop 0.075
+
+ set g_balance_grenadelauncher_switchdelay_drop 0
+ set g_balance_grenadelauncher_switchdelay_raise 0
+
+ set g_balance_grenadelauncher_reload_ammo 0 //default: 12
+ set g_balance_grenadelauncher_reload_time 2
+ // }}}
+ // {{{ electro
+ set g_balance_electro_lightning 0
+ set g_balance_electro_primary_damage 55
+ set g_balance_electro_primary_edgedamage 27.5
+ set g_balance_electro_primary_force 200
+ set g_balance_electro_primary_force_up 0
+ set g_balance_electro_primary_radius 100
+ set g_balance_electro_primary_comboradius 150
+ set g_balance_electro_primary_speed 2500
+ set g_balance_electro_primary_spread 0
+ set g_balance_electro_primary_lifetime 5
+ set g_balance_electro_primary_refire 0.6
+ set g_balance_electro_primary_animtime 0.1
+ set g_balance_electro_primary_ammo 4
+ set g_balance_electro_primary_range 0
+ 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 40
+ set g_balance_electro_secondary_edgedamage 20
+ set g_balance_electro_secondary_force 200
+ set g_balance_electro_secondary_radius 150
+ set g_balance_electro_secondary_speed 900
+ set g_balance_electro_secondary_speed_up 200
+ set g_balance_electro_secondary_speed_z 0
+ set g_balance_electro_secondary_spread 0.05
+ set g_balance_electro_secondary_lifetime 3
+ set g_balance_electro_secondary_refire 0.2
+ set g_balance_electro_secondary_refire2 1.5
+ set g_balance_electro_secondary_animtime 0.2
+ set g_balance_electro_secondary_ammo 2
+ set g_balance_electro_secondary_health 5
+ set g_balance_electro_secondary_damageforcescale 4
+ set g_balance_electro_secondary_damagedbycontents 1
+ set g_balance_electro_secondary_count 3
+ set g_balance_electro_secondary_bouncefactor 0.4
+ set g_balance_electro_secondary_bouncestop 0.05
+ set g_balance_electro_combo_damage 40
+ set g_balance_electro_combo_edgedamage 20
+ set g_balance_electro_combo_force 120
+ set g_balance_electro_combo_radius 175
+ set g_balance_electro_combo_comboradius 275
+ set g_balance_electro_combo_speed 2000
+ set g_balance_electro_combo_safeammocheck 1
+ set g_balance_electro_switchdelay_drop 0
+ set g_balance_electro_switchdelay_raise 0
+ set g_balance_electro_reload_ammo 0 //default: 20
+ set g_balance_electro_reload_time 2
+ // }}}
+ // {{{ crylink
+ set g_balance_crylink_primary_damage 12
+ set g_balance_crylink_primary_edgedamage 6
+ set g_balance_crylink_primary_force -50
+ set g_balance_crylink_primary_radius 80
+ set g_balance_crylink_primary_speed 2000
+ set g_balance_crylink_primary_spread 0.08
+ set g_balance_crylink_primary_shots 6
+ set g_balance_crylink_primary_bounces 1
+ set g_balance_crylink_primary_refire 0.7
+ set g_balance_crylink_primary_animtime 0.3
+ set g_balance_crylink_primary_ammo 3
+ set g_balance_crylink_primary_bouncedamagefactor 0.5
+ set g_balance_crylink_primary_joindelay 0.1
+ set g_balance_crylink_primary_joinspread 0.2
+ set g_balance_crylink_primary_jointime 0
+ set g_balance_crylink_primary_joinexplode 1
+ set g_balance_crylink_primary_joinexplode_damage 0
+ set g_balance_crylink_primary_joinexplode_edgedamage 0
+ set g_balance_crylink_primary_joinexplode_radius 0
+ set g_balance_crylink_primary_joinexplode_force 0
+ set g_balance_crylink_primary_linkexplode 1
+
+ set g_balance_crylink_primary_middle_lifetime 5 // range: 35000 full, fades to 70000
+ set g_balance_crylink_primary_middle_fadetime 5
+ set g_balance_crylink_primary_other_lifetime 5
+ set g_balance_crylink_primary_other_fadetime 5
+
+ set g_balance_crylink_secondary 1
+ set g_balance_crylink_secondary_damage 10
+ set g_balance_crylink_secondary_edgedamage 5
+ set g_balance_crylink_secondary_force -150
+ set g_balance_crylink_secondary_radius 100
+ set g_balance_crylink_secondary_speed 3000
+ set g_balance_crylink_secondary_spread 0.01
+ set g_balance_crylink_secondary_spreadtype 1
+ set g_balance_crylink_secondary_shots 5
+ set g_balance_crylink_secondary_bounces 0
+ set g_balance_crylink_secondary_refire 0.7
+ set g_balance_crylink_secondary_animtime 0.2
+ set g_balance_crylink_secondary_ammo 2
+ set g_balance_crylink_secondary_bouncedamagefactor 0.5
+ set g_balance_crylink_secondary_joindelay 0
+ set g_balance_crylink_secondary_joinspread 0
+ set g_balance_crylink_secondary_jointime 0
+ set g_balance_crylink_secondary_joinexplode 0
+ set g_balance_crylink_secondary_joinexplode_damage 0
+ set g_balance_crylink_secondary_joinexplode_edgedamage 0
+ set g_balance_crylink_secondary_joinexplode_radius 0
+ set g_balance_crylink_secondary_joinexplode_force 0
+ set g_balance_crylink_secondary_linkexplode 1
+
+ set g_balance_crylink_secondary_middle_lifetime 5 // range: 35000 full, fades to 70000
+ set g_balance_crylink_secondary_middle_fadetime 5
+ set g_balance_crylink_secondary_line_lifetime 5
+ set g_balance_crylink_secondary_line_fadetime 5
+
+ set g_balance_crylink_switchdelay_drop 0
+ set g_balance_crylink_switchdelay_raise 0
+
+ set g_balance_crylink_reload_ammo 0 //default: 10
+ set g_balance_crylink_reload_time 2
+ // }}}
+ // {{{ nex
+ set g_balance_nex_primary_damage 90
+ set g_balance_nex_primary_force 400
+ set g_balance_nex_primary_refire 1.5
+ set g_balance_nex_primary_animtime 0.4
+ set g_balance_nex_primary_ammo 6
+ set g_balance_nex_primary_damagefalloff_mindist 0 // 1000 For tZork ;3
+ set g_balance_nex_primary_damagefalloff_maxdist 0 // 3000
+ set g_balance_nex_primary_damagefalloff_halflife 0 // 1500
+ set g_balance_nex_primary_damagefalloff_forcehalflife 0 // 1500
+
+ set g_balance_nex_secondary 0
+ set g_balance_nex_secondary_charge 0
+ set g_balance_nex_secondary_charge_rate 0.1
+ set g_balance_nex_secondary_chargepool 0
+ set g_balance_nex_secondary_chargepool_regen 0.15
+ set g_balance_nex_secondary_chargepool_pause_regen 1
+ set g_balance_nex_secondary_chargepool_pause_health_regen 1
+ set g_balance_nex_secondary_damage 0
+ set g_balance_nex_secondary_force 0
+ set g_balance_nex_secondary_refire 0
+ set g_balance_nex_secondary_animtime 0
+ set g_balance_nex_secondary_ammo 2
+ set g_balance_nex_secondary_damagefalloff_mindist 0
+ set g_balance_nex_secondary_damagefalloff_maxdist 0
+ set g_balance_nex_secondary_damagefalloff_halflife 0
+ set g_balance_nex_secondary_damagefalloff_forcehalflife 0
+
+ set g_balance_nex_charge 1
+ set g_balance_nex_charge_mindmg 40
+ set g_balance_nex_charge_start 0.5
+ set g_balance_nex_charge_rate 0.4
+ set g_balance_nex_charge_animlimit 0.5
+ set g_balance_nex_charge_limit 1
+ set g_balance_nex_charge_rot_rate 0
+ set g_balance_nex_charge_rot_pause 0 // Dont rot down untill this long after release of charge button
+ set g_balance_nex_charge_shot_multiplier 0
+ set g_balance_nex_charge_velocity_rate 0
+ set g_balance_nex_charge_minspeed 400
+ set g_balance_nex_charge_maxspeed 800
+
+ set g_balance_nex_switchdelay_drop 0
+ set g_balance_nex_switchdelay_raise 0
+
+ set g_balance_nex_reload_ammo 0 //default: 25
+ set g_balance_nex_reload_time 2
+ // }}}
+ // {{{ minstanex
+ set g_balance_minstanex_refire 1
+ set g_balance_minstanex_animtime 0.3
+ set g_balance_minstanex_ammo 10
+ set g_balance_minstanex_laser_ammo 0
+ set g_balance_minstanex_laser_animtime 0.3
+ set g_balance_minstanex_laser_refire 0.7
+ set g_balance_minstanex_switchdelay_drop 0
+ set g_balance_minstanex_switchdelay_raise 0
+ set g_balance_minstanex_reload_ammo 0 //default: 50
+ set g_balance_minstanex_reload_time 2
+ // }}}
+ // {{{ hagar
+ set g_balance_hagar_primary_damage 25
+ set g_balance_hagar_primary_edgedamage 12.5
+ set g_balance_hagar_primary_force 92
+ set g_balance_hagar_primary_health 15
+ set g_balance_hagar_primary_damageforcescale 0
+ set g_balance_hagar_primary_radius 25
+ set g_balance_hagar_primary_spread 0.03
+ set g_balance_hagar_primary_speed 2000
+ set g_balance_hagar_primary_lifetime 5
+ set g_balance_hagar_primary_refire 0.11
+ set g_balance_hagar_primary_ammo 1
+ set g_balance_hagar_secondary 0
+ set g_balance_hagar_secondary_load 1
+ set g_balance_hagar_secondary_load_speed 0.5
+ set g_balance_hagar_secondary_load_spread 0.075
+ set g_balance_hagar_secondary_load_spread_bias 0.5
+ set g_balance_hagar_secondary_load_max 4
+ set g_balance_hagar_secondary_load_hold 4
+ set g_balance_hagar_secondary_load_releasedeath 0
+ set g_balance_hagar_secondary_load_abort 0
+ set g_balance_hagar_secondary_load_linkexplode 0
+ set g_balance_hagar_secondary_load_animtime 0.2
+ set g_balance_hagar_secondary_damage 40
+ set g_balance_hagar_secondary_edgedamage 20
+ set g_balance_hagar_secondary_force 75
+ set g_balance_hagar_secondary_health 15
+ set g_balance_hagar_secondary_damageforcescale 0
+ set g_balance_hagar_secondary_radius 80
+ set g_balance_hagar_secondary_spread 0.05
+ set g_balance_hagar_secondary_speed 2000
+ set g_balance_hagar_secondary_lifetime_min 10
+ set g_balance_hagar_secondary_lifetime_rand 0
+ set g_balance_hagar_secondary_refire 0.5
+ set g_balance_hagar_secondary_ammo 1
+ set g_balance_hagar_switchdelay_drop 0
+ set g_balance_hagar_switchdelay_raise 0
+ set g_balance_hagar_reload_ammo 0 //default: 25
+ set g_balance_hagar_reload_time 2
+ // }}}
+ // {{{ rocketlauncher
+ set g_balance_rocketlauncher_damage 80
+ set g_balance_rocketlauncher_edgedamage 40
+ set g_balance_rocketlauncher_force 350
+ set g_balance_rocketlauncher_radius 110
+ set g_balance_rocketlauncher_speed 1000
+ set g_balance_rocketlauncher_speedaccel 0
+ set g_balance_rocketlauncher_speedstart 1000
+ set g_balance_rocketlauncher_lifetime 100
+ set g_balance_rocketlauncher_refire 0.9
+ set g_balance_rocketlauncher_animtime 0.7
+ set g_balance_rocketlauncher_ammo 4
+ set g_balance_rocketlauncher_health 0 // 30 // 5 hitpoints above maximum laser value -- this way lasers can't blow it up, but grenadelauncher still can most the time.
+ set g_balance_rocketlauncher_damageforcescale 0 // low damage force scale so that it can still be affected by other hits, but not so much that it does a 90 degree turn
+ set g_balance_rocketlauncher_detonatedelay 999 // positive: timer till detonation is allowed, negative: "security device" that prevents ANY remote detonation if it could hurt its owner, zero: detonatable at any time
+ set g_balance_rocketlauncher_guiderate 0 // max degrees per second
+ set g_balance_rocketlauncher_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.2 // delay before guiding kicks in
+ set g_balance_rocketlauncher_guidestop 1 // stop guiding when firing again
+ set g_balance_rocketlauncher_remote_damage 70
+ set g_balance_rocketlauncher_remote_edgedamage 35
+ set g_balance_rocketlauncher_remote_radius 110
+ set g_balance_rocketlauncher_remote_force 350
+ set g_balance_rocketlauncher_switchdelay_drop 0
+ set g_balance_rocketlauncher_switchdelay_raise 0
+ set g_balance_rocketlauncher_reload_ammo 0 //default: 25
+ set g_balance_rocketlauncher_reload_time 2
+ // }}}
+ // {{{ 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 5
+ set g_balance_porto_secondary 1
+ set g_balance_porto_secondary_refire 1.5
+ set g_balance_porto_secondary_animtime 0.3
+ set g_balance_porto_secondary_speed 1000
+ set g_balance_porto_secondary_lifetime 5
+ set g_balance_porto_switchdelay_drop 0
+ set g_balance_porto_switchdelay_raise 0
+ set g_balance_portal_health 200 // these get recharged whenever the portal is used
+ set g_balance_portal_lifetime 15 // these get recharged whenever the portal is used
+ // }}}
+ // {{{ hook
+ set g_balance_hook_primary_fuel 5 // hook monkeys set 0
+ set g_balance_hook_primary_refire 0 // hook monkeys set 0
+ set g_balance_hook_primary_animtime 0.3 // good shoot anim
+ set g_balance_hook_primary_hooked_time_max 0 // infinite
+ set g_balance_hook_primary_hooked_time_free 2 // 2s being hooked are free
+ set g_balance_hook_primary_hooked_fuel 5 // fuel per second hooked
+ set g_balance_hook_secondary_damage 25 // not much
+ set g_balance_hook_secondary_edgedamage 5 // not much
+ set g_balance_hook_secondary_radius 500 // LOTS
+ set g_balance_hook_secondary_force -2000 // LOTS
+ set g_balance_hook_secondary_ammo 50 // a whole pack
+ set g_balance_hook_secondary_lifetime 5 // infinite
+ set g_balance_hook_secondary_speed 0 // not much throwing
+ set g_balance_hook_secondary_gravity 5 // fast falling
+ set g_balance_hook_secondary_refire 3 // don't drop too many bombs...
+ set g_balance_hook_secondary_animtime 0.3 // good shoot anim
+ set g_balance_hook_secondary_power 3 // effect behaves like a square function
+ set g_balance_hook_secondary_duration 1.5 // effect runs for three seconds
+ set g_balance_hook_secondary_health 15
+ set g_balance_hook_secondary_damageforcescale 0
+ set g_balance_hook_switchdelay_drop 0
+ set g_balance_hook_switchdelay_raise 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
+ set g_balance_tuba_pitchstep 6
+ set g_balance_tuba_switchdelay_drop 0
+ set g_balance_tuba_switchdelay_raise 0
+ // }}}
+ // {{{ fireball // this is a superweapon -- lets make it behave as one.
+ set g_balance_fireball_primary_animtime 0.2
+ set g_balance_fireball_primary_bfgdamage 100
+ set g_balance_fireball_primary_bfgforce 0
+ set g_balance_fireball_primary_bfgradius 1000
+ set g_balance_fireball_primary_damage 200
+ set g_balance_fireball_primary_damageforcescale 0
+ set g_balance_fireball_primary_edgedamage 50
+ set g_balance_fireball_primary_force 600
+ set g_balance_fireball_primary_health 0
+ set g_balance_fireball_primary_laserburntime 0.5
+ set g_balance_fireball_primary_laserdamage 80
+ set g_balance_fireball_primary_laseredgedamage 20
+ set g_balance_fireball_primary_laserradius 256
+ set g_balance_fireball_primary_lifetime 15
+ set g_balance_fireball_primary_radius 200
+ set g_balance_fireball_primary_refire 2
+ set g_balance_fireball_primary_refire2 0
+ set g_balance_fireball_primary_speed 1200
+ set g_balance_fireball_primary_spread 0
+ set g_balance_fireball_secondary_animtime 0.3
+ set g_balance_fireball_secondary_damage 40
+ set g_balance_fireball_secondary_damageforcescale 4
+ set g_balance_fireball_secondary_damagetime 5
+ set g_balance_fireball_secondary_force 100
+ set g_balance_fireball_secondary_laserburntime 0.5
+ set g_balance_fireball_secondary_laserdamage 50
+ set g_balance_fireball_secondary_laseredgedamage 20
+ set g_balance_fireball_secondary_laserradius 110
+ set g_balance_fireball_secondary_lifetime 7
+ set g_balance_fireball_secondary_refire 1.5
+ set g_balance_fireball_secondary_speed 900
+ set g_balance_fireball_secondary_speed_up 100
+ set g_balance_fireball_secondary_speed_z 0
+ set g_balance_fireball_secondary_spread 0
+ set g_balance_fireball_switchdelay_drop 0
+ set g_balance_fireball_switchdelay_raise 0
+ // }}}
// {{{ weapon properties
// {{{ laser
- set g_balance_laser_primary 1 // 0 = shockwave attack, 1 = projectile primary
+set g_balance_laser_melee_animtime 0.3
+set g_balance_laser_melee_damage 80
+set g_balance_laser_melee_delay 0.25
+set g_balance_laser_melee_force 200
+set g_balance_laser_melee_multihit 1
+set g_balance_laser_melee_no_doubleslap 1
+set g_balance_laser_melee_nonplayerdamage 40
+set g_balance_laser_melee_range 120
+set g_balance_laser_melee_refire 1.25
+set g_balance_laser_melee_swing_side 120
+set g_balance_laser_melee_swing_up 30
+set g_balance_laser_melee_time 0.15
+set g_balance_laser_melee_traces 10
+
++set g_balance_laser_primary 0 // 0 = shockwave attack, 1 = projectile primary
set g_balance_laser_primary_damage 25
set g_balance_laser_primary_edgedamage 12.5
set g_balance_laser_primary_force 300
set g_balance_laser_primary_force_zscale 1.25
set g_balance_laser_primary_force_velocitybias 0
set g_balance_laser_primary_force_other_scale 1
-set g_balance_laser_secondary 0 // when 1, a secondary laser mode exists
+
- set g_balance_laser_reload_ammo 0 //default: 6
- set g_balance_laser_reload_time 2
-
- set g_balance_laser_secondary 0 // 0 = switch away to last used weapon, 1 = projectile secondary, 2 = melee secondary
++set g_balance_laser_secondary 2 // 0 = switch away to last used weapon, 1 = projectile secondary, 2 = melee secondary
set g_balance_laser_secondary_damage 25
set g_balance_laser_secondary_edgedamage 12.5
set g_balance_laser_secondary_force 400
set g_balance_laser_secondary_force_zscale 1.25
set g_balance_laser_secondary_force_velocitybias 0
set g_balance_laser_secondary_force_other_scale 1
- set g_balance_laser_shockwave_force_zscale 1.5
+
+set g_balance_laser_shockwave_damage 20
+set g_balance_laser_shockwave_distance 2000
+set g_balance_laser_shockwave_edgedamage 0
+set g_balance_laser_shockwave_force 200
+set g_balance_laser_shockwave_force_forwardbias 50
- set g_balance_laser_shockwave_spread_max 100
- set g_balance_laser_shockwave_spread_min 20
++set g_balance_laser_shockwave_force_zscale 2
+set g_balance_laser_shockwave_jump_damage 20
+set g_balance_laser_shockwave_jump_edgedamage 0
+set g_balance_laser_shockwave_jump_force 300
+set g_balance_laser_shockwave_jump_force_velocitybias 0
+set g_balance_laser_shockwave_jump_force_zscale 1.25
+set g_balance_laser_shockwave_jump_multiplier_accuracy 0.5
+set g_balance_laser_shockwave_jump_multiplier_distance 0.5
+set g_balance_laser_shockwave_jump_multiplier_min 0
+set g_balance_laser_shockwave_jump_radius 150
+set g_balance_laser_shockwave_multiplier_accuracy 0.5
+set g_balance_laser_shockwave_multiplier_distance 0.5
+set g_balance_laser_shockwave_multiplier_min 0
+set g_balance_laser_shockwave_splash_damage 15
+set g_balance_laser_shockwave_splash_edgedamage 0
+set g_balance_laser_shockwave_splash_force 100
+set g_balance_laser_shockwave_splash_force_forwardbias 50
+set g_balance_laser_shockwave_splash_multiplier_accuracy 0.5
+set g_balance_laser_shockwave_splash_multiplier_distance 0.5
+set g_balance_laser_shockwave_splash_multiplier_min 0
+set g_balance_laser_shockwave_splash_radius 70
++set g_balance_laser_shockwave_spread_max 120
++set g_balance_laser_shockwave_spread_min 25
++
+ set g_balance_laser_switchdelay_drop 0.15
+ set g_balance_laser_switchdelay_raise 0.15
+ set g_balance_laser_reload_ammo 0 //default: 6
+ set g_balance_laser_reload_time 2
// }}}
// {{{ shotgun
set g_balance_shotgun_primary_bullets 14
set g_balance_laser_primary_force_zscale 1.25
set g_balance_laser_primary_force_velocitybias 0
set g_balance_laser_primary_force_other_scale 1
-set g_balance_laser_secondary 0 // when 1, a secondary laser mode exists
+
- set g_balance_laser_reload_ammo 0 //default: 6
- set g_balance_laser_reload_time 2
-
+set g_balance_laser_secondary 2 // 0 = switch away to last used weapon, 1 = projectile secondary, 2 = melee secondary
set g_balance_laser_secondary_damage 25
set g_balance_laser_secondary_edgedamage 12.5
set g_balance_laser_secondary_force 400
set g_balance_laser_secondary_force_zscale 1.25
set g_balance_laser_secondary_force_velocitybias 0
set g_balance_laser_secondary_force_other_scale 1
+
+set g_balance_laser_shockwave_damage 20
+set g_balance_laser_shockwave_distance 2000
+set g_balance_laser_shockwave_edgedamage 0
+set g_balance_laser_shockwave_force 200
+set g_balance_laser_shockwave_force_forwardbias 50
+set g_balance_laser_shockwave_force_zscale 2
+set g_balance_laser_shockwave_jump_damage 20
+set g_balance_laser_shockwave_jump_edgedamage 0
+set g_balance_laser_shockwave_jump_force 300
+set g_balance_laser_shockwave_jump_force_velocitybias 0
+set g_balance_laser_shockwave_jump_force_zscale 1.25
+set g_balance_laser_shockwave_jump_multiplier_accuracy 0.5
+set g_balance_laser_shockwave_jump_multiplier_distance 0.5
+set g_balance_laser_shockwave_jump_multiplier_min 0
+set g_balance_laser_shockwave_jump_radius 150
+set g_balance_laser_shockwave_multiplier_accuracy 0.5
+set g_balance_laser_shockwave_multiplier_distance 0.5
+set g_balance_laser_shockwave_multiplier_min 0
+set g_balance_laser_shockwave_splash_damage 15
+set g_balance_laser_shockwave_splash_edgedamage 0
+set g_balance_laser_shockwave_splash_force 100
+set g_balance_laser_shockwave_splash_force_forwardbias 50
+set g_balance_laser_shockwave_splash_multiplier_accuracy 0.5
+set g_balance_laser_shockwave_splash_multiplier_distance 0.5
+set g_balance_laser_shockwave_splash_multiplier_min 0
+set g_balance_laser_shockwave_splash_radius 70
+set g_balance_laser_shockwave_spread_max 120
+set g_balance_laser_shockwave_spread_min 25
++
+ set g_balance_laser_switchdelay_drop 0.15
+ set g_balance_laser_switchdelay_raise 0.15
+ set g_balance_laser_reload_ammo 0 //default: 6
+ set g_balance_laser_reload_time 2
// }}}
// {{{ shotgun
set g_balance_shotgun_primary_bullets 14
airfriction 0.04
gravity -0.2
+ // redflag_touch -- effects for touching the red flag
+ // used nowhere in code
+ effect redflag_touch
+ count 35
+ type spark
+ tex 40 40
+ color 0xFF0000 0x970000
+ size 1 3
+ alpha 0 256 556
+ gravity 1
+ bounce 1.5
+ originjitter 1 1 1
+ velocityjitter 300 300 300
+ velocitymultiplier 0.5
+ airfriction 3
+
+ // blueflag_touch -- effects for touching the blue flag
+ // used nowhere in code
+ effect blueflag_touch
+ count 35
+ type spark
+ tex 40 40
+ color 0x0000FF 0x000097
+ size 1 3
+ alpha 0 256 556
+ gravity 1
+ bounce 1.5
+ originjitter 1 1 1
+ velocityjitter 300 300 300
+ velocitymultiplier 0.5
+ airfriction 3
+
+ // red_pass
+ // used nowhere in code
+ effect red_pass
+ trailspacing 64
+ color 0xFF0000 0x970000
+ size 2 2
+ tex 32 32
+ alpha 64 128 64
+ airfriction 5
+ sizeincrease 2
+ type static
+ effect red_pass
+ trailspacing 12
+ color 0xFF0000 0x970000
+ size 1 1
+ tex 0 8
+ alpha 32 64 32
+ airfriction 9
+ sizeincrease 8
+ velocityjitter 64 64 64
+ type static
+ effect red_pass
+ trailspacing 12
+ color 0xFF0000 0x970000
+ size 4 4
+ //tex 48 55
+ alpha 256 256 1280
+ type static
+
+ // blue_pass
+ // used nowhere in code
+ effect blue_pass
+ trailspacing 64
+ color 0x0000FF 0x000097
+ size 2 2
+ tex 32 32
+ alpha 64 128 64
+ airfriction 5
+ sizeincrease 2
+ type static
+ effect blue_pass
+ trailspacing 12
+ color 0x0000FF 0x000097
+ size 1 1
+ tex 0 8
+ alpha 32 64 32
+ airfriction 9
+ sizeincrease 8
+ velocityjitter 64 64 64
+ type static
+ effect blue_pass
+ trailspacing 12
+ color 0x0000FF 0x000097
+ size 4 4
+ //tex 48 55
+ alpha 256 256 1280
+ type static
+
+ // red_cap -- red team capture effect
+ effect red_cap
+ count 500
+ type spark
+ tex 64 64
+ color 0xFF0000 0x970000
+ size 1 1
+ alpha 0 256 100
+ stretchfactor 2
+ //gravity 1
+ bounce 1.5
+ originjitter 1 1 1
+ velocityjitter 1000 1000 1500
+ velocitymultiplier 0.5
+ airfriction 2
+ stretchfactor 0.6
+ effect red_cap
+ countabsolute 1
+ type smoke
+ tex 65 65
+ size 150 150
+ alpha 190 190 180
+ sizeincrease -80
+ color 0xFF0000 0x970000
+
+ // blue_cap -- blue team capture effect
+ effect blue_cap
+ count 500
+ type spark
+ tex 64 64
+ color 0x0000FF 0x000097
+ size 1 1
+ alpha 0 256 100
+ stretchfactor 2
+ //gravity 1
+ bounce 1.5
+ originjitter 1 1 1
+ velocityjitter 1000 1000 1500
+ velocitymultiplier 0.5
+ airfriction 2
+ stretchfactor 0.6
+ effect blue_cap
+ countabsolute 1
+ type smoke
+ tex 65 65
+ size 150 150
+ alpha 190 190 180
+ sizeincrease -80
+ color 0x0000FF 0x000097
+
+ // spawn_point_red -- red team idle spawn point effect
+ effect spawn_point_red
+ count 37.5
+ type static
+ color 0xFF0F0F 0xFF0F0F
+ size 1.0 2.0
+ alpha 64 128 128
+ gravity -0.1
+ airfriction 0.2
+ liquidfriction 0.8
+ originjitter 16 16 64
+ velocityjitter 32 32 0
+ //lightradius 200
+ //lighttime 0
+ //lightcolor 0.4 0.9 0.9
+
+ // spawn_point_blue -- blue team idle spawn point effect
+ effect spawn_point_blue
+ count 37.5
+ type static
+ color 0x0F0FFF 0x0F0FFF
+ size 1.0 2.0
+ alpha 64 128 128
+ gravity -0.1
+ airfriction 0.2
+ liquidfriction 0.8
+ originjitter 16 16 64
+ velocityjitter 32 32 0
+ //lightradius 200
+ //lighttime 0
+ //lightcolor 0.4 0.9 0.9
+
+ // spawn_point_yellow -- yellow team idle spawn point effect
+ effect spawn_point_yellow
+ count 37.5
+ type static
+ color 0xFFFF0F 0xFFFF0F
+ size 1.0 2.0
+ alpha 64 128 128
+ gravity -0.1
+ airfriction 0.2
+ liquidfriction 0.8
+ originjitter 16 16 64
+ velocityjitter 32 32 0
+ //lightradius 200
+ //lighttime 0
+ //lightcolor 0.4 0.9 0.9
+
+ // spawn_point_pink -- pink team idle spawn point effect
+ effect spawn_point_pink
+ count 37.5
+ type static
+ color 0xFF0FFF 0xFF0FFF
+ size 1.0 2.0
+ alpha 64 128 128
+ gravity -0.1
+ airfriction 0.2
+ liquidfriction 0.8
+ originjitter 16 16 64
+ velocityjitter 32 32 0
+ //lightradius 200
+ //lighttime 0
+ //lightcolor 0.4 0.9 0.9
+
+ // spawn_point_neutral -- neutral idle spawn point effect
+ effect spawn_point_neutral
+ count 37.5
+ type static
+ color 0xFFFFFF 0xFFFFFF
+ size 1.0 2.0
+ alpha 64 128 128
+ gravity -0.1
+ airfriction 0.2
+ liquidfriction 0.8
+ originjitter 16 16 64
+ velocityjitter 32 32 0
+ //lightradius 200
+ //lighttime 0
+ //lightcolor 0.4 0.9 0.9
+
+ // spawn_event_red -- red team spawning effect
+ effect spawn_event_red
+ count 100
+ type spark
+ tex 64 64
+ color 0xFF0F0F 0xFF0F0F
+ size 1 1
+ alpha 0 256 256
+ stretchfactor 0.6
+ //gravity 1
+ bounce 1
+ originjitter 1 1 1
+ velocityjitter 500 500 500
+ velocitymultiplier 0.1
+ airfriction 2
+ effect spawn_event_red
+ countabsolute 1
+ type smoke
+ tex 65 65
+ size 100 100
+ alpha 190 190 180
+ sizeincrease -80
+ color 0xFF0F0F 0xFF0F0F
+
+ // spawn_event_blue -- blue team spawning effect
+ effect spawn_event_blue
+ count 100
+ type spark
+ tex 64 64
+ color 0x0F0FFF 0x0F0FFF
+ size 1 1
+ alpha 0 256 256
+ stretchfactor 0.6
+ //gravity 1
+ bounce 1
+ originjitter 1 1 1
+ velocityjitter 500 500 500
+ velocitymultiplier 0.1
+ airfriction 2
+ effect spawn_event_blue
+ countabsolute 1
+ type smoke
+ tex 65 65
+ size 100 100
+ alpha 190 190 180
+ sizeincrease -80
+ color 0x0F0FFF 0x0F0FFF
+
+ // spawn_event_yellow -- yellow team spawning effect
+ effect spawn_event_yellow
+ count 100
+ type spark
+ tex 64 64
+ color 0xFFFF0F 0xFFFF0F
+ size 1 1
+ alpha 0 256 256
+ stretchfactor 0.6
+ //gravity 1
+ bounce 1
+ originjitter 1 1 1
+ velocityjitter 500 500 500
+ velocitymultiplier 0.1
+ airfriction 2
+ effect spawn_event_yellow
+ countabsolute 1
+ type smoke
+ tex 65 65
+ size 100 100
+ alpha 190 190 180
+ sizeincrease -80
+ color 0xFFFF0F 0xFFFF0F
+
+ // spawn_event_pink -- pink team spawning effect
+ effect spawn_event_pink
+ count 100
+ type spark
+ tex 64 64
+ color 0xFF0FFF 0xFF0FFF
+ size 1 1
+ alpha 0 256 256
+ stretchfactor 0.6
+ //gravity 1
+ bounce 1
+ originjitter 1 1 1
+ velocityjitter 500 500 500
+ velocitymultiplier 0.1
+ airfriction 2
+ effect spawn_event_pink
+ countabsolute 1
+ type smoke
+ tex 65 65
+ size 100 100
+ alpha 190 190 180
+ sizeincrease -80
+ color 0xFF0FFF 0xFF0FFF
+
+ // spawn_event_neutral -- neutral spawning effect
+ effect spawn_event_neutral
+ count 100
+ type spark
+ tex 64 64
+ color 0xFFFFFF 0xFFFFFF
+ size 1 1
+ alpha 0 256 256
+ stretchfactor 0.6
+ //gravity 1
+ bounce 1
+ originjitter 1 1 1
+ velocityjitter 500 500 500
+ velocitymultiplier 0.1
+ airfriction 2
+ effect spawn_event_neutral
+ countabsolute 1
+ type smoke
+ tex 65 65
+ size 100 100
+ alpha 190 190 180
+ sizeincrease -80
+ color 0xFFFFFF 0xFFFFFF
+
+// laser_shockwave_attack
+// used nowhere in code
+effect laser_shockwave_attack
+// glow and light
+//countabsolute 1
+//type smoke
+//color 0xcc0000 0xff0000
+//tex 65 65
+//size 10 15
+//alpha 256 512 6280
+//airfriction 10
+//sizeincrease 1.5
+//stretchfactor 2
+//lightradius 200
+//lightradiusfade 2000
+//lightcolor 3 0.1 0.1
+// electricity
+effect laser_shockwave_attack
+count 1
+type spark
+color 0xb44215 0xff0000
+tex 43 43
+size 5 7
+bounce 0
+alpha 4096 4096 20000
+airfriction 1
+originjitter 2 2 2
+velocityjitter 10 10 10
+velocitymultiplier 10
+sizeincrease 1.5
+stretchfactor 2.3
+rotate -180 180 4000 -4000
+// fire
+effect laser_shockwave_attack
+count 1
+type spark
+color 0xff4200 0xff0000
+tex 8 15
+size 7 9
+bounce 0
+alpha 4096 4096 20000
+airfriction 1
+originjitter 2 2 2
+velocityjitter 10 10 10
+velocitymultiplier 10
+sizeincrease 1.5
+stretchfactor 2
+
+// new_laser_impact
+// used nowhere in code
+// decal
+effect new_laser_impact
+countabsolute 1
+type decal
+tex 8 16
+size 72 72
+alpha 256 256 0
+originjitter 2 2 2
+// flare effect
+//effect new_laser_impact
+//countabsolute 1
+//type static
+//tex 39 39
+//color 0xFF2010 0xFF2010
+//alpha 256 256 1024
+//size 24 24
+// sparks that rapidly expand and rapidly slow down to form an interesting spherical effect
+effect new_laser_impact
+count 128
+type spark
+color 0x800000 0xFF8020
+alpha 256 256 1024
+size 4 4
+bounce 1.5
+gravity 0.5
+airfriction 1
+liquidfriction 1
+originjitter 20 20 20
+velocityjitter 256 256 256
else
WarpZone_TrailParticles_WithMultiplier(world, particleeffectnum("nex_beam"), shotorg, endpos, charge, 1);
}
- vector first_min_end, prev_min_end, new_min_end;
- vector first_max_end, prev_max_end, new_max_end;
+
+.vector sw_shotorg;
+.vector sw_endpos;
+.float sw_spread_max;
+.float sw_spread_min;
+.float sw_time;
+
+void Draw_Shockwave()
+{
+ float a = bound(0, (0.5 - ((time - self.sw_time) / 0.4)), 0.5);
+
+ if not(a) { remove(self); }
+
+ vector deviation, angle;
+
+ vector sw_color = getcsqcplayercolor(self.sv_entnum); // GetTeamRGB(GetPlayerColor(self.sv_entnum));
+
++ vector first_min_end = '0 0 0', prev_min_end = '0 0 0', new_min_end = '0 0 0';
++ vector first_max_end = '0 0 0', prev_max_end = '0 0 0', new_max_end = '0 0 0';
+
+ float new_max_dist, new_min_dist;
+
+ vector shotdir = normalize(self.sw_endpos - self.sw_shotorg);
+ vectorvectors(shotdir);
+ vector right = v_right;
+ vector up = v_up;
+
+ float counter, dist_before_normal = 200, shots = 20;
+
+ vector min_end = ((self.sw_shotorg + (shotdir * dist_before_normal)) + (up * self.sw_spread_min));
+ vector max_end = (self.sw_endpos + (up * self.sw_spread_max));
+
+ float spread_to_min = vlen(normalize(min_end - self.sw_shotorg) - shotdir);
+ float spread_to_max = vlen(normalize(max_end - min_end) - shotdir);
+
+ for(counter = 0; counter < shots; ++counter)
+ {
+ // perfect circle effect lines
+ angle = '0 0 0';
+ makevectors('0 360 0' * (0.75 + (counter - 0.5) / shots));
+ angle_y = v_forward_x;
+ angle_z = v_forward_y;
+
+ // first do the spread_to_min effect
+ deviation = angle * spread_to_min;
+ deviation = ((shotdir + (right * deviation_y) + (up * deviation_z)));
+ new_min_dist = dist_before_normal;
+ new_min_end = (self.sw_shotorg + (deviation * new_min_dist));
+ //te_lightning2(world, new_min_end, self.sw_shotorg);
+
+ // then calculate spread_to_max effect
+ deviation = angle * spread_to_max;
+ deviation = ((shotdir + (right * deviation_y) + (up * deviation_z)));
+ new_max_dist = vlen(new_min_end - self.sw_endpos);
+ new_max_end = (new_min_end + (deviation * new_max_dist));
+ //te_lightning2(world, new_end, prev_min_end);
+
+
+ if(counter == 0)
+ {
+ first_min_end = new_min_end;
+ first_max_end = new_max_end;
+ }
+
+ if(counter >= 1)
+ {
+ R_BeginPolygon("", DRAWFLAG_NORMAL);
+ R_PolygonVertex(prev_min_end, '0 0 0', sw_color, a);
+ R_PolygonVertex(new_min_end, '0 0 0', sw_color, a);
+ R_PolygonVertex(self.sw_shotorg, '0 0 0', sw_color, a);
+ R_EndPolygon();
+
+ R_BeginPolygon("", DRAWFLAG_NORMAL);
+ R_PolygonVertex(new_min_end, '0 0 0', sw_color, a);
+ R_PolygonVertex(prev_min_end, '0 0 0', sw_color, a);
+ R_PolygonVertex(prev_max_end, '0 0 0', sw_color, a);
+ R_PolygonVertex(new_max_end, '0 0 0', sw_color, a);
+ R_EndPolygon();
+ }
+
+ prev_min_end = new_min_end;
+ prev_max_end = new_max_end;
+
+ if((counter + 1) == shots)
+ {
+ R_BeginPolygon("", DRAWFLAG_NORMAL);
+ R_PolygonVertex(prev_min_end, '0 0 0', sw_color, a);
+ R_PolygonVertex(first_min_end, '0 0 0', sw_color, a);
+ R_PolygonVertex(self.sw_shotorg, '0 0 0', sw_color, a);
+ R_EndPolygon();
+
+ R_BeginPolygon("", DRAWFLAG_NORMAL);
+ R_PolygonVertex(first_min_end, '0 0 0', sw_color, a);
+ R_PolygonVertex(prev_min_end, '0 0 0', sw_color, a);
+ R_PolygonVertex(prev_max_end, '0 0 0', sw_color, a);
+ R_PolygonVertex(first_max_end, '0 0 0', sw_color, a);
+ R_EndPolygon();
+ }
+ }
+}
+
+void Net_ReadShockwaveParticle()
+{
+ entity shockwave;
+ shockwave = spawn();
+ shockwave.draw = Draw_Shockwave;
+
+ shockwave.sw_shotorg_x = ReadCoord(); shockwave.sw_shotorg_y = ReadCoord(); shockwave.sw_shotorg_z = ReadCoord();
+ shockwave.sw_endpos_x = ReadCoord(); shockwave.sw_endpos_y = ReadCoord(); shockwave.sw_endpos_z = ReadCoord();
+
+ shockwave.sw_spread_max = ReadByte();
+ shockwave.sw_spread_min = ReadByte();
+
+ shockwave.sv_entnum = ReadByte();
+
+ shockwave.sw_time = time;
+}
+
const float TE_CSQC_PICTURE = 100;
const float TE_CSQC_RACE = 101;
- const float TE_CSQC_SPAWN = 102;
- const float TE_CSQC_ZCURVEPARTICLES = 103;
- const float TE_CSQC_NEXGUNBEAMPARTICLE = 104;
- const float TE_CSQC_LIGHTNINGARC = 105;
- const float TE_CSQC_TEAMNAGGER = 106;
- const float TE_CSQC_PINGPLREPORT = 107;
- const float TE_CSQC_SHOCKWAVEPARTICLE = 121;
- const float TE_CSQC_ANNOUNCE = 110;
- const float TE_CSQC_TARGET_MUSIC = 111;
- const float TE_CSQC_KILLNOTIFY = 112;
- const float TE_CSQC_KILLCENTERPRINT = 113;
- const float TE_CSQC_CENTERPRINT_GENERIC = 114;
- const float TE_CSQC_WEAPONCOMPLAIN = 115;
- const float TE_CSQC_NEX_SCOPE = 116;
- const float TE_CSQC_MINELAYER_MAXMINES = 117;
- const float TE_CSQC_HAGAR_MAXROCKETS = 118;
- const float TE_CSQC_VEHICLESETUP = 119;
- const float TE_CSQC_SVNOTICE = 120;
+ const float TE_CSQC_ZCURVEPARTICLES = 102;
+ const float TE_CSQC_NEXGUNBEAMPARTICLE = 103;
+ const float TE_CSQC_LIGHTNINGARC = 104;
+ const float TE_CSQC_TEAMNAGGER = 105;
+ const float TE_CSQC_PINGPLREPORT = 106;
+ const float TE_CSQC_TARGET_MUSIC = 107;
+ const float TE_CSQC_WEAPONCOMPLAIN = 108;
+ const float TE_CSQC_NEX_SCOPE = 109;
+ const float TE_CSQC_MINELAYER_MAXMINES = 110;
+ const float TE_CSQC_HAGAR_MAXROCKETS = 111;
+ const float TE_CSQC_VEHICLESETUP = 112;
+ const float TE_CSQC_SVNOTICE = 113;
++const float TE_CSQC_SHOCKWAVEPARTICLE = 114;
const float RACE_NET_CHECKPOINT_HIT_QUALIFYING = 0; // byte checkpoint, short time, short recordtime, string recordholder
const float RACE_NET_CHECKPOINT_CLEAR = 1;
const float ENT_CLIENT_TRIGGER_MUSIC = 26;
const float ENT_CLIENT_HOOK = 27;
const float ENT_CLIENT_LGBEAM = 28;
-const float ENT_CLIENT_GAUNTLET = 29;
-const float ENT_CLIENT_ACCURACY = 30;
-const float ENT_CLIENT_SHOWNAMES = 31;
-const float ENT_CLIENT_WARPZONE_TELEPORTED = 32;
-const float ENT_CLIENT_MODEL = 33;
-const float ENT_CLIENT_ITEM = 34;
-const float ENT_CLIENT_BUMBLE_RAYGUN = 35;
-const float ENT_CLIENT_SPAWNPOINT = 36;
-const float ENT_CLIENT_SPAWNEVENT = 37;
-const float ENT_CLIENT_NOTIFICATION = 38;
+const float ENT_CLIENT_ACCURACY = 29;
+const float ENT_CLIENT_SHOWNAMES = 30;
+const float ENT_CLIENT_WARPZONE_TELEPORTED = 31;
+const float ENT_CLIENT_MODEL = 32;
+const float ENT_CLIENT_ITEM = 33;
+const float ENT_CLIENT_BUMBLE_RAYGUN = 34;
++const float ENT_CLIENT_SPAWNPOINT = 35;
++const float ENT_CLIENT_SPAWNEVENT = 36;
++const float ENT_CLIENT_NOTIFICATION = 37;
+
const float ENT_CLIENT_TURRET = 40;
const float ENT_CLIENT_AUXILIARYXHAIR = 50;
// (4, 1)
}
- vector v1, v2;
+ .float FindConnectedComponent_processing;
+ void FindConnectedComponent(entity e, .entity fld, findNextEntityNearFunction_t nxt, isConnectedFunction_t iscon, entity pass)
+ {
+ entity queue_start, queue_end;
+
+ // we build a queue of to-be-processed entities.
+ // queue_start is the next entity to be checked for neighbors
+ // queue_end is the last entity added
+
+ if(e.FindConnectedComponent_processing)
+ error("recursion or broken cleanup");
+
+ // start with a 1-element queue
+ queue_start = queue_end = e;
+ queue_end.fld = world;
+ queue_end.FindConnectedComponent_processing = 1;
+
+ // for each queued item:
+ for(; queue_start; queue_start = queue_start.fld)
+ {
+ // find all neighbors of queue_start
+ entity t;
+ for(t = world; (t = nxt(t, queue_start, pass)); )
+ {
+ if(t.FindConnectedComponent_processing)
+ continue;
+ if(iscon(t, queue_start, pass))
+ {
+ // it is connected? ADD IT. It will look for neighbors soon too.
+ queue_end.fld = t;
+ queue_end = t;
+ queue_end.fld = world;
+ queue_end.FindConnectedComponent_processing = 1;
+ }
+ }
+ }
+
+ // unmark
+ for(queue_start = e; queue_start; queue_start = queue_start.fld)
+ queue_start.FindConnectedComponent_processing = 0;
+ }
+
++
+#ifndef MENUQC
+vector cliptoplane(vector v, vector p)
+{
+ return v - (v * p) * p;
+}
+
+vector solve_cubic_pq(float p, float q)
+{
+ float D, u, v, a;
+ D = q*q/4.0 + p*p*p/27.0;
+ if(D < 0)
+ {
+ // irreducibilis
+ a = 1.0/3.0 * acos(-q/2.0 * sqrt(-27.0/(p*p*p)));
+ u = sqrt(-4.0/3.0 * p);
+ // a in range 0..pi/3
+ // cos(a)
+ // cos(a + 2pi/3)
+ // cos(a + 4pi/3)
+ return
+ u *
+ (
+ '1 0 0' * cos(a + 2.0/3.0*M_PI)
+ +
+ '0 1 0' * cos(a + 4.0/3.0*M_PI)
+ +
+ '0 0 1' * cos(a)
+ );
+ }
+ else if(D == 0)
+ {
+ // simple
+ if(p == 0)
+ return '0 0 0';
+ u = 3*q/p;
+ v = -u/2;
+ if(u >= v)
+ return '1 1 0' * v + '0 0 1' * u;
+ else
+ return '0 1 1' * v + '1 0 0' * u;
+ }
+ else
+ {
+ // cardano
+ u = cbrt(-q/2.0 + sqrt(D));
+ v = cbrt(-q/2.0 - sqrt(D));
+ return '1 1 1' * (u + v);
+ }
+}
+vector solve_cubic_abcd(float a, float b, float c, float d)
+{
+ // y = 3*a*x + b
+ // x = (y - b) / 3a
+ float p, q;
+ vector v;
+ p = (9*a*c - 3*b*b);
+ q = (27*a*a*d - 9*a*b*c + 2*b*b*b);
+ v = solve_cubic_pq(p, q);
+ v = (v - b * '1 1 1') * (1.0 / (3.0 * a));
+ if(a < 0)
+ v += '1 0 -1' * (v_z - v_x); // swap x, z
+ return v;
+}
+
+vector findperpendicular(vector v)
+{
+ vector p;
+ p_x = v_z;
+ p_y = -v_x;
+ p_z = v_y;
+ return normalize(cliptoplane(p, v));
+}
+
+vector W_CalculateSpread(vector forward, float spread, float spreadfactor, float spreadstyle)
+{
+ float sigma;
- vector position;
++ vector v1 = '0 0 0', v2;
+ float dx, dy, r;
+ float sstyle;
+ spread *= spreadfactor; //g_weaponspreadfactor;
+ if(spread <= 0)
+ return forward;
+ sstyle = spreadstyle; //autocvar_g_projectiles_spread_style;
+
+ if(sstyle == 0)
+ {
+ // this is the baseline for the spread value!
+ // standard deviation: sqrt(2/5)
+ // density function: sqrt(1-r^2)
+ return forward + randomvec() * spread;
+ }
+ else if(sstyle == 1)
+ {
+ // same thing, basically
+ return normalize(forward + cliptoplane(randomvec() * spread, forward));
+ }
+ else if(sstyle == 2)
+ {
+ // circle spread... has at sigma=1 a standard deviation of sqrt(1/2)
+ sigma = spread * 0.89442719099991587855; // match baseline stddev
+ v1 = findperpendicular(forward);
+ v2 = cross(forward, v1);
+ // random point on unit circle
+ dx = random() * 2 * M_PI;
+ dy = sin(dx);
+ dx = cos(dx);
+ // radius in our dist function
+ r = random();
+ r = sqrt(r);
+ return normalize(forward + (v1 * dx + v2 * dy) * r * sigma);
+ }
+ else if(sstyle == 3) // gauss 3d
+ {
+ sigma = spread * 0.44721359549996; // match baseline stddev
+ // note: 2D gaussian has sqrt(2) times the stddev of 1D, so this factor is right
+ v1 = forward;
+ v1_x += gsl_ran_gaussian(sigma);
+ v1_y += gsl_ran_gaussian(sigma);
+ v1_z += gsl_ran_gaussian(sigma);
+ return v1;
+ }
+ else if(sstyle == 4) // gauss 2d
+ {
+ sigma = spread * 0.44721359549996; // match baseline stddev
+ // note: 2D gaussian has sqrt(2) times the stddev of 1D, so this factor is right
+ v1_x = gsl_ran_gaussian(sigma);
+ v1_y = gsl_ran_gaussian(sigma);
+ v1_z = gsl_ran_gaussian(sigma);
+ return normalize(forward + cliptoplane(v1, forward));
+ }
+ else if(sstyle == 5) // 1-r
+ {
+ sigma = spread * 1.154700538379252; // match baseline stddev
+ v1 = findperpendicular(forward);
+ v2 = cross(forward, v1);
+ // random point on unit circle
+ dx = random() * 2 * M_PI;
+ dy = sin(dx);
+ dx = cos(dx);
+ // radius in our dist function
+ r = random();
+ r = solve_cubic_abcd(-2, 3, 0, -r) * '0 1 0';
+ return normalize(forward + (v1 * dx + v2 * dy) * r * sigma);
+ }
+ else if(sstyle == 6) // 1-r^2
+ {
+ sigma = spread * 1.095445115010332; // match baseline stddev
+ v1 = findperpendicular(forward);
+ v2 = cross(forward, v1);
+ // random point on unit circle
+ dx = random() * 2 * M_PI;
+ dy = sin(dx);
+ dx = cos(dx);
+ // radius in our dist function
+ r = random();
+ r = sqrt(1 - r);
+ r = sqrt(1 - r);
+ return normalize(forward + (v1 * dx + v2 * dy) * r * sigma);
+ }
+ else if(sstyle == 7) // (1-r) (2-r)
+ {
+ sigma = spread * 1.224744871391589; // match baseline stddev
+ v1 = findperpendicular(forward);
+ v2 = cross(forward, v1);
+ // random point on unit circle
+ dx = random() * 2 * M_PI;
+ dy = sin(dx);
+ dx = cos(dx);
+ // radius in our dist function
+ r = random();
+ r = 1 - sqrt(r);
+ r = 1 - sqrt(r);
+ return normalize(forward + (v1 * dx + v2 * dy) * r * sigma);
+ }
+ else
+ error("g_projectiles_spread_style must be 0 (sphere), 1 (flattened sphere), 2 (circle), 3 (gauss 3D), 4 (gauss plane), 5 (linear falloff), 6 (quadratic falloff), 7 (stronger falloff)!");
+ return '0 0 0';
+ /*
+ * how to derive falloff functions:
+ * rho(r) := (2-r) * (1-r);
+ * a : 0;
+ * b : 1;
+ * rhor(r) := r * rho(r);
+ * cr(t) := integrate(rhor(r), r, a, t);
+ * scr(t) := integrate(rhor(r) * r^2, r, a, t);
+ * variance : scr(b) / cr(b);
+ * solve(cr(r) = rand * cr(b), r), programmmode:false;
+ * sqrt(0.4 / variance), numer;
+ */
+}
+#endif
+
+#ifdef SVQC
+vector combine_to_vector(float x, float y, float z)
+{
+ vector result; result_x = x; result_y = y; result_z = z;
+ return result;
+}
+
+vector get_corner_position(entity box, float corner)
+{
+ switch(corner)
+ {
+ case 1: return combine_to_vector(box.absmin_x, box.absmin_y, box.absmin_z);
+ case 2: return combine_to_vector(box.absmax_x, box.absmin_y, box.absmin_z);
+ case 3: return combine_to_vector(box.absmin_x, box.absmax_y, box.absmin_z);
+ case 4: return combine_to_vector(box.absmin_x, box.absmin_y, box.absmax_z);
+ case 5: return combine_to_vector(box.absmax_x, box.absmax_y, box.absmin_z);
+ case 6: return combine_to_vector(box.absmin_x, box.absmax_y, box.absmax_z);
+ case 7: return combine_to_vector(box.absmax_x, box.absmin_y, box.absmax_z);
+ case 8: return combine_to_vector(box.absmax_x, box.absmax_y, box.absmax_z);
+ default: return '0 0 0';
+ }
+}
+#endif
++
+ // todo: this sucks, lets find a better way to do backtraces?
+ #ifndef MENUQC
+ void backtrace(string msg)
+ {
+ float dev, war;
+ #ifdef SVQC
+ dev = autocvar_developer;
+ war = autocvar_prvm_backtraceforwarnings;
+ #else
+ dev = cvar("developer");
+ war = cvar("prvm_backtraceforwarnings");
+ #endif
+ cvar_set("developer", "1");
+ cvar_set("prvm_backtraceforwarnings", "1");
+ print("\n");
+ print("--- CUT HERE ---\nWARNING: ");
+ print(msg);
+ print("\n");
+ remove(world); // isn't there any better way to cause a backtrace?
+ print("\n--- CUT UNTIL HERE ---\n");
+ cvar_set("developer", ftos(dev));
+ cvar_set("prvm_backtraceforwarnings", ftos(war));
+ }
+ #endif
+
+ // color code replace, place inside of sprintf and parse the string
+ string CCR(string input)
+ {
+ // See the autocvar declarations in util.qh for default values
+
+ // foreground/normal colors
+ input = strreplace("^F1", strcat("^", autocvar_hud_colorset_foreground_1), input);
+ input = strreplace("^F2", strcat("^", autocvar_hud_colorset_foreground_2), input);
+ input = strreplace("^F3", strcat("^", autocvar_hud_colorset_foreground_3), input);
+ input = strreplace("^F4", strcat("^", autocvar_hud_colorset_foreground_4), input);
+
+ // "kill" colors
+ input = strreplace("^K1", strcat("^", autocvar_hud_colorset_kill_1), input);
+ input = strreplace("^K2", strcat("^", autocvar_hud_colorset_kill_2), input);
+ input = strreplace("^K3", strcat("^", autocvar_hud_colorset_kill_3), input);
+
+ // background colors
+ input = strreplace("^BG", strcat("^", autocvar_hud_colorset_background), input);
+ input = strreplace("^N", "^7", input); // "none"-- reset to white...
+ return input;
+ }
+
+ vector vec3(float x, float y, float z)
+ {
+ vector v;
+ v_x = x;
+ v_y = y;
+ v_z = z;
+ return v;
+ }
+
+ #ifndef MENUQC
+ vector animfixfps(entity e, vector a, vector b)
+ {
+ // multi-frame anim: keep as-is
+ if(a_y == 1)
+ {
+ float dur;
+ dur = frameduration(e.modelindex, a_x);
+ if(dur <= 0 && b_y)
+ {
+ a = b;
+ dur = frameduration(e.modelindex, a_x);
+ }
+ if(dur > 0)
+ a_z = 1.0 / dur;
+ }
+ return a;
+ }
+ #endif
+
+ #ifdef SVQC
+ void dedicated_print(string input) // print(), but only print if the server is not local
+ {
+ if(server_is_dedicated) { print(input); }
+ }
+ #endif
+
+ #ifndef MENUQC
+ float Announcer_PickNumber(float num)
+ {
+ switch(num)
+ {
+ case 10: num = ANNCE_NUM_10; break;
+ case 9: num = ANNCE_NUM_9; break;
+ case 8: num = ANNCE_NUM_8; break;
+ case 7: num = ANNCE_NUM_7; break;
+ case 6: num = ANNCE_NUM_6; break;
+ case 5: num = ANNCE_NUM_5; break;
+ case 4: num = ANNCE_NUM_4; break;
+ case 3: num = ANNCE_NUM_3; break;
+ case 2: num = ANNCE_NUM_2; break;
+ case 1: num = ANNCE_NUM_1; break;
+ }
+ return num;
+ }
+ #endif
// as it may exceed 0..1 bounds, or go in reverse
float cubic_speedfunc_is_sane(float startspeedfactor, float endspeedfactor);
- vector W_CalculateSpread(vector forward, float spread, float spreadfactor, float spreadstyle)
+ typedef entity(entity cur, entity near, entity pass) findNextEntityNearFunction_t;
+ typedef float(entity a, entity b, entity pass) isConnectedFunction_t;
+ void FindConnectedComponent(entity e, .entity fld, findNextEntityNearFunction_t nxt, isConnectedFunction_t iscon, entity pass);
+
+#ifndef MENUQC
++vector W_CalculateSpread(vector forward, float spread, float spreadfactor, float spreadstyle);
+#endif
+
+#ifdef SVQC
+vector get_corner_position(entity box, float corner);
+#endif
++
+ // expand multiple arguments into one argument by stripping parenthesis
+ #define XPD(...) __VA_ARGS__
+
+ #ifndef MENUQC
+ void backtrace(string msg);
+ #endif
+
+ // color code replace, place inside of sprintf and parse the string... defaults described as constants
+ // foreground/normal colors
+ var string autocvar_hud_colorset_foreground_1 = "2"; // F1 - Green // primary priority (important names, etc)
+ var string autocvar_hud_colorset_foreground_2 = "3"; // F2 - Yellow // secondary priority (items, locations, numbers, etc)
+ var string autocvar_hud_colorset_foreground_3 = "4"; // F3 - Blue // tertiary priority or relatively inconsequential text
+ var string autocvar_hud_colorset_foreground_4 = "1"; // F4 - Red // notice/attention grabbing texting
+ // "kill" colors
+ var string autocvar_hud_colorset_kill_1 = "1"; // K1 - Red // "bad" or "dangerous" text (death messages against you, kill notifications, etc)
+ var string autocvar_hud_colorset_kill_2 = "3"; // K2 - Yellow // similar to above, but less important... OR, a highlight out of above message type
+ var string autocvar_hud_colorset_kill_3 = "4"; // K3 - Blue // "good" or "beneficial" text (you fragging someone, etc)
+ // background color
+ var string autocvar_hud_colorset_background = "7"; // BG - White // neutral/unimportant text
+
+ string CCR(string input);
+
+ #ifndef MENUQC
+ #ifdef CSQC
+ #define GENTLE (autocvar_cl_gentle || autocvar_cl_gentle_messages)
+ #else
+ #define GENTLE autocvar_sv_gentle
+ #endif
+ #define normal_or_gentle(normal,gentle) (GENTLE ? ((gentle != "") ? gentle : normal) : normal)
+ #endif
+
+ // allow writing to also pass through to spectators (like so spectators see the same centerprints as players for example)
+ #define WRITESPECTATABLE_MSG_ONE_VARNAME(varname,statement) entity varname; varname = msg_entity; FOR_EACH_REALCLIENT(msg_entity) if(msg_entity == varname || (msg_entity.classname == STR_SPECTATOR && msg_entity.enemy == varname)) statement msg_entity = varname
+ #define WRITESPECTATABLE_MSG_ONE(statement) WRITESPECTATABLE_MSG_ONE_VARNAME(oldmsg_entity, statement)
+ #define WRITESPECTATABLE(msg,statement) if(msg == MSG_ONE) { WRITESPECTATABLE_MSG_ONE(statement); } else statement float WRITESPECTATABLE_workaround = 0
+
+ vector vec3(float x, float y, float z);
+
+ #ifndef MENUQC
+ vector animfixfps(entity e, vector a, vector b);
+ #endif
+
+ #ifdef SVQC
+ void dedicated_print(string input);
+ #endif
+
+ // todo: better way to do this?
+ #ifdef MENUQC
+ #define PROGNAME "MENUQC"
+ #else
+ #ifdef SVQC
+ #define PROGNAME "SVQC"
+ #else
+ #define PROGNAME "CSQC"
+ #endif
+ #endif
+
+ #ifndef MENUQC
+ float Announcer_PickNumber(float num);
+ #endif
float autocvar_g_balance_laser_primary_delay;
float autocvar_g_balance_laser_primary_edgedamage;
float autocvar_g_balance_laser_primary_force;
--float autocvar_g_balance_laser_primary_force_other_scale;
--float autocvar_g_balance_laser_primary_force_velocitybias;
--float autocvar_g_balance_laser_primary_force_zscale;
++//float autocvar_g_balance_laser_primary_force_other_scale;
++//float autocvar_g_balance_laser_primary_force_velocitybias;
++//float autocvar_g_balance_laser_primary_force_zscale;
float autocvar_g_balance_laser_primary_lifetime;
float autocvar_g_balance_laser_primary_radius;
float autocvar_g_balance_laser_primary_refire;
float autocvar_g_balance_laser_primary_shotangle;
float autocvar_g_balance_laser_primary_speed;
- float autocvar_g_balance_laser_primary_spread;
++//float autocvar_g_balance_laser_primary_spread;
+float autocvar_g_balance_laser_reload_ammo;
+float autocvar_g_balance_laser_reload_time;
float autocvar_g_balance_laser_secondary;
float autocvar_g_balance_laser_secondary_animtime;
float autocvar_g_balance_laser_secondary_damage;
float autocvar_g_balance_laser_secondary_edgedamage;
float autocvar_g_balance_laser_secondary_force;
--float autocvar_g_balance_laser_secondary_force_other_scale;
--float autocvar_g_balance_laser_secondary_force_velocitybias;
--float autocvar_g_balance_laser_secondary_force_zscale;
++//float autocvar_g_balance_laser_secondary_force_other_scale;
++//float autocvar_g_balance_laser_secondary_force_velocitybias;
++//float autocvar_g_balance_laser_secondary_force_zscale;
float autocvar_g_balance_laser_secondary_lifetime;
float autocvar_g_balance_laser_secondary_radius;
-float autocvar_g_balance_laser_secondary_speed;
-float autocvar_g_balance_laser_reload_ammo;
-float autocvar_g_balance_laser_reload_time;
+float autocvar_g_balance_laser_secondary_refire;
- float autocvar_g_balance_laser_secondary_speed;
++//float autocvar_g_balance_laser_secondary_speed;
+float autocvar_g_balance_laser_shockwave_damage;
+float autocvar_g_balance_laser_shockwave_distance;
+float autocvar_g_balance_laser_shockwave_edgedamage;
+float autocvar_g_balance_laser_shockwave_force;
+float autocvar_g_balance_laser_shockwave_force_forwardbias;
+float autocvar_g_balance_laser_shockwave_force_zscale;
+float autocvar_g_balance_laser_shockwave_jump_damage;
+float autocvar_g_balance_laser_shockwave_jump_edgedamage;
+float autocvar_g_balance_laser_shockwave_jump_force;
+float autocvar_g_balance_laser_shockwave_jump_force_velocitybias;
+float autocvar_g_balance_laser_shockwave_jump_force_zscale;
+float autocvar_g_balance_laser_shockwave_jump_multiplier_accuracy;
+float autocvar_g_balance_laser_shockwave_jump_multiplier_distance;
+float autocvar_g_balance_laser_shockwave_jump_multiplier_min;
+float autocvar_g_balance_laser_shockwave_jump_radius;
+float autocvar_g_balance_laser_shockwave_multiplier_accuracy;
+float autocvar_g_balance_laser_shockwave_multiplier_distance;
+float autocvar_g_balance_laser_shockwave_multiplier_min;
+float autocvar_g_balance_laser_shockwave_splash_damage;
+float autocvar_g_balance_laser_shockwave_splash_edgedamage;
+float autocvar_g_balance_laser_shockwave_splash_force;
+float autocvar_g_balance_laser_shockwave_splash_force_forwardbias;
+float autocvar_g_balance_laser_shockwave_splash_multiplier_accuracy;
+float autocvar_g_balance_laser_shockwave_splash_multiplier_distance;
+float autocvar_g_balance_laser_shockwave_splash_multiplier_min;
+float autocvar_g_balance_laser_shockwave_splash_radius;
+float autocvar_g_balance_laser_shockwave_spread_max;
+float autocvar_g_balance_laser_shockwave_spread_min;
float autocvar_g_balance_minelayer_ammo;
float autocvar_g_balance_minelayer_animtime;
float autocvar_g_balance_minelayer_damage;
break;
case CHIMPULSE_R00T:
IS_CHEAT(i, 0, 0);
+ RandomSelection_Init();
FOR_EACH_PLAYER(e)
- {
- get_model_parameters(e.playermodel, e.skin);
- if(get_model_parameters_sex == "Female")
- {
- makevectors(e.angles);
- traceline(e.origin, e.origin + v_right * 256, MOVE_NORMAL, e);
- }
- else
- {
- org_x = random();
- org_y = random();
- org_z = 0;
- org = normalize(org);
- traceline(e.origin, e.origin + org * 256, MOVE_NORMAL, e); // random direction
- }
+ if(e.deadflag == DEAD_NO)
+ if(IsDifferentTeam(e, self))
+ RandomSelection_Add(e, 0, string_null, 1, 1);
+ if(RandomSelection_chosen_ent)
+ e = RandomSelection_chosen_ent;
+ else
+ e = self;
- org = findbetterlocation(trace_endpos, 12);
+ pointparticles(particleeffectnum("rocket_explode"), e.origin, '0 0 0', 1);
+ sound(e, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
+
+ e2 = spawn();
+ setorigin(e2, e.origin);
- RadiusDamage(e2, self, 1000, 0, 128, world, 500, DEATH_CHEAT, e);
++ RadiusDamage(e2, self, 1000, 0, 128, world, world, 500, DEATH_CHEAT, e);
+ remove(e2);
- e2 = spawn();
- setorigin(e2, org);
- pointparticles(particleeffectnum("rocket_explode"), org, '0 0 0', 1);
- sound(e2, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
- RadiusDamage(e2, e, 1000, 0, 128, e, world, 500, DEATH_CHEAT, world);
- remove(e2);
- }
print("404 Sportsmanship not found.\n");
DID_CHEAT();
break;
while (targ)
{
next = targ.chain;
- if (targ != inflictor)
- if (ignore != targ) if(targ.takedamage)
+ if ((targ != inflictor) || inflictorselfdamage)
+ if (((cantbe != targ) && !mustbe) || (mustbe == targ))
+ if (targ.takedamage)
+ {
+ vector nearest;
+ vector diff;
+ float power;
+
+ // LordHavoc: measure distance to nearest point on target (not origin)
+ // (this guarentees 100% damage on a touch impact)
+ nearest = targ.WarpZone_findradius_nearest;
+ diff = targ.WarpZone_findradius_dist;
+ // round up a little on the damage to ensure full damage on impacts
+ // and turn the distance into a fraction of the radius
+ power = 1 - ((vlen (diff) - bound(MIN_DAMAGEEXTRARADIUS, targ.damageextraradius, MAX_DAMAGEEXTRARADIUS)) / rad);
+ //bprint(" ");
+ //bprint(ftos(power));
+ //if (targ == attacker)
+ // print(ftos(power), "\n");
+ if (power > 0)
{
- vector nearest;
- vector diff;
- float power;
-
- // LordHavoc: measure distance to nearest point on target (not origin)
- // (this guarentees 100% damage on a touch impact)
- nearest = targ.WarpZone_findradius_nearest;
- diff = targ.WarpZone_findradius_dist;
- // round up a little on the damage to ensure full damage on impacts
- // and turn the distance into a fraction of the radius
- power = 1 - ((vlen (diff) - bound(MIN_DAMAGEEXTRARADIUS, targ.damageextraradius, MAX_DAMAGEEXTRARADIUS)) / rad);
- //bprint(" ");
- //bprint(ftos(power));
- //if (targ == attacker)
- // print(ftos(power), "\n");
- if (power > 0)
+ float finaldmg;
+ if (power > 1)
+ power = 1;
+ finaldmg = coredamage * power + edgedamage * (1 - power);
+ if (finaldmg > 0)
{
- float finaldmg;
- if (power > 1)
- power = 1;
- finaldmg = coredamage * power + edgedamage * (1 - power);
- if (finaldmg > 0)
- {
- float a;
- float c;
- vector hitloc;
- vector myblastorigin;
- vector center;
-
- myblastorigin = WarpZone_TransformOrigin(targ, blastorigin);
-
- // if it's a player, use the view origin as reference
- center = CENTER_OR_VIEWOFS(targ);
+ float a;
+ float c;
+ vector hitloc;
+ vector myblastorigin;
+ vector center;
- force = normalize(center - myblastorigin);
- force = force * (finaldmg / coredamage) * forceintensity;
- hitloc = nearest;
+ myblastorigin = WarpZone_TransformOrigin(targ, inflictororigin);
- if(targ != directhitentity)
- {
- float hits;
- float total;
- float hitratio;
- float mininv_f, mininv_d;
+ // if it's a player, use the view origin as reference
- if (targ.classname == "player")
- center = targ.origin + targ.view_ofs;
- else
- center = targ.origin + (targ.mins + targ.maxs) * 0.5;
++ center = CENTER_OR_VIEWOFS(targ);
- // test line of sight to multiple positions on box,
- // and do damage if any of them hit
- hits = 0;
+ force = normalize(center - myblastorigin);
+ force = force * (finaldmg / coredamage) * forceintensity;
+ hitloc = nearest;
- // we know: max stddev of hitratio = 1 / (2 * sqrt(n))
- // so for a given max stddev:
- // n = (1 / (2 * max stddev of hitratio))^2
+ if(targ != directhitentity)
+ {
+ float hits;
+ float total;
+ float hitratio;
+ float mininv_f, mininv_d;
- mininv_d = (finaldmg * (1-tfloordmg)) / autocvar_g_throughfloor_damage_max_stddev;
- mininv_f = (vlen(force) * (1-tfloorforce)) / autocvar_g_throughfloor_force_max_stddev;
+ // test line of sight to multiple positions on box,
+ // and do damage if any of them hit
+ hits = 0;
- if(autocvar_g_throughfloor_debug)
- print(sprintf("THROUGHFLOOR: D=%f F=%f max(dD)=1/%f max(dF)=1/%f", finaldmg, vlen(force), mininv_d, mininv_f));
+ // we know: max stddev of hitratio = 1 / (2 * sqrt(n))
+ // so for a given max stddev:
+ // n = (1 / (2 * max stddev of hitratio))^2
- total = 0.25 * pow(max(mininv_f, mininv_d), 2);
+ mininv_d = (finaldmg * (1-tfloordmg)) / autocvar_g_throughfloor_damage_max_stddev;
+ mininv_f = (vlen(force) * (1-tfloorforce)) / autocvar_g_throughfloor_force_max_stddev;
- if(autocvar_g_throughfloor_debug)
- print(sprintf(" steps=%f", total));
+ if(autocvar_g_throughfloor_debug)
+ print(sprintf("THROUGHFLOOR: D=%f F=%f max(dD)=1/%f max(dF)=1/%f", finaldmg, vlen(force), mininv_d, mininv_f));
- if (IS_PLAYER(targ))
- total = ceil(bound(autocvar_g_throughfloor_min_steps_player, total, autocvar_g_throughfloor_max_steps_player));
- else
- total = ceil(bound(autocvar_g_throughfloor_min_steps_other, total, autocvar_g_throughfloor_max_steps_other));
+ total = 0.25 * pow(max(mininv_f, mininv_d), 2);
- if(autocvar_g_throughfloor_debug)
- print(sprintf(" steps=%f dD=%f dF=%f", total, finaldmg * (1-tfloordmg) / (2 * sqrt(total)), vlen(force) * (1-tfloorforce) / (2 * sqrt(total))));
+ if(autocvar_g_throughfloor_debug)
+ print(sprintf(" steps=%f", total));
- if (targ.classname == "player")
- for(c = 0; c < total; ++c)
- {
- //traceline(targ.WarpZone_findradius_findorigin, nearest, MOVE_NOMONSTERS, inflictor);
- WarpZone_TraceLine(blastorigin, WarpZone_UnTransformOrigin(targ, nearest), MOVE_NOMONSTERS, inflictor);
- if (trace_fraction == 1 || trace_ent == targ)
- {
- ++hits;
- if (hits > 1)
- hitloc = hitloc + nearest;
- else
- hitloc = nearest;
- }
- nearest_x = targ.origin_x + targ.mins_x + random() * targ.size_x;
- nearest_y = targ.origin_y + targ.mins_y + random() * targ.size_y;
- nearest_z = targ.origin_z + targ.mins_z + random() * targ.size_z;
- }
-
- nearest = hitloc * (1 / max(1, hits));
- hitratio = (hits / total);
- a = bound(0, tfloordmg + (1-tfloordmg) * hitratio, 1);
- finaldmg = finaldmg * a;
- a = bound(0, tfloorforce + (1-tfloorforce) * hitratio, 1);
- force = force * a;
++ if (IS_PLAYER(targ))
+ total = ceil(bound(autocvar_g_throughfloor_min_steps_player, total, autocvar_g_throughfloor_max_steps_player));
+ else
+ total = ceil(bound(autocvar_g_throughfloor_min_steps_other, total, autocvar_g_throughfloor_max_steps_other));
- if(autocvar_g_throughfloor_debug)
- print(sprintf(" D=%f F=%f\n", finaldmg, vlen(force)));
- }
+ if(autocvar_g_throughfloor_debug)
+ print(sprintf(" steps=%f dD=%f dF=%f", total, finaldmg * (1-tfloordmg) / (2 * sqrt(total)), vlen(force) * (1-tfloorforce) / (2 * sqrt(total))));
- // laser force adjustments :P
- if(DEATH_WEAPONOF(deathtype) == WEP_LASER)
+ for(c = 0; c < total; ++c)
{
- if (targ == attacker)
- {
- vector vel;
-
- float force_zscale;
- float force_velocitybiasramp;
- float force_velocitybias;
-
- force_velocitybiasramp = autocvar_sv_maxspeed;
- if(deathtype & HITTYPE_SECONDARY)
- {
- force_zscale = autocvar_g_balance_laser_secondary_force_zscale;
- force_velocitybias = autocvar_g_balance_laser_secondary_force_velocitybias;
- }
- else
- {
- force_zscale = autocvar_g_balance_laser_primary_force_zscale;
- force_velocitybias = autocvar_g_balance_laser_primary_force_velocitybias;
- }
-
- vel = targ.velocity;
- vel_z = 0;
- vel = normalize(vel) * bound(0, vlen(vel) / force_velocitybiasramp, 1) * force_velocitybias;
- force =
- vlen(force)
- *
- normalize(normalize(force) + vel);
-
- force_z *= force_zscale;
- }
- else
+ //traceline(targ.WarpZone_findradius_findorigin, nearest, MOVE_NOMONSTERS, inflictor);
+ WarpZone_TraceLine(inflictororigin, WarpZone_UnTransformOrigin(targ, nearest), MOVE_NOMONSTERS, inflictor);
+ if (trace_fraction == 1 || trace_ent == targ)
{
- if(deathtype & HITTYPE_SECONDARY)
- {
- force *= autocvar_g_balance_laser_secondary_force_other_scale;
- }
+ ++hits;
+ if (hits > 1)
+ hitloc = hitloc + nearest;
else
- {
- force *= autocvar_g_balance_laser_primary_force_other_scale;
- }
+ hitloc = nearest;
}
+ nearest_x = targ.origin_x + targ.mins_x + random() * targ.size_x;
+ nearest_y = targ.origin_y + targ.mins_y + random() * targ.size_y;
+ nearest_z = targ.origin_z + targ.mins_z + random() * targ.size_z;
}
- //if (targ == attacker)
- //{
- // print("hits ", ftos(hits), " / ", ftos(total));
- // print(" finaldmg ", ftos(finaldmg), " force ", vtos(force));
- // print(" (", ftos(a), ")\n");
- //}
- if(finaldmg || vlen(force))
- {
- if(targ.iscreature)
- {
- total_damage_to_creatures += finaldmg;
+ nearest = hitloc * (1 / max(1, hits));
+ hitratio = (hits / total);
+ a = bound(0, tfloordmg + (1-tfloordmg) * hitratio, 1);
+ finaldmg = finaldmg * a;
+ a = bound(0, tfloorforce + (1-tfloorforce) * hitratio, 1);
+ force = force * a;
- if(accuracy_isgooddamage(attacker, targ))
- stat_damagedone += finaldmg;
- }
+ if(autocvar_g_throughfloor_debug)
+ print(sprintf(" D=%f F=%f\n", finaldmg, vlen(force)));
+ }
- if(targ == directhitentity || DEATH_ISSPECIAL(deathtype))
- Damage (targ, inflictor, attacker, finaldmg, deathtype, nearest, force);
- else
- Damage (targ, inflictor, attacker, finaldmg, deathtype | HITTYPE_SPLASH, nearest, force);
+ //if (targ == attacker)
+ //{
+ // print("hits ", ftos(hits), " / ", ftos(total));
+ // print(" finaldmg ", ftos(finaldmg), " force ", vtos(force));
+ // print(" (", ftos(a), ")\n");
+ //}
+ if(finaldmg || vlen(force))
+ {
+ if(targ.iscreature)
+ {
+ total_damage_to_creatures += finaldmg;
+
+ if(accuracy_isgooddamage(attacker, targ))
+ stat_damagedone += finaldmg;
}
+
+ if(targ == directhitentity || DEATH_ISSPECIAL(deathtype))
+ Damage (targ, inflictor, attacker, finaldmg, deathtype, nearest, force);
+ else
+ Damage (targ, inflictor, attacker, finaldmg, deathtype | HITTYPE_SPLASH, nearest, force);
}
}
}
--- /dev/null
- RadiusDamage(e, world, autocvar_g_touchexplode_damage, autocvar_g_touchexplode_edgedamage, autocvar_g_touchexplode_radius, world, autocvar_g_touchexplode_force, DEATH_TOUCHEXPLODE, world);
+ .float touchexplode_time;
+
+ void PlayerTouchExplode(entity p1, entity p2)
+ {
+ vector org;
+ org = (p1.origin + p2.origin) * 0.5;
+ org_z += (p1.mins_z + p2.mins_z) * 0.5;
+
+ sound(self, CH_TRIGGER, "weapons/grenade_impact.wav", VOL_BASE, ATTN_NORM);
+ pointparticles(particleeffectnum("explosion_small"), org, '0 0 0', 1);
+
+ entity e;
+ e = spawn();
+ setorigin(e, org);
++ RadiusDamage(e, world, autocvar_g_touchexplode_damage, autocvar_g_touchexplode_edgedamage, autocvar_g_touchexplode_radius, world, world, autocvar_g_touchexplode_force, DEATH_TOUCHEXPLODE, world);
+ remove(e);
+ }
+
+ MUTATOR_HOOKFUNCTION(touchexplode_PlayerThink)
+ {
+ if(time > self.touchexplode_time)
+ if not(gameover)
+ if(IS_PLAYER(self))
+ if(self.deadflag == DEAD_NO)
+ if not(IS_INDEPENDENT_PLAYER(self))
+ FOR_EACH_PLAYER(other) if(self != other)
+ {
+ if(time > other.touchexplode_time)
+ if(other.deadflag == DEAD_NO)
+ if not(IS_INDEPENDENT_PLAYER(other))
+ if(boxesoverlap(self.absmin, self.absmax, other.absmin, other.absmax))
+ {
+ PlayerTouchExplode(self, other);
+ self.touchexplode_time = other.touchexplode_time = time + 0.2;
+ }
+ }
+
+ return FALSE;
+ }
+
+ MUTATOR_DEFINITION(mutator_touchexplode)
+ {
+ MUTATOR_HOOK(PlayerPreThink, touchexplode_PlayerThink, CBC_ORDER_ANY);
+
+ return FALSE;
+ }
{
self.takedamage = DAMAGE_NO;
- self.event_damage = SUB_Null;
+ self.event_damage = func_null;
#ifdef TURRET_DEBUG
float d;
- d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, self, self.owner.shot_force, self.totalfrags, world);
+ d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, self, world, self.owner.shot_force, self.totalfrags, world);
self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d;
self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
#else
}
void walker_rocket_explode()
{
- RadiusDamage (self, self.owner, autocvar_g_turrets_unit_walker_std_rocket_dmg, 0, autocvar_g_turrets_unit_walker_std_rocket_radius, self, world, autocvar_g_turrets_unit_walker_std_rocket_force, DEATH_TURRET_WALKER_ROCKET, world);
- RadiusDamage (self, self.owner, autocvar_g_turrets_unit_walker_std_rocket_dmg, 0, autocvar_g_turrets_unit_walker_std_rocket_radius, self, autocvar_g_turrets_unit_walker_std_rocket_force, DEATH_TURRET_WALK_ROCKET, world);
++ RadiusDamage (self, self.owner, autocvar_g_turrets_unit_walker_std_rocket_dmg, 0, autocvar_g_turrets_unit_walker_std_rocket_radius, self, world, autocvar_g_turrets_unit_walker_std_rocket_force, DEATH_TURRET_WALK_ROCKET, world);
++
remove (self);
}
{
RadiusDamage(self, self.enemy, autocvar_g_vehicle_bumblebee_blowup_coredamage,
autocvar_g_vehicle_bumblebee_blowup_edgedamage,
- autocvar_g_vehicle_bumblebee_blowup_radius, self,
+ autocvar_g_vehicle_bumblebee_blowup_radius, self, world,
autocvar_g_vehicle_bumblebee_blowup_forceintensity,
- DEATH_WAKIBLOWUP, world);
+ DEATH_VH_BUMB_DEATH, world);
sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
pointparticles(particleeffectnum("explosion_large"), randomvec() * 80 + (self.origin + '0 0 100'), '0 0 0', 1);
RadiusDamage (self, self.enemy, autocvar_g_vehicle_racer_blowup_coredamage,
autocvar_g_vehicle_racer_blowup_edgedamage,
- autocvar_g_vehicle_racer_blowup_radius, world,
+ autocvar_g_vehicle_racer_blowup_radius, world, world,
autocvar_g_vehicle_racer_blowup_forceintensity,
- DEATH_WAKIBLOWUP, world);
+ DEATH_VH_WAKI_DEATH, world);
self.nextthink = time + autocvar_g_vehicle_racer_respawntime;
- self.think = racer_spawn;
+ self.think = racer_spawn_default;
self.movetype = MOVETYPE_NONE;
self.effects = EF_NODRAW;
{
RadiusDamage (self, self.realowner, autocvar_g_vehicle_raptor_bomblet_damage,
autocvar_g_vehicle_raptor_bomblet_edgedamage,
- autocvar_g_vehicle_raptor_bomblet_radius, world,
+ autocvar_g_vehicle_raptor_bomblet_radius, world, world,
- autocvar_g_vehicle_raptor_bomblet_force, DEATH_RAPTOR_BOMB, world);
+ autocvar_g_vehicle_raptor_bomblet_force, DEATH_VH_RAPT_BOMB, world);
remove(self);
}
{
self.deadflag = DEAD_DEAD;
self.vehicle_exit(VHEF_NORMAL);
- RadiusDamage (self, self.enemy, 250, 15, 250, world, 250, DEATH_VH_RAPT_DEATH, world);
+
- RadiusDamage (self, self.enemy, 250, 15, 250, world, world, 250, DEATH_WAKIBLOWUP, world);
++ RadiusDamage (self, self.enemy, 250, 15, 250, world, world, 250, DEATH_VH_RAPT_DEATH, world);
self.alpha = -1;
self.movetype = MOVETYPE_NONE;
SUB_SetFade(g1, time, min(autocvar_g_vehicle_spiderbot_respawntime, 10));
SUB_SetFade(g2, time, min(autocvar_g_vehicle_spiderbot_respawntime, 10));
- RadiusDamage (self, self.enemy, 250, 15, 250, world, world, 250, DEATH_SBBLOWUP, world);
- RadiusDamage (self, self.enemy, 250, 15, 250, world, 250, DEATH_VH_SPID_DEATH, world);
++ RadiusDamage (self, self.enemy, 250, 15, 250, world, world, 250, DEATH_VH_SPID_DEATH, world);
self.alpha = self.tur_head.alpha = self.gun1.alpha = self.gun2.alpha = -1;
self.movetype = MOVETYPE_NONE;
PROJECTILE_TOUCH;
- self.event_damage = SUB_Null;
+ self.event_damage = func_null;
- RadiusDamage (self, self.realowner, self.shot_dmg, 0, self.shot_radius, self, self.shot_force, self.totalfrags, other);
+ RadiusDamage (self, self.realowner, self.shot_dmg, 0, self.shot_radius, self, world, self.shot_force, self.totalfrags, other);
remove (self);
}
f = autocvar_g_balance_crylink_primary_bouncedamagefactor;
if(a)
f *= a;
- if (RadiusDamage (self, self.realowner, autocvar_g_balance_crylink_primary_damage * f, autocvar_g_balance_crylink_primary_edgedamage * f, autocvar_g_balance_crylink_primary_radius, world, world, autocvar_g_balance_crylink_primary_force * f, self.projectiledeathtype, other) && autocvar_g_balance_crylink_primary_linkexplode)
+
- float totaldamage = RadiusDamage(self, self.realowner, autocvar_g_balance_crylink_primary_damage * f, autocvar_g_balance_crylink_primary_edgedamage * f, autocvar_g_balance_crylink_primary_radius, world, autocvar_g_balance_crylink_primary_force * f, self.projectiledeathtype, other);
++ float totaldamage = RadiusDamage(self, self.realowner, autocvar_g_balance_crylink_primary_damage * f, autocvar_g_balance_crylink_primary_edgedamage * f, autocvar_g_balance_crylink_primary_radius, world, world, autocvar_g_balance_crylink_primary_force * f, self.projectiledeathtype, other);
+
+ if(totaldamage && ((autocvar_g_balance_crylink_primary_linkexplode == 2) || ((autocvar_g_balance_crylink_primary_linkexplode == 1) && !W_Crylink_Touch_WouldHitFriendly(self, autocvar_g_balance_crylink_primary_radius))))
{
if(self == self.realowner.crylink_lastgroup)
self.realowner.crylink_lastgroup = world;
f = autocvar_g_balance_crylink_secondary_bouncedamagefactor;
if(a)
f *= a;
- if (RadiusDamage (self, self.realowner, autocvar_g_balance_crylink_secondary_damage * f, autocvar_g_balance_crylink_secondary_edgedamage * f, autocvar_g_balance_crylink_secondary_radius, world, world, autocvar_g_balance_crylink_secondary_force * f, self.projectiledeathtype, other) && autocvar_g_balance_crylink_secondary_linkexplode)
+
- float totaldamage = RadiusDamage(self, self.realowner, autocvar_g_balance_crylink_secondary_damage * f, autocvar_g_balance_crylink_secondary_edgedamage * f, autocvar_g_balance_crylink_secondary_radius, world, autocvar_g_balance_crylink_secondary_force * f, self.projectiledeathtype, other);
++ float totaldamage = RadiusDamage(self, self.realowner, autocvar_g_balance_crylink_secondary_damage * f, autocvar_g_balance_crylink_secondary_edgedamage * f, autocvar_g_balance_crylink_secondary_radius, world, world, autocvar_g_balance_crylink_secondary_force * f, self.projectiledeathtype, other);
+
+ if(totaldamage && ((autocvar_g_balance_crylink_secondary_linkexplode == 2) || ((autocvar_g_balance_crylink_secondary_linkexplode == 1) && !W_Crylink_Touch_WouldHitFriendly(self, autocvar_g_balance_crylink_secondary_radius))))
{
if(self == self.realowner.crylink_lastgroup)
self.realowner.crylink_lastgroup = world;
{
W_Plasma_TriggerCombo(self.origin, autocvar_g_balance_electro_combo_comboradius, self.realowner);
- self.event_damage = SUB_Null;
+ self.event_damage = func_null;
- RadiusDamage (self, self.realowner, autocvar_g_balance_electro_combo_damage, autocvar_g_balance_electro_combo_edgedamage, autocvar_g_balance_electro_combo_radius, world, autocvar_g_balance_electro_combo_force, WEP_ELECTRO | HITTYPE_BOUNCE, world); // use THIS type for a combo because primary can't bounce
+ RadiusDamage (self, self.realowner, autocvar_g_balance_electro_combo_damage, autocvar_g_balance_electro_combo_edgedamage, autocvar_g_balance_electro_combo_radius, world, world, autocvar_g_balance_electro_combo_force, WEP_ELECTRO | HITTYPE_BOUNCE, world); // use THIS type for a combo because primary can't bounce
++
remove (self);
}
void W_Hagar_Explode (void)
{
- self.event_damage = SUB_Null;
+ self.event_damage = func_null;
- RadiusDamage (self, self.realowner, autocvar_g_balance_hagar_primary_damage, autocvar_g_balance_hagar_primary_edgedamage, autocvar_g_balance_hagar_primary_radius, world, autocvar_g_balance_hagar_primary_force, self.projectiledeathtype, other);
+ RadiusDamage (self, self.realowner, autocvar_g_balance_hagar_primary_damage, autocvar_g_balance_hagar_primary_edgedamage, autocvar_g_balance_hagar_primary_radius, world, world, autocvar_g_balance_hagar_primary_force, self.projectiledeathtype, other);
remove (self);
}
void W_Hagar_Explode2 (void)
{
- self.event_damage = SUB_Null;
+ self.event_damage = func_null;
- RadiusDamage (self, self.realowner, autocvar_g_balance_hagar_secondary_damage, autocvar_g_balance_hagar_secondary_edgedamage, autocvar_g_balance_hagar_secondary_radius, world, autocvar_g_balance_hagar_secondary_force, self.projectiledeathtype, other);
+ RadiusDamage (self, self.realowner, autocvar_g_balance_hagar_secondary_damage, autocvar_g_balance_hagar_secondary_edgedamage, autocvar_g_balance_hagar_secondary_radius, world, world, autocvar_g_balance_hagar_secondary_force, self.projectiledeathtype, other);
remove (self);
}
{
PROJECTILE_TOUCH;
- self.event_damage = SUB_Null;
+ self.event_damage = func_null;
if(self.projectiledeathtype & HITTYPE_SECONDARY)
- RadiusDamage (self, self.realowner, autocvar_g_balance_hlac_secondary_damage, autocvar_g_balance_hlac_secondary_edgedamage, autocvar_g_balance_hlac_secondary_radius, world, autocvar_g_balance_hlac_secondary_force, self.projectiledeathtype, other);
+ RadiusDamage (self, self.realowner, autocvar_g_balance_hlac_secondary_damage, autocvar_g_balance_hlac_secondary_edgedamage, autocvar_g_balance_hlac_secondary_radius, world, world, autocvar_g_balance_hlac_secondary_force, self.projectiledeathtype, other);
else
- RadiusDamage (self, self.realowner, autocvar_g_balance_hlac_primary_damage, autocvar_g_balance_hlac_primary_edgedamage, autocvar_g_balance_hlac_primary_radius, world, autocvar_g_balance_hlac_primary_force, self.projectiledeathtype, other);
+ RadiusDamage (self, self.realowner, autocvar_g_balance_hlac_primary_damage, autocvar_g_balance_hlac_primary_edgedamage, autocvar_g_balance_hlac_primary_radius, world, world, autocvar_g_balance_hlac_primary_force, self.projectiledeathtype, other);
remove (self);
}
#ifdef REGISTER_WEAPON
- REGISTER_WEAPON(LASER, W_Laser, 0, 1, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH, 0, "laser", "laser", _("Blaster"))
+ REGISTER_WEAPON(
+ /* WEP_##id */ LASER,
+ /* function */ w_laser,
+ /* ammotype */ 0,
+ /* impulse */ 1,
+ /* flags */ WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH,
+ /* rating */ 0,
+ /* model */ "laser",
+ /* shortname */ "laser",
-/* fullname */ _("Laser")
++/* fullname */ _("Blaster")
+ );
#else
#ifdef SVQC
void(float imp) W_SwitchWeapon;
{
PROJECTILE_TOUCH;
- self.event_damage = SUB_Null;
+ self.event_damage = func_null;
- if (self.dmg)
- RadiusDamage (self, self.realowner, autocvar_g_balance_laser_secondary_damage, autocvar_g_balance_laser_secondary_edgedamage, autocvar_g_balance_laser_secondary_radius, world, autocvar_g_balance_laser_secondary_force, self.projectiledeathtype, other);
+
+ if(self.dmg)
+ RadiusDamage(self, self.realowner, autocvar_g_balance_laser_secondary_damage, autocvar_g_balance_laser_secondary_edgedamage, autocvar_g_balance_laser_secondary_radius, world, world, autocvar_g_balance_laser_secondary_force, self.projectiledeathtype, other);
++
else
- RadiusDamage (self, self.realowner, autocvar_g_balance_laser_primary_damage, autocvar_g_balance_laser_primary_edgedamage, autocvar_g_balance_laser_primary_radius, world, autocvar_g_balance_laser_primary_force, self.projectiledeathtype, other);
+ RadiusDamage(self, self.realowner, autocvar_g_balance_laser_primary_damage, autocvar_g_balance_laser_primary_edgedamage, autocvar_g_balance_laser_primary_radius, world, world, autocvar_g_balance_laser_primary_force, self.projectiledeathtype, other);
- remove (self);
+ remove(self);
}
void W_Laser_Think()
CSQCProjectile(self, TRUE, PROJECTILE_LASER, TRUE);
}
-void W_Laser_Attack (float issecondary)
+
+float W_Laser_Shockwave_CheckSpread(vector targetorg, vector nearest_on_line, vector sw_shotorg, vector attack_endpos)
+{
+ float spreadlimit;
+ float distance_of_attack = vlen(sw_shotorg - attack_endpos);
+ float distance_from_line = vlen(targetorg - nearest_on_line);
+
+ spreadlimit = (distance_of_attack ? min(1, (vlen(sw_shotorg - nearest_on_line) / distance_of_attack)) : 1);
+ spreadlimit = (autocvar_g_balance_laser_shockwave_spread_min * (1 - spreadlimit) + autocvar_g_balance_laser_shockwave_spread_max * spreadlimit);
+
+ if(spreadlimit && (distance_from_line <= spreadlimit) && ((vlen(normalize(targetorg - sw_shotorg) - normalize(attack_endpos - sw_shotorg)) * RAD2DEG) <= 90))
+ return bound(0, (distance_from_line / spreadlimit), 1);
+ else
+ return FALSE;
+}
+
+float W_Laser_Shockwave_IsVisible(entity head, vector nearest_on_line, vector sw_shotorg, vector attack_endpos)
+{
+ vector nearest_to_attacker = head.WarpZone_findradius_nearest;
+ vector center = (head.origin + (head.mins + head.maxs) * 0.5);
+ vector corner;
+ float i;
+
+ // STEP ONE: Check if the nearest point is clear
+ if(W_Laser_Shockwave_CheckSpread(nearest_to_attacker, nearest_on_line, sw_shotorg, attack_endpos))
+ {
+ WarpZone_TraceLine(sw_shotorg, nearest_to_attacker, MOVE_NOMONSTERS, self);
+ if(trace_fraction == 1) { return TRUE; } // yes, the nearest point is clear and we can allow the damage
+ }
+
+ // STEP TWO: Check if shotorg to center point is clear
+ if(W_Laser_Shockwave_CheckSpread(center, nearest_on_line, sw_shotorg, attack_endpos))
+ {
+ WarpZone_TraceLine(sw_shotorg, center, MOVE_NOMONSTERS, self);
+ if(trace_fraction == 1) { return TRUE; } // yes, the center point is clear and we can allow the damage
+ }
+
+ // STEP THREE: Check each corner to see if they are clear
+ for(i=1; i<=8; ++i)
+ {
+ corner = get_corner_position(head, i);
+ if(W_Laser_Shockwave_CheckSpread(corner, nearest_on_line, sw_shotorg, attack_endpos))
+ {
+ WarpZone_TraceLine(sw_shotorg, corner, MOVE_NOMONSTERS, self);
+ if(trace_fraction == 1) { return TRUE; } // yes, this corner is clear and we can allow the damage
+ }
+ }
+
+ return FALSE;
+}
+
+#define PLAYER_CENTER(ent) (ent.origin + ((ent.classname == "player") ? ent.view_ofs : ((ent.mins + ent.maxs) * 0.5)))
+
+entity shockwave_hit[32];
+float shockwave_hit_damage[32];
+vector shockwave_hit_force[32];
+
+float W_Laser_Shockwave_CheckHit(float queue, entity head, vector final_force, float final_damage)
+{
+ if not(head) { return FALSE; }
+ float i;
+
+ ++queue;
+
+ for(i = 1; i <= queue; ++i)
+ {
+ if(shockwave_hit[i] == head)
+ {
+ if(vlen(final_force) > vlen(shockwave_hit_force[i])) { shockwave_hit_force[i] = final_force; }
+ if(final_damage > shockwave_hit_damage[i]) { shockwave_hit_damage[i] = final_damage; }
+ return FALSE;
+ }
+ }
+
+ shockwave_hit[queue] = head;
+ shockwave_hit_force[queue] = final_force;
+ shockwave_hit_damage[queue] = final_damage;
+ return TRUE;
+}
+
+void W_Laser_Shockwave()
+{
+ // declarations
+ float multiplier, multiplier_from_accuracy, multiplier_from_distance;
- float final_damage, final_spread;
++ float final_damage; //, final_spread;
+ vector final_force, center, vel;
+ entity head, next;
+
- float i, queue;
++ float i, queue = 0;
+
+ // set up the shot direction
+ W_SetupShot(self, FALSE, 3, "weapons/lasergun_fire.wav", CH_WEAPON_B, autocvar_g_balance_laser_shockwave_damage);
+ vector attack_endpos = (w_shotorg + (w_shotdir * autocvar_g_balance_laser_shockwave_distance));
+ WarpZone_TraceLine(w_shotorg, attack_endpos, MOVE_NOMONSTERS, self);
+ vector attack_hitpos = trace_endpos;
+ float distance_to_end = vlen(w_shotorg - attack_endpos);
+ float distance_to_hit = vlen(w_shotorg - attack_hitpos);
- entity transform = WarpZone_trace_transform;
++ //entity transform = WarpZone_trace_transform;
+
+ // do the firing effect now
+ SendCSQCShockwaveParticle(attack_endpos);
+ Damage_DamageInfo(attack_hitpos, autocvar_g_balance_laser_shockwave_splash_damage, autocvar_g_balance_laser_shockwave_splash_edgedamage, autocvar_g_balance_laser_shockwave_splash_radius, w_shotdir * autocvar_g_balance_laser_shockwave_splash_force, WEP_LASER, 0, self);
+
+ // splash damage/jumping trace
+ head = WarpZone_FindRadius(attack_hitpos, max(autocvar_g_balance_laser_shockwave_splash_radius, autocvar_g_balance_laser_shockwave_jump_radius), FALSE);
+ while(head)
+ {
+ next = head.chain;
+
+ if(head.takedamage)
+ {
+ // if it's a player, use the view origin as reference (stolen from RadiusDamage functions in g_damage.qc)
+ center = PLAYER_CENTER(head);
+
+ float distance_to_head = vlen(attack_hitpos - head.WarpZone_findradius_nearest);
+
+ if((head == self) && (distance_to_head <= autocvar_g_balance_laser_shockwave_jump_radius))
+ {
+ multiplier_from_accuracy = (1 - (distance_to_head ? min(1, (distance_to_head / autocvar_g_balance_laser_shockwave_jump_radius)) : 0));
+ multiplier_from_distance = (1 - (distance_to_hit ? min(1, (distance_to_hit / distance_to_end)) : 0));
+ multiplier = max(autocvar_g_balance_laser_shockwave_jump_multiplier_min, ((multiplier_from_accuracy * autocvar_g_balance_laser_shockwave_jump_multiplier_accuracy) + (multiplier_from_distance * autocvar_g_balance_laser_shockwave_jump_multiplier_distance)));
+
+ final_force = ((normalize(center - attack_hitpos) * autocvar_g_balance_laser_shockwave_jump_force) * multiplier);
+ vel = head.velocity; vel_z = 0;
+ vel = normalize(vel) * bound(0, vlen(vel) / autocvar_sv_maxspeed, 1) * autocvar_g_balance_laser_shockwave_jump_force_velocitybias;
+ final_force = (vlen(final_force) * normalize(normalize(final_force) + vel));
+ final_force_z *= autocvar_g_balance_laser_shockwave_jump_force_zscale;
+ final_damage = (autocvar_g_balance_laser_shockwave_jump_damage * multiplier + autocvar_g_balance_laser_shockwave_jump_edgedamage * (1 - multiplier));
+
+ Damage(head, self, self, final_damage, WEP_LASER, head.origin, final_force);
+ //print("SELF HIT: multiplier = ", ftos(multiplier), strcat(", damage = ", ftos(final_damage), ", force = ", ftos(vlen(final_force))),"... multiplier_from_accuracy = ", ftos(multiplier_from_accuracy), ", multiplier_from_distance = ", ftos(multiplier_from_distance), ".\n");
+ }
+ else if (distance_to_head <= autocvar_g_balance_laser_shockwave_splash_radius)
+ {
+ multiplier_from_accuracy = (1 - (distance_to_head ? min(1, (distance_to_head / autocvar_g_balance_laser_shockwave_splash_radius)) : 0));
+ multiplier_from_distance = (1 - (distance_to_hit ? min(1, (distance_to_hit / distance_to_end)) : 0));
+ multiplier = max(autocvar_g_balance_laser_shockwave_splash_multiplier_min, ((multiplier_from_accuracy * autocvar_g_balance_laser_shockwave_splash_multiplier_accuracy) + (multiplier_from_distance * autocvar_g_balance_laser_shockwave_splash_multiplier_distance)));
+
+ final_force = normalize(center - (attack_hitpos - (w_shotdir * autocvar_g_balance_laser_shockwave_splash_force_forwardbias)));
+ //te_lightning2(world, attack_hitpos, (attack_hitpos + (final_force * 200)));
+ final_force = ((final_force * autocvar_g_balance_laser_shockwave_splash_force) * multiplier);
+ final_force_z *= autocvar_g_balance_laser_shockwave_force_zscale;
+ final_damage = (autocvar_g_balance_laser_shockwave_splash_damage * multiplier + autocvar_g_balance_laser_shockwave_splash_edgedamage * (1 - multiplier));
+
+ if(W_Laser_Shockwave_CheckHit(queue, head, final_force, final_damage)) { ++queue; }
+ //print("SPLASH HIT: multiplier = ", ftos(multiplier), strcat(", damage = ", ftos(final_damage), ", force = ", ftos(vlen(final_force))),"... multiplier_from_accuracy = ", ftos(multiplier_from_accuracy), ", multiplier_from_distance = ", ftos(multiplier_from_distance), ".\n");
+ }
+ }
+ head = next;
+ }
+
+ // cone damage trace
+ head = WarpZone_FindRadius(w_shotorg, autocvar_g_balance_laser_shockwave_distance, FALSE);
+ while(head)
+ {
+ next = head.chain;
+
+ if((head != self) && head.takedamage)
+ {
+ // if it's a player, use the view origin as reference (stolen from RadiusDamage functions in g_damage.qc)
+ center = PLAYER_CENTER(head);
+
+ // find the closest point on the enemy to the center of the attack
+ float ang; // angle between shotdir and h
+ float h; // hypotenuse, which is the distance between attacker to head
+ float a; // adjacent side, which is the distance between attacker and the point on w_shotdir that is closest to head.origin
+
+ h = vlen(center - self.origin);
+ ang = acos(dotproduct(normalize(center - self.origin), w_shotdir));
+ a = h * cos(ang);
+
+ vector nearest_on_line = (w_shotorg + a * w_shotdir);
+ vector nearest_to_attacker = WarpZoneLib_NearestPointOnBox(center + head.mins, center + head.maxs, nearest_on_line);
+ float distance_to_target = vlen(w_shotorg - nearest_to_attacker); // todo: use the findradius function for this
+
+ if((distance_to_target <= autocvar_g_balance_laser_shockwave_distance)
+ && (W_Laser_Shockwave_IsVisible(head, nearest_on_line, w_shotorg, attack_endpos)))
+ {
+ multiplier_from_accuracy = (1 - W_Laser_Shockwave_CheckSpread(nearest_to_attacker, nearest_on_line, w_shotorg, attack_endpos));
+ multiplier_from_distance = (1 - (distance_to_hit ? min(1, (distance_to_target / distance_to_end)) : 0));
+ multiplier = max(autocvar_g_balance_laser_shockwave_multiplier_min, ((multiplier_from_accuracy * autocvar_g_balance_laser_shockwave_multiplier_accuracy) + (multiplier_from_distance * autocvar_g_balance_laser_shockwave_multiplier_distance)));
+
+ final_force = normalize(center - (nearest_on_line - (w_shotdir * autocvar_g_balance_laser_shockwave_force_forwardbias)));
+ //te_lightning2(world, nearest_on_line, (attack_hitpos + (final_force * 200)));
+ final_force = ((final_force * autocvar_g_balance_laser_shockwave_force) * multiplier);
+ final_force_z *= autocvar_g_balance_laser_shockwave_force_zscale;
+ final_damage = (autocvar_g_balance_laser_shockwave_damage * multiplier + autocvar_g_balance_laser_shockwave_edgedamage * (1 - multiplier));
+
+ if(W_Laser_Shockwave_CheckHit(queue, head, final_force, final_damage)) { ++queue; }
+ //print("CONE HIT: multiplier = ", ftos(multiplier), strcat(", damage = ", ftos(final_damage), ", force = ", ftos(vlen(final_force))),"... multiplier_from_accuracy = ", ftos(multiplier_from_accuracy), ", multiplier_from_distance = ", ftos(multiplier_from_distance), ".\n");
+ }
+ }
+ head = next;
+ }
+
+ for(i = 1; i <= queue; ++i)
+ {
+ head = shockwave_hit[i];
+ final_force = shockwave_hit_force[i];
+ final_damage = shockwave_hit_damage[i];
+
+ Damage(head, self, self, final_damage, WEP_LASER, head.origin, final_force);
+ print("SHOCKWAVE by ", self.netname, ": damage = ", ftos(final_damage), ", force = ", ftos(vlen(final_force)), ".\n");
+
+ shockwave_hit[i] = world;
- shockwave_hit_force = '0 0 0';
- shockwave_hit_damage = 0;
++ shockwave_hit_force[i] = '0 0 0';
++ shockwave_hit_damage[i] = 0;
+ }
+ //print("queue was ", ftos(queue), ".\n\n");
+}
+
+void W_Laser_Melee_Think()
+{
+ // declarations
+ float i, f, swing, swing_factor, swing_damage, meleetime, is_player;
+ entity target_victim;
+ vector targpos;
+
+ if(!self.cnt) // set start time of melee
+ {
+ self.cnt = time;
+ W_PlayStrengthSound(self.realowner);
+ }
+
+ makevectors(self.realowner.v_angle); // update values for v_* vectors
+
+ // calculate swing percentage based on time
+ meleetime = autocvar_g_balance_laser_melee_time * W_WeaponRateFactor();
+ swing = bound(0, (self.cnt + meleetime - time) / meleetime, 10);
+ f = ((1 - swing) * autocvar_g_balance_laser_melee_traces);
+
+ // check to see if we can still continue, otherwise give up now
+ if((self.realowner.deadflag != DEAD_NO) && autocvar_g_balance_laser_melee_no_doubleslap)
+ {
+ remove(self);
+ return;
+ }
+
+ // if okay, perform the traces needed for this frame
+ for(i=self.swing_prev; i < f; ++i)
+ {
+ swing_factor = ((1 - (i / autocvar_g_balance_laser_melee_traces)) * 2 - 1);
+
+ targpos = (self.realowner.origin + self.realowner.view_ofs
+ + (v_forward * autocvar_g_balance_laser_melee_range)
+ + (v_up * swing_factor * autocvar_g_balance_laser_melee_swing_up)
+ + (v_right * swing_factor * autocvar_g_balance_laser_melee_swing_side));
+
+ WarpZone_traceline_antilag(self.realowner, self.realowner.origin + self.realowner.view_ofs, targpos, FALSE, self.realowner, ANTILAG_LATENCY(self.realowner));
+
+ // draw lightning beams for debugging
+ te_lightning2(world, targpos, self.realowner.origin + self.realowner.view_ofs + v_forward * 5 - v_up * 5);
+ te_customflash(targpos, 40, 2, '1 1 1');
+
+ is_player = (trace_ent.classname == "player" || trace_ent.classname == "body");
+
+ if((trace_fraction < 1) // if trace is good, apply the damage and remove self
+ && (trace_ent.takedamage == DAMAGE_AIM)
+ && (trace_ent != self.swing_alreadyhit)
+ && (is_player || autocvar_g_balance_laser_melee_nonplayerdamage))
+ {
+ target_victim = trace_ent; // so it persists through other calls
+
+ if(is_player) // this allows us to be able to nerf the non-player damage done in e.g. assault or onslaught.
+ swing_damage = (autocvar_g_balance_laser_melee_damage * min(1, swing_factor + 1));
+ else
+ swing_damage = (autocvar_g_balance_laser_melee_nonplayerdamage * min(1, swing_factor + 1));
+
+ //print(strcat(self.realowner.netname, " hitting ", target_victim.netname, " with ", strcat(ftos(swing_damage), " damage (factor: ", ftos(swing_factor), ") at "), ftos(time), " seconds.\n"));
+
+ Damage(target_victim, self.realowner, self.realowner,
+ swing_damage, WEP_LASER | HITTYPE_SECONDARY,
+ self.realowner.origin + self.realowner.view_ofs,
+ v_forward * autocvar_g_balance_laser_melee_force);
+
+ if(accuracy_isgooddamage(self.realowner, target_victim)) { accuracy_add(self.realowner, WEP_LASER, 0, swing_damage); }
+
+ if(autocvar_g_balance_laser_melee_multihit) // allow multiple hits with one swing, but not against the same player twice.
+ {
+ self.swing_alreadyhit = target_victim;
+ continue; // move along to next trace
+ }
+ else
+ {
+ remove(self);
+ return;
+ }
+ }
+ }
+
+ if(time >= self.cnt + meleetime)
+ {
+ // melee is finished
+ remove(self);
+ return;
+ }
+ else
+ {
+ // set up next frame
+ self.swing_prev = i;
+ self.nextthink = time;
+ }
+}
+
+void W_Laser_Melee()
+{
+ sound(self, CH_WEAPON_A, "weapons/shotgun_melee.wav", VOL_BASE, ATTN_NORM);
+ weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_laser_melee_animtime, w_ready);
+
+ entity meleetemp;
+ meleetemp = spawn();
+ meleetemp.owner = meleetemp.realowner = self;
+ meleetemp.think = W_Laser_Melee_Think;
+ meleetemp.nextthink = time + autocvar_g_balance_laser_melee_delay * W_WeaponRateFactor();
+ W_SetupShot_Range(self, TRUE, 0, "", 0, autocvar_g_balance_laser_melee_damage, autocvar_g_balance_laser_melee_range);
+}
+
+void W_Laser_Attack(float issecondary)
{
entity missile;
vector s_forward;
a = autocvar_g_balance_laser_primary_shotangle;
s_forward = v_forward * cos(a * DEG2RAD) + v_up * sin(a * DEG2RAD);
- if(nodamage)
- W_SetupShot_Dir(self, s_forward, FALSE, 3, "weapons/lasergun_fire.wav", CH_WEAPON_B, 0);
- else if(issecondary == 1)
- if(issecondary == 1)
- W_SetupShot_Dir (self, s_forward, FALSE, 3, "weapons/lasergun_fire.wav", CH_WEAPON_B, autocvar_g_balance_laser_secondary_damage);
++ //if(nodamage)
++ // W_SetupShot_Dir(self, s_forward, FALSE, 3, "weapons/lasergun_fire.wav", CH_WEAPON_B, 0);
++ /*else*/if(issecondary == 1)
+ W_SetupShot_Dir(self, s_forward, FALSE, 3, "weapons/lasergun_fire.wav", CH_WEAPON_B, autocvar_g_balance_laser_secondary_damage);
else
- W_SetupShot_Dir (self, s_forward, FALSE, 3, "weapons/lasergun_fire.wav", CH_WEAPON_B, autocvar_g_balance_laser_primary_damage);
+ W_SetupShot_Dir(self, s_forward, FALSE, 3, "weapons/lasergun_fire.wav", CH_WEAPON_B, autocvar_g_balance_laser_primary_damage);
pointparticles(particleeffectnum("laser_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
- missile = spawn ();
+ missile = spawn();
missile.owner = missile.realowner = self;
missile.classname = "laserbolt";
missile.dmg = 0;
weapon_defaultspawnfunc(WEP_LASER);
}
-float w_laser(float req)
+float W_Laser(float request)
{
- float r1;
- float r2;
- if (req == WR_AIM)
+ switch(request)
{
- if(autocvar_g_balance_laser_secondary)
+ case WR_AIM:
{
- r1 = autocvar_g_balance_laser_primary_damage;
- r2 = autocvar_g_balance_laser_secondary_damage;
- if (random() * (r2 + r1) > r1)
- self.BUTTON_ATCK2 = bot_aim(autocvar_g_balance_laser_secondary_speed, 0, autocvar_g_balance_laser_secondary_lifetime, FALSE);
+ if((autocvar_g_balance_laser_secondary == 2) && (vlen(self.origin-self.enemy.origin) <= autocvar_g_balance_laser_melee_range))
+ self.BUTTON_ATCK2 = bot_aim(1000000, 0, 0.001, FALSE);
else
- self.BUTTON_ATCK = bot_aim(autocvar_g_balance_laser_primary_speed, 0, autocvar_g_balance_laser_primary_lifetime, FALSE);
+ self.BUTTON_ATCK = bot_aim(1000000, 0, 1, FALSE);
+ return TRUE;
}
- else
- self.BUTTON_ATCK = bot_aim(autocvar_g_balance_laser_primary_speed, 0, autocvar_g_balance_laser_primary_lifetime, FALSE);
- }
- else if (req == WR_THINK)
- {
- if(autocvar_g_balance_laser_reload_ammo && self.clip_load < 1) // forced reload
- weapon_action(self.weapon, WR_RELOAD);
- else if (self.BUTTON_ATCK)
+
+ case WR_THINK:
{
- if (weapon_prepareattack(0, autocvar_g_balance_laser_primary_refire))
+ if(autocvar_g_balance_laser_reload_ammo && self.clip_load < 1) // forced reload
+ weapon_action(self.weapon, WR_RELOAD);
+ else if(self.BUTTON_ATCK)
{
- W_DecreaseAmmo(ammo_none, 1, TRUE);
+ if(weapon_prepareattack(0, autocvar_g_balance_laser_primary_refire))
+ {
+ W_DecreaseAmmo(ammo_none, 1, TRUE);
- W_Laser_Attack(0);
- weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_laser_primary_animtime, w_ready);
- }
- }
- else if (self.BUTTON_ATCK2)
- {
- if(autocvar_g_balance_laser_secondary)
- {
- W_DecreaseAmmo(ammo_none, 1, TRUE);
+ if not(autocvar_g_balance_laser_primary)
+ W_Laser_Shockwave();
+ else
+ W_Laser_Attack(FALSE);
- if (weapon_prepareattack(0, 0))
- {
- W_Laser_Attack2();
- weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_laser_secondary_animtime, w_ready);
+ weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_laser_primary_animtime, w_ready);
}
}
- else
+ else if(self.BUTTON_ATCK2)
{
- if(self.switchweapon == WEP_LASER) // don't do this if already switching
- W_LastWeapon();
+ switch(autocvar_g_balance_laser_secondary)
+ {
+ case 0: // switch to last used weapon
+ {
+ if(self.switchweapon == WEP_LASER) // don't do this if already switching
+ W_LastWeapon();
+
+ break;
+ }
+
+ case 1: // normal projectile secondary
+ {
+ if(weapon_prepareattack(1, autocvar_g_balance_laser_secondary_refire))
+ {
+ W_DecreaseAmmo(ammo_none, 1, TRUE);
+ W_Laser_Attack(TRUE);
+ weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_laser_secondary_animtime, w_ready);
+ }
+
+ break;
+ }
+
+ case 2: // melee attack secondary
+ {
+ if(!self.crouch) // we are not currently crouching; this fixes an exploit where your melee anim is not visible, and besides wouldn't make much sense
+ if(weapon_prepareattack(1, autocvar_g_balance_laser_melee_refire))
+ {
+ // attempt forcing playback of the anim by switching to another anim (that we never play) here...
+ W_Laser_Melee();
+ weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_laser_melee_animtime, w_ready);
+ }
+ }
+ }
}
+ return TRUE;
+ }
+
+ case WR_PRECACHE:
+ {
+ precache_model("models/weapons/g_laser.md3");
+ precache_model("models/weapons/v_laser.md3");
+ precache_model("models/weapons/h_laser.iqm");
+ precache_sound("weapons/lasergun_fire.wav");
+ return TRUE;
+ }
+
+ case WR_SETUP:
+ {
+ weapon_setup(WEP_LASER);
+ self.current_ammo = ammo_none;
+ return TRUE;
+ }
+
+ case WR_CHECKAMMO1:
+ case WR_CHECKAMMO2:
+ {
+ return TRUE; // laser has infinite ammo
+ }
+
+ case WR_RELOAD:
+ {
+ W_Reload(0, autocvar_g_balance_laser_reload_ammo, autocvar_g_balance_laser_reload_time, "weapons/reload.wav");
+ return TRUE;
+ }
++
++ case WR_SUICIDEMESSAGE:
++ {
++ return WEAPON_LASER_SUICIDE;
++ }
++
++ case WR_KILLMESSAGE:
++ {
++ return WEAPON_LASER_MURDER;
+ }
}
- else if (req == WR_PRECACHE)
- {
- precache_model ("models/weapons/g_laser.md3");
- precache_model ("models/weapons/v_laser.md3");
- precache_model ("models/weapons/h_laser.iqm");
- precache_sound ("weapons/lasergun_fire.wav");
- precache_sound ("weapons/gauntlet_fire.wav");
- //precache_sound ("weapons/reload.wav"); // until weapons have individual reload sounds, precache the reload sound somewhere else
- }
- else if (req == WR_SETUP)
- {
- weapon_setup(WEP_LASER);
- self.current_ammo = ammo_none;
- }
- else if (req == WR_CHECKAMMO1)
- {
- return TRUE;
- }
- else if (req == WR_CHECKAMMO2)
- {
- return TRUE;
- }
- else if (req == WR_RELOAD)
- {
- W_Reload(0, autocvar_g_balance_laser_reload_ammo, autocvar_g_balance_laser_reload_time, "weapons/reload.wav");
- }
- else if (req == WR_SUICIDEMESSAGE)
- {
- return WEAPON_LASER_SUICIDE;
- }
- else if (req == WR_KILLMESSAGE)
- {
- return WEAPON_LASER_MURDER;
- }
+
return TRUE;
}
#endif
#ifdef CSQC
-float w_laser(float req)
+float W_Laser(float request)
{
- if(req == WR_IMPACTEFFECT)
- {
- vector org2;
- org2 = w_org + w_backoff * 6;
- pointparticles(particleeffectnum("laser_impact"), org2, w_backoff * 1000, 1);
- if(!w_issilent)
- sound(self, CH_SHOTS, "weapons/laserimpact.wav", VOL_BASE, ATTN_NORM);
- }
- else if(req == WR_PRECACHE)
+ switch(request)
{
- precache_sound("weapons/laserimpact.wav");
+ case WR_IMPACTEFFECT:
+ {
+ vector org2;
+ org2 = w_org + w_backoff * 6;
+ pointparticles(particleeffectnum("new_laser_impact"), org2, w_backoff * 1000, 1);
+ if(!w_issilent) { sound(self, CH_SHOTS, "weapons/laserimpact.wav", VOL_BASE, ATTN_NORM); }
+ return TRUE;
+ }
+
+ case WR_PRECACHE:
+ {
+ precache_sound("weapons/laserimpact.wav");
+ return TRUE;
+ }
- case WR_SUICIDEMESSAGE:
- {
- w_deathtypestring = _("%s lasered themself to hell");
- return TRUE;
- }
- case WR_KILLMESSAGE:
- {
- if(w_deathtype & HITTYPE_SECONDARY)
- w_deathtypestring = _("%s was cut in half by %s's gauntlet"); // unchecked: SPLASH // TODO
- else
- w_deathtypestring = _("%s was lasered to death by %s"); // unchecked: SPLASH
- return TRUE;
- }
}
+
return TRUE;
}
#endif
if(IsDifferentTeam(self.realowner, other))
if(other.deadflag == DEAD_NO)
if(IsFlying(other))
- AnnounceTo(self.realowner, "airshot");
+ Send_Notification(NOTIF_ONE, self.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_AIRSHOT);
- self.event_damage = SUB_Null;
+ self.event_damage = func_null;
self.takedamage = DAMAGE_NO;
- RadiusDamage (self, self.realowner, autocvar_g_balance_minelayer_damage, autocvar_g_balance_minelayer_edgedamage, autocvar_g_balance_minelayer_radius, world, autocvar_g_balance_minelayer_force, self.projectiledeathtype, other);
+ RadiusDamage (self, self.realowner, autocvar_g_balance_minelayer_damage, autocvar_g_balance_minelayer_edgedamage, autocvar_g_balance_minelayer_radius, world, world, autocvar_g_balance_minelayer_force, self.projectiledeathtype, other);
if (self.realowner.weapon == WEP_MINE_LAYER)
{
self.takedamage = DAMAGE_NO;
if(self.movetype == MOVETYPE_NONE || self.movetype == MOVETYPE_FOLLOW)
- self.velocity = self.oldvelocity;
+ self.velocity = self.mine_orientation; // particle fx and decals need .velocity
- RadiusDamage (self, self.realowner, autocvar_g_balance_minelayer_remote_damage, autocvar_g_balance_minelayer_remote_edgedamage, autocvar_g_balance_minelayer_remote_radius, world, autocvar_g_balance_minelayer_remote_force, self.projectiledeathtype | HITTYPE_BOUNCE, world);
+ RadiusDamage (self, self.realowner, autocvar_g_balance_minelayer_remote_damage, autocvar_g_balance_minelayer_remote_edgedamage, autocvar_g_balance_minelayer_remote_radius, world, world, autocvar_g_balance_minelayer_remote_force, self.projectiledeathtype | HITTYPE_BOUNCE, world);
if (self.realowner.weapon == WEP_MINE_LAYER)
{
if(IsDifferentTeam(self.realowner, other))
if(other.deadflag == DEAD_NO)
if(IsFlying(other))
- AnnounceTo(self.realowner, "airshot");
+ Send_Notification(NOTIF_ONE, self.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_AIRSHOT);
- self.event_damage = SUB_Null;
+ self.event_damage = func_null;
self.takedamage = DAMAGE_NO;
- RadiusDamage (self, self.realowner, autocvar_g_balance_rocketlauncher_damage, autocvar_g_balance_rocketlauncher_edgedamage, autocvar_g_balance_rocketlauncher_radius, world, autocvar_g_balance_rocketlauncher_force, self.projectiledeathtype, other);
+ RadiusDamage (self, self.realowner, autocvar_g_balance_rocketlauncher_damage, autocvar_g_balance_rocketlauncher_edgedamage, autocvar_g_balance_rocketlauncher_radius, world, world, autocvar_g_balance_rocketlauncher_force, self.projectiledeathtype, other);
if (self.realowner.weapon == WEP_ROCKET_LAUNCHER)
{
{
W_Rocket_Unregister();
- self.event_damage = SUB_Null;
+ self.event_damage = func_null;
self.takedamage = DAMAGE_NO;
- RadiusDamage (self, self.realowner, autocvar_g_balance_rocketlauncher_remote_damage, autocvar_g_balance_rocketlauncher_remote_edgedamage, autocvar_g_balance_rocketlauncher_remote_radius, world, autocvar_g_balance_rocketlauncher_remote_force, self.projectiledeathtype | HITTYPE_BOUNCE, world);
+ RadiusDamage (self, self.realowner, autocvar_g_balance_rocketlauncher_remote_damage, autocvar_g_balance_rocketlauncher_remote_edgedamage, autocvar_g_balance_rocketlauncher_remote_radius, world, world, autocvar_g_balance_rocketlauncher_remote_force, self.projectiledeathtype | HITTYPE_BOUNCE, world);
if (self.realowner.weapon == WEP_ROCKET_LAUNCHER)
{
// ============================
void Seeker_Missile_Explode ()
{
- self.event_damage = SUB_Null;
+ self.event_damage = func_null;
- RadiusDamage (self, self.realowner, autocvar_g_balance_seeker_missile_damage, autocvar_g_balance_seeker_missile_edgedamage, autocvar_g_balance_seeker_missile_radius, world, autocvar_g_balance_seeker_missile_force, self.projectiledeathtype, other);
+ RadiusDamage (self, self.realowner, autocvar_g_balance_seeker_missile_damage, autocvar_g_balance_seeker_missile_edgedamage, autocvar_g_balance_seeker_missile_radius, world, world, autocvar_g_balance_seeker_missile_force, self.projectiledeathtype, other);
+
+
remove (self);
}
// ============================
void Seeker_Flac_Explode ()
{
- self.event_damage = SUB_Null;
+ self.event_damage = func_null;
- RadiusDamage (self, self.realowner, autocvar_g_balance_seeker_flac_damage, autocvar_g_balance_seeker_flac_edgedamage, autocvar_g_balance_seeker_flac_radius, world, autocvar_g_balance_seeker_flac_force, self.projectiledeathtype, other);
+ RadiusDamage (self, self.realowner, autocvar_g_balance_seeker_flac_damage, autocvar_g_balance_seeker_flac_edgedamage, autocvar_g_balance_seeker_flac_radius, world, world, autocvar_g_balance_seeker_flac_force, self.projectiledeathtype, other);
remove (self);
}