]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into Lyberta/StandaloneOverkillWeapons
authorLyberta <lyberta@lyberta.net>
Thu, 29 Jun 2017 11:52:57 +0000 (14:52 +0300)
committerLyberta <lyberta@lyberta.net>
Thu, 29 Jun 2017 11:52:57 +0000 (14:52 +0300)
1  2 
bal-wep-overkill.cfg
defaultXonotic.cfg
qcsrc/client/view.qc
qcsrc/common/stats.qh
qcsrc/server/client.qc
qcsrc/server/defs.qh

diff --combined bal-wep-overkill.cfg
index d55cf92666795a8b1e7b610c4e98c337d474a33a,9cfffed10b02114e478653d4ea7ea117ad744c0e..67cc81523f1f1d7db4021952f921fdabae9f77ec
@@@ -32,7 -32,7 +32,7 @@@ set g_balance_blaster_weaponstartoverri
  set g_balance_blaster_weaponthrowable 0
  // }}}
  // {{{ #2: Shotgun
- set g_balance_shotgun_primary_ammo 6.25
+ set g_balance_shotgun_primary_ammo 3
  set g_balance_shotgun_primary_animtime 0.65
  set g_balance_shotgun_primary_bullets 10
  set g_balance_shotgun_primary_damage 17
@@@ -40,7 -40,7 +40,7 @@@ set g_balance_shotgun_primary_force 8
  set g_balance_shotgun_primary_refire 0.75
  set g_balance_shotgun_primary_solidpenetration 3.8
  set g_balance_shotgun_primary_spread 0.07
- set g_balance_shotgun_reload_ammo 50
+ set g_balance_shotgun_reload_ammo 24
  set g_balance_shotgun_reload_time 2
  set g_balance_shotgun_secondary 1
  set g_balance_shotgun_secondary_animtime 1.15
@@@ -778,16 -778,16 +778,16 @@@ set g_balance_arc_weaponstartoverride -
  set g_balance_arc_weaponthrowable 1
  // }}}
  // {{{ #21: Heavy Machine Gun
 -set g_balance_hmg_ammo 1
 -set g_balance_hmg_damage 30
 -set g_balance_hmg_force 10
 -set g_balance_hmg_refire 0.05
 +set g_balance_hmg_primary_ammo 1
 +set g_balance_hmg_primary_damage 30
 +set g_balance_hmg_primary_force 10
 +set g_balance_hmg_primary_refire 0.05
 +set g_balance_hmg_primary_solidpenetration 32
 +set g_balance_hmg_primary_spread_add 0.005
 +set g_balance_hmg_primary_spread_max 0.06
 +set g_balance_hmg_primary_spread_min 0.01
  set g_balance_hmg_reload_ammo 120
  set g_balance_hmg_reload_time 1
 -set g_balance_hmg_solidpenetration 32
 -set g_balance_hmg_spread_add 0.005
 -set g_balance_hmg_spread_max 0.06
 -set g_balance_hmg_spread_min 0.01
  set g_balance_hmg_switchdelay_drop 0.2
  set g_balance_hmg_switchdelay_raise 0.2
  set g_balance_hmg_weaponreplace ""
@@@ -796,21 -796,21 +796,21 @@@ set g_balance_hmg_weaponstartoverride 
  set g_balance_hmg_weaponthrowable 0
  // }}}
  // {{{ #22: Rocket Propelled Chainsaw
 -set g_balance_rpc_ammo 10
 -set g_balance_rpc_animtime 1
 -set g_balance_rpc_damage 150
 -set g_balance_rpc_damage2 500
 -set g_balance_rpc_damageforcescale 2
 -set g_balance_rpc_edgedamage 50
 -set g_balance_rpc_force 400
 -set g_balance_rpc_health 25
 -set g_balance_rpc_lifetime 30
 -set g_balance_rpc_radius 300
 -set g_balance_rpc_refire 1
 +set g_balance_rpc_primary_ammo 10
 +set g_balance_rpc_primary_animtime 1
 +set g_balance_rpc_primary_damage 150
 +set g_balance_rpc_primary_damage2 500
 +set g_balance_rpc_primary_damageforcescale 2
 +set g_balance_rpc_primary_edgedamage 50
 +set g_balance_rpc_primary_force 400
 +set g_balance_rpc_primary_health 25
 +set g_balance_rpc_primary_lifetime 30
 +set g_balance_rpc_primary_radius 300
 +set g_balance_rpc_primary_refire 1
 +set g_balance_rpc_primary_speed 2500
 +set g_balance_rpc_primary_speedaccel 5000
  set g_balance_rpc_reload_ammo 10
  set g_balance_rpc_reload_time 1
 -set g_balance_rpc_speed 2500
 -set g_balance_rpc_speedaccel 5000
  set g_balance_rpc_switchdelay_drop 0.2
  set g_balance_rpc_switchdelay_raise 0.2
  set g_balance_rpc_weaponreplace ""
