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 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 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 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 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 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 20
+set g_balance_electro_reload_time 2
// }}}
// {{{ crylink
set g_balance_crylink_primary_damage 10
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 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 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 5
+set g_balance_minstanex_reload_ammo 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 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 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 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
+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 60
+set g_balance_fireball_reload_time 2
// }}}
// {{{ seeker
set g_balance_seeker_flac_ammo 0.5
set g_balance_seeker_tag_refire 0.7
set g_balance_seeker_tag_speed 5000
set g_balance_seeker_tag_spread 0
+set g_balance_seeker_reload_ammo 15
+set g_balance_seeker_reload_time 2
// End new seeker
float sniperrifle_scope;
float nex_scope;
-float cr_maxbullets;
-
float bgmtime;
string weaponorder_byimpulse;
serverflags = ReadByte();
- cr_maxbullets = ReadByte();
-
g_trueaim_minrange = ReadCoord();
if(!postinit)
// TrueAim check
float shottype;
- float bullets, ring_scale;
+ 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;
if(nex_charge_movingavg == 0) // this should only happen if we have just loaded up the game
nex_charge_movingavg = nex_charge;
- // ring around crosshair representing bullets left in camping rifle clip
- if (activeweapon == WEP_SNIPERRIFLE && cr_maxbullets)
+ // ring around crosshair representing bullets left in weapon clip
+ weapon_clipload = getstati(STAT_WEAPON_CLIPLOAD);
+ if (weapon_clipload)
{
- bullets = getstati(STAT_BULLETS_LOADED);
- f = bound(0, bullets / cr_maxbullets, 1);
+ weapon_clipsize = getstati(STAT_WEAPON_CLIPSIZE);
+ f = bound(0, weapon_clipload / weapon_clipsize, 1);
a = autocvar_crosshair_ring_sniperrifle_alpha;
DrawCircleClippedPic(wcross_origin, wcross_size_x * ring_scale, "gfx/crosshair_ring.tga", f, wcross_color, wcross_alpha * a, DRAWFLAG_ADDITIVE);
}
- else if (activeweapon == WEP_NEX && nex_charge) // ring around crosshair representing velocity-dependent damage for the nex
+ if (activeweapon == WEP_NEX && nex_charge) // ring around crosshair representing velocity-dependent damage for the nex
{
if(nex_chargepool || use_nex_chargepool)
{
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 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_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;
// 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 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_limit;
float autocvar_g_balance_nex_charge_maxspeed;
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;
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);
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
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;
}
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)
void W_Reload()
{
- self.wish_reload = 1;
+ weapon_action(self.weapon, WR_RELOAD);
}
// switch between weapons
#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)
+
+.float reload_complain;
+float W_ReloadCheck(float ammo_amount, float ammo_shot)
+{
+ entity e;
+ e = get_weaponinfo(self.weapon);
+
+ // our weapon is fully loaded, no need to reload
+ if (self.clip_load >= cvar(strcat("g_balance_", e.netname, "_reload_ammo")))
+ return 0;
+
+ // no ammo, so nothing to load
+ if(!ammo_amount)
+ {
+ 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 loaded amount of ammo is not enough to keep using this weapon
+ if(self.clip_load < ammo_shot)
+ {
+ self.clip_load = -1; // reload later
+ W_SwitchToOtherWeapon(self);
+ }
+ return 0;
+ }
+
+ if (self.weaponentity)
+ {
+ if (self.weaponentity.wframe == WFRAME_RELOAD)
+ return 0;
+
+ // allow switching away while reloading, but this will cause a new reload!
+ self.weaponentity.state = WS_READY;
+ }
+
+ return 1;
+}
\ No newline at end of file
float client_cefc_accumulatortime;
#endif
-.float sniperrifle_bulletcounter;
-.float wish_reload;
+.float clip_load;
+.float old_clip_load;
+.float clip_size;
#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_NEX_CHARGE, AS_FLOAT, nex_charge);
.entity queuenext;
.entity queueprev;
+// weapon load persistence, for weapons that support reloading
+.float crylink_load;
+
+void W_Crylink_SetAmmoCounter()
+{
+ // set clip_load to the weapon we have switched to, if the gun uses reloading
+ if(!autocvar_g_balance_crylink_reload_ammo)
+ self.clip_load = 0; // also keeps crosshair ammo from displaying
+ else
+ {
+ self.clip_load = self.crylink_load;
+ self.clip_size = autocvar_g_balance_crylink_reload_ammo; // for the crosshair ammo display
+ }
+}
+
+void W_Crylink_ReloadedAndReady()
+{
+ float t;
+
+ // now 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
+ while(self.clip_load < autocvar_g_balance_crylink_reload_ammo && self.ammo_cells) // make sure we don't add more ammo than we have
+ {
+ self.clip_load += 1;
+ self.ammo_cells -= 1;
+ }
+ self.crylink_load = self.clip_load;
+
+ t = ATTACK_FINISHED(self) - autocvar_g_balance_crylink_reload_time - 1;
+ ATTACK_FINISHED(self) = t;
+ w_ready();
+}
+
+void W_Crylink_Reload()
+{
+ // return if reloading is disabled for this weapon
+ if(!autocvar_g_balance_crylink_reload_ammo)
+ return;
+
+ if(!W_ReloadCheck(self.ammo_cells, min(autocvar_g_balance_crylink_primary_ammo, autocvar_g_balance_crylink_secondary_ammo)))
+ return;
+
+ float t;
+
+ sound (self, CHAN_WEAPON2, "weapons/reload.wav", VOL_BASE, ATTN_NORM);
+
+ t = max(time, ATTACK_FINISHED(self)) + autocvar_g_balance_crylink_reload_time + 1;
+ ATTACK_FINISHED(self) = t;
+
+ weapon_thinkf(WFRAME_RELOAD, autocvar_g_balance_crylink_reload_time, W_Crylink_ReloadedAndReady);
+
+ self.old_clip_load = self.clip_load;
+ self.clip_load = -1;
+}
+
void W_Crylink_CheckLinks(entity e)
{
float i;
vector forward, right, up;
float maxdmg;
+ // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_cells = self.ammo_cells - autocvar_g_balance_crylink_primary_ammo;
+ {
+ if(autocvar_g_balance_crylink_reload_ammo)
+ {
+ self.clip_load -= autocvar_g_balance_crylink_primary_ammo;
+ self.crylink_load = self.clip_load;
+ }
+ else
+ self.ammo_cells -= autocvar_g_balance_crylink_primary_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 this weapon is reloadable, decrease its load. Else decrease the player's ammo
if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_cells = self.ammo_cells - autocvar_g_balance_crylink_secondary_ammo;
+ {
+ if(autocvar_g_balance_crylink_reload_ammo)
+ {
+ self.clip_load -= autocvar_g_balance_crylink_secondary_ammo;
+ self.crylink_load = self.clip_load;
+ }
+ else
+ self.ammo_cells -= autocvar_g_balance_crylink_secondary_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
+ W_Crylink_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");
}
else if (req == WR_SETUP)
+ {
weapon_setup(WEP_CRYLINK);
+ W_Crylink_SetAmmoCounter();
+ }
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 += (autocvar_g_balance_crylink_reload_ammo && self.crylink_load >= 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 += (autocvar_g_balance_crylink_reload_ammo && self.crylink_load >= autocvar_g_balance_crylink_secondary_ammo);
+ return ammo_amount;
+ }
+ else if (req == WR_RESETPLAYER)
+ {
+ // all weapons must be fully loaded when we spawn
+ self.crylink_load = autocvar_g_balance_crylink_reload_ammo;
+ }
+ else if (req == WR_RELOAD)
+ {
+ W_Crylink_Reload();
}
return TRUE;
};
.float electro_count;
.float electro_secondarytime;
+// weapon load persistence, for weapons that support reloading
+.float electro_load;
+
+void W_Electro_SetAmmoCounter()
+{
+ // set clip_load to the weapon we have switched to, if the gun uses reloading
+ if(!autocvar_g_balance_electro_reload_ammo)
+ self.clip_load = 0; // also keeps crosshair ammo from displaying
+ else
+ {
+ self.clip_load = self.electro_load;
+ self.clip_size = autocvar_g_balance_electro_reload_ammo; // for the crosshair ammo display
+ }
+}
+
+void W_Electro_ReloadedAndReady()
+{
+ float t;
+
+ // now 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
+ while(self.clip_load < autocvar_g_balance_electro_reload_ammo && self.ammo_cells) // make sure we don't add more ammo than we have
+ {
+ self.clip_load += 1;
+ self.ammo_cells -= 1;
+ }
+ self.electro_load = self.clip_load;
+
+ t = ATTACK_FINISHED(self) - autocvar_g_balance_electro_reload_time - 1;
+ ATTACK_FINISHED(self) = t;
+ w_ready();
+}
+
+void W_Electro_Reload()
+{
+ // return if reloading is disabled for this weapon
+ if(!autocvar_g_balance_electro_reload_ammo)
+ return;
+
+ if(!W_ReloadCheck(self.ammo_cells, min(autocvar_g_balance_electro_primary_ammo, autocvar_g_balance_electro_secondary_ammo)))
+ return;
+
+ float t;
+
+ sound (self, CHAN_WEAPON2, "weapons/reload.wav", VOL_BASE, ATTN_NORM);
+
+ t = max(time, ATTACK_FINISHED(self)) + autocvar_g_balance_electro_reload_time + 1;
+ ATTACK_FINISHED(self) = t;
+
+ weapon_thinkf(WFRAME_RELOAD, autocvar_g_balance_electro_reload_time, W_Electro_ReloadedAndReady);
+
+ self.old_clip_load = self.clip_load;
+ self.clip_load = -1;
+}
+
void W_Plasma_Explode_Combo (void);
void W_Plasma_TriggerCombo(vector org, float rad, entity own)
{
local entity proj;
+ // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
+ if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
+ {
+ if(autocvar_g_balance_electro_reload_ammo)
+ {
+ self.clip_load -= autocvar_g_balance_electro_primary_ammo;
+ self.electro_load = self.clip_load;
+ }
+ else
+ self.ammo_cells -= autocvar_g_balance_electro_primary_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;
+ // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
+ if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
+ {
+ if(autocvar_g_balance_electro_reload_ammo)
+ {
+ self.clip_load -= autocvar_g_balance_electro_secondary_ammo;
+ self.electro_load = self.clip_load;
+ }
+ else
+ self.ammo_cells -= autocvar_g_balance_electro_secondary_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;
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 (self.owner.weaponentity.state != WS_INUSE || !lgbeam_checkammo() || self.owner.deadflag != DEAD_NO || !self.owner.BUTTON_ATCK || self.owner.freezetag_frozen)
{
if(self == self.owner.lgbeam)
self.owner.lgbeam = world;
float dt, f;
dt = frametime;
+ // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
if not(self.owner.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, self.owner.clip_load / autocvar_g_balance_electro_primary_ammo);
+ self.owner.clip_load = max(0, self.owner.clip_load - autocvar_g_balance_electro_primary_ammo * frametime);
+ self.owner.electro_load = self.owner.clip_load;
+ }
+ else
+ {
+ 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);
+ }
}
}
.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 (self.BUTTON_ATCK)
+ if(autocvar_g_balance_electro_reload_ammo && self.clip_load < min(autocvar_g_balance_electro_primary_ammo, autocvar_g_balance_electro_secondary_ammo)) // forced reload
+ W_Electro_Reload();
+ else if (self.BUTTON_ATCK)
{
if(autocvar_g_balance_electro_lightning)
if(self.BUTTON_ATCK_prev)
}
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");
if(autocvar_g_balance_electro_lightning)
{
precache_sound ("weapons/lgbeam_fire.wav");
}
}
else if (req == WR_SETUP)
+ {
weapon_setup(WEP_ELECTRO);
+ W_Electro_SetAmmoCounter();
+ }
else if (req == WR_CHECKAMMO1)
{
if(autocvar_g_balance_electro_lightning)
- return !autocvar_g_balance_electro_primary_ammo || (self.ammo_cells > 0);
+ ammo_amount = !autocvar_g_balance_electro_primary_ammo || (self.ammo_cells > 0);
else
- return self.ammo_cells >= autocvar_g_balance_electro_primary_ammo;
+ ammo_amount = self.ammo_cells >= autocvar_g_balance_electro_primary_ammo;
+ if(autocvar_g_balance_electro_reload_ammo)
+ {
+ if(autocvar_g_balance_electro_lightning)
+ ammo_amount += !autocvar_g_balance_electro_primary_ammo || (self.electro_load > 0);
+ else
+ ammo_amount += self.electro_load >= 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 += (autocvar_g_balance_electro_reload_ammo && self.electro_load >= autocvar_g_balance_electro_secondary_ammo);
+ return ammo_amount;
+ }
else if (req == WR_RESETPLAYER)
{
self.electro_secondarytime = time;
+
+ // all weapons must be fully loaded when we spawn
+ self.electro_load = autocvar_g_balance_electro_reload_ammo;
+ }
+ else if (req == WR_RELOAD)
+ {
+ W_Shotgun_Reload();
}
return TRUE;
};
.vector fireball_impactvec;
.float fireball_primarytime;
+// weapon load persistence, for weapons that support reloading
+.float fireball_load;
+
+void W_Fireball_SetAmmoCounter()
+{
+ // set clip_load to the weapon we have switched to, if the gun uses reloading
+ if(!autocvar_g_balance_fireball_reload_ammo)
+ self.clip_load = 0; // also keeps crosshair ammo from displaying
+ else
+ {
+ self.clip_load = self.fireball_load;
+ self.clip_size = autocvar_g_balance_fireball_reload_ammo; // for the crosshair ammo display
+ }
+}
+
+void W_Fireball_ReloadedAndReady()
+{
+ float t;
+
+ // now 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
+ while(self.clip_load < autocvar_g_balance_fireball_reload_ammo && self.ammo_fuel) // make sure we don't add more ammo than we have
+ {
+ self.clip_load += 1;
+ self.ammo_fuel -= 1;
+
+ // 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;
+ }
+ self.fireball_load = self.clip_load;
+
+ t = ATTACK_FINISHED(self) - autocvar_g_balance_fireball_reload_time - 1;
+ ATTACK_FINISHED(self) = t;
+ w_ready();
+}
+
+void W_Fireball_Reload()
+{
+ // return if reloading is disabled for this weapon
+ if(!autocvar_g_balance_fireball_reload_ammo)
+ return;
+
+ if(!W_ReloadCheck(self.ammo_fuel, min(autocvar_g_balance_fireball_primary_ammo, autocvar_g_balance_fireball_secondary_ammo)))
+ return;
+
+ float t;
+
+ sound (self, CHAN_WEAPON2, "weapons/reload.wav", VOL_BASE, ATTN_NORM);
+
+ t = max(time, ATTACK_FINISHED(self)) + autocvar_g_balance_fireball_reload_time + 1;
+ ATTACK_FINISHED(self) = t;
+
+ weapon_thinkf(WFRAME_RELOAD, autocvar_g_balance_fireball_reload_time, W_Fireball_ReloadedAndReady);
+
+ self.old_clip_load = self.clip_load;
+ self.clip_load = -1;
+}
+
void W_Fireball_Explode (void)
{
entity e;
void W_Fireball_Attack1_Frame0()
{
+ // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_fuel = self.ammo_fuel - autocvar_g_balance_fireball_primary_ammo;
+ {
+ if(autocvar_g_balance_fireball_reload_ammo)
+ {
+ self.clip_load -= autocvar_g_balance_fireball_primary_ammo;
+ self.fireball_load = self.clip_load;
+ }
+ else
+ self.ammo_fuel -= autocvar_g_balance_fireball_primary_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 this weapon is reloadable, decrease its load. Else decrease the player's ammo
if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_fuel = self.ammo_fuel - autocvar_g_balance_fireball_secondary_ammo;
+ {
+ if(autocvar_g_balance_fireball_reload_ammo)
+ {
+ self.clip_load -= autocvar_g_balance_fireball_secondary_ammo;
+ self.fireball_load = self.clip_load;
+ }
+ else
+ self.ammo_fuel -= autocvar_g_balance_fireball_secondary_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
+ W_Fireball_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");
}
else if (req == WR_SETUP)
+ {
weapon_setup(WEP_FIREBALL);
+ W_Fireball_SetAmmoCounter();
+ }
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 += (autocvar_g_balance_fireball_reload_ammo && self.fireball_load >= 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 += (autocvar_g_balance_fireball_reload_ammo && self.fireball_load >= autocvar_g_balance_fireball_secondary_ammo);
+ return ammo_amount;
+ }
else if (req == WR_RESETPLAYER)
{
self.fireball_primarytime = time;
+
+ // all weapons must be fully loaded when we spawn
+ self.fireball_load = autocvar_g_balance_fireball_reload_ammo;
+ }
+ else if (req == WR_RELOAD)
+ {
+ W_Fireball_Reload();
}
return TRUE;
};
.float gl_detonate_later;
.float gl_bouncecnt;
+// weapon load persistence, for weapons that support reloading
+.float grenadelauncher_load;
+
+void W_GrenadeLauncher_SetAmmoCounter()
+{
+ // set clip_load to the weapon we have switched to, if the gun uses reloading
+ if(!autocvar_g_balance_grenadelauncher_reload_ammo)
+ self.clip_load = 0; // also keeps crosshair ammo from displaying
+ else
+ {
+ self.clip_load = self.grenadelauncher_load;
+ self.clip_size = autocvar_g_balance_grenadelauncher_reload_ammo; // for the crosshair ammo display
+ }
+}
+
+void W_GrenadeLauncher_ReloadedAndReady()
+{
+ float t;
+
+ // now 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
+ while(self.clip_load < autocvar_g_balance_grenadelauncher_reload_ammo && self.ammo_rockets) // make sure we don't add more ammo than we have
+ {
+ self.clip_load += 1;
+ self.ammo_rockets -= 1;
+ }
+ self.grenadelauncher_load = self.clip_load;
+
+ t = ATTACK_FINISHED(self) - autocvar_g_balance_grenadelauncher_reload_time - 1;
+ ATTACK_FINISHED(self) = t;
+ w_ready();
+}
+
+void W_GrenadeLauncher_Reload()
+{
+ // return if reloading is disabled for this weapon
+ if(!autocvar_g_balance_grenadelauncher_reload_ammo)
+ return;
+
+ if(!W_ReloadCheck(self.ammo_rockets, min(autocvar_g_balance_grenadelauncher_primary_ammo, autocvar_g_balance_grenadelauncher_secondary_ammo)))
+ return;
+
+ float t;
+
+ sound (self, CHAN_WEAPON2, "weapons/reload.wav", VOL_BASE, ATTN_NORM);
+
+ t = max(time, ATTACK_FINISHED(self)) + autocvar_g_balance_grenadelauncher_reload_time + 1;
+ ATTACK_FINISHED(self) = t;
+
+ weapon_thinkf(WFRAME_RELOAD, autocvar_g_balance_grenadelauncher_reload_time, W_GrenadeLauncher_ReloadedAndReady);
+
+ self.old_clip_load = self.clip_load;
+ self.clip_load = -1;
+}
+
void W_Grenade_Explode (void)
{
if(other.takedamage == DAMAGE_AIM)
{
local entity gren;
+ // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_rockets = self.ammo_rockets - autocvar_g_balance_grenadelauncher_primary_ammo;
+ {
+ if(autocvar_g_balance_grenadelauncher_reload_ammo)
+ {
+ self.clip_load -= autocvar_g_balance_grenadelauncher_primary_ammo;
+ self.grenadelauncher_load = self.clip_load;
+ }
+ else
+ self.ammo_rockets -= autocvar_g_balance_grenadelauncher_primary_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 this weapon is reloadable, decrease its load. Else decrease the player's ammo
if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_rockets = self.ammo_rockets - autocvar_g_balance_grenadelauncher_secondary_ammo;
+ {
+ if(autocvar_g_balance_grenadelauncher_reload_ammo)
+ {
+ self.clip_load -= autocvar_g_balance_grenadelauncher_secondary_ammo;
+ self.grenadelauncher_load = self.clip_load;
+ }
+ else
+ self.ammo_rockets -= autocvar_g_balance_grenadelauncher_secondary_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
+ W_GrenadeLauncher_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");
}
else if (req == WR_SETUP)
+ {
weapon_setup(WEP_GRENADE_LAUNCHER);
+ W_GrenadeLauncher_SetAmmoCounter();
+ }
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 += (autocvar_g_balance_grenadelauncher_reload_ammo && self.grenadelauncher_load >= 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 += (autocvar_g_balance_grenadelauncher_reload_ammo && self.grenadelauncher_load >= autocvar_g_balance_grenadelauncher_secondary_ammo);
+ return ammo_amount;
+ }
+ else if (req == WR_RESETPLAYER)
+ {
+ // all weapons must be fully loaded when we spawn
+ self.grenadelauncher_load = autocvar_g_balance_grenadelauncher_reload_ammo;
+ }
+ else if (req == WR_RELOAD)
+ {
+ W_GrenadeLauncher_Reload();
+ }
return TRUE;
};
#endif
#else
#ifdef SVQC
// NO bounce protection, as bounces are limited!
+
+// weapon load persistence, for weapons that support reloading
+.float hagar_load;
+
+void W_Hagar_SetAmmoCounter()
+{
+ // set clip_load to the weapon we have switched to, if the gun uses reloading
+ if(!autocvar_g_balance_hagar_reload_ammo)
+ self.clip_load = 0; // also keeps crosshair ammo from displaying
+ else
+ {
+ self.clip_load = self.hagar_load;
+ self.clip_size = autocvar_g_balance_hagar_reload_ammo; // for the crosshair ammo display
+ }
+}
+
+void W_Hagar_ReloadedAndReady()
+{
+ float t;
+
+ // now 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
+ while(self.clip_load < autocvar_g_balance_hagar_reload_ammo && self.ammo_rockets) // make sure we don't add more ammo than we have
+ {
+ self.clip_load += 1;
+ self.ammo_rockets -= 1;
+ }
+ self.hagar_load = self.clip_load;
+
+ t = ATTACK_FINISHED(self) - autocvar_g_balance_hagar_reload_time - 1;
+ ATTACK_FINISHED(self) = t;
+ w_ready();
+}
+
+void W_Hagar_Reload()
+{
+ // return if reloading is disabled for this weapon
+ if(!autocvar_g_balance_hagar_reload_ammo)
+ return;
+
+ if(!W_ReloadCheck(self.ammo_rockets, min(autocvar_g_balance_hagar_primary_ammo, autocvar_g_balance_hagar_secondary_ammo)))
+ return;
+
+ float t;
+
+ sound (self, CHAN_WEAPON2, "weapons/reload.wav", VOL_BASE, ATTN_NORM);
+
+ t = max(time, ATTACK_FINISHED(self)) + autocvar_g_balance_hagar_reload_time + 1;
+ ATTACK_FINISHED(self) = t;
+
+ weapon_thinkf(WFRAME_RELOAD, autocvar_g_balance_hagar_reload_time, W_Hagar_ReloadedAndReady);
+
+ self.old_clip_load = self.clip_load;
+ self.clip_load = -1;
+}
+
void W_Hagar_Explode (void)
{
self.event_damage = SUB_Null;
{
local entity missile;
+ // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_rockets = self.ammo_rockets - autocvar_g_balance_hagar_primary_ammo;
+ {
+ if(autocvar_g_balance_hagar_reload_ammo)
+ {
+ self.clip_load -= autocvar_g_balance_hagar_primary_ammo;
+ self.hagar_load = self.clip_load;
+ }
+ else
+ self.ammo_rockets -= autocvar_g_balance_hagar_primary_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 this weapon is reloadable, decrease its load. Else decrease the player's ammo
if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_rockets = self.ammo_rockets - autocvar_g_balance_hagar_secondary_ammo;
+ {
+ if(autocvar_g_balance_hagar_reload_ammo)
+ {
+ self.clip_load -= autocvar_g_balance_hagar_secondary_ammo;
+ self.hagar_load = self.clip_load;
+ }
+ else
+ self.ammo_rockets -= autocvar_g_balance_hagar_secondary_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
+ W_Hagar_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");
}
else if (req == WR_SETUP)
+ {
weapon_setup(WEP_HAGAR);
+ W_Hagar_SetAmmoCounter();
+ }
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 += (autocvar_g_balance_hagar_reload_ammo && self.hagar_load >= 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 += (autocvar_g_balance_hagar_reload_ammo && self.hagar_load >= autocvar_g_balance_hagar_secondary_ammo);
+ return ammo_amount;
+ }
+ else if (req == WR_RESETPLAYER)
+ {
+ // all weapons must be fully loaded when we spawn
+ self.hagar_load = autocvar_g_balance_hagar_reload_ammo;
+ }
+ else if (req == WR_RELOAD)
+ {
+ W_Hagar_Reload();
+ }
return TRUE;
};
#endif
#else
#ifdef SVQC
+// weapon load persistence, for weapons that support reloading
+.float hlac_load;
+
+void W_HLAC_SetAmmoCounter()
+{
+ // set clip_load to the weapon we have switched to, if the gun uses reloading
+ if(!autocvar_g_balance_hlac_reload_ammo)
+ self.clip_load = 0; // also keeps crosshair ammo from displaying
+ else
+ {
+ self.clip_load = self.hlac_load;
+ self.clip_size = autocvar_g_balance_hlac_reload_ammo; // for the crosshair ammo display
+ }
+}
+
+void W_HLAC_ReloadedAndReady()
+{
+ float t;
+
+ // now 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
+ while(self.clip_load < autocvar_g_balance_hlac_reload_ammo && self.ammo_cells) // make sure we don't add more ammo than we have
+ {
+ self.clip_load += 1;
+ self.ammo_cells -= 1;
+ }
+ self.hlac_load = self.clip_load;
+
+ t = ATTACK_FINISHED(self) - autocvar_g_balance_hlac_reload_time - 1;
+ ATTACK_FINISHED(self) = t;
+ w_ready();
+}
+
+void W_HLAC_Reload()
+{
+ // return if reloading is disabled for this weapon
+ if(!autocvar_g_balance_hlac_reload_ammo)
+ return;
+
+ if(!W_ReloadCheck(self.ammo_cells, min(autocvar_g_balance_hlac_primary_ammo, autocvar_g_balance_hlac_secondary_ammo)))
+ return;
+
+ float t;
+
+ sound (self, CHAN_WEAPON2, "weapons/reload.wav", VOL_BASE, ATTN_NORM);
+
+ t = max(time, ATTACK_FINISHED(self)) + autocvar_g_balance_hlac_reload_time + 1;
+ ATTACK_FINISHED(self) = t;
+
+ weapon_thinkf(WFRAME_RELOAD, autocvar_g_balance_hlac_reload_time, W_HLAC_ReloadedAndReady);
+
+ self.old_clip_load = self.clip_load;
+ self.clip_load = -1;
+}
+
void W_HLAC_Touch (void)
{
PROJECTILE_TOUCH;
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;
- }
+ // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
+ if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
+ {
+ if(autocvar_g_balance_hlac_reload_ammo)
+ {
+ self.clip_load -= autocvar_g_balance_hlac_primary_ammo;
+ self.hlac_load = self.clip_load;
+ }
+ else
+ self.ammo_cells -= autocvar_g_balance_hlac_primary_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;
- }
+ // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
+ if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
+ {
+ if(autocvar_g_balance_hlac_reload_ammo)
+ {
+ self.clip_load -= autocvar_g_balance_hlac_secondary_ammo;
+ self.hlac_load = self.clip_load;
+ }
+ else
+ self.ammo_cells -= autocvar_g_balance_hlac_secondary_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
+ W_HLAC_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");
}
else if (req == WR_SETUP)
+ {
weapon_setup(WEP_HLAC);
+ W_HLAC_SetAmmoCounter();
+ }
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 += (autocvar_g_balance_hlac_reload_ammo && self.hlac_load >= 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 += (autocvar_g_balance_hlac_reload_ammo && self.hlac_load >= autocvar_g_balance_hlac_secondary_ammo);
+ return ammo_amount;
+ }
+ else if (req == WR_RESETPLAYER)
+ {
+ // all weapons must be fully loaded when we spawn
+ self.hlac_load = autocvar_g_balance_hlac_reload_ammo;
+ }
+ else if (req == WR_RELOAD)
+ {
+ W_HLAC_Reload();
+ }
return TRUE;
};
#endif
.float hook_time_hooked;
.float hook_time_fueldecrease;
+void W_Hook_SetAmmoCounter()
+{
+ // this weapon doesn't have a reload system, so always set the clip to 0 when switching to it
+ self.clip_load = self.clip_size = 0; // also keeps crosshair ammo from displaying
+}
+
void W_Hook_ExplodeThink (void)
{
float dt, dmg_remaining_next, f;
else if (req == WR_SETUP)
{
weapon_setup(WEP_HOOK);
+ W_Hook_SetAmmoCounter();
self.hook_state &~= HOOK_WAITING_FOR_RELEASE;
}
else if (req == WR_CHECKAMMO1)
#ifdef SVQC
void(float imp) W_SwitchWeapon;
+// weapon load persistence, for weapons that support reloading
+.float laser_load;
+
+void W_Laser_SetAmmoCounter()
+{
+ // set clip_load to the weapon we have switched to, if the gun uses reloading
+ if(!autocvar_g_balance_laser_reload_ammo)
+ self.clip_load = 0; // also keeps crosshair ammo from displaying
+ else
+ {
+ self.clip_load = self.laser_load;
+ self.clip_size = autocvar_g_balance_laser_reload_ammo; // for the crosshair ammo display
+ }
+}
+
+void W_Laser_ReloadedAndReady()
+{
+ float t;
+
+ self.clip_load = autocvar_g_balance_laser_reload_ammo; // maximum load since this weapon uses no ammo
+ self.laser_load = self.clip_load;
+
+ t = ATTACK_FINISHED(self) - autocvar_g_balance_laser_reload_time - 1;
+ ATTACK_FINISHED(self) = t;
+ w_ready();
+}
+
+void W_Laser_Reload()
+{
+ // return if reloading is disabled for this weapon
+ if(!autocvar_g_balance_laser_reload_ammo)
+ return;
+
+ if(!W_ReloadCheck(1, 0))
+ return;
+
+ float t;
+
+ sound (self, CHAN_WEAPON2, "weapons/reload.wav", VOL_BASE, ATTN_NORM);
+
+ t = max(time, ATTACK_FINISHED(self)) + autocvar_g_balance_laser_reload_time + 1;
+ ATTACK_FINISHED(self) = t;
+
+ weapon_thinkf(WFRAME_RELOAD, autocvar_g_balance_laser_reload_time, W_Laser_ReloadedAndReady);
+
+ self.clip_load = -1;
+}
+
void W_Laser_Touch (void)
{
PROJECTILE_TOUCH;
}
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
+ W_Laser_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))
+ {
+ // if this weapon is reloadable, decrease its load
+ if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
+ {
+ if(autocvar_g_balance_laser_reload_ammo)
+ {
+ self.clip_load -= 1;
+ self.laser_load = self.clip_load;
+ }
+ }
+
+ 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)
{
+ // if this weapon is reloadable, decrease its load
+ if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
+ {
+ if(autocvar_g_balance_laser_reload_ammo)
+ {
+ self.clip_load -= 1;
+ self.laser_load = self.clip_load;
+ }
+ }
+
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");
}
else if (req == WR_SETUP)
+ {
weapon_setup(WEP_LASER);
+ W_Laser_SetAmmoCounter();
+ }
else if (req == WR_CHECKAMMO1)
+ {
return TRUE;
+ }
else if (req == WR_CHECKAMMO2)
+ {
return TRUE;
+ }
+ else if (req == WR_RESETPLAYER)
+ {
+ // all weapons must be fully loaded when we spawn
+ self.laser_load = autocvar_g_balance_laser_reload_ammo;
+ }
+ else if (req == WR_RELOAD)
+ {
+ W_Laser_Reload();
+ }
return TRUE;
};
#endif
.float minelayer_detonate, minelayer_mines;
.float mine_time;
+// weapon load persistence, for weapons that support reloading
+.float minelayer_load;
+
+void W_MineLayer_SetAmmoCounter()
+{
+ // set clip_load to the weapon we have switched to, if the gun uses reloading
+ if(!autocvar_g_balance_minelayer_reload_ammo)
+ self.clip_load = 0; // also keeps crosshair ammo from displaying
+ else
+ {
+ self.clip_load = self.minelayer_load;
+ self.clip_size = autocvar_g_balance_minelayer_reload_ammo; // for the crosshair ammo display
+ }
+}
+
+void W_MineLayer_ReloadedAndReady()
+{
+ float t;
+
+ // now 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
+ while(self.clip_load < autocvar_g_balance_minelayer_reload_ammo && self.ammo_rockets) // make sure we don't add more ammo than we have
+ {
+ self.clip_load += 1;
+ self.ammo_rockets -= 1;
+ }
+ self.minelayer_load = self.clip_load;
+
+ t = ATTACK_FINISHED(self) - autocvar_g_balance_minelayer_reload_time - 1;
+ ATTACK_FINISHED(self) = t;
+ w_ready();
+}
+
+void W_MineLayer_Reload()
+{
+ // return if reloading is disabled for this weapon
+ if(!autocvar_g_balance_minelayer_reload_ammo)
+ return;
+
+ if(!W_ReloadCheck(self.ammo_rockets, autocvar_g_balance_minelayer_ammo))
+ return;
+
+ float t;
+
+ sound (self, CHAN_WEAPON2, "weapons/reload.wav", VOL_BASE, ATTN_NORM);
+
+ t = max(time, ATTACK_FINISHED(self)) + autocvar_g_balance_minelayer_reload_time + 1;
+ ATTACK_FINISHED(self) = t;
+
+ weapon_thinkf(WFRAME_RELOAD, autocvar_g_balance_minelayer_reload_time, W_MineLayer_ReloadedAndReady);
+
+ self.old_clip_load = self.clip_load;
+ self.clip_load = -1;
+}
+
void spawnfunc_weapon_minelayer (void)
{
weapon_defaultspawnfunc(WEP_MINE_LAYER);
}
}
+ // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_rockets = self.ammo_rockets - autocvar_g_balance_minelayer_ammo;
+ {
+ if(autocvar_g_balance_minelayer_reload_ammo)
+ {
+ self.clip_load -= autocvar_g_balance_minelayer_ammo;
+ self.minelayer_load = self.clip_load;
+ }
+ else
+ self.ammo_rockets -= autocvar_g_balance_minelayer_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
+ W_MineLayer_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");
}
else if (req == WR_SETUP)
{
weapon_setup(WEP_MINE_LAYER);
+ W_MineLayer_SetAmmoCounter();
}
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(self.ammo_rockets < autocvar_g_balance_minelayer_ammo)
+ ammo_amount = FALSE;
+ if(autocvar_g_balance_electro_reload_ammo && self.minelayer_load < autocvar_g_balance_minelayer_ammo)
+ ammo_amount = FALSE;
+ }
+ return ammo_amount;
}
else if (req == WR_CHECKAMMO2)
+ {
return FALSE;
+ }
+ else if (req == WR_RESETPLAYER)
+ {
+ // all weapons must be fully loaded when we spawn
+ self.minelayer_load = autocvar_g_balance_minelayer_reload_ammo;
+ }
+ else if (req == WR_RELOAD)
+ {
+ W_MineLayer_Reload();
+ }
return TRUE;
};
#endif
#ifdef SVQC
.float minstanex_lasthit;
+// weapon load persistence, for weapons that support reloading
+.float minstanex_load;
+
+void W_Minstanex_SetAmmoCounter()
+{
+ // set clip_load to the weapon we have switched to, if the gun uses reloading
+ if(!autocvar_g_balance_minstanex_reload_ammo)
+ self.clip_load = 0; // also keeps crosshair ammo from displaying
+ else
+ {
+ self.clip_load = self.minstanex_load;
+ self.clip_size = autocvar_g_balance_minstanex_reload_ammo; // for the crosshair ammo display
+ }
+}
+
+void W_Minstanex_ReloadedAndReady()
+{
+ float t;
+
+ // now 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
+ while(self.clip_load < autocvar_g_balance_minstanex_reload_ammo && self.ammo_cells) // make sure we don't add more ammo than we have
+ {
+ self.clip_load += 1;
+ self.ammo_cells -= 1;
+ }
+ self.minstanex_load = self.clip_load;
+
+ t = ATTACK_FINISHED(self) - autocvar_g_balance_minstanex_reload_time - 1;
+ ATTACK_FINISHED(self) = t;
+ w_ready();
+}
+
+void W_Minstanex_Reload()
+{
+ // return if reloading is disabled for this weapon
+ if(!autocvar_g_balance_minstanex_reload_ammo)
+ return;
+
+ if(autocvar_g_balance_minstanex_laser_ammo)
+ {
+ if(!W_ReloadCheck(self.ammo_cells, min(autocvar_g_balance_minstanex_ammo, autocvar_g_balance_minstanex_laser_ammo)))
+ return;
+ }
+ else if(!W_ReloadCheck(self.ammo_cells, autocvar_g_balance_minstanex_ammo))
+ return;
+
+ float t;
+
+ sound (self, CHAN_WEAPON2, "weapons/reload.wav", VOL_BASE, ATTN_NORM);
+
+ t = max(time, ATTACK_FINISHED(self)) + autocvar_g_balance_minstanex_reload_time + 1;
+ ATTACK_FINISHED(self) = t;
+
+ weapon_thinkf(WFRAME_RELOAD, autocvar_g_balance_minstanex_reload_time, W_Minstanex_ReloadedAndReady);
+
+ self.old_clip_load = self.clip_load;
+ self.clip_load = -1;
+}
+
void W_MinstaNex_Attack (void)
{
float flying;
if (trace_ent.solid == SOLID_BSP && !(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT))
Damage_DamageInfo(trace_endpos, 10000, 0, 0, 800 * w_shotdir, WEP_MINSTANEX, self);
+ // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
{
- if (g_minstagib)
- self.ammo_cells = self.ammo_cells - 1;
+ if(autocvar_g_balance_minstanex_reload_ammo)
+ {
+ if (g_minstagib)
+ self.clip_load -= - 1;
+ else
+ self.clip_load -= autocvar_g_balance_minstanex_ammo;
+ self.minstanex_load = self.clip_load;
+ }
else
- self.ammo_cells = self.ammo_cells - autocvar_g_balance_minstanex_ammo;
+ {
+ if (g_minstagib)
+ self.ammo_cells -= - 1;
+ else
+ self.ammo_cells -= autocvar_g_balance_minstanex_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
+ W_Minstanex_Reload();
+ else if(autocvar_g_balance_minstanex_reload_ammo && self.clip_load < minstanex_ammo) // forced reload
+ W_Minstanex_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)
+ {
+ if(autocvar_g_balance_minstanex_reload_ammo)
+ self.clip_load -= autocvar_g_balance_minstanex_laser_ammo;
+ else
+ self.ammo_cells -= autocvar_g_balance_minstanex_laser_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");
w_laser(WR_PRECACHE);
}
else if (req == WR_SETUP)
{
weapon_setup(WEP_MINSTANEX);
+ W_Minstanex_SetAmmoCounter();
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 += (autocvar_g_balance_minstanex_reload_ammo && self.minstanex_load >= 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 += (autocvar_g_balance_minstanex_reload_ammo && self.minstanex_load >= autocvar_g_balance_minstanex_laser_ammo);
+ return ammo_amount;
+ }
else if (req == WR_RESETPLAYER)
{
self.minstanex_lasthit = 0;
+
+ // all weapons must be fully loaded when we spawn
+ self.minstanex_load = autocvar_g_balance_minstanex_reload_ammo;
+ }
+ else if (req == WR_RELOAD)
+ {
+ W_Minstanex_Reload();
}
return TRUE;
};
REGISTER_WEAPON(NEX, w_nex, IT_CELLS, 7, WEP_FLAG_NORMAL | WEP_TYPE_HITSCAN, BOT_PICKUP_RATING_HIGH, "nex", "nex", _("Nex"))
#else
#ifdef SVQC
+
+// weapon load persistence, for weapons that support reloading
+.float nex_load;
+
+void W_Nex_SetAmmoCounter()
+{
+ // set clip_load to the weapon we have switched to, if the gun uses reloading
+ if(!autocvar_g_balance_nex_reload_ammo)
+ self.clip_load = 0; // also keeps crosshair ammo from displaying
+ else
+ {
+ self.clip_load = self.nex_load;
+ self.clip_size = autocvar_g_balance_nex_reload_ammo; // for the crosshair ammo display
+ }
+}
+
+void W_Nex_ReloadedAndReady()
+{
+ float t;
+
+ // now 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
+ while(self.clip_load < autocvar_g_balance_nex_reload_ammo && self.ammo_cells) // make sure we don't add more ammo than we have
+ {
+ self.clip_load += 1;
+ self.ammo_cells -= 1;
+ }
+ self.nex_load = self.clip_load;
+
+ t = ATTACK_FINISHED(self) - autocvar_g_balance_nex_reload_time - 1;
+ ATTACK_FINISHED(self) = t;
+ w_ready();
+}
+
+void W_Nex_Reload()
+{
+ // return if reloading is disabled for this weapon
+ if(!autocvar_g_balance_nex_reload_ammo)
+ return;
+
+ if(!W_ReloadCheck(self.ammo_cells, min(autocvar_g_balance_nex_primary_ammo, autocvar_g_balance_nex_secondary_ammo)))
+ return;
+
+ float t;
+
+ sound (self, CHAN_WEAPON2, "weapons/reload.wav", VOL_BASE, ATTN_NORM);
+
+ t = max(time, ATTACK_FINISHED(self)) + autocvar_g_balance_nex_reload_time + 1;
+ ATTACK_FINISHED(self) = t;
+
+ weapon_thinkf(WFRAME_RELOAD, autocvar_g_balance_nex_reload_time, W_Nex_ReloadedAndReady);
+
+ self.old_clip_load = self.clip_load;
+ self.clip_load = -1;
+}
+
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 this weapon is reloadable, decrease its load. Else decrease the player's ammo
if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_cells = self.ammo_cells - myammo;
+ {
+ if(autocvar_g_balance_nex_reload_ammo)
+ {
+ self.clip_load -= myammo;
+ self.nex_load = self.clip_load;
+ }
+ else
+ self.ammo_cells -= myammo;
+ }
}
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
+ W_Nex_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.nex_load = 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");
}
else if (req == WR_SETUP)
+ {
weapon_setup(WEP_NEX);
+ W_Nex_SetAmmoCounter();
+ }
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.nex_load >= 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 += (autocvar_g_balance_nex_reload_ammo && self.nex_load >= autocvar_g_balance_nex_secondary_ammo);
+ return ammo_amount;
+ }
+ else if (req == WR_RESETPLAYER)
+ {
+ // all weapons must be fully loaded when we spawn
+ self.nex_load = autocvar_g_balance_nex_reload_ammo;
+ }
+ else if (req == WR_RELOAD)
+ {
+ W_Nex_Reload();
+ }
+
return TRUE;
};
#endif
.float porto_v_angle_held;
.vector right_vector;
+void W_Porto_SetAmmoCounter()
+{
+ // this weapon doesn't have a reload system, so always set the clip to 0 when switching to it
+ self.clip_load = self.clip_size = 0; // also keeps crosshair ammo from displaying
+}
+
void W_Porto_Success (void)
{
if(self.owner == world)
precache_sound ("porto/unsupported.wav");
}
else if (req == WR_SETUP)
+ {
weapon_setup(WEP_PORTO);
+ W_Porto_SetAmmoCounter();
+ }
else if (req == WR_RESETPLAYER)
{
self.porto_current = world;
.float rl_release;
.float rl_detonate_later;
+// weapon load persistence, for weapons that support reloading
+.float rocketlauncher_load;
+
+void W_RocketLauncher_SetAmmoCounter()
+{
+ // set clip_load to the weapon we have switched to, if the gun uses reloading
+ if(!autocvar_g_balance_rocketlauncher_reload_ammo)
+ self.clip_load = 0; // also keeps crosshair ammo from displaying
+ else
+ {
+ self.clip_load = self.rocketlauncher_load;
+ self.clip_size = autocvar_g_balance_rocketlauncher_reload_ammo; // for the crosshair ammo display
+ }
+}
+
+void W_RocketLauncher_ReloadedAndReady()
+{
+ float t;
+
+ // now 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
+ while(self.clip_load < autocvar_g_balance_rocketlauncher_reload_ammo && self.ammo_rockets) // make sure we don't add more ammo than we have
+ {
+ self.clip_load += 1;
+ self.ammo_rockets -= 1;
+ }
+ self.rocketlauncher_load = self.clip_load;
+
+ t = ATTACK_FINISHED(self) - autocvar_g_balance_rocketlauncher_reload_time - 1;
+ ATTACK_FINISHED(self) = t;
+ w_ready();
+}
+
+void W_RocketLauncher_Reload()
+{
+ // return if reloading is disabled for this weapon
+ if(!autocvar_g_balance_rocketlauncher_reload_ammo)
+ return;
+
+ if(!W_ReloadCheck(self.ammo_rockets, autocvar_g_balance_rocketlauncher_ammo))
+ return;
+
+ float t;
+
+ sound (self, CHAN_WEAPON2, "weapons/reload.wav", VOL_BASE, ATTN_NORM);
+
+ t = max(time, ATTACK_FINISHED(self)) + autocvar_g_balance_rocketlauncher_reload_time + 1;
+ ATTACK_FINISHED(self) = t;
+
+ weapon_thinkf(WFRAME_RELOAD, autocvar_g_balance_rocketlauncher_reload_time, W_RocketLauncher_ReloadedAndReady);
+
+ self.old_clip_load = self.clip_load;
+ self.clip_load = -1;
+}
+
void W_Rocket_Unregister()
{
if(self.owner && self.owner.lastrocket == self)
local entity missile;
local entity flash;
+ // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_rockets = self.ammo_rockets - autocvar_g_balance_rocketlauncher_ammo;
+ {
+ if(autocvar_g_balance_rocketlauncher_reload_ammo)
+ {
+ self.clip_load -= autocvar_g_balance_rocketlauncher_ammo;
+ self.rocketlauncher_load = self.clip_load;
+ }
+ else
+ self.ammo_rockets -= autocvar_g_balance_rocketlauncher_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
+ W_RocketLauncher_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");
}
else if (req == WR_SETUP)
{
weapon_setup(WEP_ROCKET_LAUNCHER);
+ W_RocketLauncher_SetAmmoCounter();
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(self.ammo_rockets < autocvar_g_balance_rocketlauncher_ammo)
+ ammo_amount = FALSE;
+ if(autocvar_g_balance_electro_reload_ammo && self.minelayer_load < autocvar_g_balance_rocketlauncher_ammo)
+ ammo_amount = FALSE;
+ }
+ return ammo_amount;
}
else if (req == WR_CHECKAMMO2)
return FALSE;
else if (req == WR_RESETPLAYER)
{
self.rl_release = 0;
+
+ // all weapons must be fully loaded when we spawn
+ self.rocketlauncher_load = autocvar_g_balance_rocketlauncher_reload_ammo;
+ }
+ else if (req == WR_RELOAD)
+ {
+ W_RocketLauncher_Reload();
}
return TRUE;
};
//.float proxytime; = autoswitch
//.float tl; = wait
+// weapon load persistence, for weapons that support reloading
+.float seeker_load;
+
+void W_Seeker_SetAmmoCounter()
+{
+ // set clip_load to the weapon we have switched to, if the gun uses reloading
+ if(!autocvar_g_balance_seeker_reload_ammo)
+ self.clip_load = 0; // also keeps crosshair ammo from displaying
+ else
+ {
+ self.clip_load = self.seeker_load;
+ self.clip_size = autocvar_g_balance_seeker_reload_ammo; // for the crosshair ammo display
+ }
+}
+
+void W_Seeker_ReloadedAndReady()
+{
+ float t;
+
+ // now 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
+ while(self.clip_load < autocvar_g_balance_seeker_reload_ammo && self.ammo_rockets) // make sure we don't add more ammo than we have
+ {
+ self.clip_load += 1;
+ self.ammo_rockets -= 1;
+ }
+ self.seeker_load = self.clip_load;
+
+ t = ATTACK_FINISHED(self) - autocvar_g_balance_seeker_reload_time - 1;
+ ATTACK_FINISHED(self) = t;
+ w_ready();
+}
+
+void W_Seeker_Reload()
+{
+ // return if reloading is disabled for this weapon
+ if(!autocvar_g_balance_seeker_reload_ammo)
+ return;
+
+ if(!W_ReloadCheck(self.ammo_rockets, min(autocvar_g_balance_seeker_missile_ammo, autocvar_g_balance_seeker_tag_ammo)))
+ return;
+
+ float t;
+
+ sound (self, CHAN_WEAPON2, "weapons/reload.wav", VOL_BASE, ATTN_NORM);
+
+ t = max(time, ATTACK_FINISHED(self)) + autocvar_g_balance_seeker_reload_time + 1;
+ ATTACK_FINISHED(self) = t;
+
+ weapon_thinkf(WFRAME_RELOAD, autocvar_g_balance_seeker_reload_time, W_Seeker_ReloadedAndReady);
+
+ self.old_clip_load = self.clip_load;
+ self.clip_load = -1;
+}
+
void Seeker_Missile_Explode ()
{
self.event_damage = SUB_Null;
{
local entity missile;
+ // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_rockets = self.ammo_rockets - autocvar_g_balance_seeker_missile_ammo;
+ {
+ if(autocvar_g_balance_seeker_reload_ammo)
+ {
+ self.clip_load -= autocvar_g_balance_seeker_missile_ammo;
+ self.seeker_load = self.clip_load;
+ }
+ else
+ self.ammo_rockets -= autocvar_g_balance_seeker_missile_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 this weapon is reloadable, decrease its load. Else decrease the player's ammo
if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_rockets = self.ammo_rockets - autocvar_g_balance_seeker_tag_ammo;
+ {
+ if(autocvar_g_balance_seeker_reload_ammo)
+ {
+ self.clip_load -= autocvar_g_balance_seeker_tag_ammo;
+ self.seeker_load = self.clip_load;
+ }
+ else
+ self.ammo_rockets -= autocvar_g_balance_seeker_tag_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 this weapon is reloadable, decrease its load. Else decrease the player's ammo
if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_rockets = self.ammo_rockets - autocvar_g_balance_seeker_flac_ammo;
+ {
+ if(autocvar_g_balance_seeker_reload_ammo)
+ {
+ self.clip_load -= autocvar_g_balance_seeker_flac_ammo;
+ self.seeker_load = self.clip_load;
+ }
+ else
+ self.ammo_rockets -= autocvar_g_balance_seeker_flac_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
+ W_Seeker_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");
}
else if (req == WR_SETUP)
+ {
weapon_setup(WEP_SEEKER);
+ W_Seeker_SetAmmoCounter();
+ }
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 += (autocvar_g_balance_seeker_reload_ammo && self.seeker_load >= 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 += (autocvar_g_balance_seeker_reload_ammo && self.seeker_load >= autocvar_g_balance_seeker_flac_ammo);
+ return ammo_amount;
+ }
+ else if (req == WR_RESETPLAYER)
+ {
+ // all weapons must be fully loaded when we spawn
+ self.seeker_load = autocvar_g_balance_seeker_reload_ammo;
+ }
+ else if (req == WR_RELOAD)
+ {
+ W_Seeker_Reload();
+ }
return TRUE;
};
#endif
REGISTER_WEAPON(SHOTGUN, w_shotgun, IT_SHELLS, 2, WEP_FLAG_NORMAL | WEP_TYPE_HITSCAN, BOT_PICKUP_RATING_LOW, "shotgun", "shotgun", _("Shotgun"))
#else
#ifdef SVQC
+
+// weapon load persistence, for weapons that support reloading
+.float shotgun_load;
+
+void W_Shotgun_SetAmmoCounter()
+{
+ // set clip_load to the weapon we have switched to, if the gun uses reloading
+ if(!autocvar_g_balance_shotgun_reload_ammo)
+ self.clip_load = 0; // also keeps crosshair ammo from displaying
+ else
+ {
+ self.clip_load = self.shotgun_load;
+ self.clip_size = autocvar_g_balance_shotgun_reload_ammo; // for the crosshair ammo display
+ }
+}
+
+void W_Shotgun_ReloadedAndReady()
+{
+ float t;
+
+ // now 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
+ while(self.clip_load < autocvar_g_balance_shotgun_reload_ammo && self.ammo_shells) // make sure we don't add more ammo than we have
+ {
+ self.clip_load += 1;
+ self.ammo_shells -= 1;
+ }
+ self.shotgun_load = self.clip_load;
+
+ t = ATTACK_FINISHED(self) - autocvar_g_balance_shotgun_reload_time - 1;
+ ATTACK_FINISHED(self) = t;
+ w_ready();
+}
+
+void W_Shotgun_Reload()
+{
+ // return if reloading is disabled for this weapon
+ if(!autocvar_g_balance_shotgun_reload_ammo)
+ return;
+
+ if(!W_ReloadCheck(self.ammo_shells, autocvar_g_balance_shotgun_primary_ammo))
+ return;
+
+ float t;
+
+ sound (self, CHAN_WEAPON2, "weapons/reload.wav", VOL_BASE, ATTN_NORM);
+
+ t = max(time, ATTACK_FINISHED(self)) + autocvar_g_balance_shotgun_reload_time + 1;
+ ATTACK_FINISHED(self) = t;
+
+ weapon_thinkf(WFRAME_RELOAD, autocvar_g_balance_shotgun_reload_time, W_Shotgun_ReloadedAndReady);
+
+ self.old_clip_load = self.clip_load;
+ self.clip_load = -1;
+}
+
void W_Shotgun_Attack (void)
{
float sc;
bulletspeed = autocvar_g_balance_shotgun_primary_speed;
bulletconstant = autocvar_g_balance_shotgun_primary_bulletconstant;
+ // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
+ if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
+ {
+ if(autocvar_g_balance_shotgun_reload_ammo)
+ {
+ self.clip_load -= ammoamount;
+ self.shotgun_load = self.clip_load;
+ }
+ else
+ self.ammo_shells -= ammoamount;
+ }
+
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
+ W_Shotgun_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.BUTTON_ATCK2 && autocvar_g_balance_shotgun_secondary)
- if (weapon_prepareattack(1, autocvar_g_balance_shotgun_secondary_refire))
- {
- // attempt forcing playback of the anim by switching to another anim (that we never play) here...
- weapon_thinkf(WFRAME_FIRE1, 0, W_Shotgun_Attack2);
+ if (self.BUTTON_ATCK2 && autocvar_g_balance_shotgun_secondary)
+ if (weapon_prepareattack(1, autocvar_g_balance_shotgun_secondary_refire))
+ {
+ // attempt forcing playback of the anim by switching to another anim (that we never play) here...
+ weapon_thinkf(WFRAME_FIRE1, 0, W_Shotgun_Attack2);
+ }
}
}
else if (req == WR_PRECACHE)
precache_sound ("misc/itempickup.wav");
precache_sound ("weapons/shotgun_fire.wav");
precache_sound ("weapons/shotgun_melee.wav");
+ precache_sound ("weapons/reload.wav");
}
else if (req == WR_SETUP)
+ {
weapon_setup(WEP_SHOTGUN);
+ W_Shotgun_SetAmmoCounter();
+ }
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 += (autocvar_g_balance_shotgun_reload_ammo && self.shotgun_load >= 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_RESETPLAYER)
+ {
+ // all weapons must be fully loaded when we spawn
+ self.shotgun_load = autocvar_g_balance_shotgun_reload_ammo;
+ }
+ else if (req == WR_RELOAD)
+ {
+ W_Shotgun_Reload();
+ }
return TRUE;
};
#endif
.float sniperrifle_accumulator;
-float W_SniperRifle_CheckMaxBullets(float checkammo)
+// weapon load persistence, for weapons that support reloading
+.float sniperrifle_load;
+
+void W_SniperRifle_SetAmmoCounter()
{
- 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);
+ // set clip_load to the weapon we have switched to, if the gun uses reloading
+ if(!autocvar_g_balance_sniperrifle_reload_ammo)
+ self.clip_load = 0; // also keeps crosshair ammo from displaying
+ else
+ {
+ self.clip_load = self.sniperrifle_load;
+ self.clip_size = autocvar_g_balance_sniperrifle_reload_ammo; // for the crosshair ammo display
+ }
}
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;
+
+ // now 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
+ while(self.clip_load < autocvar_g_balance_sniperrifle_reload_ammo && self.ammo_nails) // make sure we don't add more ammo than we have
+ {
+ self.clip_load += 1;
+ self.ammo_nails -= 1;
+ }
+ self.sniperrifle_load = self.clip_load;
+
+ t = ATTACK_FINISHED(self) - autocvar_g_balance_sniperrifle_reload_time - 1;
ATTACK_FINISHED(self) = t;
w_ready();
}
-float W_SniperRifle_Reload()
+void W_SniperRifle_Reload()
{
- float t;
+ // return if reloading is disabled for this weapon
+ if(!autocvar_g_balance_sniperrifle_reload_ammo)
+ return;
- W_SniperRifle_CheckMaxBullets(TRUE);
+ if(!W_ReloadCheck(self.ammo_nails, min(autocvar_g_balance_sniperrifle_primary_ammo, autocvar_g_balance_sniperrifle_secondary_ammo)))
+ return;
- 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;
- }
+ float t;
- sound (self, CHAN_WEAPON2, "weapons/campingrifle_reload.wav", VOL_BASE, ATTN_NORM);
+ sound (self, CHAN_WEAPON2, "weapons/reload.wav", VOL_BASE, ATTN_NORM);
- t = max(time, ATTACK_FINISHED(self)) + autocvar_g_balance_sniperrifle_reloadtime + 1;
+ t = max(time, ATTACK_FINISHED(self)) + autocvar_g_balance_sniperrifle_reload_time + 1;
ATTACK_FINISHED(self) = t;
- weapon_thinkf(WFRAME_RELOAD, autocvar_g_balance_sniperrifle_reloadtime, W_SniperRifle_ReloadedAndReady);
-
- self.sniperrifle_bulletcounter = -1;
-
- return 1;
-}
+ weapon_thinkf(WFRAME_RELOAD, autocvar_g_balance_sniperrifle_reload_time, W_SniperRifle_ReloadedAndReady);
-void W_SniperRifle_CheckReloadAndReady()
-{
- w_ready();
- if(self.sniperrifle_bulletcounter <= 0)
- if(W_SniperRifle_Reload())
- return;
+ self.old_clip_load = self.clip_load;
+ self.clip_load = -1;
}
void W_SniperRifle_FireBullet(float pSpread, float pDamage, float pHeadshotAddedDamage, float pForce, float pSpeed, float pLifetime, float pAmmo, float deathtype, float pBulletConstant)
{
+ // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
- self.ammo_nails -= pAmmo;
+ {
+ if(autocvar_g_balance_sniperrifle_reload_ammo)
+ {
+ self.clip_load -= pAmmo;
+ self.sniperrifle_load = self.clip_load;
+ }
+ else
+ self.ammo_nails -= pAmmo;
+ }
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
+ W_SniperRifle_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;
+ W_SniperRifle_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");
}
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;
+ W_SniperRifle_SetAmmoCounter();
}
else if (req == WR_CHECKAMMO1)
- return self.ammo_nails >= autocvar_g_balance_sniperrifle_primary_ammo;
+ {
+ ammo_amount = self.ammo_cells >= autocvar_g_balance_sniperrifle_primary_ammo;
+ ammo_amount += (autocvar_g_balance_sniperrifle_reload_ammo && self.sniperrifle_load >= 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_cells >= autocvar_g_balance_sniperrifle_secondary_ammo;
+ ammo_amount += (autocvar_g_balance_sniperrifle_reload_ammo && self.sniperrifle_load >= 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);
+
+ // all weapons must be fully loaded when we spawn
+ self.sniperrifle_load = autocvar_g_balance_sniperrifle_reload_ammo;
+ }
+ else if (req == WR_RELOAD)
+ {
+ W_SniperRifle_Reload();
}
return TRUE;
};
.entity tuba_note;
.float tuba_smoketime;
+void W_Tuba_SetAmmoCounter()
+{
+ // this weapon doesn't have a reload system, so always set the clip to 0 when switching to it
+ self.clip_load = self.clip_size = 0; // also keeps crosshair ammo from displaying
+}
+
float Tuba_GetNote(entity pl, float hittype)
{
float note;
// precache_sound(TUBA_NOTE(i));
}
else if (req == WR_SETUP)
+ {
weapon_setup(WEP_TUBA);
+ W_Porto_SetAmmoCounter();
+ }
else if (req == WR_CHECKAMMO1)
return TRUE; // TODO use fuel?
else if (req == WR_CHECKAMMO2)
#else
#ifdef SVQC
+// weapon load persistence, for weapons that support reloading
+.float uzi_load;
+
+void W_UZI_SetAmmoCounter()
+{
+ // set clip_load to the weapon we have switched to, if the gun uses reloading
+ if(!autocvar_g_balance_uzi_reload_ammo)
+ self.clip_load = 0; // also keeps crosshair ammo from displaying
+ else
+ {
+ self.clip_load = self.uzi_load;
+ self.clip_size = autocvar_g_balance_uzi_reload_ammo; // for the crosshair ammo display
+ }
+}
+
+void W_UZI_ReloadedAndReady()
+{
+ float t;
+
+ // now 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
+ while(self.clip_load < autocvar_g_balance_uzi_reload_ammo && self.ammo_nails) // make sure we don't add more ammo than we have
+ {
+ self.clip_load += 1;
+ self.ammo_nails -= 1;
+ }
+ self.uzi_load = self.clip_load;
+
+ t = ATTACK_FINISHED(self) - autocvar_g_balance_uzi_reload_time - 1;
+ ATTACK_FINISHED(self) = t;
+ w_ready();
+}
+
+void W_UZI_Reload()
+{
+ // return if reloading is disabled for this weapon
+ if(!autocvar_g_balance_uzi_reload_ammo)
+ return;
+
+ if(!W_ReloadCheck(self.ammo_nails, min(max(autocvar_g_balance_uzi_sustained_ammo, autocvar_g_balance_uzi_first_ammo), autocvar_g_balance_uzi_burst_ammo)))
+ return;
+
+ float t;
+
+ sound (self, CHAN_WEAPON2, "weapons/reload.wav", VOL_BASE, ATTN_NORM);
+
+ t = max(time, ATTACK_FINISHED(self)) + autocvar_g_balance_uzi_reload_time + 1;
+ ATTACK_FINISHED(self) = t;
+
+ weapon_thinkf(WFRAME_RELOAD, autocvar_g_balance_uzi_reload_time, W_UZI_ReloadedAndReady);
+
+ self.old_clip_load = self.clip_load;
+ self.clip_load = -1;
+}
+
// 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 this weapon is reloadable, decrease its load. Else decrease the player's ammo
+ if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
+ {
+ if(autocvar_g_balance_uzi_reload_ammo)
+ {
+ if (self.misc_bulletcounter == 1)
+ self.clip_load -= autocvar_g_balance_uzi_first_ammo;
+ else
+ self.clip_load -= autocvar_g_balance_uzi_sustained_ammo;
+ self.uzi_load = self.clip_load;
+ }
+ else
+ {
+ if (self.misc_bulletcounter == 1)
+ self.ammo_nails -= autocvar_g_balance_uzi_first_ammo;
+ else
+ self.ammo_nails -= autocvar_g_balance_uzi_sustained_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;
+
+ // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
+ if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
+ {
+ if(autocvar_g_balance_uzi_reload_ammo)
+ {
+ self.clip_load -= autocvar_g_balance_uzi_sustained_ammo;
+ self.uzi_load = self.clip_load;
+ }
+ else
+ self.ammo_nails -= autocvar_g_balance_uzi_sustained_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
+ W_UZI_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;
+
+ // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
+ if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
+ {
+ if(autocvar_g_balance_uzi_reload_ammo)
+ {
+ self.clip_load -= autocvar_g_balance_uzi_burst_ammo;
+ self.uzi_load = self.clip_load;
+ }
+ else
+ self.ammo_nails -= autocvar_g_balance_uzi_burst_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");
}
else if (req == WR_SETUP)
+ {
weapon_setup(WEP_UZI);
+ W_UZI_SetAmmoCounter();
+ }
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.uzi_load >= autocvar_g_balance_uzi_sustained_ammo;
+ else
+ ammo_amount += self.uzi_load >= 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.uzi_load >= autocvar_g_balance_uzi_burst_ammo;
+ else
+ ammo_amount += self.uzi_load >= autocvar_g_balance_uzi_first_ammo;
+ }
+ return ammo_amount;
+ }
+ else if (req == WR_RESETPLAYER)
+ {
+ // all weapons must be fully loaded when we spawn
+ self.uzi_load = autocvar_g_balance_uzi_reload_ammo;
+ }
+ else if (req == WR_RELOAD)
+ {
+ W_UZI_Reload();
+ }
return TRUE;
};
#endif