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_reload_ammo 0 //default: 6
+set g_balance_laser_reload_time 2
// }}}
// {{{ shotgun
set g_balance_shotgun_primary_bullets 18
set g_balance_shotgun_secondary_force 150
set g_balance_shotgun_secondary_refire 1.1
set g_balance_shotgun_secondary_animtime 1
+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_speed 18000
set g_balance_uzi_bulletconstant 115 // 13.1qu
+
+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_bouncefactor 0.5
set g_balance_grenadelauncher_bouncestop 0.12
+
+set g_balance_grenadelauncher_reload_ammo 0 //default: 12
+set g_balance_grenadelauncher_reload_time 2
// }}}
// {{{ minelayer
set g_balance_minelayer_damage 42
set g_balance_minelayer_remote_edgedamage 40
set g_balance_minelayer_remote_radius 200
set g_balance_minelayer_remote_force 300
+set g_balance_minelayer_reload_ammo 0 //default: 15
+set g_balance_minelayer_reload_time 2
// }}}
// {{{ electro
set g_balance_electro_lightning 1
set g_balance_electro_combo_radius 250
set g_balance_electro_combo_comboradius 0
set g_balance_electro_combo_speed 400
+set g_balance_electro_reload_ammo 0 //default: 20
+set g_balance_electro_reload_time 2
// }}}
// {{{ crylink
set g_balance_crylink_primary_damage 7 // LOG: 10 -> 7
set g_balance_crylink_secondary_middle_fadetime 5
set g_balance_crylink_secondary_line_lifetime 2 // range: 4000 full, fades to 8000
set g_balance_crylink_secondary_line_fadetime 0.25
+
+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_charge_velocity_rate 0
set g_balance_nex_charge_minspeed 600
set g_balance_nex_charge_maxspeed 1000
+
+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.50
set g_balance_minstanex_ammo 10
+set g_balance_minstanex_laser_ammo 0
+set g_balance_minstanex_reload_ammo 0 //default: 50
+set g_balance_minstanex_reload_time 2
// }}}
// {{{ hagar
set g_balance_hagar_primary_damage 14
set g_balance_hagar_secondary_lifetime_rand 0
set g_balance_hagar_secondary_refire 0.12
set g_balance_hagar_secondary_ammo 1
+set g_balance_hagar_reload_ammo 0 //default: 25
+set g_balance_hagar_reload_time 2
// }}}
// {{{ rocketlauncher
set g_balance_rocketlauncher_damage 82
set g_balance_rocketlauncher_remote_edgedamage 20
set g_balance_rocketlauncher_remote_radius 120
set g_balance_rocketlauncher_remote_force 350
+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_hlac_secondary_animtime 0.4
set g_balance_hlac_secondary_ammo 4
set g_balance_hlac_secondary_shots 6
+
+set g_balance_hlac_reload_ammo 0 //default: 20
+set g_balance_hlac_reload_time 2
// }}}
// {{{ sniperrifle
-set g_balance_sniperrifle_magazinecapacity 8 // make it pretty much useless in close combat
-set g_balance_sniperrifle_reloadtime 2 // matches reload anim
-set g_balance_sniperrifle_auto_reload_on_switch 0
set g_balance_sniperrifle_bursttime 0
set g_balance_sniperrifle_primary_tracer 1
set g_balance_sniperrifle_primary_damage 60
set g_balance_sniperrifle_secondary_bulletconstant 110 // 15.5qu
set g_balance_sniperrifle_secondary_burstcost 0
set g_balance_sniperrifle_secondary_bullethail 0 // empty magazine on shot
+set g_balance_sniperrifle_reload_ammo 60 //default: 60
+set g_balance_sniperrifle_reload_time 2
// }}}
// {{{ tuba
set g_balance_tuba_refire 0.05
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_reload_ammo 0 //default: 60
+set g_balance_fireball_reload_time 2
// }}}
// {{{ seeker
set g_balance_seeker_flac_ammo 0.5
set g_balance_seeker_tag_refire 0.75 // LOG: 0.7 -> 0.75
set g_balance_seeker_tag_speed 5000
set g_balance_seeker_tag_spread 0
+set g_balance_seeker_reload_ammo 0 //default: 15
+set g_balance_seeker_reload_time 2
// End new seeker
seta crosshair_color_by_health 0 "if enabled, crosshair color will depend on current health"
// ring around crosshair, used for various purposes (such as indicating bullets left in clip, nex charge)
-seta crosshair_ring 1 "main cvar to enable or disable crosshair rings"
+seta crosshair_ring 1 "main cvar to enable or disable normal crosshair rings"
seta crosshair_ring_inner 0 "allow inner rings to be drawn too"
-seta crosshair_ring_size 2 "bullet counter ring size for Rifle, velocity ring for Nex"
+seta crosshair_ring_size 2 "ring size"
seta crosshair_ring_alpha 0.2 "ring alpha"
-seta crosshair_ring_sniperrifle 1 "draw a ring showing the ammount of ammo left in the sniperrifle
-seta crosshair_ring_sniperrifle_alpha 0.15
-
seta crosshair_ring_nex 1 "draw a ring showing the current charge of the nexgun"
seta crosshair_ring_nex_alpha 0.15
seta crosshair_ring_nex_inner_alpha 0.15
seta crosshair_ring_minelayer 1
seta crosshair_ring_minelayer_alpha 0.15
+seta crosshair_ring_reload 1 "main cvar to enable or disable ammo crosshair rings"
+seta crosshair_ring_reload_size 2 "reload ring size"
+seta crosshair_ring_reload_alpha 0.2 "reload ring alpha"
+
seta cl_reticle_stretch 0 "whether to stretch reticles so they fit the screen (brakes image proportions)"
seta cl_reticle_item_nex 1 "draw aiming reticle for the nex weapon's zoom, 0 disables and values between 0 and 1 change alpha"
seta cl_reticle_item_normal 1 "draw reticle when zooming with the zoom button, 0 disables and values between 0 and 1 change alpha"
float sniperrifle_scope;
float nex_scope;
-float cr_maxbullets;
-
float minelayer_maxmines;
float bgmtime;
serverflags = ReadByte();
- cr_maxbullets = ReadByte();
-
minelayer_maxmines = ReadByte();
g_trueaim_minrange = ReadCoord();
// TrueAim check
float shottype;
+
+ float weapon_clipload, weapon_clipsize, ring_scale;
+
// wcross_origin = '0.5 0 0' * vid_conwidth + '0 0.5 0' * vid_conheight;
wcross_origin = project_3d_to_2d(view_origin + MAX_SHOT_DISTANCE * view_forward);
wcross_origin_z = 0;
wcross_alpha *= 1 - autocvar__menu_alpha;
wcross_size = drawgetimagesize(wcross_name) * wcross_scale;
+ float ring_value, ring_scale, ring_alpha, ring_inner_value, ring_inner_alpha;
+ string ring_image, ring_inner_image;
+ vector ring_rgb, ring_inner_rgb;
+
+ // normal crosshair ring
if (autocvar_crosshair_ring)
{
- float ring_value, ring_alpha, ring_inner_value, ring_inner_alpha;
- string ring_image, ring_inner_image;
- vector ring_rgb, ring_inner_rgb;
-
- float ring_scale = autocvar_crosshair_ring_size;
-
+ ring_scale = autocvar_crosshair_ring_size;
+
float nex_charge, nex_chargepool;
nex_charge = getstatf(STAT_NEX_CHARGE);
nex_chargepool = getstatf(STAT_NEX_CHARGEPOOL);
-
+
if(nex_charge_movingavg == 0) // this should only happen if we have just loaded up the game
nex_charge_movingavg = nex_charge;
-
- if (activeweapon == WEP_SNIPERRIFLE && cr_maxbullets && autocvar_crosshair_ring_sniperrifle) // ring around crosshair representing bullets left in camping rifle clip
- {
- ring_value = bound(0, getstati(STAT_BULLETS_LOADED) / cr_maxbullets, 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.
- ring_alpha = wcross_alpha * autocvar_crosshair_ring_sniperrifle_alpha;
- ring_image = "gfx/crosshair_ring_sniperrifle.tga";
- ring_rgb = wcross_color;
- }
- else if (activeweapon == WEP_NEX && nex_charge && autocvar_crosshair_ring_nex) // ring around crosshair representing velocity-dependent damage for the nex
+
+ if (activeweapon == WEP_NEX && nex_charge && autocvar_crosshair_ring_nex) // ring around crosshair representing velocity-dependent damage for the nex
{
if (nex_chargepool || use_nex_chargepool) {
use_nex_chargepool = 1;
ring_image = "gfx/crosshair_ring.tga";
ring_rgb = wcross_color;
}
-
+
if (autocvar_crosshair_ring_inner && ring_inner_value) // lets draw a ring inside a ring so you can ring while you ring
DrawCircleClippedPic(wcross_origin, wcross_size_x * ring_scale, ring_inner_image, ring_inner_value, ring_inner_rgb, ring_inner_alpha, DRAWFLAG_ADDITIVE);
-
+
if (ring_value)
DrawCircleClippedPic(wcross_origin, wcross_size_x * ring_scale, ring_image, ring_value, ring_rgb, ring_alpha, DRAWFLAG_ADDITIVE);
}
+ // ammo crosshair ring
+ if(autocvar_crosshair_ring_reload)
+ {
+ weapon_clipload = getstati(STAT_WEAPON_CLIPLOAD);
+ if (weapon_clipload) // ring around crosshair representing ammo left in the weapon clip
+ {
+ weapon_clipsize = getstati(STAT_WEAPON_CLIPSIZE);
+ ring_value = bound(0, weapon_clipload / weapon_clipsize, 1);
+ ring_scale = autocvar_crosshair_ring_reload_size;
+ ring_alpha = autocvar_crosshair_ring_reload_alpha;
+ ring_image = "gfx/crosshair_ring.tga";
+ ring_rgb = wcross_color;
+
+ DrawCircleClippedPic(wcross_origin, wcross_size_x * ring_scale, ring_image, ring_value, ring_rgb, ring_alpha, DRAWFLAG_ADDITIVE);
+ }
+ }
+
#define CROSSHAIR_DO_BLUR(M,sz,wcross_name,wcross_alpha) \
do \
{ \
float autocvar_crosshair_ring_nex_inner_color_green;
float autocvar_crosshair_ring_nex_inner_color_red;
float autocvar_crosshair_ring_size;
-float autocvar_crosshair_ring_sniperrifle;
-float autocvar_crosshair_ring_sniperrifle_alpha;
+float autocvar_crosshair_ring_reload;
+float autocvar_crosshair_ring_reload_size;
+float autocvar_crosshair_ring_reload_alpha;
float autocvar_crosshair_size;
float autocvar_ekg;
float autocvar_fov;
const float TE_CSQC_NOTIFY = 112;
const float TE_CSQC_WEAPONCOMPLAIN = 113;
const float TE_CSQC_NEX_SCOPE = 116;
-const float TE_CSQC_CR_MAXBULLETS = 117;
-const float TE_CSQC_MINELAYER_MAXMINES = 118;
+const float TE_CSQC_MINELAYER_MAXMINES = 117;
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 STAT_NB_METERSTART = 45;
const float STAT_SHOTORG = 46; // compressShotOrigin
const float STAT_LEADLIMIT = 47;
-const float STAT_BULLETS_LOADED = 48;
-const float STAT_NEX_CHARGE = 49;
-const float STAT_LAST_PICKUP = 50;
-const float STAT_HUD = 51;
-const float STAT_NEX_CHARGEPOOL = 52;
-const float STAT_HIT_TIME = 53;
-const float STAT_TYPEHIT_TIME = 54;
-const float STAT_LAYED_MINES = 55;
+const float STAT_WEAPON_CLIPLOAD = 48;
+const float STAT_WEAPON_CLIPSIZE = 49;
+const float STAT_NEX_CHARGE = 50;
+const float STAT_LAST_PICKUP = 51;
+const float STAT_HUD = 52;
+const float STAT_NEX_CHARGEPOOL = 53;
+const float STAT_HIT_TIME = 54;
+const float STAT_TYPEHIT_TIME = 55;
+const float STAT_LAYED_MINES = 56;
// see DP source, quakedef.h
const float STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW = 222;
float WR_RELOAD = 9; // (SVQC) does not need to do anything
float WR_RESETPLAYER = 10; // (SVQC) does not need to do anything
float WR_IMPACTEFFECT = 11; // (CSQC) impact effect
+float WR_SWITCHABLE = 12; // (CSQC) impact effect
float HUD_PANEL_WEAPONS = 0;
float BOT_PICKUP_RATING_MID = 5000;
float BOT_PICKUP_RATING_HIGH = 10000;
-float WEP_TYPE_OTHER = 0x00; // e.g: Hook, Port-o-launch, etc
-float WEP_TYPE_SPLASH = 0x01;
-float WEP_TYPE_HITSCAN = 0x02;
-float WEP_TYPEMASK = 0x0F;
-float WEP_FLAG_CANCLIMB = 0x10;
-float WEP_FLAG_NORMAL = 0x20;
-float WEP_FLAG_HIDDEN = 0x40;
+float WEP_TYPE_OTHER = 0x00; // e.g: Hook, Port-o-launch, etc
+float WEP_TYPE_SPLASH = 0x01;
+float WEP_TYPE_HITSCAN = 0x02;
+float WEP_TYPEMASK = 0x0F;
+float WEP_FLAG_CANCLIMB = 0x10;
+float WEP_FLAG_NORMAL = 0x20;
+float WEP_FLAG_HIDDEN = 0x40;
+float WEP_FLAG_RELOADABLE = 0x80;
float IT_UNLIMITED_WEAPON_AMMO = 1;
// when this bit is set, using a weapon does not reduce ammo. Checkpoints can give this powerup.
float autocvar_g_balance_armor_rotlinear;
float autocvar_g_balance_armor_rotstable;
float autocvar_g_balance_armor_start;
-float autocvar_g_balance_sniperrifle_auto_reload_on_switch;
float autocvar_g_balance_sniperrifle_bursttime;
-float autocvar_g_balance_sniperrifle_magazinecapacity;
float autocvar_g_balance_sniperrifle_primary_ammo;
float autocvar_g_balance_sniperrifle_primary_animtime;
float autocvar_g_balance_sniperrifle_primary_bulletconstant;
float autocvar_g_balance_sniperrifle_primary_speed;
float autocvar_g_balance_sniperrifle_primary_spread;
float autocvar_g_balance_sniperrifle_primary_tracer;
-float autocvar_g_balance_sniperrifle_reloadtime;
float autocvar_g_balance_sniperrifle_secondary;
float autocvar_g_balance_sniperrifle_secondary_ammo;
float autocvar_g_balance_sniperrifle_secondary_animtime;
float autocvar_g_balance_sniperrifle_secondary_speed;
float autocvar_g_balance_sniperrifle_secondary_spread;
float autocvar_g_balance_sniperrifle_secondary_tracer;
+float autocvar_g_balance_sniperrifle_reload_ammo;
+float autocvar_g_balance_sniperrifle_reload_time;
float autocvar_g_balance_cloaked_alpha;
float autocvar_g_balance_crylink_primary_ammo;
float autocvar_g_balance_crylink_primary_animtime;
float autocvar_g_balance_crylink_secondary_shots;
float autocvar_g_balance_crylink_secondary_speed;
float autocvar_g_balance_crylink_secondary_spread;
+float autocvar_g_balance_crylink_reload_ammo;
+float autocvar_g_balance_crylink_reload_time;
float autocvar_g_balance_ctf_damageforcescale;
float autocvar_g_balance_ctf_delay_collect;
float autocvar_g_balance_curse_empathy_minhealth;
float autocvar_g_balance_electro_secondary_refire;
float autocvar_g_balance_electro_secondary_refire2;
float autocvar_g_balance_electro_secondary_speed;
+float autocvar_g_balance_electro_reload_ammo;
+float autocvar_g_balance_electro_reload_time;
float autocvar_g_balance_falldamage_deadminspeed;
float autocvar_g_balance_falldamage_factor;
float autocvar_g_balance_falldamage_maxdamage;
float autocvar_g_balance_fireball_secondary_refire;
float autocvar_g_balance_fireball_secondary_speed;
float autocvar_g_balance_fireball_secondary_speed_up;
+float autocvar_g_balance_fireball_reload_ammo;
+float autocvar_g_balance_fireball_reload_time;
float autocvar_g_balance_firetransfer_damage;
float autocvar_g_balance_firetransfer_time;
float autocvar_g_balance_fuel_limit;
float autocvar_g_balance_grenadelauncher_secondary_speed;
float autocvar_g_balance_grenadelauncher_secondary_speed_up;
float autocvar_g_balance_grenadelauncher_secondary_type;
+float autocvar_g_balance_grenadelauncher_reload_ammo;
+float autocvar_g_balance_grenadelauncher_reload_time;
float autocvar_g_balance_hagar_primary_ammo;
float autocvar_g_balance_hagar_primary_damage;
float autocvar_g_balance_hagar_primary_edgedamage;
float autocvar_g_balance_hagar_secondary_lifetime_rand;
float autocvar_g_balance_hagar_secondary_radius;
float autocvar_g_balance_hagar_secondary_refire;
+float autocvar_g_balance_hagar_reload_ammo;
+float autocvar_g_balance_hagar_reload_time;
float autocvar_g_balance_health_limit;
float autocvar_g_balance_health_regen;
float autocvar_g_balance_health_regenlinear;
float autocvar_g_balance_hlac_secondary_speed;
float autocvar_g_balance_hlac_secondary_spread;
float autocvar_g_balance_hlac_secondary_spread_crouchmod;
+float autocvar_g_balance_hlac_reload_ammo;
+float autocvar_g_balance_hlac_reload_time;
float autocvar_g_balance_hook_primary_animtime;
float autocvar_g_balance_hook_primary_fuel;
float autocvar_g_balance_hook_primary_hooked_fuel;
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_minelayer_ammo;
float autocvar_g_balance_minelayer_animtime;
float autocvar_g_balance_minelayer_damage;
float autocvar_g_balance_minelayer_remote_radius;
float autocvar_g_balance_minelayer_speed;
float autocvar_g_balance_minelayer_time;
+float autocvar_g_balance_minelayer_reload_ammo;
+float autocvar_g_balance_minelayer_reload_time;
float autocvar_g_balance_minstanex_ammo;
+float autocvar_g_balance_minstanex_laser_ammo;
float autocvar_g_balance_minstanex_animtime;
float autocvar_g_balance_minstanex_refire;
+float autocvar_g_balance_minstanex_reload_ammo;
+float autocvar_g_balance_minstanex_reload_time;
float autocvar_g_balance_nex_charge;
float autocvar_g_balance_nex_charge_animlimit;
float autocvar_g_balance_nex_charge_limit;
float autocvar_g_balance_nex_secondary_damagefalloff_mindist;
float autocvar_g_balance_nex_secondary_force;
float autocvar_g_balance_nex_secondary_refire;
+float autocvar_g_balance_nex_reload_ammo;
+float autocvar_g_balance_nex_reload_time;
float autocvar_g_balance_nexball_primary_animtime;
float autocvar_g_balance_nexball_primary_refire;
float autocvar_g_balance_nexball_primary_speed;
float autocvar_g_balance_rocketlauncher_speed;
float autocvar_g_balance_rocketlauncher_speedaccel;
float autocvar_g_balance_rocketlauncher_speedstart;
+float autocvar_g_balance_rocketlauncher_reload_ammo;
+float autocvar_g_balance_rocketlauncher_reload_time;
float autocvar_g_balance_rune_defense_combo_takedamage;
float autocvar_g_balance_rune_defense_takedamage;
float autocvar_g_balance_rune_regen_combo_hpmod;
float autocvar_g_balance_seeker_tag_lifetime;
float autocvar_g_balance_seeker_tag_refire;
float autocvar_g_balance_seeker_tag_speed;
+float autocvar_g_balance_seeker_reload_ammo;
+float autocvar_g_balance_seeker_reload_time;
float autocvar_g_balance_selfdamagepercent;
float autocvar_g_balance_shotgun_primary_ammo;
float autocvar_g_balance_shotgun_primary_animtime;
float autocvar_g_balance_shotgun_secondary_melee_swing;
float autocvar_g_balance_shotgun_secondary_melee_time;
float autocvar_g_balance_shotgun_secondary_refire;
+float autocvar_g_balance_shotgun_reload_ammo;
+float autocvar_g_balance_shotgun_reload_time;
float autocvar_g_balance_teams;
float autocvar_g_balance_teams_force;
float autocvar_g_balance_teams_prevent_imbalance;
float autocvar_g_balance_uzi_sustained_force;
float autocvar_g_balance_uzi_sustained_refire;
float autocvar_g_balance_uzi_sustained_spread;
+float autocvar_g_balance_uzi_reload_ammo;
+float autocvar_g_balance_uzi_reload_time;
float autocvar_g_balance_weaponswitchdelay;
float autocvar_g_ballistics_density_corpse;
float autocvar_g_ballistics_density_player;
bot_aimdir(v, -1);
}
havocbot_movetogoal();
+
+ // if the bot is not attacking, consider reloading weapons
+ if not(self.aistatus & AI_STATUS_ATTACKING)
+ {
+ float i;
+ entity e;
+
+ // we are currently holding a weapon that's not fully loaded, reload it
+ if(skill >= 2) // bots can only reload the held weapon on purpose past this skill
+ if(self.clip_load < self.clip_size)
+ self.impulse = 20; // "press" the reload button, not sure if this is done right
+
+ // if we're not reloading a weapon, switch to any weapon in our invnetory that's not fully loaded to reload it next
+ // the code above executes next frame, starting the reloading then
+ if(skill >= 5) // bots can only look for unloaded weapons past this skill
+ if(self.clip_load >= 0) // only if we're not reloading a weapon already
+ {
+ for(i = WEP_FIRST; i <= WEP_LAST; ++i)
+ {
+ e = get_weaponinfo(i);
+ if(self.weapon_load[i] < cvar(strcat("g_balance_", e.netname, "_reload_ammo")))
+ self.switchweapon = i;
+ }
+ }
+ }
};
void havocbot_keyboard_movement(vector destorg)
self.havocbot_stickenemy = TRUE;
};
+float havocbot_chooseweapon_checkreload(float new_weapon)
+{
+ // bots under this skill cannot find unloaded weapons to reload idly when not in combat,
+ // so skip this for them, or they'll never get to reload their weapons at all.
+ // this also allows bots under this skill to be more stupid, and reload more often during combat :)
+ if(skill < 5)
+ return FALSE;
+
+ // if this weapon is scheduled for reloading, don't switch to it during combat
+ if (self.weapon_load[new_weapon] < 0)
+ {
+ local float i, other_weapon_available;
+ for(i = WEP_FIRST; i <= WEP_LAST; ++i)
+ {
+ // if we are out of ammo for all other weapons, it's an emergency to switch to anything else
+ if (weapon_action(i, WR_CHECKAMMO1) + weapon_action(i, WR_CHECKAMMO2))
+ other_weapon_available = TRUE;
+ }
+ if(other_weapon_available)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
void havocbot_chooseweapon()
{
local float i;
if(i < 1)
return;
- // Workaround for rifle reloading (..)
- if(self.weapon == WEP_SNIPERRIFLE)
- if(i < autocvar_g_balance_sniperrifle_reloadtime + 1)
- return;
-
local float w;
local float distance; distance=bound(10,vlen(self.origin-self.enemy.origin)-200,10000);
if ( distance > bot_distance_far ) {
for(i=0; i < WEP_COUNT && bot_weapons_far[i] != -1 ; ++i){
w = bot_weapons_far[i];
- if ( client_hasweapon(self, w, TRUE, FALSE) ){
- if ( self.weapon == w && combo)
+ if ( client_hasweapon(self, w, TRUE, FALSE) )
+ {
+ if ((self.weapon == w && combo) || havocbot_chooseweapon_checkreload(w))
continue;
self.switchweapon = w;
return;
if ( distance > bot_distance_close) {
for(i=0; i < WEP_COUNT && bot_weapons_mid[i] != -1 ; ++i){
w = bot_weapons_mid[i];
- if ( client_hasweapon(self, w, TRUE, FALSE) ){
- if ( self.weapon == w && combo)
+ if ( client_hasweapon(self, w, TRUE, FALSE) )
+ {
+ if ((self.weapon == w && combo) || havocbot_chooseweapon_checkreload(w))
continue;
self.switchweapon = w;
return;
// Choose weapons for close distance
for(i=0; i < WEP_COUNT && bot_weapons_close[i] != -1 ; ++i){
w = bot_weapons_close[i];
- if ( client_hasweapon(self, w, TRUE, FALSE) ){
- if ( self.weapon == w && combo)
+ if ( client_hasweapon(self, w, TRUE, FALSE) )
+ {
+ if ((self.weapon == w && combo) || havocbot_chooseweapon_checkreload(w))
continue;
self.switchweapon = w;
return;
// reset fields the weapons may use
for (j = WEP_FIRST; j <= WEP_LAST; ++j)
+ {
weapon_action(j, WR_RESETPLAYER);
+ // all weapons must be fully loaded when we spawn
+ entity e;
+ e = get_weaponinfo(j);
+ if(e.spawnflags & WEP_FLAG_RELOADABLE) // prevent accessing undefined cvars
+ self.weapon_load[j] = cvar(strcat("g_balance_", e.netname, "_reload_ammo"));
+ }
+
oldself = self;
self = spot;
activator = oldself;
self.cnt = self.switchweapon;
self.weapon = 0;
- self.wish_reload = 0;
-
if(!self.alivetime)
self.alivetime = time;
} else if(self.classname == "observer" || (g_ca && !allowed_to_spawn)) {
WriteByte(MSG_ENTITY, autocvar_g_balance_nex_secondary); // client has to know if it should zoom or not
WriteByte(MSG_ENTITY, autocvar_g_balance_sniperrifle_secondary); // client has to know if it should zoom or not
WriteByte(MSG_ENTITY, serverflags); // client has to know if it should zoom or not
- WriteByte(MSG_ENTITY, autocvar_g_balance_sniperrifle_magazinecapacity); // rifle max bullets
WriteByte(MSG_ENTITY, autocvar_g_balance_minelayer_limit); // minelayer max mines
WriteCoord(MSG_ENTITY, autocvar_g_trueaim_minrange);
return TRUE;
self.ammo_nails = spectatee.ammo_nails;
self.ammo_rockets = spectatee.ammo_rockets;
self.ammo_fuel = spectatee.ammo_fuel;
+ self.clip_load = spectatee.clip_load;
+ self.clip_size = spectatee.clip_size;
self.effects = spectatee.effects & EFMASK_CHEAP; // eat performance
self.health = spectatee.health;
self.impulse = 0;
self.weapon = spectatee.weapon;
self.nex_charge = spectatee.nex_charge;
self.nex_chargepool_ammo = spectatee.nex_chargepool_ammo;
- self.sniperrifle_bulletcounter = spectatee.sniperrifle_bulletcounter;
self.minelayer_mines = spectatee.minelayer_mines;
self.punchangle = spectatee.punchangle;
self.view_ofs = spectatee.view_ofs;
}
target_voicescript_next(self);
+
+ // if a player goes unarmed after holding a loaded weapon, empty his clip size and remove the crosshair ammo ring
+ if(!self.weapon)
+ self.clip_load = self.clip_size = 0;
}
float isInvisibleString(string s)
W_PreviousWeapon (1);
break;
case 20:
- W_Reload ();
+ W_TriggerReload ();
break;
}
}
-void W_Reload()
+void W_TriggerReload()
{
- self.wish_reload = 1;
+ weapon_action(self.weapon, WR_RELOAD);
}
// switch between weapons
}
else
{
- W_Reload();
+ W_TriggerReload();
}
};
wep.ammofield = thisammo;
own.ammofield -= thisammo;
s = strcat(s, " and ", ftos(thisammo), " ", Item_CounterFieldName(j));
+
+ // if our weapon is loaded, give its load back to the player
+ if(self.weapon_load[self.weapon] > 0)
+ {
+ own.ammofield += self.weapon_load[self.weapon];
+ self.weapon_load[self.weapon] = -1; // schedule the weapon for reloading
+ }
}
}
s = substring(s, 5, -1);
setanim(self, self.anim_draw, FALSE, TRUE, TRUE);
self.weaponentity.state = WS_RAISE;
weapon_action(self.switchweapon, WR_SETUP);
+
+ // set our clip load to the load of the weapon we switched to, if it's reloadable
+ entity e;
+ e = get_weaponinfo(self.switchweapon);
+ if(e.spawnflags & WEP_FLAG_RELOADABLE && cvar(strcat("g_balance_", e.netname, "_reload_ammo"))) // prevent accessing undefined cvars
+ {
+ self.clip_load = self.weapon_load[self.switchweapon];
+ self.clip_size = cvar(strcat("g_balance_", e.netname, "_reload_ammo"));
+ }
+ else
+ self.clip_load = self.clip_size = 0;
+
// VorteX: add player model weapon select frame here
// setcustomframe(PlayerWeaponRaise);
weapon_thinkf(WFRAME_IDLE, autocvar_g_balance_weaponswitchdelay, w_ready);
#define W_SETUPPROJECTILEVELOCITY_UP(m,s) W_SetupProjectileVelocityEx(m, w_shotdir, v_up, cvar(#s "_speed"), cvar(#s "_speed_up"), cvar(#s "_speed_z"), cvar(#s "_spread"), FALSE)
#define W_SETUPPROJECTILEVELOCITY(m,s) W_SetupProjectileVelocityEx(m, w_shotdir, v_up, cvar(#s "_speed"), 0, 0, cvar(#s "_spread"), FALSE)
+
+void W_DecreaseAmmo(.float ammo_type, float ammo_use, float ammo_reload)
+{
+ if(self.items & IT_UNLIMITED_WEAPON_AMMO)
+ return;
+
+ // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
+ if(ammo_reload)
+ {
+ self.clip_load -= ammo_use;
+ self.weapon_load[self.weapon] = self.clip_load;
+ }
+ else
+ self.(self.current_ammo) -= ammo_use;
+}
+
+// weapon reloading code
+
+.float reload_ammo_amount, reload_ammo_min, reload_time;
+.float reload_complain;
+.string reload_sound;
+
+void W_ReloadedAndReady()
+{
+ // finish the reloading process, and do the ammo transfer
+
+ self.clip_load = self.old_clip_load; // restore the ammo counter, in case we still had ammo in the weapon before reloading
+
+ // if the gun uses no ammo, max out weapon load, else decrease ammo as we increase weapon load
+ if(!self.reload_ammo_min)
+ self.clip_load = self.reload_ammo_amount;
+ else
+ {
+ while(self.clip_load < self.reload_ammo_amount && self.(self.current_ammo)) // make sure we don't add more ammo than we have
+ {
+ self.clip_load += 1;
+ self.(self.current_ammo) -= 1;
+ }
+ }
+ self.weapon_load[self.weapon] = self.clip_load;
+
+ // do not set ATTACK_FINISHED in reload code any more. This causes annoying delays if eg: You start reloading a weapon,
+ // then quickly switch to another weapon and back. Reloading is canceled, but the reload delay is still there,
+ // so your weapon is disabled for a few seconds without reason
+
+ //ATTACK_FINISHED(self) -= self.reload_time - 1;
+
+ w_ready();
+}
+
+void W_Reload(float sent_ammo_min, float sent_ammo_amount, float sent_time, string sent_sound)
+{
+ // set global values to work with
+
+ self.reload_ammo_min = sent_ammo_min;
+ self.reload_ammo_amount = sent_ammo_amount;
+ self.reload_time = sent_time;
+ self.reload_sound = sent_sound;
+
+ // check if we meet the necessary conditions to reload
+
+ entity e;
+ e = get_weaponinfo(self.weapon);
+
+ // don't reload weapons that don't have the RELOADABLE flag
+ if not(e.spawnflags & WEP_FLAG_RELOADABLE)
+ {
+ dprint("Warning: Attempted to reload a weapon that does not have the WEP_FLAG_RELOADABLE flag. Fix your code!\n");
+ return;
+ }
+
+ // return if reloading is disabled for this weapon
+ if(!self.reload_ammo_amount)
+ return;
+
+ // our weapon is fully loaded, no need to reload
+ if (self.clip_load >= self.reload_ammo_amount)
+ return;
+
+ // no ammo, so nothing to load
+ if(!self.(self.current_ammo) && self.reload_ammo_min)
+ {
+ if(clienttype(self) == CLIENTTYPE_REAL && self.reload_complain < time)
+ {
+ play2(self, "weapons/unavailable.wav");
+ sprint(self, strcat("You don't have enough ammo to reload the ^2", W_Name(self.weapon), "\n"));
+ self.reload_complain = time + 1;
+ }
+ // switch away if the amount of ammo is not enough to keep using this weapon
+ if not(weapon_action(self.weapon, WR_CHECKAMMO1) + weapon_action(self.weapon, WR_CHECKAMMO2))
+ {
+ self.clip_load = -1; // reload later
+ W_SwitchToOtherWeapon(self);
+ }
+ return;
+ }
+
+ if (self.weaponentity)
+ {
+ if (self.weaponentity.wframe == WFRAME_RELOAD)
+ return;
+
+ // allow switching away while reloading, but this will cause a new reload!
+ self.weaponentity.state = WS_READY;
+ }
+
+ // now begin the reloading process
+
+ sound (self, CHAN_WEAPON2, self.reload_sound, VOL_BASE, ATTN_NORM);
+
+ // do not set ATTACK_FINISHED in reload code any more. This causes annoying delays if eg: You start reloading a weapon,
+ // then quickly switch to another weapon and back. Reloading is canceled, but the reload delay is still there,
+ // so your weapon is disabled for a few seconds without reason
+
+ //ATTACK_FINISHED(self) = max(time, ATTACK_FINISHED(self)) + self.reload_time + 1;
+
+ weapon_thinkf(WFRAME_RELOAD, self.reload_time, W_ReloadedAndReady);
+
+ if(self.clip_load < 0)
+ self.clip_load = 0;
+ self.old_clip_load = self.clip_load;
+ self.clip_load = self.weapon_load[self.weapon] = -1;
+}
\ No newline at end of file
float client_cefc_accumulatortime;
#endif
+..float current_ammo;
+
+.float weapon_load[WEP_MAXCOUNT]; FTEQCC_YOU_SUCK_THIS_IS_NOT_UNREFERENCED(weapon_load);
+.float ammo_none; // used by the reloading system, must always be 0
+.float clip_load;
+.float old_clip_load;
+.float clip_size;
.float minelayer_mines;
-.float sniperrifle_bulletcounter;
-.float wish_reload;
#define PROJECTILE_MAKETRIGGER(e) (e).solid = SOLID_CORPSE; (e).dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE
// when doing this, hagar can go through clones
addstat(STAT_FUEL, AS_INT, ammo_fuel);
addstat(STAT_SHOTORG, AS_INT, stat_shotorg);
addstat(STAT_LEADLIMIT, AS_FLOAT, stat_leadlimit);
- addstat(STAT_BULLETS_LOADED, AS_INT, sniperrifle_bulletcounter);
+ addstat(STAT_WEAPON_CLIPLOAD, AS_INT, clip_load);
+ addstat(STAT_WEAPON_CLIPSIZE, AS_INT, clip_size);
addstat(STAT_LAST_PICKUP, AS_FLOAT, last_pickup);
addstat(STAT_HIT_TIME, AS_FLOAT, hit_time);
addstat(STAT_TYPEHIT_TIME, AS_FLOAT, typehit_time);
precache_model ("models/sprites/10.spr32");
// common weapon precaches
+ precache_sound ("weapons/reload.wav"); // until weapons have individual reload sounds, precache the reload sound here
precache_sound ("weapons/weapon_switch.wav");
precache_sound ("weapons/weaponpickup.wav");
precache_sound ("weapons/unavailable.wav");
#ifdef REGISTER_WEAPON
-REGISTER_WEAPON(CRYLINK, w_crylink, IT_CELLS, 6, WEP_FLAG_NORMAL | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_MID, "crylink", "crylink", _("Crylink"));
+REGISTER_WEAPON(CRYLINK, w_crylink, IT_CELLS, 6, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_MID, "crylink", "crylink", _("Crylink"));
#else
#ifdef SVQC
.float gravity;
vector forward, right, up;
float maxdmg;
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_cells = self.ammo_cells - autocvar_g_balance_crylink_primary_ammo;
+ W_DecreaseAmmo(ammo_cells, autocvar_g_balance_crylink_primary_ammo, autocvar_g_balance_crylink_reload_ammo);
maxdmg = autocvar_g_balance_crylink_primary_damage*autocvar_g_balance_crylink_primary_shots;
maxdmg *= 1 + autocvar_g_balance_crylink_primary_bouncedamagefactor * autocvar_g_balance_crylink_primary_bounces;
local entity proj, prevproj, firstproj;
float maxdmg;
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_cells = self.ammo_cells - autocvar_g_balance_crylink_secondary_ammo;
+ W_DecreaseAmmo(ammo_cells, autocvar_g_balance_crylink_secondary_ammo, autocvar_g_balance_crylink_reload_ammo);
maxdmg = autocvar_g_balance_crylink_secondary_damage*autocvar_g_balance_crylink_secondary_shots;
maxdmg *= 1 + autocvar_g_balance_crylink_secondary_bouncedamagefactor * autocvar_g_balance_crylink_secondary_bounces;
float w_crylink(float req)
{
+ float ammo_amount;
if (req == WR_AIM)
{
if (random() < 0.10)
}
else if (req == WR_THINK)
{
- if (self.BUTTON_ATCK)
+ if(autocvar_g_balance_crylink_reload_ammo && self.clip_load < min(autocvar_g_balance_crylink_primary_ammo, autocvar_g_balance_crylink_secondary_ammo)) // forced reload
+ weapon_action(self.weapon, WR_RELOAD);
+ else if (self.BUTTON_ATCK)
{
if (!self.crylink_waitrelease)
if (weapon_prepareattack(0, autocvar_g_balance_crylink_primary_refire))
precache_sound ("weapons/crylink_fire.wav");
precache_sound ("weapons/crylink_fire2.wav");
precache_sound ("weapons/crylink_linkjoin.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_CRYLINK);
+ self.current_ammo = ammo_cells;
+ }
else if (req == WR_CHECKAMMO1)
{
// don't "run out of ammo" and switch weapons while waiting for release
if(self.crylink_lastgroup && self.crylink_waitrelease)
return TRUE;
- return self.ammo_cells >= autocvar_g_balance_crylink_primary_ammo;
+
+ ammo_amount = self.ammo_cells >= autocvar_g_balance_crylink_primary_ammo;
+ ammo_amount += self.weapon_load[WEP_CRYLINK] >= autocvar_g_balance_crylink_primary_ammo;
+ return ammo_amount;
}
else if (req == WR_CHECKAMMO2)
{
// don't "run out of ammo" and switch weapons while waiting for release
if(self.crylink_lastgroup && self.crylink_waitrelease)
return TRUE;
- return self.ammo_cells >= autocvar_g_balance_crylink_secondary_ammo;
+
+ ammo_amount = self.ammo_cells >= autocvar_g_balance_crylink_secondary_ammo;
+ ammo_amount += self.weapon_load[WEP_CRYLINK] >= autocvar_g_balance_crylink_secondary_ammo;
+ return ammo_amount;
+ }
+ else if (req == WR_RELOAD)
+ {
+ W_Reload(min(autocvar_g_balance_crylink_primary_ammo, autocvar_g_balance_crylink_secondary_ammo), autocvar_g_balance_crylink_reload_ammo, autocvar_g_balance_crylink_reload_time, "weapons/reload.wav");
}
return TRUE;
};
#ifdef REGISTER_WEAPON
-REGISTER_WEAPON(ELECTRO, w_electro, IT_CELLS, 5, WEP_FLAG_NORMAL | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_MID, "electro", "electro", _("Electro"));
+REGISTER_WEAPON(ELECTRO, w_electro, IT_CELLS, 5, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_MID, "electro", "electro", _("Electro"));
#else
#ifdef SVQC
.float electro_count;
{
local entity proj;
+ W_DecreaseAmmo(ammo_cells, autocvar_g_balance_electro_primary_ammo, autocvar_g_balance_electro_reload_ammo);
+
W_SetupShot_ProjectileSize (self, '0 0 -3', '0 0 -3', FALSE, 2, "weapons/electro_fire.wav", CHAN_WEAPON, autocvar_g_balance_electro_primary_damage);
pointparticles(particleeffectnum("electro_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
proj.projectiledeathtype = WEP_ELECTRO;
setorigin(proj, w_shotorg);
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_cells = self.ammo_cells - autocvar_g_balance_electro_primary_ammo;
proj.movetype = MOVETYPE_FLY;
W_SETUPPROJECTILEVELOCITY(proj, g_balance_electro_primary);
proj.angles = vectoangles(proj.velocity);
{
local entity proj;
+ W_DecreaseAmmo(ammo_cells, autocvar_g_balance_electro_secondary_ammo, autocvar_g_balance_electro_reload_ammo);
+
W_SetupShot_ProjectileSize (self, '0 0 -4', '0 0 -4', FALSE, 2, "weapons/electro_fire2.wav", CHAN_WEAPON, autocvar_g_balance_electro_secondary_damage);
w_shotdir = v_forward; // no TrueAim for grenades please
proj.projectiledeathtype = WEP_ELECTRO | HITTYPE_SECONDARY;
setorigin(proj, w_shotorg);
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_cells = self.ammo_cells - autocvar_g_balance_electro_secondary_ammo;
//proj.glow_size = 50;
//proj.glow_color = 45;
proj.movetype = MOVETYPE_BOUNCE;
CSQCProjectile(proj, TRUE, PROJECTILE_ELECTRO, FALSE); // no culling, it has sound
other = proj; MUTATOR_CALLHOOK(EditProjectile);
- }
+}
.vector hook_start, hook_end;
float lgbeam_send(entity to, float sf)
}
.entity lgbeam;
.float prevlgfire;
+float lgbeam_checkammo()
+{
+ if(self.owner.items & IT_UNLIMITED_WEAPON_AMMO)
+ return TRUE;
+ else if(autocvar_g_balance_electro_reload_ammo)
+ return self.owner.clip_load > 0;
+ else
+ return self.owner.ammo_cells > 0;
+}
+
void lgbeam_think()
{
- self.owner.prevlgfire = time;
- if (self != self.owner.lgbeam)
+ entity owner_player;
+ owner_player = self.owner;
+
+ owner_player.prevlgfire = time;
+ if (self != owner_player.lgbeam)
{
remove(self);
return;
}
- if (self.owner.weaponentity.state != WS_INUSE || (self.owner.ammo_cells <= 0 && !(self.owner.items & IT_UNLIMITED_WEAPON_AMMO)) || self.owner.deadflag != DEAD_NO || !self.owner.BUTTON_ATCK || self.owner.freezetag_frozen)
+
+ if (owner_player.weaponentity.state != WS_INUSE || !lgbeam_checkammo() || owner_player.deadflag != DEAD_NO || !owner_player.BUTTON_ATCK || owner_player.freezetag_frozen)
{
- if(self == self.owner.lgbeam)
- self.owner.lgbeam = world;
+ if(self == owner_player.lgbeam)
+ owner_player.lgbeam = world;
remove(self);
return;
}
self.nextthink = time;
- makevectors(self.owner.v_angle);
+ makevectors(owner_player.v_angle);
float dt, f;
dt = frametime;
- if not(self.owner.items & IT_UNLIMITED_WEAPON_AMMO)
+
+ // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
+ if not(owner_player.items & IT_UNLIMITED_WEAPON_AMMO)
{
if(autocvar_g_balance_electro_primary_ammo)
{
- dt = min(dt, self.owner.ammo_cells / autocvar_g_balance_electro_primary_ammo);
- self.owner.ammo_cells = max(0, self.owner.ammo_cells - autocvar_g_balance_electro_primary_ammo * frametime);
+ if(autocvar_g_balance_electro_reload_ammo)
+ {
+ dt = min(dt, owner_player.clip_load / autocvar_g_balance_electro_primary_ammo);
+ owner_player.clip_load = max(0, owner_player.clip_load - autocvar_g_balance_electro_primary_ammo * frametime);
+ owner_player.weapon_load[WEP_ELECTRO] = owner_player.clip_load;
+ }
+ else
+ {
+ dt = min(dt, owner_player.ammo_cells / autocvar_g_balance_electro_primary_ammo);
+ owner_player.ammo_cells = max(0, owner_player.ammo_cells - autocvar_g_balance_electro_primary_ammo * frametime);
+ }
}
}
- W_SetupShot_Range(self.owner, TRUE, 0, "", 0, autocvar_g_balance_electro_primary_damage * dt, autocvar_g_balance_electro_primary_range);
- WarpZone_traceline_antilag(self.owner, w_shotorg, w_shotend, MOVE_NORMAL, self.owner, ANTILAG_LATENCY(self.owner));
+ W_SetupShot_Range(owner_player, TRUE, 0, "", 0, autocvar_g_balance_electro_primary_damage * dt, autocvar_g_balance_electro_primary_range);
+ WarpZone_traceline_antilag(owner_player, w_shotorg, w_shotend, MOVE_NORMAL, owner_player, ANTILAG_LATENCY(owner_player));
// apply the damage
if(trace_ent)
f = ExponentialFalloff(autocvar_g_balance_electro_primary_falloff_mindist, autocvar_g_balance_electro_primary_falloff_maxdist, autocvar_g_balance_electro_primary_falloff_halflifedist, vlen(WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos) - w_shotorg));
- if(accuracy_isgooddamage(self.owner, trace_ent))
- accuracy_add(self.owner, WEP_ELECTRO, 0, autocvar_g_balance_electro_primary_damage * dt * f);
- Damage (trace_ent, self.owner, self.owner, autocvar_g_balance_electro_primary_damage * dt * f, WEP_ELECTRO, trace_endpos, force * dt);
+ if(accuracy_isgooddamage(owner_player, trace_ent))
+ accuracy_add(owner_player, WEP_ELECTRO, 0, autocvar_g_balance_electro_primary_damage * dt * f);
+ Damage (trace_ent, owner_player, owner_player, autocvar_g_balance_electro_primary_damage * dt * f, WEP_ELECTRO, trace_endpos, force * dt);
}
- W_Plasma_TriggerCombo(trace_endpos, autocvar_g_balance_electro_primary_comboradius, self.owner);
+ W_Plasma_TriggerCombo(trace_endpos, autocvar_g_balance_electro_primary_comboradius, owner_player);
// draw effect
if(w_shotorg != self.hook_start)
.float BUTTON_ATCK_prev;
float w_electro(float req)
{
+ float ammo_amount;
if (req == WR_AIM)
{
self.BUTTON_ATCK=FALSE;
}
else if (req == WR_THINK)
{
+ if(autocvar_g_balance_electro_reload_ammo) // forced reload
+ {
+ if(autocvar_g_balance_electro_lightning)
+ {
+ if(self.clip_load > 0)
+ ammo_amount = 1;
+ }
+ else if(self.clip_load >= autocvar_g_balance_electro_primary_ammo)
+ ammo_amount = 1;
+ if(self.clip_load >= autocvar_g_balance_electro_secondary_ammo)
+ ammo_amount += 1;
+
+ if(!ammo_amount)
+ {
+ weapon_action(self.weapon, WR_RELOAD);
+ return FALSE;
+ }
+ }
if (self.BUTTON_ATCK)
{
if(autocvar_g_balance_electro_lightning)
}
self.BUTTON_ATCK_prev = 0;
}
- }
- if (self.BUTTON_ATCK2)
- if (time >= self.electro_secondarytime)
- if (weapon_prepareattack(1, autocvar_g_balance_electro_secondary_refire))
- {
- W_Electro_Attack2();
- self.electro_count = autocvar_g_balance_electro_secondary_count;
- weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_electro_secondary_animtime, w_electro_checkattack);
- self.electro_secondarytime = time + autocvar_g_balance_electro_secondary_refire2 * W_WeaponRateFactor();
+ if (self.BUTTON_ATCK2)
+ {
+ if (time >= self.electro_secondarytime)
+ if (weapon_prepareattack(1, autocvar_g_balance_electro_secondary_refire))
+ {
+ W_Electro_Attack2();
+ self.electro_count = autocvar_g_balance_electro_secondary_count;
+ weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_electro_secondary_animtime, w_electro_checkattack);
+ self.electro_secondarytime = time + autocvar_g_balance_electro_secondary_refire2 * W_WeaponRateFactor();
+ }
+ }
}
}
else if (req == WR_PRECACHE)
precache_sound ("weapons/electro_fire2.wav");
precache_sound ("weapons/electro_impact.wav");
precache_sound ("weapons/electro_impact_combo.wav");
+ //precache_sound ("weapons/reload.wav"); // until weapons have individual reload sounds, precache the reload sound somewhere else
if(autocvar_g_balance_electro_lightning)
{
precache_sound ("weapons/lgbeam_fire.wav");
}
}
else if (req == WR_SETUP)
+ {
weapon_setup(WEP_ELECTRO);
+ self.current_ammo = ammo_cells;
+ }
else if (req == WR_CHECKAMMO1)
{
if(autocvar_g_balance_electro_lightning)
- return !autocvar_g_balance_electro_primary_ammo || (self.ammo_cells > 0);
+ {
+ if(!autocvar_g_balance_electro_primary_ammo)
+ ammo_amount = 1;
+ else
+ ammo_amount = self.ammo_cells > 0;
+ ammo_amount += self.weapon_load[WEP_ELECTRO] > 0;
+ }
else
- return self.ammo_cells >= autocvar_g_balance_electro_primary_ammo;
+ {
+ ammo_amount = self.ammo_cells >= autocvar_g_balance_electro_primary_ammo;
+ ammo_amount += self.weapon_load[WEP_ELECTRO] >= autocvar_g_balance_electro_primary_ammo;
+ }
+ return ammo_amount;
}
else if (req == WR_CHECKAMMO2)
- return self.ammo_cells >= autocvar_g_balance_electro_secondary_ammo;
+ {
+ ammo_amount = self.ammo_cells >= autocvar_g_balance_electro_secondary_ammo;
+ ammo_amount += self.weapon_load[WEP_ELECTRO] >= autocvar_g_balance_electro_secondary_ammo;
+ return ammo_amount;
+ }
else if (req == WR_RESETPLAYER)
{
self.electro_secondarytime = time;
}
+ else if (req == WR_RELOAD)
+ {
+ W_Reload(min(autocvar_g_balance_electro_primary_ammo, autocvar_g_balance_electro_secondary_ammo), autocvar_g_balance_electro_reload_ammo, autocvar_g_balance_electro_reload_time, "weapons/reload.wav");
+ }
return TRUE;
};
#endif
#ifdef REGISTER_WEAPON
-REGISTER_WEAPON(FIREBALL, w_fireball, IT_FUEL, 9, WEP_TYPE_SPLASH, BOT_PICKUP_RATING_MID, "fireball", "fireball", _("Fireball"));
+REGISTER_WEAPON(FIREBALL, w_fireball, IT_FUEL, 9, WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_MID, "fireball", "fireball", _("Fireball"));
#else
#ifdef SVQC
.float bot_primary_fireballmooth; // whatever a mooth is
void W_Fireball_Attack1_Frame0()
{
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_fuel = self.ammo_fuel - autocvar_g_balance_fireball_primary_ammo;
+ W_DecreaseAmmo(ammo_fuel, autocvar_g_balance_fireball_primary_ammo, autocvar_g_balance_fireball_reload_ammo);
W_Fireball_AttackEffect(0, '-1.25 -3.75 0');
sound (self, CHAN_WEAPON, "weapons/fireball_prefire2.wav", VOL_BASE, ATTN_NORM);
vector f_diff;
float c;
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_fuel = self.ammo_fuel - autocvar_g_balance_fireball_secondary_ammo;
+ W_DecreaseAmmo(ammo_fuel, autocvar_g_balance_fireball_secondary_ammo, autocvar_g_balance_fireball_reload_ammo);
c = mod(self.bulletcounter, 4);
switch(c)
float w_fireball(float req)
{
+ float ammo_amount;
if (req == WR_AIM)
{
self.BUTTON_ATCK = FALSE;
}
else if (req == WR_THINK)
{
- if (self.BUTTON_ATCK)
- if (time >= self.fireball_primarytime)
- if (weapon_prepareattack(0, autocvar_g_balance_fireball_primary_refire))
+ if(autocvar_g_balance_fireball_reload_ammo && self.clip_load < min(autocvar_g_balance_fireball_primary_ammo, autocvar_g_balance_fireball_secondary_ammo)) // forced reload
+ weapon_action(self.weapon, WR_RELOAD);
+ else if (self.BUTTON_ATCK)
{
- W_Fireball_Attack1_Frame0();
- self.fireball_primarytime = time + autocvar_g_balance_fireball_primary_refire2;
+ if (time >= self.fireball_primarytime)
+ if (weapon_prepareattack(0, autocvar_g_balance_fireball_primary_refire))
+ {
+ W_Fireball_Attack1_Frame0();
+ self.fireball_primarytime = time + autocvar_g_balance_fireball_primary_refire2;
+ }
}
- if (self.BUTTON_ATCK2)
- if (weapon_prepareattack(1, autocvar_g_balance_fireball_secondary_refire))
+ else if (self.BUTTON_ATCK2)
{
- W_Fireball_Attack2();
- weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_fireball_secondary_animtime, w_ready);
+ if (weapon_prepareattack(1, autocvar_g_balance_fireball_secondary_refire))
+ {
+ W_Fireball_Attack2();
+ weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_fireball_secondary_animtime, w_ready);
+ }
}
}
else if (req == WR_PRECACHE)
precache_sound ("weapons/fireball_fire.wav");
precache_sound ("weapons/fireball_fire2.wav");
precache_sound ("weapons/fireball_prefire2.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_FIREBALL);
+ self.current_ammo = ammo_fuel;
+ }
else if (req == WR_CHECKAMMO1)
- return self.ammo_fuel >= autocvar_g_balance_fireball_primary_ammo;
+ {
+ ammo_amount = self.ammo_fuel >= autocvar_g_balance_fireball_primary_ammo;
+ ammo_amount += self.weapon_load[WEP_FIREBALL] >= autocvar_g_balance_fireball_primary_ammo;
+ return ammo_amount;
+ }
else if (req == WR_CHECKAMMO2)
- return self.ammo_fuel >= autocvar_g_balance_fireball_secondary_ammo;
+ {
+ ammo_amount = self.ammo_fuel >= autocvar_g_balance_fireball_secondary_ammo;
+ ammo_amount += self.weapon_load[WEP_FIREBALL] >= autocvar_g_balance_fireball_secondary_ammo;
+ return ammo_amount;
+ }
else if (req == WR_RESETPLAYER)
{
self.fireball_primarytime = time;
}
+ else if (req == WR_RELOAD)
+ {
+ // fuel can be a non-whole number, which brakes stuff here when between 0 and 1
+ if(self.ammo_fuel < 1)
+ self.ammo_fuel = 0;
+
+ W_Reload(min(autocvar_g_balance_fireball_primary_ammo, autocvar_g_balance_fireball_secondary_ammo), autocvar_g_balance_fireball_reload_ammo, autocvar_g_balance_fireball_reload_time, "weapons/reload.wav");
+ }
return TRUE;
};
#endif
#ifdef REGISTER_WEAPON
-REGISTER_WEAPON(GRENADE_LAUNCHER, w_glauncher, IT_ROCKETS, 4, WEP_FLAG_NORMAL | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_MID, "gl", "grenadelauncher", _("Mortar"))
+REGISTER_WEAPON(GRENADE_LAUNCHER, w_glauncher, IT_ROCKETS, 4, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_MID, "gl", "grenadelauncher", _("Mortar"))
#else
#ifdef SVQC
.float gl_detonate_later;
{
local entity gren;
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_rockets = self.ammo_rockets - autocvar_g_balance_grenadelauncher_primary_ammo;
+ W_DecreaseAmmo(ammo_rockets, autocvar_g_balance_grenadelauncher_primary_ammo, autocvar_g_balance_grenadelauncher_reload_ammo);
+
W_SetupShot_ProjectileSize (self, '-3 -3 -3', '3 3 3', FALSE, 4, "weapons/grenade_fire.wav", CHAN_WEAPON, autocvar_g_balance_grenadelauncher_primary_damage);
w_shotdir = v_forward; // no TrueAim for grenades please
{
local entity gren;
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_rockets = self.ammo_rockets - autocvar_g_balance_grenadelauncher_secondary_ammo;
+ W_DecreaseAmmo(ammo_rockets, autocvar_g_balance_grenadelauncher_secondary_ammo, autocvar_g_balance_grenadelauncher_reload_ammo);
+
W_SetupShot_ProjectileSize (self, '-3 -3 -3', '3 3 3', FALSE, 4, "weapons/grenade_fire.wav", CHAN_WEAPON, autocvar_g_balance_grenadelauncher_secondary_damage);
w_shotdir = v_forward; // no TrueAim for grenades please
{
entity nade;
float nadefound;
+ float ammo_amount;
if (req == WR_AIM)
{
}
else if (req == WR_THINK)
{
- if (self.BUTTON_ATCK)
- if (weapon_prepareattack(0, autocvar_g_balance_grenadelauncher_primary_refire))
+ if(autocvar_g_balance_grenadelauncher_reload_ammo && self.clip_load < min(autocvar_g_balance_grenadelauncher_primary_ammo, autocvar_g_balance_grenadelauncher_secondary_ammo)) // forced reload
+ weapon_action(self.weapon, WR_RELOAD);
+ else if (self.BUTTON_ATCK)
{
- W_Grenade_Attack();
- weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_grenadelauncher_primary_animtime, w_ready);
+ if (weapon_prepareattack(0, autocvar_g_balance_grenadelauncher_primary_refire))
+ {
+ W_Grenade_Attack();
+ weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_grenadelauncher_primary_animtime, w_ready);
+ }
}
- if (self.BUTTON_ATCK2)
+ else if (self.BUTTON_ATCK2)
{
if (cvar("g_balance_grenadelauncher_secondary_remote_detonateprimary"))
{
precache_sound ("weapons/grenade_bounce6.wav");
precache_sound ("weapons/grenade_stick.wav");
precache_sound ("weapons/grenade_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_GRENADE_LAUNCHER);
+ self.current_ammo = ammo_rockets;
+ }
else if (req == WR_CHECKAMMO1)
- return self.ammo_rockets >= autocvar_g_balance_grenadelauncher_primary_ammo;
+ {
+ ammo_amount = self.ammo_rockets >= autocvar_g_balance_grenadelauncher_primary_ammo;
+ ammo_amount += self.weapon_load[WEP_GRENADE_LAUNCHER] >= autocvar_g_balance_grenadelauncher_primary_ammo;
+ return ammo_amount;
+ }
else if (req == WR_CHECKAMMO2)
- return self.ammo_rockets >= autocvar_g_balance_grenadelauncher_secondary_ammo;
+ {
+ ammo_amount = self.ammo_rockets >= autocvar_g_balance_grenadelauncher_secondary_ammo;
+ ammo_amount += self.weapon_load[WEP_GRENADE_LAUNCHER] >= autocvar_g_balance_grenadelauncher_secondary_ammo;
+ return ammo_amount;
+ }
+ else if (req == WR_RELOAD)
+ {
+ W_Reload(min(autocvar_g_balance_grenadelauncher_primary_ammo, autocvar_g_balance_grenadelauncher_secondary_ammo), autocvar_g_balance_grenadelauncher_reload_ammo, autocvar_g_balance_grenadelauncher_reload_time, "weapons/reload.wav");
+ }
return TRUE;
};
#endif
#ifdef REGISTER_WEAPON
-REGISTER_WEAPON(HAGAR, w_hagar, IT_ROCKETS, 8, WEP_FLAG_NORMAL | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_MID, "hagar", "hagar", _("Hagar"))
+REGISTER_WEAPON(HAGAR, w_hagar, IT_ROCKETS, 8, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_MID, "hagar", "hagar", _("Hagar"))
#else
#ifdef SVQC
// NO bounce protection, as bounces are limited!
+
void W_Hagar_Explode (void)
{
self.event_damage = SUB_Null;
{
local entity missile;
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_rockets = self.ammo_rockets - autocvar_g_balance_hagar_primary_ammo;
+ W_DecreaseAmmo(ammo_rockets, autocvar_g_balance_hagar_primary_ammo, autocvar_g_balance_hagar_reload_ammo);
+
W_SetupShot (self, FALSE, 2, "weapons/hagar_fire.wav", CHAN_WEAPON, autocvar_g_balance_hagar_primary_damage);
pointparticles(particleeffectnum("hagar_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
{
local entity missile;
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_rockets = self.ammo_rockets - autocvar_g_balance_hagar_secondary_ammo;
+ W_DecreaseAmmo(ammo_rockets, autocvar_g_balance_hagar_secondary_ammo, autocvar_g_balance_hagar_reload_ammo);
+
W_SetupShot (self, FALSE, 2, "weapons/hagar_fire.wav", CHAN_WEAPON, autocvar_g_balance_hagar_secondary_damage);
pointparticles(particleeffectnum("hagar_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
float w_hagar(float req)
{
+ float ammo_amount;
if (req == WR_AIM)
if (random()>0.15)
self.BUTTON_ATCK = bot_aim(autocvar_g_balance_hagar_primary_speed, 0, autocvar_g_balance_hagar_primary_lifetime, FALSE);
}
else if (req == WR_THINK)
{
- if (self.BUTTON_ATCK)
- if (weapon_prepareattack(0, autocvar_g_balance_hagar_primary_refire))
+ if(autocvar_g_balance_hagar_reload_ammo && self.clip_load < min(autocvar_g_balance_hagar_primary_ammo, autocvar_g_balance_hagar_secondary_ammo)) // forced reload
+ weapon_action(self.weapon, WR_RELOAD);
+ else if (self.BUTTON_ATCK)
{
- W_Hagar_Attack();
- weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_hagar_primary_refire, w_ready);
+ if (weapon_prepareattack(0, autocvar_g_balance_hagar_primary_refire))
+ {
+ W_Hagar_Attack();
+ weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_hagar_primary_refire, w_ready);
+ }
}
- if (self.BUTTON_ATCK2 && autocvar_g_balance_hagar_secondary)
- if (weapon_prepareattack(1, autocvar_g_balance_hagar_secondary_refire))
+ else if (self.BUTTON_ATCK2 && autocvar_g_balance_hagar_secondary)
{
- W_Hagar_Attack2();
- weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_hagar_secondary_refire, w_ready);
+ if (weapon_prepareattack(1, autocvar_g_balance_hagar_secondary_refire))
+ {
+ W_Hagar_Attack2();
+ weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_hagar_secondary_refire, w_ready);
+ }
}
}
else if (req == WR_PRECACHE)
precache_model ("models/weapons/v_hagar.md3");
precache_model ("models/weapons/h_hagar.iqm");
precache_sound ("weapons/hagar_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_HAGAR);
+ self.current_ammo = ammo_rockets;
+ }
else if (req == WR_CHECKAMMO1)
- return self.ammo_rockets >= autocvar_g_balance_hagar_primary_ammo;
+ {
+ ammo_amount = self.ammo_rockets >= autocvar_g_balance_hagar_primary_ammo;
+ ammo_amount += self.weapon_load[WEP_HAGAR] >= autocvar_g_balance_hagar_primary_ammo;
+ return ammo_amount;
+ }
else if (req == WR_CHECKAMMO2)
- return self.ammo_rockets >= autocvar_g_balance_hagar_secondary_ammo;
+ {
+ ammo_amount = self.ammo_rockets >= autocvar_g_balance_hagar_secondary_ammo;
+ ammo_amount += self.weapon_load[WEP_HAGAR] >= autocvar_g_balance_hagar_secondary_ammo;
+ return ammo_amount;
+ }
+ else if (req == WR_RELOAD)
+ {
+ W_Reload(min(autocvar_g_balance_hagar_primary_ammo, autocvar_g_balance_hagar_secondary_ammo), autocvar_g_balance_hagar_reload_ammo, autocvar_g_balance_hagar_reload_time, "weapons/reload.wav");
+ }
return TRUE;
};
#endif
#ifdef REGISTER_WEAPON
-REGISTER_WEAPON(HLAC, w_hlac, IT_CELLS, 6, WEP_FLAG_NORMAL | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_MID, "hlac", "hlac", _("Heavy Laser Assault Cannon"))
+REGISTER_WEAPON(HLAC, w_hlac, IT_CELLS, 6, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_MID, "hlac", "hlac", _("Heavy Laser Assault Cannon"))
#else
#ifdef SVQC
local entity missile;
float spread;
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- {
- self.ammo_cells = self.ammo_cells - autocvar_g_balance_hlac_primary_ammo;
- }
+ W_DecreaseAmmo(ammo_cells, autocvar_g_balance_hlac_primary_ammo, autocvar_g_balance_hlac_reload_ammo);
spread = autocvar_g_balance_hlac_primary_spread_min + (autocvar_g_balance_hlac_primary_spread_add * self.misc_bulletcounter);
spread = min(spread,autocvar_g_balance_hlac_primary_spread_max);
{
float i;
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- {
- self.ammo_cells = self.ammo_cells - autocvar_g_balance_hlac_secondary_ammo;
- }
+ W_DecreaseAmmo(ammo_cells, autocvar_g_balance_hlac_secondary_ammo, autocvar_g_balance_hlac_reload_ammo);
for(i=autocvar_g_balance_hlac_secondary_shots;i>0;--i)
W_HLAC_Attack2f();
float w_hlac(float req)
{
+ float ammo_amount;
if (req == WR_AIM)
self.BUTTON_ATCK = bot_aim(autocvar_g_balance_hlac_primary_speed, 0, autocvar_g_balance_hlac_primary_lifetime, FALSE);
else if (req == WR_THINK)
{
- if (self.BUTTON_ATCK)
- if (weapon_prepareattack(0, autocvar_g_balance_hlac_primary_refire))
+ if(autocvar_g_balance_hlac_reload_ammo && self.clip_load < min(autocvar_g_balance_hlac_primary_ammo, autocvar_g_balance_hlac_secondary_ammo)) // forced reload
+ weapon_action(self.weapon, WR_RELOAD);
+ else if (self.BUTTON_ATCK)
{
- self.misc_bulletcounter = 0;
- W_HLAC_Attack();
- weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_hlac_primary_refire, HLAC_fire1_02);
+ if (weapon_prepareattack(0, autocvar_g_balance_hlac_primary_refire))
+ {
+ self.misc_bulletcounter = 0;
+ W_HLAC_Attack();
+ weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_hlac_primary_refire, HLAC_fire1_02);
+ }
}
- if (self.BUTTON_ATCK2 && autocvar_g_balance_hlac_secondary)
- if (weapon_prepareattack(1, autocvar_g_balance_hlac_secondary_refire))
+ else if (self.BUTTON_ATCK2 && autocvar_g_balance_hlac_secondary)
{
- W_HLAC_Attack2();
- weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_hlac_secondary_animtime, w_ready);
+ if (weapon_prepareattack(1, autocvar_g_balance_hlac_secondary_refire))
+ {
+ W_HLAC_Attack2();
+ weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_hlac_secondary_animtime, w_ready);
+ }
}
-
}
else if (req == WR_PRECACHE)
{
precache_model ("models/weapons/v_hlac.md3");
precache_model ("models/weapons/h_hlac.iqm");
precache_sound ("weapons/lasergun_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_HLAC);
+ self.current_ammo = ammo_cells;
+ }
else if (req == WR_CHECKAMMO1)
- return self.ammo_cells >= autocvar_g_balance_hlac_primary_ammo;
+ {
+ ammo_amount = self.ammo_cells >= autocvar_g_balance_hlac_primary_ammo;
+ ammo_amount += self.weapon_load[WEP_HLAC] >= autocvar_g_balance_hlac_primary_ammo;
+ return ammo_amount;
+ }
else if (req == WR_CHECKAMMO2)
- return self.ammo_cells >= autocvar_g_balance_hlac_secondary_ammo;
+ {
+ ammo_amount = self.ammo_cells >= autocvar_g_balance_hlac_secondary_ammo;
+ ammo_amount += self.weapon_load[WEP_HLAC] >= autocvar_g_balance_hlac_secondary_ammo;
+ return ammo_amount;
+ }
+ else if (req == WR_RELOAD)
+ {
+ W_Reload(min(autocvar_g_balance_hlac_primary_ammo, autocvar_g_balance_hlac_secondary_ammo), autocvar_g_balance_hlac_reload_ammo, autocvar_g_balance_hlac_reload_time, "weapons/reload.wav");
+ }
return TRUE;
};
#endif
local entity gren;
if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_cells = self.ammo_cells - autocvar_g_balance_hook_secondary_ammo;
+ W_DecreaseAmmo(ammo_cells, autocvar_g_balance_hook_secondary_ammo, FALSE);
W_SetupShot (self, FALSE, 4, "weapons/hookbomb_fire.wav", CHAN_WEAPON, autocvar_g_balance_hook_secondary_damage);
gren = spawn ();
if (weapon_prepareattack(0, -1))
{
if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_fuel = self.ammo_fuel - autocvar_g_balance_hook_primary_fuel;
+ W_DecreaseAmmo(ammo_fuel, autocvar_g_balance_hook_primary_fuel, FALSE);
self.hook_state |= HOOK_FIRING;
weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_hook_primary_animtime, w_ready);
}
{
if ( self.ammo_fuel >= (time - self.hook_time_fueldecrease) * hooked_fuel )
{
- self.ammo_fuel -= (time - self.hook_time_fueldecrease) * hooked_fuel;
+ W_DecreaseAmmo(ammo_fuel, (time - self.hook_time_fueldecrease) * hooked_fuel, FALSE);
self.hook_time_fueldecrease = time;
// decrease next frame again
}
else if (req == WR_SETUP)
{
weapon_setup(WEP_HOOK);
+ self.current_ammo = ammo_fuel;
self.hook_state &~= HOOK_WAITING_FOR_RELEASE;
}
else if (req == WR_CHECKAMMO1)
#ifdef REGISTER_WEAPON
-REGISTER_WEAPON(LASER, w_laser, 0, 1, WEP_FLAG_NORMAL | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH, 0, "laser", "laser", _("Laser"))
+REGISTER_WEAPON(LASER, w_laser, 0, 1, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH, 0, "laser", "laser", _("Laser"))
#else
#ifdef SVQC
void(float imp) W_SwitchWeapon;
}
else if (req == WR_THINK)
{
- if (self.BUTTON_ATCK)
- 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_Laser_Attack(0);
- weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_laser_primary_animtime, w_ready);
+ 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);
+ }
}
- if (self.BUTTON_ATCK2)
+ else if (self.BUTTON_ATCK2)
{
if(autocvar_g_balance_laser_secondary)
{
+ W_DecreaseAmmo(ammo_none, 1, TRUE);
+
if (weapon_prepareattack(0, 0))
{
W_Laser_Attack2();
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");
+ }
return TRUE;
};
#endif
#ifdef REGISTER_WEAPON
-REGISTER_WEAPON(MINE_LAYER, w_minelayer, IT_ROCKETS, 4, WEP_FLAG_NORMAL | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_HIGH, "minelayer", "minelayer", _("Mine Layer"))
+REGISTER_WEAPON(MINE_LAYER, w_minelayer, IT_ROCKETS, 4, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_HIGH, "minelayer", "minelayer", _("Mine Layer"))
#else
#ifdef SVQC
void W_Mine_Think (void);
}
}
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_rockets = self.ammo_rockets - autocvar_g_balance_minelayer_ammo;
+ W_DecreaseAmmo(ammo_rockets, autocvar_g_balance_minelayer_ammo, autocvar_g_balance_minelayer_reload_ammo);
W_SetupShot_ProjectileSize (self, '-4 -4 -4', '4 4 4', FALSE, 5, "weapons/mine_fire.wav", CHAN_WEAPON, autocvar_g_balance_minelayer_damage);
pointparticles(particleeffectnum("rocketlauncher_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
{
entity mine;
float minfound;
+ float ammo_amount;
+
if (req == WR_AIM)
{
// aim and decide to fire if appropriate
}
else if (req == WR_THINK)
{
- if (self.BUTTON_ATCK)
+ if(autocvar_g_balance_minelayer_reload_ammo && self.clip_load < autocvar_g_balance_minelayer_ammo) // forced reload
+ weapon_action(self.weapon, WR_RELOAD);
+ else if (self.BUTTON_ATCK)
{
if(weapon_prepareattack(0, autocvar_g_balance_minelayer_refire))
{
}
}
- if (self.BUTTON_ATCK2)
+ else if (self.BUTTON_ATCK2)
{
minfound = 0;
for(mine = world; (mine = find(mine, classname, "mine")); ) if(mine.owner == self)
precache_sound ("weapons/mine_fire.wav");
precache_sound ("weapons/mine_stick.wav");
precache_sound ("weapons/mine_trigger.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_MINE_LAYER);
+ self.current_ammo = ammo_rockets;
}
else if (req == WR_CHECKAMMO1)
{
// don't switch while placing a mine
- if ((ATTACK_FINISHED(self) <= time || self.weapon != WEP_MINE_LAYER)
- && self.ammo_rockets < autocvar_g_balance_minelayer_ammo)
- return FALSE;
+ if (ATTACK_FINISHED(self) <= time || self.weapon != WEP_MINE_LAYER)
+ {
+ if(autocvar_g_balance_minelayer_reload_ammo)
+ {
+ if(self.ammo_rockets < autocvar_g_balance_minelayer_ammo && self.weapon_load[WEP_MINE_LAYER] < autocvar_g_balance_minelayer_ammo)
+ ammo_amount = TRUE;
+ }
+ else if(self.ammo_rockets < autocvar_g_balance_minelayer_ammo)
+ ammo_amount = TRUE;
+ return !ammo_amount;
+ }
}
else if (req == WR_CHECKAMMO2)
+ {
return FALSE;
+ }
+ else if (req == WR_RELOAD)
+ {
+ W_Reload(autocvar_g_balance_minelayer_ammo, autocvar_g_balance_minelayer_reload_ammo, autocvar_g_balance_minelayer_reload_time, "weapons/reload.wav");
+ }
return TRUE;
};
#endif
#ifdef REGISTER_WEAPON
-REGISTER_WEAPON(MINSTANEX, w_minstanex, IT_CELLS, 7, WEP_FLAG_HIDDEN | WEP_FLAG_CANCLIMB | WEP_TYPE_HITSCAN, BOT_PICKUP_RATING_HIGH, "minstanex", "minstanex", _("MinstaNex"))
+REGISTER_WEAPON(MINSTANEX, w_minstanex, IT_CELLS, 7, WEP_FLAG_HIDDEN | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_HITSCAN, BOT_PICKUP_RATING_HIGH, "minstanex", "minstanex", _("MinstaNex"))
#else
#ifdef SVQC
.float minstanex_lasthit;
if (trace_ent.solid == SOLID_BSP && !(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT))
Damage_DamageInfo(trace_endpos, 10000, 0, 0, 800 * w_shotdir, WEP_MINSTANEX, self);
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- {
- if (g_minstagib)
- self.ammo_cells = self.ammo_cells - 1;
- else
- self.ammo_cells = self.ammo_cells - autocvar_g_balance_minstanex_ammo;
- }
+ if (g_minstagib)
+ W_DecreaseAmmo(ammo_cells, 1, autocvar_g_balance_minstanex_reload_ammo);
+ else
+ W_DecreaseAmmo(ammo_cells, autocvar_g_balance_minstanex_ammo, autocvar_g_balance_minstanex_reload_ammo);
}
void spawnfunc_weapon_minstanex (void); // defined in t_items.qc
+float minstanex_ammo;
float w_minstanex(float req)
{
+ float ammo_amount;
if (req == WR_AIM)
{
- if(self.ammo_cells>0)
+ if(self.ammo_cells > 0)
self.BUTTON_ATCK = bot_aim(1000000, 0, 1, FALSE);
else
self.BUTTON_ATCK2 = bot_aim(autocvar_g_balance_laser_primary_speed, 0, autocvar_g_balance_laser_primary_lifetime, FALSE);
}
else if (req == WR_THINK)
{
- if (self.BUTTON_ATCK)
+ if(g_minstagib)
+ minstanex_ammo = 1;
+ else
+ minstanex_ammo = autocvar_g_balance_minstanex_ammo;
+
+ // if the laser uses load, we also consider its ammo for reloading
+ if(autocvar_g_balance_minstanex_reload_ammo && autocvar_g_balance_minstanex_laser_ammo && self.clip_load < min(minstanex_ammo, autocvar_g_balance_minstanex_laser_ammo)) // forced reload
+ weapon_action(self.weapon, WR_RELOAD);
+ else if(autocvar_g_balance_minstanex_reload_ammo && self.clip_load < minstanex_ammo) // forced reload
+ weapon_action(self.weapon, WR_RELOAD);
+ else if (self.BUTTON_ATCK)
{
if (weapon_prepareattack(0, autocvar_g_balance_minstanex_refire))
{
{
self.jump_interval = time + autocvar_g_balance_laser_primary_refire * W_WeaponRateFactor();
+ // decrease ammo for the laser?
+ if(autocvar_g_balance_minstanex_laser_ammo)
+ W_DecreaseAmmo(ammo_cells, autocvar_g_balance_minstanex_laser_ammo, autocvar_g_balance_minstanex_reload_ammo);
+
// ugly minstagib hack to reuse the fire mode of the laser
float w;
w = self.weapon;
precache_sound ("weapons/nexwhoosh1.wav");
precache_sound ("weapons/nexwhoosh2.wav");
precache_sound ("weapons/nexwhoosh3.wav");
+ //precache_sound ("weapons/reload.wav"); // until weapons have individual reload sounds, precache the reload sound somewhere else
w_laser(WR_PRECACHE);
}
else if (req == WR_SETUP)
{
weapon_setup(WEP_MINSTANEX);
+ self.current_ammo = ammo_cells;
self.minstanex_lasthit = 0;
}
else if (req == WR_CHECKAMMO1)
{
- if (g_minstagib)
- return self.ammo_cells >= 1;
- else
- return self.ammo_cells >= autocvar_g_balance_minstanex_ammo;
+ ammo_amount = self.ammo_cells >= autocvar_g_balance_minstanex_ammo;
+ ammo_amount += self.weapon_load[WEP_MINSTANEX] >= autocvar_g_balance_minstanex_ammo;
+ return ammo_amount;
}
else if (req == WR_CHECKAMMO2)
- return TRUE;
+ {
+ if(!autocvar_g_balance_minstanex_laser_ammo)
+ return TRUE;
+ ammo_amount = self.ammo_cells >= autocvar_g_balance_minstanex_laser_ammo;
+ ammo_amount += self.weapon_load[WEP_MINSTANEX] >= autocvar_g_balance_minstanex_laser_ammo;
+ return ammo_amount;
+ }
else if (req == WR_RESETPLAYER)
{
self.minstanex_lasthit = 0;
}
+ else if (req == WR_RELOAD)
+ {
+ float used_ammo;
+ if(autocvar_g_balance_minstanex_laser_ammo)
+ used_ammo = min(autocvar_g_balance_minstanex_ammo, autocvar_g_balance_minstanex_laser_ammo);
+ else
+ used_ammo = autocvar_g_balance_minstanex_ammo;
+
+ W_Reload(used_ammo, autocvar_g_balance_minstanex_reload_ammo, autocvar_g_balance_minstanex_reload_time, "weapons/reload.wav");
+ }
return TRUE;
};
#endif
#ifdef REGISTER_WEAPON
-REGISTER_WEAPON(NEX, w_nex, IT_CELLS, 7, WEP_FLAG_NORMAL | WEP_TYPE_HITSCAN, BOT_PICKUP_RATING_HIGH, "nex", "nex", _("Nex"))
+REGISTER_WEAPON(NEX, w_nex, IT_CELLS, 7, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN, BOT_PICKUP_RATING_HIGH, "nex", "nex", _("Nex"))
#else
#ifdef SVQC
+
void SendCSQCNexBeamParticle(float charge) {
vector v;
v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
if (trace_ent.solid == SOLID_BSP && !(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT))
Damage_DamageInfo(trace_endpos, mydmg, 0, 0, myforce * w_shotdir, WEP_NEX, self);
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_cells = self.ammo_cells - myammo;
+ W_DecreaseAmmo(ammo_cells, myammo, autocvar_g_balance_nex_reload_ammo);
}
void spawnfunc_weapon_nex (void); // defined in t_items.qc
float w_nex(float req)
{
float dt;
+ float ammo_amount;
if (req == WR_AIM)
{
self.BUTTON_ATCK = bot_aim(1000000, 0, 1, FALSE);
self.pauseregen_finished = max(self.pauseregen_finished, time + autocvar_g_balance_nex_secondary_chargepool_pause_health_regen);
}
- if (self.BUTTON_ATCK)
+ if(autocvar_g_balance_nex_reload_ammo && self.clip_load < min(autocvar_g_balance_nex_primary_ammo, autocvar_g_balance_nex_secondary_ammo)) // forced reload
+ weapon_action(self.weapon, WR_RELOAD);
+ else
{
- if (weapon_prepareattack(0, autocvar_g_balance_nex_primary_refire))
+ if (self.BUTTON_ATCK)
{
- W_Nex_Attack(0);
- weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_nex_primary_animtime, w_ready);
+ if (weapon_prepareattack(0, autocvar_g_balance_nex_primary_refire))
+ {
+ W_Nex_Attack(0);
+ weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_nex_primary_animtime, w_ready);
+ }
}
- }
- if ((autocvar_g_balance_nex_secondary_charge && !autocvar_g_balance_nex_secondary) ? self.BUTTON_ZOOM : self.BUTTON_ATCK2)
- {
- if(autocvar_g_balance_nex_secondary_charge)
+ if ((autocvar_g_balance_nex_secondary_charge && !autocvar_g_balance_nex_secondary) ? self.BUTTON_ZOOM : self.BUTTON_ATCK2)
{
- self.nex_charge_rottime = time + autocvar_g_balance_nex_charge_rot_pause;
- dt = frametime / W_TICSPERFRAME;
-
- if(self.nex_charge < 1)
+ if(autocvar_g_balance_nex_secondary_charge)
{
- if(autocvar_g_balance_nex_secondary_chargepool)
+ self.nex_charge_rottime = time + autocvar_g_balance_nex_charge_rot_pause;
+ dt = frametime / W_TICSPERFRAME;
+
+ if(self.nex_charge < 1)
{
- if(autocvar_g_balance_nex_secondary_ammo)
+ if(autocvar_g_balance_nex_secondary_chargepool)
{
- // always deplete if secondary is held
- self.nex_chargepool_ammo = max(0, self.nex_chargepool_ammo - autocvar_g_balance_nex_secondary_ammo * dt);
+ if(autocvar_g_balance_nex_secondary_ammo)
+ {
+ // always deplete if secondary is held
+ self.nex_chargepool_ammo = max(0, self.nex_chargepool_ammo - autocvar_g_balance_nex_secondary_ammo * dt);
- dt = min(dt, (1 - self.nex_charge) / autocvar_g_balance_nex_secondary_charge_rate);
- self.nex_chargepool_pauseregen_finished = time + autocvar_g_balance_nex_secondary_chargepool_pause_regen;
- dt = min(dt, self.nex_chargepool_ammo);
- dt = max(0, dt);
+ dt = min(dt, (1 - self.nex_charge) / autocvar_g_balance_nex_secondary_charge_rate);
+ self.nex_chargepool_pauseregen_finished = time + autocvar_g_balance_nex_secondary_chargepool_pause_regen;
+ dt = min(dt, self.nex_chargepool_ammo);
+ dt = max(0, dt);
- self.nex_charge += dt * autocvar_g_balance_nex_secondary_charge_rate;
+ self.nex_charge += dt * autocvar_g_balance_nex_secondary_charge_rate;
+ }
}
- }
- else if(autocvar_g_balance_nex_secondary_ammo)
- {
- if(self.BUTTON_ATCK2) // only eat ammo when the button is pressed
+ else if(autocvar_g_balance_nex_secondary_ammo)
{
- dt = min(dt, (1 - self.nex_charge) / autocvar_g_balance_nex_secondary_charge_rate);
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
+ if(self.BUTTON_ATCK2) // only eat ammo when the button is pressed
{
- dt = min(dt, (self.ammo_cells - autocvar_g_balance_nex_primary_ammo) / autocvar_g_balance_nex_secondary_ammo);
- dt = max(0, dt);
- if(dt > 0)
+ dt = min(dt, (1 - self.nex_charge) / autocvar_g_balance_nex_secondary_charge_rate);
+ if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
{
- self.ammo_cells = max(autocvar_g_balance_nex_secondary_ammo, self.ammo_cells - autocvar_g_balance_nex_secondary_ammo * dt);
+ // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
+ if(autocvar_g_balance_nex_reload_ammo)
+ {
+ dt = min(dt, (self.clip_load - autocvar_g_balance_nex_primary_ammo) / autocvar_g_balance_nex_secondary_ammo);
+ dt = max(0, dt);
+ if(dt > 0)
+ {
+ self.clip_load = max(autocvar_g_balance_nex_secondary_ammo, self.clip_load - autocvar_g_balance_nex_secondary_ammo * dt);
+ }
+ self.weapon_load[WEP_NEX] = self.clip_load;
+ }
+ else
+ {
+ dt = min(dt, (self.ammo_cells - autocvar_g_balance_nex_primary_ammo) / autocvar_g_balance_nex_secondary_ammo);
+ dt = max(0, dt);
+ if(dt > 0)
+ {
+ self.ammo_cells = max(autocvar_g_balance_nex_secondary_ammo, self.ammo_cells - autocvar_g_balance_nex_secondary_ammo * dt);
+ }
+ }
}
+ self.nex_charge += dt * autocvar_g_balance_nex_secondary_charge_rate;
}
- self.nex_charge += dt * autocvar_g_balance_nex_secondary_charge_rate;
}
- }
- else
- {
- dt = min(dt, (1 - self.nex_charge) / autocvar_g_balance_nex_secondary_charge_rate);
- self.nex_charge += dt * autocvar_g_balance_nex_secondary_charge_rate;
+ else
+ {
+ dt = min(dt, (1 - self.nex_charge) / autocvar_g_balance_nex_secondary_charge_rate);
+ self.nex_charge += dt * autocvar_g_balance_nex_secondary_charge_rate;
+ }
}
}
- }
- else if(autocvar_g_balance_nex_secondary)
- {
- if (weapon_prepareattack(0, autocvar_g_balance_nex_secondary_refire))
+ else if(autocvar_g_balance_nex_secondary)
{
- W_Nex_Attack(1);
- weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_nex_secondary_animtime, w_ready);
+ if (weapon_prepareattack(0, autocvar_g_balance_nex_secondary_refire))
+ {
+ W_Nex_Attack(1);
+ weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_nex_secondary_animtime, w_ready);
+ }
}
}
}
precache_sound ("weapons/nexwhoosh1.wav");
precache_sound ("weapons/nexwhoosh2.wav");
precache_sound ("weapons/nexwhoosh3.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_NEX);
+ self.current_ammo = ammo_cells;
+ }
else if (req == WR_CHECKAMMO1)
- return self.ammo_cells >= autocvar_g_balance_nex_primary_ammo;
+ {
+ ammo_amount = self.ammo_cells >= autocvar_g_balance_nex_primary_ammo;
+ ammo_amount += (autocvar_g_balance_nex_reload_ammo && self.weapon_load[WEP_NEX] >= autocvar_g_balance_nex_primary_ammo);
+ return ammo_amount;
+ }
else if (req == WR_CHECKAMMO2)
- return self.ammo_cells >= autocvar_g_balance_nex_primary_ammo; // don't allow charging if we don't have enough ammo
+ {
+ // don't allow charging if we don't have enough ammo
+ ammo_amount = self.ammo_cells >= autocvar_g_balance_nex_secondary_ammo;
+ ammo_amount += self.weapon_load[WEP_NEX] >= autocvar_g_balance_nex_secondary_ammo;
+ return ammo_amount;
+ }
+ else if (req == WR_RELOAD)
+ {
+ W_Reload(min(autocvar_g_balance_nex_primary_ammo, autocvar_g_balance_nex_secondary_ammo), autocvar_g_balance_nex_reload_ammo, autocvar_g_balance_nex_reload_time, "weapons/reload.wav");
+ }
+
return TRUE;
};
#endif
precache_sound ("porto/unsupported.wav");
}
else if (req == WR_SETUP)
+ {
weapon_setup(WEP_PORTO);
+ self.current_ammo = ammo_none;
+ }
else if (req == WR_RESETPLAYER)
{
self.porto_current = world;
#ifdef REGISTER_WEAPON
-REGISTER_WEAPON(ROCKET_LAUNCHER, w_rlauncher, IT_ROCKETS, 9, WEP_FLAG_NORMAL | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_HIGH, "rl", "rocketlauncher", _("Rocket Launcher"))
+REGISTER_WEAPON(ROCKET_LAUNCHER, w_rlauncher, IT_ROCKETS, 9, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_HIGH, "rl", "rocketlauncher", _("Rocket Launcher"))
#else
#ifdef SVQC
.float rl_release;
local entity missile;
local entity flash;
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_rockets = self.ammo_rockets - autocvar_g_balance_rocketlauncher_ammo;
+ W_DecreaseAmmo(ammo_rockets, autocvar_g_balance_rocketlauncher_ammo, autocvar_g_balance_rocketlauncher_reload_ammo);
W_SetupShot_ProjectileSize (self, '-3 -3 -3', '3 3 3', FALSE, 5, "weapons/rocket_fire.wav", CHAN_WEAPON, autocvar_g_balance_rocketlauncher_damage);
pointparticles(particleeffectnum("rocketlauncher_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
{
entity rock;
float rockfound;
+ float ammo_amount;
+
if (req == WR_AIM)
{
// aim and decide to fire if appropriate
}
else if (req == WR_THINK)
{
- if (self.BUTTON_ATCK)
+ if(autocvar_g_balance_rocketlauncher_reload_ammo && self.clip_load < autocvar_g_balance_rocketlauncher_ammo) // forced reload
+ weapon_action(self.weapon, WR_RELOAD);
+ else
{
- if(self.rl_release || autocvar_g_balance_rocketlauncher_guidestop)
- if(weapon_prepareattack(0, autocvar_g_balance_rocketlauncher_refire))
+ if (self.BUTTON_ATCK)
{
- W_Rocket_Attack();
- weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_rocketlauncher_animtime, w_ready);
- self.rl_release = 0;
+ if(self.rl_release || autocvar_g_balance_rocketlauncher_guidestop)
+ if(weapon_prepareattack(0, autocvar_g_balance_rocketlauncher_refire))
+ {
+ W_Rocket_Attack();
+ weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_rocketlauncher_animtime, w_ready);
+ self.rl_release = 0;
+ }
}
- }
- else
- self.rl_release = 1;
+ else
+ self.rl_release = 1;
- if (self.BUTTON_ATCK2)
- {
- rockfound = 0;
- for(rock = world; (rock = find(rock, classname, "rocket")); ) if(rock.owner == self)
+ if (self.BUTTON_ATCK2)
{
- if(!rock.rl_detonate_later)
+ rockfound = 0;
+ for(rock = world; (rock = find(rock, classname, "rocket")); ) if(rock.owner == self)
{
- rock.rl_detonate_later = TRUE;
- rockfound = 1;
+ if(!rock.rl_detonate_later)
+ {
+ rock.rl_detonate_later = TRUE;
+ rockfound = 1;
+ }
}
+ if(rockfound)
+ sound (self, CHAN_WEAPON2, "weapons/rocket_det.wav", VOL_BASE, ATTN_NORM);
}
- if(rockfound)
- sound (self, CHAN_WEAPON2, "weapons/rocket_det.wav", VOL_BASE, ATTN_NORM);
}
}
else if (req == WR_PRECACHE)
precache_sound ("weapons/rocket_det.wav");
precache_sound ("weapons/rocket_fire.wav");
precache_sound ("weapons/rocket_mode.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_ROCKET_LAUNCHER);
+ self.current_ammo = ammo_rockets;
self.rl_release = 1;
}
else if (req == WR_CHECKAMMO1)
{
// don't switch while guiding a missile
- if ((ATTACK_FINISHED(self) <= time || self.weapon != WEP_ROCKET_LAUNCHER)
- && self.ammo_rockets < autocvar_g_balance_rocketlauncher_ammo)
- return FALSE;
+ if (ATTACK_FINISHED(self) <= time || self.weapon != WEP_ROCKET_LAUNCHER)
+ {
+ if(autocvar_g_balance_rocketlauncher_reload_ammo)
+ {
+ if(self.ammo_rockets < autocvar_g_balance_rocketlauncher_ammo && self.weapon_load[WEP_ROCKET_LAUNCHER] < autocvar_g_balance_rocketlauncher_ammo)
+ ammo_amount = TRUE;
+ }
+ else if(self.ammo_rockets < autocvar_g_balance_rocketlauncher_ammo)
+ ammo_amount = TRUE;
+ return !ammo_amount;
+ }
}
else if (req == WR_CHECKAMMO2)
return FALSE;
{
self.rl_release = 0;
}
+ else if (req == WR_RELOAD)
+ {
+ W_Reload(autocvar_g_balance_rocketlauncher_ammo, autocvar_g_balance_rocketlauncher_reload_ammo, autocvar_g_balance_rocketlauncher_reload_time, "weapons/reload.wav");
+ }
return TRUE;
};
#endif
#ifdef REGISTER_WEAPON
-REGISTER_WEAPON(SEEKER, w_seeker, IT_ROCKETS, 8, WEP_FLAG_NORMAL | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_MID, "seeker", "seeker", _("T.A.G. Seeker"))
+REGISTER_WEAPON(SEEKER, w_seeker, IT_ROCKETS, 8, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_MID, "seeker", "seeker", _("T.A.G. Seeker"))
#else
#ifdef SVQC
//.float proxytime; = autoswitch
{
local entity missile;
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_rockets = self.ammo_rockets - autocvar_g_balance_seeker_missile_ammo;
+ W_DecreaseAmmo(ammo_rockets, autocvar_g_balance_seeker_missile_ammo, autocvar_g_balance_seeker_reload_ammo);
makevectors(self.v_angle);
W_SetupShot_ProjectileSize (self, '-2 -2 -2', '2 2 2', FALSE, 2, "weapons/seeker_fire.wav", CHAN_WEAPON, 0);
void Seeker_Fire_Tag()
{
local entity missile;
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_rockets = self.ammo_rockets - autocvar_g_balance_seeker_tag_ammo;
+ W_DecreaseAmmo(ammo_rockets, autocvar_g_balance_seeker_tag_ammo, autocvar_g_balance_seeker_reload_ammo);
W_SetupShot_ProjectileSize (self, '-2 -2 -2', '2 2 2', FALSE, 2, "weapons/tag_fire.wav", CHAN_WEAPON, autocvar_g_balance_seeker_missile_damage * autocvar_g_balance_seeker_missile_count);
vector f_diff;
float c;
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_rockets = self.ammo_rockets - autocvar_g_balance_seeker_flac_ammo;
+ W_DecreaseAmmo(ammo_rockets, autocvar_g_balance_seeker_flac_ammo, autocvar_g_balance_seeker_reload_ammo);
c = mod(self.bulletcounter, 4);
switch(c)
float w_seeker(float req)
{
+ float ammo_amount;
+
if (req == WR_AIM)
self.BUTTON_ATCK = bot_aim(autocvar_g_balance_seeker_tag_speed, 0, 20, FALSE);
else if (req == WR_THINK)
{
- if (self.BUTTON_ATCK)
+ if(autocvar_g_balance_seeker_reload_ammo && self.clip_load < min(autocvar_g_balance_seeker_missile_ammo, autocvar_g_balance_seeker_tag_ammo)) // forced reload
+ weapon_action(self.weapon, WR_RELOAD);
+
+ else if (self.BUTTON_ATCK)
+ {
if (weapon_prepareattack(0, autocvar_g_balance_seeker_tag_refire))
{
Seeker_Fire_Tag();
weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_seeker_tag_animtime, w_ready);
}
+ }
- if (self.BUTTON_ATCK2)
+ else if (self.BUTTON_ATCK2)
+ {
if (weapon_prepareattack(1, autocvar_g_balance_seeker_flac_refire))
{
Seeker_Fire_Flac();
weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_seeker_flac_animtime, w_ready);
}
-
+ }
}
else if (req == WR_PRECACHE)
{
precache_sound ("weapons/tag_fire.wav");
precache_sound ("weapons/flac_fire.wav");
precache_sound ("weapons/seeker_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_SEEKER);
+ self.current_ammo = ammo_rockets;
+ }
else if (req == WR_CHECKAMMO1)
- return self.ammo_rockets >= autocvar_g_balance_seeker_tag_ammo + autocvar_g_balance_seeker_missile_ammo;
+ {
+ ammo_amount = self.ammo_cells >= autocvar_g_balance_seeker_missile_ammo;
+ ammo_amount += self.weapon_load[WEP_SEEKER] >= autocvar_g_balance_seeker_missile_ammo;
+ return ammo_amount;
+ }
else if (req == WR_CHECKAMMO2)
- return self.ammo_rockets >= autocvar_g_balance_seeker_flac_ammo;
+ {
+ ammo_amount = self.ammo_cells >= autocvar_g_balance_seeker_flac_ammo;
+ ammo_amount += self.weapon_load[WEP_SEEKER] >= autocvar_g_balance_seeker_flac_ammo;
+ return ammo_amount;
+ }
+ else if (req == WR_RELOAD)
+ {
+ W_Reload(min(autocvar_g_balance_seeker_missile_ammo, autocvar_g_balance_seeker_tag_ammo), autocvar_g_balance_seeker_reload_ammo, autocvar_g_balance_seeker_reload_time, "weapons/reload.wav");
+ }
return TRUE;
};
#endif
#ifdef REGISTER_WEAPON
-REGISTER_WEAPON(SHOTGUN, w_shotgun, IT_SHELLS, 2, WEP_FLAG_NORMAL | WEP_TYPE_HITSCAN, BOT_PICKUP_RATING_LOW, "shotgun", "shotgun", _("Shotgun"))
+REGISTER_WEAPON(SHOTGUN, w_shotgun, IT_SHELLS, 2, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN, BOT_PICKUP_RATING_LOW, "shotgun", "shotgun", _("Shotgun"))
#else
#ifdef SVQC
+
void W_Shotgun_Attack (void)
{
float sc;
bulletspeed = autocvar_g_balance_shotgun_primary_speed;
bulletconstant = autocvar_g_balance_shotgun_primary_bulletconstant;
+ W_DecreaseAmmo(ammo_shells, ammoamount, autocvar_g_balance_shotgun_reload_ammo);
+
W_SetupShot (self, autocvar_g_antilag_bullets && bulletspeed >= autocvar_g_antilag_bullets, 5, "weapons/shotgun_fire.wav", CHAN_WEAPON, d * bullets);
for (sc = 0;sc < bullets;sc = sc + 1)
fireBallisticBullet(w_shotorg, w_shotdir, spread, bulletspeed, 5, d, 0, f, WEP_SHOTGUN, 0, 1, bulletconstant);
endFireBallisticBullet();
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_shells = self.ammo_shells - ammoamount;
pointparticles(particleeffectnum("shotgun_muzzleflash"), w_shotorg, w_shotdir * 1000, autocvar_g_balance_shotgun_primary_ammo);
flash.nextthink = time + 0.06;
flash.effects = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION;
W_AttachToShotorg(flash, '5 0 0');
-
}
void shotgun_meleethink (void)
float w_shotgun(float req)
{
+ float ammo_amount;
if (req == WR_AIM)
if(vlen(self.origin-self.enemy.origin) <= autocvar_g_balance_shotgun_secondary_melee_range)
self.BUTTON_ATCK2 = bot_aim(1000000, 0, 0.001, FALSE);
self.BUTTON_ATCK = bot_aim(1000000, 0, 0.001, FALSE);
else if (req == WR_THINK)
{
- if (self.BUTTON_ATCK)
+ if(autocvar_g_balance_shotgun_reload_ammo && self.clip_load < autocvar_g_balance_shotgun_primary_ammo) // forced reload
+ {
+ // don't force reload an empty shotgun if its melee attack is active
+ if not(autocvar_g_balance_shotgun_secondary && self.ammo_shells < autocvar_g_balance_shotgun_primary_ammo)
+ weapon_action(self.weapon, WR_RELOAD);
+ }
+ else
{
- if (time >= self.shotgun_primarytime) // handle refire separately so the secondary can be fired straight after a primary
+ if (self.BUTTON_ATCK)
{
- if(weapon_prepareattack(0, autocvar_g_balance_shotgun_primary_animtime))
+ if (time >= self.shotgun_primarytime) // handle refire separately so the secondary can be fired straight after a primary
{
- W_Shotgun_Attack();
- self.shotgun_primarytime = time + autocvar_g_balance_shotgun_primary_refire;
- weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_shotgun_primary_animtime, w_ready);
+ if(weapon_prepareattack(0, autocvar_g_balance_shotgun_primary_animtime))
+ {
+ W_Shotgun_Attack();
+ self.shotgun_primarytime = time + autocvar_g_balance_shotgun_primary_refire;
+ weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_shotgun_primary_animtime, w_ready);
+ }
}
}
}
+ if (self.clip_load >= 0) // we are not currently reloading
if (self.BUTTON_ATCK2 && autocvar_g_balance_shotgun_secondary)
if (weapon_prepareattack(1, autocvar_g_balance_shotgun_secondary_refire))
{
precache_sound ("misc/itempickup.wav");
precache_sound ("weapons/shotgun_fire.wav");
precache_sound ("weapons/shotgun_melee.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_SHOTGUN);
+ self.current_ammo = ammo_shells;
+ }
else if (req == WR_CHECKAMMO1)
- return self.ammo_shells >= autocvar_g_balance_shotgun_primary_ammo;
+ {
+ ammo_amount = self.ammo_shells >= autocvar_g_balance_shotgun_primary_ammo;
+ ammo_amount += self.weapon_load[WEP_SHOTGUN] >= autocvar_g_balance_shotgun_primary_ammo;
+ return ammo_amount;
+ }
else if (req == WR_CHECKAMMO2)
{
+ // melee attack is always available
return TRUE;
}
+ else if (req == WR_RELOAD)
+ {
+ W_Reload(autocvar_g_balance_shotgun_primary_ammo, autocvar_g_balance_shotgun_reload_ammo, autocvar_g_balance_shotgun_reload_time, "weapons/reload.wav");
+ }
return TRUE;
};
#endif
#ifdef REGISTER_WEAPON
-REGISTER_WEAPON(SNIPERRIFLE, w_sniperrifle, IT_NAILS, 7, WEP_FLAG_NORMAL | WEP_TYPE_HITSCAN, BOT_PICKUP_RATING_MID, "campingrifle", "sniperrifle", _("Sniper Rifle"))
+REGISTER_WEAPON(SNIPERRIFLE, w_sniperrifle, IT_NAILS, 7, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN, BOT_PICKUP_RATING_MID, "campingrifle", "sniperrifle", _("Sniper Rifle"))
#else
#ifdef SVQC
//Sniper rifle Primary mode: manually operated bolt*, Secondary: full automatic**
.float sniperrifle_accumulator;
-float W_SniperRifle_CheckMaxBullets(float checkammo)
-{
- float maxbulls;
- maxbulls = autocvar_g_balance_sniperrifle_magazinecapacity;
- if(!maxbulls)
- maxbulls = 8; // match HUD
- if(checkammo)
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- maxbulls = min(maxbulls, floor(self.ammo_nails / min(autocvar_g_balance_sniperrifle_primary_ammo, autocvar_g_balance_sniperrifle_secondary_ammo)));
- if(self.sniperrifle_bulletcounter > maxbulls || !autocvar_g_balance_sniperrifle_magazinecapacity)
- self.sniperrifle_bulletcounter = maxbulls;
- return (self.sniperrifle_bulletcounter == maxbulls);
-}
-
-void W_SniperRifle_ReloadedAndReady()
-{
- float t;
- self.sniperrifle_bulletcounter = autocvar_g_balance_sniperrifle_magazinecapacity;
- W_SniperRifle_CheckMaxBullets(TRUE);
- t = ATTACK_FINISHED(self) - autocvar_g_balance_sniperrifle_reloadtime - 1;
- ATTACK_FINISHED(self) = t;
- w_ready();
-}
-
-float W_SniperRifle_Reload()
-{
- float t;
-
- W_SniperRifle_CheckMaxBullets(TRUE);
-
- if(self.ammo_nails < min(autocvar_g_balance_sniperrifle_primary_ammo, autocvar_g_balance_sniperrifle_secondary_ammo)) // when we get here, bulletcounter must be 0 or -1
- {
- print("cannot reload... not enough bullets\n");
- self.sniperrifle_bulletcounter = -1; // reload later
- W_SwitchToOtherWeapon(self);
- return 0;
- }
-
- if (self.sniperrifle_bulletcounter >= autocvar_g_balance_sniperrifle_magazinecapacity)
- return 0;
-
- if (self.weaponentity)
- {
- if (self.weaponentity.wframe == WFRAME_RELOAD)
- return 0;
-
- // allow to switch away while reloading, but this will cause a new reload!
- self.weaponentity.state = WS_READY;
- }
-
- sound (self, CHAN_WEAPON2, "weapons/campingrifle_reload.wav", VOL_BASE, ATTN_NORM);
-
- t = max(time, ATTACK_FINISHED(self)) + autocvar_g_balance_sniperrifle_reloadtime + 1;
- ATTACK_FINISHED(self) = t;
-
- weapon_thinkf(WFRAME_RELOAD, autocvar_g_balance_sniperrifle_reloadtime, W_SniperRifle_ReloadedAndReady);
-
- self.sniperrifle_bulletcounter = -1;
-
- return 1;
-}
-
-void W_SniperRifle_CheckReloadAndReady()
-{
- w_ready();
- if(self.sniperrifle_bulletcounter <= 0)
- if(W_SniperRifle_Reload())
- return;
-}
-
void W_SniperRifle_FireBullet(float pSpread, float pDamage, float pHeadshotAddedDamage, float pForce, float pSpeed, float pLifetime, float pAmmo, float deathtype, float pBulletConstant)
{
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_nails -= pAmmo;
+ W_DecreaseAmmo(ammo_nails, pAmmo, autocvar_g_balance_sniperrifle_reload_ammo);
if(deathtype & HITTYPE_SECONDARY)
W_SetupShot (self, autocvar_g_antilag_bullets && pSpeed >= autocvar_g_antilag_bullets, 2, "weapons/campingrifle_fire2.wav", CHAN_WEAPON, autocvar_g_balance_sniperrifle_secondary_damage + autocvar_g_balance_sniperrifle_secondary_headshotaddeddamage);
else
W_SetupShot (self, autocvar_g_antilag_bullets && pSpeed >= autocvar_g_antilag_bullets, 2, "weapons/campingrifle_fire.wav", CHAN_WEAPON, autocvar_g_balance_sniperrifle_primary_damage + autocvar_g_balance_sniperrifle_primary_headshotaddeddamage);
- pointparticles(particleeffectnum("shotgun_muzzleflash"), w_shotorg, w_shotdir * 2000, 1);
+ pointparticles(particleeffectnum("sniperrifle_muzzleflash"), w_shotorg, w_shotdir * 2000, 1);
if(self.BUTTON_ZOOM) // if zoomed, shoot from the eye
{
if (autocvar_g_casings >= 2)
SpawnCasing (((random () * 50 + 50) * v_right) - (v_forward * (random () * 25 + 25)) - ((random () * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, self);
-
- self.sniperrifle_bulletcounter = self.sniperrifle_bulletcounter - 1;
- W_SniperRifle_CheckMaxBullets(TRUE);
}
void W_SniperRifle_Attack()
void W_SniperRifle_BulletHail_Continue()
{
float r, sw, af;
- W_SniperRifle_CheckReloadAndReady();
- if(self.sniperrifle_bulletcounter < 0)
- return; // reloading, so we are done
+
sw = self.switchweapon; // make it not detect weapon changes as reason to abort firing
af = ATTACK_FINISHED(self);
self.switchweapon = self.weapon;
else
{
// just one shot
- weapon_thinkf(fr, animtime, W_SniperRifle_CheckReloadAndReady);
+ weapon_thinkf(fr, animtime, w_ready);
}
}
.float bot_secondary_sniperriflemooth;
float w_sniperrifle(float req)
{
- float full;
+ float ammo_amount;
+
if (req == WR_AIM)
{
self.BUTTON_ATCK=FALSE;
}
else if (req == WR_THINK)
{
- if(self.sniperrifle_bulletcounter < 0) // forced reload (e.g. because interrupted)
- {
- self.wish_reload = 1;
- }
+ if(autocvar_g_balance_sniperrifle_reload_ammo && self.clip_load < min(autocvar_g_balance_sniperrifle_primary_ammo, autocvar_g_balance_sniperrifle_secondary_ammo)) // forced reload
+ weapon_action(self.weapon, WR_RELOAD);
else
{
self.sniperrifle_accumulator = bound(time - autocvar_g_balance_sniperrifle_bursttime, self.sniperrifle_accumulator, time);
if (autocvar_g_balance_sniperrifle_secondary)
{
if(autocvar_g_balance_sniperrifle_secondary_reload)
- self.wish_reload = 1;
+ weapon_action(self.weapon, WR_RELOAD);
else
{
if (weapon_prepareattack_check(1, autocvar_g_balance_sniperrifle_secondary_refire))
}
}
}
- if(self.wish_reload)
- {
- if(self.switchweapon == self.weapon)
- {
- if(self.weaponentity.state == WS_READY)
- {
- self.wish_reload = 0;
- W_SniperRifle_Reload();
- }
- }
- }
}
else if (req == WR_PRECACHE)
{
precache_model ("models/weapons/g_campingrifle.md3");
precache_model ("models/weapons/v_campingrifle.md3");
precache_model ("models/weapons/h_campingrifle.iqm");
- precache_sound ("weapons/campingrifle_reload.wav");
precache_sound ("weapons/campingrifle_fire.wav");
precache_sound ("weapons/campingrifle_fire2.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_SNIPERRIFLE);
-
- full = W_SniperRifle_CheckMaxBullets(TRUE);
- if(autocvar_g_balance_sniperrifle_auto_reload_on_switch)
- if(!full)
- self.sniperrifle_bulletcounter = -1;
+ self.current_ammo = ammo_nails;
}
else if (req == WR_CHECKAMMO1)
- return self.ammo_nails >= autocvar_g_balance_sniperrifle_primary_ammo;
+ {
+ ammo_amount = self.ammo_nails >= autocvar_g_balance_sniperrifle_primary_ammo;
+ ammo_amount += self.weapon_load[WEP_SNIPERRIFLE] >= autocvar_g_balance_sniperrifle_primary_ammo;
+ return ammo_amount;
+ }
else if (req == WR_CHECKAMMO2)
- return self.ammo_nails >= autocvar_g_balance_sniperrifle_secondary_ammo;
- else if (req == WR_RELOAD)
{
- self.wish_reload = 1;
+ ammo_amount = self.ammo_nails >= autocvar_g_balance_sniperrifle_secondary_ammo;
+ ammo_amount += self.weapon_load[WEP_SNIPERRIFLE] >= autocvar_g_balance_sniperrifle_secondary_ammo;
+ return ammo_amount;
}
else if (req == WR_RESETPLAYER)
{
self.sniperrifle_accumulator = time - autocvar_g_balance_sniperrifle_bursttime;
- self.sniperrifle_bulletcounter = autocvar_g_balance_sniperrifle_magazinecapacity;
- W_SniperRifle_CheckMaxBullets(FALSE);
+ }
+ else if (req == WR_RELOAD)
+ {
+ W_Reload(min(autocvar_g_balance_sniperrifle_primary_ammo, autocvar_g_balance_sniperrifle_secondary_ammo), autocvar_g_balance_sniperrifle_reload_ammo, autocvar_g_balance_sniperrifle_reload_time, "weapons/reload.wav");
}
return TRUE;
};
// precache_sound(TUBA_NOTE(i));
}
else if (req == WR_SETUP)
+ {
weapon_setup(WEP_TUBA);
+ self.current_ammo = ammo_none;
+ }
else if (req == WR_CHECKAMMO1)
return TRUE; // TODO use fuel?
else if (req == WR_CHECKAMMO2)
#ifdef REGISTER_WEAPON
-REGISTER_WEAPON(UZI, w_uzi, IT_NAILS, 3, WEP_FLAG_NORMAL | WEP_TYPE_HITSCAN, BOT_PICKUP_RATING_MID, "uzi", "uzi", _("Machine Gun"))
+REGISTER_WEAPON(UZI, w_uzi, IT_NAILS, 3, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN, BOT_PICKUP_RATING_MID, "uzi", "uzi", _("Machine Gun"))
#else
#ifdef SVQC
// leilei's fancy muzzleflash stuff
-void Uzi_Flash_Go()
+void UZI_Flash_Go()
{
self.frame = self.frame + 2;
self.scale = self.scale * 0.5;
setmodel(self.muzzle_flash, "models/uziflash.md3"); // precision set below
self.muzzle_flash.scale = 0.75;
- self.muzzle_flash.think = Uzi_Flash_Go;
+ self.muzzle_flash.think = UZI_Flash_Go;
self.muzzle_flash.nextthink = time + 0.02;
self.muzzle_flash.frame = 2;
self.muzzle_flash.alpha = 0.75;
self.muzzle_flash.owner = self;
}
-void W_Uzi_Attack (float deathtype)
+void W_UZI_Attack (float deathtype)
{
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- {
- if (self.misc_bulletcounter == 1)
- self.ammo_nails = self.ammo_nails - autocvar_g_balance_uzi_first_ammo;
- else
- self.ammo_nails = self.ammo_nails - autocvar_g_balance_uzi_sustained_ammo;
- }
W_SetupShot (self, autocvar_g_antilag_bullets && autocvar_g_balance_uzi_speed >= autocvar_g_antilag_bullets, 0, "weapons/uzi_fire.wav", CHAN_WEAPON, ((self.misc_bulletcounter == 1) ? autocvar_g_balance_uzi_first_damage : autocvar_g_balance_uzi_sustained_damage));
if (!g_norecoil)
{
// casing code
if (autocvar_g_casings >= 2)
SpawnCasing (((random () * 50 + 50) * v_right) - (v_forward * (random () * 25 + 25)) - ((random () * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, self);
+
+ if (self.misc_bulletcounter == 1)
+ W_DecreaseAmmo(ammo_nails, autocvar_g_balance_uzi_first_ammo, autocvar_g_balance_uzi_reload_ammo);
+ else
+ W_DecreaseAmmo(ammo_nails, autocvar_g_balance_uzi_sustained_ammo, autocvar_g_balance_uzi_reload_ammo);
}
// weapon frames
return;
}
self.misc_bulletcounter = self.misc_bulletcounter + 1;
- W_Uzi_Attack(WEP_UZI);
+ W_UZI_Attack(WEP_UZI);
weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_uzi_sustained_refire, uzi_fire1_02);
}
else
void uzi_mode1_fire_auto()
{
float uzi_spread;
+
+ W_DecreaseAmmo(ammo_nails, autocvar_g_balance_uzi_sustained_ammo, autocvar_g_balance_uzi_reload_ammo);
if (self.BUTTON_ATCK)
weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_uzi_sustained_refire, uzi_mode1_fire_auto);
if (autocvar_g_casings >= 2) // casing code
SpawnCasing (((random () * 50 + 50) * v_right) - (v_forward * (random () * 25 + 25)) - ((random () * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, self);
-
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_nails = self.ammo_nails - autocvar_g_balance_uzi_sustained_ammo;
-
}
void uzi_mode1_fire_burst()
float w_uzi(float req)
{
+ float ammo_amount;
if (req == WR_AIM)
if(vlen(self.origin-self.enemy.origin) < 3000 - bound(0, skill, 10) * 200)
self.BUTTON_ATCK = bot_aim(1000000, 0, 0.001, FALSE);
}
else if (req == WR_THINK)
{
- if(autocvar_g_balance_uzi_mode == 1)
+ if(autocvar_g_balance_uzi_reload_ammo && self.clip_load < min(max(autocvar_g_balance_uzi_sustained_ammo, autocvar_g_balance_uzi_first_ammo), autocvar_g_balance_uzi_burst_ammo)) // forced reload
+ weapon_action(self.weapon, WR_RELOAD);
+ else if(autocvar_g_balance_uzi_mode == 1)
{
if (self.BUTTON_ATCK)
if (weapon_prepareattack(0, 0))
w_ready();
return FALSE;
}
-
- if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_nails = self.ammo_nails - autocvar_g_balance_uzi_burst_ammo;
+
+ W_DecreaseAmmo(ammo_nails, autocvar_g_balance_uzi_burst_ammo, autocvar_g_balance_uzi_reload_ammo);
self.misc_bulletcounter = autocvar_g_balance_uzi_burst * -1;
uzi_mode1_fire_burst();
if (weapon_prepareattack(0, 0))
{
self.misc_bulletcounter = 1;
- W_Uzi_Attack(WEP_UZI); // sets attack_finished
+ W_UZI_Attack(WEP_UZI); // sets attack_finished
weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_uzi_sustained_refire, uzi_fire1_02);
}
if (weapon_prepareattack(1, 0))
{
self.misc_bulletcounter = 1;
- W_Uzi_Attack(WEP_UZI | HITTYPE_SECONDARY); // sets attack_finished
+ W_UZI_Attack(WEP_UZI | HITTYPE_SECONDARY); // sets attack_finished
weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_uzi_first_refire, w_ready);
}
}
precache_model ("models/weapons/v_uzi.md3");
precache_model ("models/weapons/h_uzi.iqm");
precache_sound ("weapons/uzi_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_UZI);
+ self.current_ammo = ammo_nails;
+ }
else if (req == WR_CHECKAMMO1)
+ {
if(autocvar_g_balance_uzi_mode == 1)
- return self.ammo_nails >= autocvar_g_balance_uzi_sustained_ammo;
+ ammo_amount = self.ammo_nails >= autocvar_g_balance_uzi_sustained_ammo;
else
- return self.ammo_nails >= autocvar_g_balance_uzi_first_ammo;
+ ammo_amount = self.ammo_nails >= autocvar_g_balance_uzi_first_ammo;
+
+ if(autocvar_g_balance_uzi_reload_ammo)
+ {
+ if(autocvar_g_balance_uzi_mode == 1)
+ ammo_amount += self.weapon_load[WEP_UZI] >= autocvar_g_balance_uzi_sustained_ammo;
+ else
+ ammo_amount += self.weapon_load[WEP_UZI] >= autocvar_g_balance_uzi_first_ammo;
+ }
+ return ammo_amount;
+ }
else if (req == WR_CHECKAMMO2)
+ {
if(autocvar_g_balance_uzi_mode == 1)
- return self.ammo_nails >= autocvar_g_balance_uzi_burst_ammo;
+ ammo_amount = self.ammo_nails >= autocvar_g_balance_uzi_burst_ammo;
else
- return self.ammo_nails >= autocvar_g_balance_uzi_first_ammo;
+ ammo_amount = self.ammo_nails >= autocvar_g_balance_uzi_first_ammo;
+
+ if(autocvar_g_balance_uzi_reload_ammo)
+ {
+ if(autocvar_g_balance_uzi_mode == 1)
+ ammo_amount += self.weapon_load[WEP_UZI] >= autocvar_g_balance_uzi_burst_ammo;
+ else
+ ammo_amount += self.weapon_load[WEP_UZI] >= autocvar_g_balance_uzi_first_ammo;
+ }
+ return ammo_amount;
+ }
+ else if (req == WR_RELOAD)
+ {
+ W_Reload(min(max(autocvar_g_balance_uzi_sustained_ammo, autocvar_g_balance_uzi_first_ammo), autocvar_g_balance_uzi_burst_ammo), autocvar_g_balance_uzi_reload_ammo, autocvar_g_balance_uzi_reload_time, "weapons/reload.wav");
+ }
return TRUE;
};
#endif