@@@ -818,132 -818,3 +818,132 @@@ set g_balance_rpc_weaponstart 
  set g_balance_rpc_weaponstartoverride 0
  set g_balance_rpc_weaponthrowable 0
  // }}}
 +// {{{ Overkill Shotgun
 +set g_balance_okshotgun_primary_ammo 3
 +set g_balance_okshotgun_primary_animtime 0.65
 +set g_balance_okshotgun_primary_bot_range 512
 +set g_balance_okshotgun_primary_bullets 10
 +set g_balance_okshotgun_primary_damage 17
 +set g_balance_okshotgun_primary_force 80
 +set g_balance_okshotgun_primary_refire 0.75
 +set g_balance_okshotgun_primary_solidpenetration 3.8
 +set g_balance_okshotgun_primary_spread 0.07
 +set g_balance_okshotgun_reload_ammo 24
 +set g_balance_okshotgun_reload_time 2
 +set g_balance_okshotgun_secondary_ammo 0
 +set g_balance_okshotgun_secondary_animtime 0.2
 +set g_balance_okshotgun_secondary_damage 25
 +set g_balance_okshotgun_secondary_delay 0
 +set g_balance_okshotgun_secondary_edgedamage 12.5
 +set g_balance_okshotgun_secondary_force 300
 +set g_balance_okshotgun_secondary_lifetime 5
 +set g_balance_okshotgun_secondary_radius 70
 +set g_balance_okshotgun_secondary_refire 0.7
 +set g_balance_okshotgun_secondary_refire_type 1
 +set g_balance_okshotgun_secondary_shotangle 0
 +set g_balance_okshotgun_secondary_speed 6000
 +set g_balance_okshotgun_secondary_spread 0
 +set g_balance_okshotgun_switchdelay_drop 0.2
 +set g_balance_okshotgun_switchdelay_raise 0.2
 +set g_balance_okshotgun_weaponreplace ""
 +set g_balance_okshotgun_weaponstart 0
 +set g_balance_okshotgun_weaponstartoverride -1
 +set g_balance_okshotgun_weaponthrowable 1
 +// }}}
 +// {{{ Overkill Machine Gun
 +set g_balance_okmachinegun_burst 3
 +set g_balance_okmachinegun_burst_ammo 3
 +set g_balance_okmachinegun_burst_animtime 0.3
 +set g_balance_okmachinegun_burst_refire 0.06
 +set g_balance_okmachinegun_burst_refire2 0.45
 +set g_balance_okmachinegun_burst_speed 0
 +set g_balance_okmachinegun_first 1
 +set g_balance_okmachinegun_first_ammo 1
 +set g_balance_okmachinegun_first_damage 14
 +set g_balance_okmachinegun_first_force 5
 +set g_balance_okmachinegun_first_refire 0.125
 +set g_balance_okmachinegun_first_spread 0.03
 +set g_balance_okmachinegun_mode 1
 +set g_balance_okmachinegun_reload_ammo 30
 +set g_balance_okmachinegun_reload_time 1.5
 +set g_balance_okmachinegun_secondary_ammo 0
 +set g_balance_okmachinegun_secondary_animtime 0.2
 +set g_balance_okmachinegun_secondary_damage 25
 +set g_balance_okmachinegun_secondary_delay 0
 +set g_balance_okmachinegun_secondary_edgedamage 12.5
 +set g_balance_okmachinegun_secondary_force 300
 +set g_balance_okmachinegun_secondary_lifetime 5
 +set g_balance_okmachinegun_secondary_radius 70
 +set g_balance_okmachinegun_secondary_refire 0.7
 +set g_balance_okmachinegun_secondary_refire_type 1
 +set g_balance_okmachinegun_secondary_shotangle 0
 +set g_balance_okmachinegun_secondary_speed 6000
 +set g_balance_okmachinegun_secondary_spread 0
 +set g_balance_okmachinegun_solidpenetration 13.1
 +set g_balance_okmachinegun_spread_add 0.012
 +set g_balance_okmachinegun_spread_max 0.05
 +set g_balance_okmachinegun_spread_min 0
 +set g_balance_okmachinegun_sustained_ammo 1
 +set g_balance_okmachinegun_sustained_damage 25
 +set g_balance_okmachinegun_sustained_force 5
 +set g_balance_okmachinegun_sustained_refire 0.1
 +set g_balance_okmachinegun_sustained_spread 0.01
 +set g_balance_okmachinegun_switchdelay_drop 0.2
 +set g_balance_okmachinegun_switchdelay_raise 0.2
 +set g_balance_okmachinegun_weaponreplace ""
 +set g_balance_okmachinegun_weaponstart 0
 +set g_balance_okmachinegun_weaponstartoverride -1
 +set g_balance_okmachinegun_weaponthrowable 1
 +// }}}
 +// {{{ Overkill Vortex
 +set g_balance_okvortex_charge 0
 +set g_balance_okvortex_charge_animlimit 0.5
 +set g_balance_okvortex_charge_limit 1
 +set g_balance_okvortex_charge_maxspeed 800
 +set g_balance_okvortex_charge_mindmg 40
 +set g_balance_okvortex_charge_minspeed 400
 +set g_balance_okvortex_charge_rate 0.6
 +set g_balance_okvortex_charge_rot_pause 0
 +set g_balance_okvortex_charge_rot_rate 0
 +set g_balance_okvortex_charge_shot_multiplier 0
 +set g_balance_okvortex_charge_start 0.5
 +set g_balance_okvortex_charge_velocity_rate 0
 +set g_balance_okvortex_primary_ammo 10
 +set g_balance_okvortex_primary_animtime 0.65
 +set g_balance_okvortex_primary_damage 100
 +set g_balance_okvortex_primary_damagefalloff_forcehalflife 0
 +set g_balance_okvortex_primary_damagefalloff_halflife 0
 +set g_balance_okvortex_primary_damagefalloff_maxdist 0
 +set g_balance_okvortex_primary_damagefalloff_mindist 0
 +set g_balance_okvortex_primary_force 500
 +set g_balance_okvortex_primary_refire 1
 +set g_balance_okvortex_reload_ammo 50
 +set g_balance_okvortex_reload_time 2
 +set g_balance_okvortex_secondary 2
 +set g_balance_okvortex_secondary_ammo 0
 +set g_balance_okvortex_secondary_animtime 0.2
 +set g_balance_okvortex_secondary_chargepool 0
 +set g_balance_okvortex_secondary_chargepool_pause_regen 1
 +set g_balance_okvortex_secondary_chargepool_regen 0.15
 +set g_balance_okvortex_secondary_damage 25
 +set g_balance_okvortex_secondary_damagefalloff_forcehalflife 0
 +set g_balance_okvortex_secondary_damagefalloff_halflife 0
 +set g_balance_okvortex_secondary_damagefalloff_maxdist 0
 +set g_balance_okvortex_secondary_damagefalloff_mindist 0
 +set g_balance_okvortex_secondary_force 300
 +set g_balance_okvortex_secondary_refire 0.7
 +set g_balance_okvortex_secondary_refire_type 1
 +set g_balance_okvortex_secondary_delay 0
 +set g_balance_okvortex_secondary_edgedamage 12.5
 +set g_balance_okvortex_secondary_lifetime 5
 +set g_balance_okvortex_secondary_radius 70
 +set g_balance_okvortex_secondary_shotangle 0
 +set g_balance_okvortex_secondary_speed 6000
 +set g_balance_okvortex_secondary_spread 0
 +set g_balance_okvortex_switchdelay_drop 0.2
 +set g_balance_okvortex_switchdelay_raise 0.2
 +set g_balance_okvortex_weaponreplace ""
 +set g_balance_okvortex_weaponstart 0
 +set g_balance_okvortex_weaponstartoverride -1
 +set g_balance_okvortex_weaponthrowable 1
 +// }}}
diff --combined defaultXonotic.cfg
index ab7f0e56977f35b490484f1057e4d640ccea7868,f2a6a201237ff547f7c6b245444c8d5a7cd8f4e8..1312d6fa299d1e125b890099581981de504c9bea
@@@ -229,6 -229,7 +229,7 @@@ seta cl_hitsound_max_pitch 1.5 "maximu
  seta cl_hitsound_nom_damage 25 "damage amount at which hitsound bases pitch off"
  
  seta cl_eventchase_death 1 "camera goes into 3rd person mode when the player is dead; set to 2 to active the effect only when the corpse doesn't move anymore"
+ seta cl_eventchase_frozen 0 "camera goes into 3rd person mode when the player is frozen"
  seta cl_eventchase_nexball 1 "camera goes into 3rd person mode when in nexball game-mode"
  seta cl_eventchase_distance 140 "final camera distance"
  seta cl_eventchase_generator_distance 400 "final camera distance while viewing generator explosion"
@@@ -299,6 -300,7 +300,7 @@@ set sv_friction_slick 0.
  set sv_slick_applygravity 0
  
  set sv_aircontrol_backwards 0 "apply forward aircontrol options to backward movement"
+ set sv_aircontrol_sidewards 0 "apply forward aircontrol options to sideward movement"
  
  set sv_player_viewoffset "0 0 35" "view offset of the player model"
  set sv_player_mins "-16 -16 -24" "playermodel mins"
@@@ -373,9 -375,9 +375,9 @@@ set bot_ai_keyboard_threshold 0.5
  set bot_ai_aimskill_offset 0.3 "Amount of error induced to the bots aim"
  set bot_ai_aimskill_think 1 "Aiming velocity. Use values below 1 for slower aiming"
  set bot_ai_custom_weapon_priority_distances "300 850" "Define close and far distances in any order. Based on the distance to the enemy bots will choose different weapons"
 -set bot_ai_custom_weapon_priority_far   "vaporizer vortex rifle electro devastator mortar hagar hlac crylink blaster machinegun fireball seeker shotgun shockwave tuba minelayer"     "Desired weapons for far distances ordered by priority"
 -set bot_ai_custom_weapon_priority_mid   "vaporizer devastator vortex fireball seeker mortar electro machinegun arc crylink hlac hagar shotgun shockwave blaster rifle tuba minelayer" "Desired weapons for middle distances ordered by priority"
 -set bot_ai_custom_weapon_priority_close "vaporizer vortex shotgun shockwave machinegun arc hlac tuba seeker hagar crylink mortar electro devastator blaster fireball rifle minelayer" "Desired weapons for close distances ordered by priority"
 +set bot_ai_custom_weapon_priority_far   "vaporizer okvortex vortex rifle electro devastator mortar hagar hlac crylink blaster okmachinegun machinegun fireball seeker okshotgun shotgun shockwave tuba minelayer"     "Desired weapons for far distances ordered by priority"
 +set bot_ai_custom_weapon_priority_mid   "vaporizer devastator okvortex vortex fireball seeker mortar electro okmachinegun machinegun arc crylink hlac hagar okshotgun shotgun shockwave blaster rifle tuba minelayer" "Desired weapons for middle distances ordered by priority"
 +set bot_ai_custom_weapon_priority_close "vaporizer okvortex vortex okshotgun shotgun shockwave okmachinegun machinegun arc hlac tuba seeker hagar crylink mortar electro devastator blaster fireball rifle minelayer" "Desired weapons for close distances ordered by priority"
  set bot_ai_weapon_combo 1     "Enable bots to do weapon combos"
  set bot_ai_weapon_combo_threshold 0.4 "Try to make a combo N seconds after the last attack"
  set bot_ai_friends_aware_pickup_radius "500"  "Bots will not pickup items if a team mate is this distance near the item"
@@@ -1058,13 -1060,13 +1060,13 @@@ sv_allowdownloads 0 // download protoco
  
  set g_jump_grunt 0    "Do you make a grunting noise every time you jump? Is it the same grunting noise every time?"
  
 -seta cl_weaponpriority "vaporizer hmg rpc vortex fireball mortar machinegun hagar rifle arc electro devastator crylink minelayer shotgun shockwave hlac tuba blaster porto seeker hook" "weapon priority list"
 +seta cl_weaponpriority "vaporizer hmg rpc okvortex okshotgun okmachinegun vortex fireball mortar machinegun hagar rifle arc electro devastator crylink minelayer shotgun shockwave hlac tuba blaster porto seeker hook" "weapon priority list"
  seta cl_weaponpriority_useforcycling 0 "when set, weapon cycling by the mouse wheel makes use of the weapon priority list (the special value 2 uses the weapon ID list for cycling)"
  seta cl_weaponpriority0 "rpc devastator mortar hagar seeker fireball"                   "use weapon_priority_0_prev for prev gun from this list, weapon_priority_0_best for best gun, weapon_priority_0_next for next gun.  Default value: explosives"
 -seta cl_weaponpriority1 "vaporizer vortex crylink hlac arc electro blaster shockwave"   "use weapon_priority_1_prev for prev gun from this list, weapon_priority_1_best for best gun, weapon_priority_1_next for next gun.  Default value: energy"
 -seta cl_weaponpriority2 "vaporizer vortex rifle"                                        "use weapon_priority_2_prev for prev gun from this list, weapon_priority_2_best for best gun, weapon_priority_2_next for next gun.  Default value: hitscan exact"
 -seta cl_weaponpriority3 "vaporizer hmg vortex rifle machinegun shotgun shockwave"       "use weapon_priority_3_prev for prev gun from this list, weapon_priority_3_best for best gun, weapon_priority_3_next for next gun.  Default value: hitscan all"
 -seta cl_weaponpriority4 "mortar minelayer hlac hagar crylink seeker shotgun shockwave"  "use weapon_priority_4_prev for prev gun from this list, weapon_priority_4_best for best gun, weapon_priority_4_next for next gun.  Default value: spam weapons"
 +seta cl_weaponpriority1 "vaporizer okvortex vortex crylink hlac arc electro blaster shockwave"   "use weapon_priority_1_prev for prev gun from this list, weapon_priority_1_best for best gun, weapon_priority_1_next for next gun.  Default value: energy"
 +seta cl_weaponpriority2 "vaporizer okvortex vortex rifle"                                        "use weapon_priority_2_prev for prev gun from this list, weapon_priority_2_best for best gun, weapon_priority_2_next for next gun.  Default value: hitscan exact"
 +seta cl_weaponpriority3 "vaporizer hmg okvortex vortex rifle okmachinegun machinegun okshotgun shotgun shockwave"       "use weapon_priority_3_prev for prev gun from this list, weapon_priority_3_best for best gun, weapon_priority_3_next for next gun.  Default value: hitscan all"
 +seta cl_weaponpriority4 "mortar minelayer hlac hagar crylink seeker okshotgun shotgun shockwave"  "use weapon_priority_4_prev for prev gun from this list, weapon_priority_4_best for best gun, weapon_priority_4_next for next gun.  Default value: spam weapons"
  seta cl_weaponpriority5 "blaster shockwave hook porto"                                  "use weapon_priority_5_prev for prev gun from this list, weapon_priority_5_best for best gun, weapon_priority_5_next for next gun.  Default value: weapons for moving"
  seta cl_weaponpriority6 ""                                                              "use weapon_priority_6_prev for prev gun from this list, weapon_priority_6_best for best gun, weapon_priority_6_next for next gun"
  seta cl_weaponpriority7 ""                                                              "use weapon_priority_7_prev for prev gun from this list, weapon_priority_7_best for best gun, weapon_priority_7_next for next gun"
diff --combined qcsrc/client/view.qc
index 6648b7ecbf557922991c0e7373caebefc3eef5b9,75afcfccb1691869a863bab13166837ee142f32c..efdf2e108060e6b54753226af9fa0e09cd31bb73
@@@ -26,7 -26,6 +26,7 @@@
  
  #include <common/vehicles/all.qh>
  #include <common/weapons/_all.qh>
 +#include <common/mutators/mutator/overkill/okvortex.qh>
  #include <common/viewloc.qh>
  #include <common/minigames/cl_minigames.qh>
  #include <common/minigames/cl_minigames_hud.qh>
@@@ -63,10 -62,9 +63,9 @@@ float autocvar_cl_leanmodel_highpass = 
  float autocvar_cl_leanmodel_lowpass = 0.05;
  
  #define avg_factor(avg_time) (1 - exp(-frametime / max(0.001, avg_time)))
- #define lowpass(value, frac, ref_store, ret) MACRO_BEGIN \
- { \
-       ret = ref_store = ref_store * (1 - frac) + (value) * frac; \
- } MACRO_END
+ #define lowpass(value, frac, ref_store, ret) \
+       ret = ref_store = ref_store * (1 - frac) + (value) * frac;
  
  #define lowpass_limited(value, frac, limit, ref_store, ret) MACRO_BEGIN \
  { \
@@@ -468,7 -466,7 +467,7 @@@ vector GetCurrentFov(float fov
                {
                        entity wepent = viewmodels[slot];
                        if(wepent.switchweapon == wepent.activeweapon)
 -                      if((wepent.activeweapon == WEP_VORTEX && !WEP_CVAR(vortex, secondary)) || (wepent.activeweapon == WEP_RIFLE && !WEP_CVAR(rifle, secondary))) // do NOT use switchweapon here
 +                      if((wepent.activeweapon == WEP_VORTEX && !WEP_CVAR(vortex, secondary)) || (wepent.activeweapon == WEP_RIFLE && !WEP_CVAR(rifle, secondary)) || (wepent.activeweapon == WEP_OVERKILL_VORTEX && !WEP_CVAR(okvortex, secondary))) // do NOT use switchweapon here
                                zoomdir += button_attack2;
                }
        }
@@@ -660,7 -658,6 +659,7 @@@ float TrueAimCheck(entity wepent
                case WEP_MORTAR: // toss curve
                        return SHOTTYPE_HITWORLD;
                case WEP_VORTEX:
 +              case WEP_OVERKILL_VORTEX:
                case WEP_VAPORIZER:
                        mv = MOVE_NORMAL;
                        break;
@@@ -772,6 -769,8 +771,8 @@@ bool WantEventchase(entity this
                        return true;
                if(MUTATOR_CALLHOOK(WantEventchase, this))
                        return true;
+               if(autocvar_cl_eventchase_frozen && STAT(FROZEN))
+                       return true;
                if(autocvar_cl_eventchase_death && (STAT(HEALTH) <= 0))
                {
                        if(autocvar_cl_eventchase_death == 2)
@@@ -1183,10 -1182,6 +1184,10 @@@ void HUD_Crosshair(entity this
                                vortex_charge = STAT(VORTEX_CHARGE);
                                vortex_chargepool = STAT(VORTEX_CHARGEPOOL);
  
 +                              float okvortex_charge, okvortex_chargepool;
 +                              okvortex_charge = STAT(OVERKILL_VORTEX_CHARGE);
 +                              okvortex_chargepool = STAT(OVERKILL_VORTEX_CHARGEPOOL);
 +
                                float arc_heat = STAT(ARC_HEAT);
  
                                if(vortex_charge_movingavg == 0) // this should only happen if we have just loaded up the game
                                        }
  
                                        ring_inner_alpha = autocvar_crosshair_ring_vortex_inner_alpha;
-                                       ring_inner_rgb = eX * autocvar_crosshair_ring_vortex_inner_color_red + eY * autocvar_crosshair_ring_vortex_inner_color_green + eZ * autocvar_crosshair_ring_vortex_inner_color_blue;
+                                       ring_inner_rgb = vec3(autocvar_crosshair_ring_vortex_inner_color_red, autocvar_crosshair_ring_vortex_inner_color_green, autocvar_crosshair_ring_vortex_inner_color_blue);
                                        ring_inner_image = "gfx/crosshair_ring_inner.tga";
  
                                        // draw the outer ring to show the current charge of the weapon
                                        ring_rgb = wcross_color;
                                        ring_image = "gfx/crosshair_ring_nexgun.tga";
                                }
 +                              else if (autocvar_crosshair_ring && (wepent.activeweapon == WEP_OVERKILL_VORTEX) && okvortex_charge && autocvar_crosshair_ring_vortex)
 +                              {
 +                                      if (okvortex_chargepool || use_vortex_chargepool) {
 +                                              use_vortex_chargepool = 1;
 +                                              ring_inner_value = okvortex_chargepool;
 +                                      } else {
 +                                              vortex_charge_movingavg = (1 - autocvar_crosshair_ring_vortex_currentcharge_movingavg_rate) * vortex_charge_movingavg + autocvar_crosshair_ring_vortex_currentcharge_movingavg_rate * okvortex_charge;
 +                                              ring_inner_value = bound(0, autocvar_crosshair_ring_vortex_currentcharge_scale * (okvortex_charge - vortex_charge_movingavg), 1);
 +                                      }
 +
 +                                      ring_inner_alpha = autocvar_crosshair_ring_vortex_inner_alpha;
 +                                      ring_inner_rgb = eX * autocvar_crosshair_ring_vortex_inner_color_red + eY * autocvar_crosshair_ring_vortex_inner_color_green + eZ * autocvar_crosshair_ring_vortex_inner_color_blue;
 +                                      ring_inner_image = "gfx/crosshair_ring_inner.tga";
 +
 +                                      // draw the outer ring to show the current charge of the weapon
 +                                      ring_value = okvortex_charge;
 +                                      ring_alpha = autocvar_crosshair_ring_vortex_alpha;
 +                                      ring_rgb = wcross_color;
 +                                      ring_image = "gfx/crosshair_ring_nexgun.tga";
 +                              }
                                else if (autocvar_crosshair_ring && wepent.activeweapon == WEP_MINE_LAYER && WEP_CVAR(minelayer, limit) && autocvar_crosshair_ring_minelayer)
                                {
                                        ring_value = bound(0, STAT(LAYED_MINES) / WEP_CVAR(minelayer, limit), 1); // if you later need to use the count of bullets in another place, then add a float for it. For now, no need to.
@@@ -1386,29 -1361,33 +1387,33 @@@ void HUD_Draw(entity this
        if(!intermission)
        if (MUTATOR_CALLHOOK(HUD_Draw_overlay))
        {
-               drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, M_ARGV(0, vector), autocvar_hud_colorflash_alpha * M_ARGV(1, float), DRAWFLAG_ADDITIVE);
+               drawfill('0 0 0', vec2(vid_conwidth, vid_conheight), M_ARGV(0, vector), autocvar_hud_colorflash_alpha * M_ARGV(1, float), DRAWFLAG_ADDITIVE);
        }
        else if(STAT(FROZEN))
        {
-               drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, ((STAT(REVIVE_PROGRESS)) ? ('0.25 0.90 1' + ('1 0 0' * STAT(REVIVE_PROGRESS)) + ('0 1 1' * STAT(REVIVE_PROGRESS) * -1)) : '0.25 0.90 1'), autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
+               vector col = '0.25 0.90 1';
+               if(STAT(REVIVE_PROGRESS))
+                       col += vec3(STAT(REVIVE_PROGRESS), -STAT(REVIVE_PROGRESS), -STAT(REVIVE_PROGRESS));
+               drawfill('0 0 0', vec2(vid_conwidth, vid_conheight), col, autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
        }
  
        HUD_Scale_Enable();
        if(!intermission)
        if(STAT(NADE_TIMER) && autocvar_cl_nade_timer) // give nade top priority, as it's a matter of life and death
        {
-               DrawCircleClippedPic(eX * 0.5 * vid_conwidth + eY * 0.6 * vid_conheight, 0.1 * vid_conheight, "gfx/crosshair_ring.tga", STAT(NADE_TIMER), '0.25 0.90 1' + ('1 0 0' * STAT(NADE_TIMER)) - ('0 1 1' * STAT(NADE_TIMER)), autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
-               drawstring_aspect(eY * 0.64 * vid_conheight, ((autocvar_cl_nade_timer == 2) ? _("Nade timer") : ""), eX * vid_conwidth + eY * 0.025 * vid_conheight, '1 1 1', 1, DRAWFLAG_NORMAL);
+               vector col = '0.25 0.90 1' + vec3(STAT(NADE_TIMER), -STAT(NADE_TIMER), -STAT(NADE_TIMER));
+               DrawCircleClippedPic(vec2(0.5 * vid_conwidth, 0.6 * vid_conheight), 0.1 * vid_conheight, "gfx/crosshair_ring.tga", STAT(NADE_TIMER), col, autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
+               drawstring_aspect(eY * 0.64 * vid_conheight, ((autocvar_cl_nade_timer == 2) ? _("Nade timer") : ""), vec2(vid_conwidth, 0.025 * vid_conheight), '1 1 1', 1, DRAWFLAG_NORMAL);
        }
        else if(STAT(CAPTURE_PROGRESS))
        {
-               DrawCircleClippedPic(eX * 0.5 * vid_conwidth + eY * 0.6 * vid_conheight, 0.1 * vid_conheight, "gfx/crosshair_ring.tga", STAT(CAPTURE_PROGRESS), '0.25 0.90 1', autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
-               drawstring_aspect(eY * 0.64 * vid_conheight, _("Capture progress"), eX * vid_conwidth + eY * 0.025 * vid_conheight, '1 1 1', 1, DRAWFLAG_NORMAL);
+               DrawCircleClippedPic(vec2(0.5 * vid_conwidth, 0.6 * vid_conheight), 0.1 * vid_conheight, "gfx/crosshair_ring.tga", STAT(CAPTURE_PROGRESS), '0.25 0.90 1', autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
+               drawstring_aspect(eY * 0.64 * vid_conheight, _("Capture progress"), vec2(vid_conwidth, 0.025 * vid_conheight), '1 1 1', 1, DRAWFLAG_NORMAL);
        }
        else if(STAT(REVIVE_PROGRESS))
        {
-               DrawCircleClippedPic(eX * 0.5 * vid_conwidth + eY * 0.6 * vid_conheight, 0.1 * vid_conheight, "gfx/crosshair_ring.tga", STAT(REVIVE_PROGRESS), '0.25 0.90 1', autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
-               drawstring_aspect(eY * 0.64 * vid_conheight, _("Revival progress"), eX * vid_conwidth + eY * 0.025 * vid_conheight, '1 1 1', 1, DRAWFLAG_NORMAL);
+               DrawCircleClippedPic(vec2(0.5 * vid_conwidth, 0.6 * vid_conheight), 0.1 * vid_conheight, "gfx/crosshair_ring.tga", STAT(REVIVE_PROGRESS), '0.25 0.90 1', autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
+               drawstring_aspect(eY * 0.64 * vid_conheight, _("Revival progress"), vec2(vid_conwidth, 0.025 * vid_conheight), '1 1 1', 1, DRAWFLAG_NORMAL);
        }
        HUD_Scale_Disable();
  
@@@ -2111,7 -2090,7 +2116,7 @@@ void CSQC_UpdateView(entity this, floa
                contentavgalpha = contentavgalpha * (1 - contentalpha_temp) + incontent * contentalpha_temp;
  
                if(contentavgalpha)
-                       drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, liquidcolor_prev, contentavgalpha * liquidalpha_prev, DRAWFLAG_NORMAL);
+                       drawfill('0 0 0', vec2(vid_conwidth, vid_conheight), liquidcolor_prev, contentavgalpha * liquidalpha_prev, DRAWFLAG_NORMAL);
  
                if(autocvar_hud_postprocessing)
                {
                        if(autocvar_cl_gentle_damage == 2)
                        {
                                if(myhealth_flash < pain_threshold) // only randomize when the flash is gone
-                                       myhealth_gentlergb = eX * random() + eY * random() + eZ * random();
+                                       myhealth_gentlergb = randomvec();
                        }
                        else
                                myhealth_gentlergb = stov(autocvar_hud_damage_gentle_color);
  
                        if(myhealth_flash_temp > 0)
-                               drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, myhealth_gentlergb, autocvar_hud_damage_gentle_alpha_multiplier * bound(0, myhealth_flash_temp, 1) * autocvar_hud_damage, DRAWFLAG_NORMAL);
+                               drawfill('0 0 0', vec2(vid_conwidth, vid_conheight), myhealth_gentlergb, autocvar_hud_damage_gentle_alpha_multiplier * bound(0, myhealth_flash_temp, 1) * autocvar_hud_damage, DRAWFLAG_NORMAL);
                }
                else if(myhealth_flash_temp > 0)
                        drawpic(splash_pos, "gfx/blood", splash_size, stov(autocvar_hud_damage_color), bound(0, myhealth_flash_temp, 1) * autocvar_hud_damage, DRAWFLAG_NORMAL);
diff --combined qcsrc/common/stats.qh
index bea426a3412513f65256ab8a8ef73cfbf0feebc8,2cb353361eb0867750cbbfc2a9ee47e26086dca7..8b6b1cfdf6a12b4137a488ddd8503d50246d3c11
@@@ -78,11 -78,9 +78,11 @@@ REGISTER_STAT(WEAPON_CLIPLOAD, int
  REGISTER_STAT(WEAPON_CLIPSIZE, int)
  
  REGISTER_STAT(VORTEX_CHARGE, float)
 +REGISTER_STAT(OVERKILL_VORTEX_CHARGE, float)
  REGISTER_STAT(LAST_PICKUP, float)
  REGISTER_STAT(HUD, int)
  REGISTER_STAT(VORTEX_CHARGEPOOL, float)
 +REGISTER_STAT(OVERKILL_VORTEX_CHARGEPOOL, float)
  REGISTER_STAT(HIT_TIME, float)
  REGISTER_STAT(DAMAGE_DEALT_TOTAL, int)
  REGISTER_STAT(TYPEHIT_TIME, float)
@@@ -297,6 -295,7 +297,7 @@@ REGISTER_STAT(MOVEVARS_AIRSPEEDLIMIT_NO
  REGISTER_STAT(MOVEVARS_AIRSTRAFEACCEL_QW, float)
  REGISTER_STAT(MOVEVARS_AIRCONTROL_POWER, float)
  REGISTER_STAT(MOVEVARS_AIRCONTROL_BACKWARDS, bool)
+ REGISTER_STAT(MOVEVARS_AIRCONTROL_SIDEWARDS, bool)
  noref bool autocvar_sv_gameplayfix_nogravityonground;
  REGISTER_STAT(MOVEFLAGS, int, MOVEFLAG_VALID
                                | (autocvar_sv_gameplayfix_q2airaccelerate ? MOVEFLAG_Q2AIRACCELERATE : 0)
diff --combined qcsrc/server/client.qc
index af5cdb1315258d4a5c91301843778e5305b047e2,381373ad2bcb713d93ccc4046efa6ac2341c14ed..7401c2cd1a1f7f141f0a392f82d28154bb7f79e8
@@@ -56,8 -56,6 +56,8 @@@
  
  #include "../lib/warpzone/server.qh"
  
 +#include <common/mutators/mutator/overkill/okvortex.qh>
 +
  STATIC_METHOD(Client, Add, void(Client this, int _team))
  {
      ClientConnect(this);
@@@ -660,6 -658,8 +660,8 @@@ void PutClientInServer(entity this
                if(!this.bot_attack)
                        IL_PUSH(g_bot_targets, this);
                this.bot_attack = true;
+               if(!this.monster_attack)
+                       IL_PUSH(g_monster_targets, this);
                this.monster_attack = true;
                navigation_dynamicgoal_init(this, false);
  
@@@ -1706,8 -1706,6 +1708,8 @@@ void SpectateCopy(entity this, entity s
        this.dual_weapons = spectatee.dual_weapons;
        this.vortex_charge = spectatee.vortex_charge;
        this.vortex_chargepool_ammo = spectatee.vortex_chargepool_ammo;
 +      this.okvortex_charge = spectatee.okvortex_charge;
 +      this.okvortex_chargepool_ammo = spectatee.okvortex_chargepool_ammo;
        this.hagar_load = spectatee.hagar_load;
        this.arc_heat_percent = spectatee.arc_heat_percent;
        this.minelayer_mines = spectatee.minelayer_mines;
@@@ -2537,13 -2535,7 +2539,13 @@@ void PlayerPreThink (entity this
                {
                        .entity weaponentity = weaponentities[slot];
                        if (WEP_CVAR(vortex, charge_rot_rate) && this.(weaponentity).vortex_charge > WEP_CVAR(vortex, charge_limit) && this.(weaponentity).vortex_charge_rottime < time)
 +                      {
                                this.(weaponentity).vortex_charge = bound(WEP_CVAR(vortex, charge_limit), this.(weaponentity).vortex_charge - WEP_CVAR(vortex, charge_rot_rate) * frametime / W_TICSPERFRAME, 1);
 +                      }
 +                      if (WEP_CVAR(okvortex, charge_rot_rate) && this.(weaponentity).okvortex_charge > WEP_CVAR(okvortex, charge_limit) && this.(weaponentity).okvortex_charge_rottime < time)
 +                      {
 +                              this.(weaponentity).okvortex_charge = bound(WEP_CVAR(okvortex, charge_limit), this.(weaponentity).okvortex_charge - WEP_CVAR(okvortex, charge_rot_rate) * frametime / W_TICSPERFRAME, 1);
 +                      }
                }
  
                if (frametime) player_anim(this);
diff --combined qcsrc/server/defs.qh
index db879a05bd985919be09ff7456cb59e862e4c26a,a6ca911bdc64fe4d5cbe29ae4d8bb149348b349e..8cdb562f5b140cd52c471ef34ff6706743ccc63e
@@@ -220,9 -220,9 +220,9 @@@ float TemporaryDB
  
  .float team_saved;
  
float some_spawn_has_been_used;
float have_team_spawns; // 0 = no team spawns requested, -1 = team spawns requested but none found, 1 = team spawns requested and found
float have_team_spawns_forteam[17]; // 0 = this team has no spawns, 1 = this team has spawns; team 0 is the "no-team"
bool some_spawn_has_been_used;
int have_team_spawns; // 0 = no team spawns requested, -1 = team spawns requested but none found, 1 = team spawns requested and found
int have_team_spawns_forteams; // if Xth bit is 1 then team X has spawns else it has no spawns; team 0 is the "no-team"
  
  // set when showing a kill countdown
  .entity killindicator;
@@@ -338,9 -338,6 +338,9 @@@ float client_cefc_accumulatortime
  .float vortex_charge = _STAT(VORTEX_CHARGE);
  .float vortex_charge_rottime;
  .float vortex_chargepool_ammo = _STAT(VORTEX_CHARGEPOOL);
 +.float okvortex_charge = _STAT(OVERKILL_VORTEX_CHARGE);
 +.float okvortex_charge_rottime;
 +.float okvortex_chargepool_ammo = _STAT(OVERKILL_VORTEX_CHARGEPOOL);
  .float hagar_load = _STAT(HAGAR_LOAD);
  
  .int grab; // 0 = can't grab, 1 = owner can grab, 2 = owner and team mates can grab, 3 = anyone can grab
@@@ -482,3 -479,9 +482,9 @@@ STATIC_INIT(g_locations) { g_locations 
  
  IntrusiveList g_saved_team;
  STATIC_INIT(g_saved_team) { g_saved_team = IL_NEW(); }
+ IntrusiveList g_monster_targets;
+ STATIC_INIT(g_monster_targets) { g_monster_targets = IL_NEW(); }
+ IntrusiveList g_pathlib_nodes;
+ STATIC_INIT(g_pathlib_nodes) { g_pathlib_nodes = IL_NEW(); }