1 //Camping rifle Primary mode: manually operated bolt*, Secondary: full automatic**
2 //* Manually operating the bolt means that all the power of the gas is used to propell the bullet. In this mode the bolt is prevented from moving backwards in response to the firing of the bullet.
3 //** In fully automatic mode some of the gas is used to extract and reload the next cartrige, thus there is less power and range.
5 float W_CampingRifle_CheckMaxBullets()
8 maxbulls = cvar("g_balance_campingrifle_magazinecapacity");
9 if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
10 maxbulls = min(maxbulls, floor(self.ammo_nails / min(cvar("g_balance_campingrifle_primary_ammo"), cvar("g_balance_campingrifle_secondary_ammo"))));
11 if(self.campingrifle_bulletcounter > maxbulls)
12 self.campingrifle_bulletcounter = maxbulls;
13 return (self.campingrifle_bulletcounter == maxbulls);
16 void W_Campingrifle_ReloadedAndReady()
19 self.campingrifle_bulletcounter = cvar("g_balance_campingrifle_magazinecapacity");
20 W_CampingRifle_CheckMaxBullets();
21 t = ATTACK_FINISHED(self) - cvar("g_balance_campingrifle_reloadtime") - 1;
22 ATTACK_FINISHED(self) = t;
26 void W_Campingrifle_Reload()
30 if (self.campingrifle_bulletcounter >= cvar("g_balance_campingrifle_magazinecapacity"))
33 if(self.ammo_nails < min(cvar("g_balance_campingrifle_primary_ammo"), cvar("g_balance_campingrifle_secondary_ammo")))
35 self.campingrifle_bulletcounter = -1; // reload later
39 if (self.weaponentity)
41 if (self.weaponentity.wframe == WFRAME_RELOAD)
44 // allow to switch away while reloading, but this will cause a new reload!
45 self.weaponentity.state = WS_READY;
48 sound (self, CHAN_WEAPON2, "weapons/campingrifle_reload.wav", VOL_BASE, ATTN_NORM);
50 t = max(time, ATTACK_FINISHED(self)) + cvar("g_balance_campingrifle_reloadtime") + 1;
51 ATTACK_FINISHED(self) = t;
53 weapon_thinkf(WFRAME_RELOAD, cvar("g_balance_campingrifle_reloadtime"), W_Campingrifle_ReloadedAndReady);
55 self.campingrifle_bulletcounter = -1;
58 void W_Campingrifle_CheckReloadAndReady()
61 if (self.campingrifle_bulletcounter <= 0)
62 W_Campingrifle_Reload();
67 void W_CampingRifle_FireBullet(float pSpread, float pDamage, float pHeadshotAddedDamage, float pForce, float pSpeed, float pLifetime, float pAmmo, float deathtype, float pBulletConstant)
69 if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
70 self.ammo_nails -= pAmmo;
72 if(deathtype & HITTYPE_SECONDARY)
73 W_SetupShot (self, cvar("g_antilag_bullets") && pSpeed >= cvar("g_antilag_bullets"), 2, "weapons/campingrifle_fire2.wav", cvar("g_balance_campingrifle_secondary_damage"));
75 W_SetupShot (self, cvar("g_antilag_bullets") && pSpeed >= cvar("g_antilag_bullets"), 2, "weapons/campingrifle_fire.wav", cvar("g_balance_campingrifle_primary_damage"));
77 pointparticles(particleeffectnum("shotgun_muzzleflash"), w_shotorg, w_shotdir * 2000, 1);
79 if(self.BUTTON_ZOOM) // if zoomed, shoot from the eye
81 w_shotdir = v_forward;
82 w_shotorg = self.origin + self.view_ofs + ((w_shotorg - self.origin - self.view_ofs) * v_forward) * v_forward;
85 fireBallisticBullet(w_shotorg, w_shotdir, pSpread, pSpeed, pLifetime, pDamage, pHeadshotAddedDamage / pDamage, pForce, deathtype, EF_RED, 1, pBulletConstant);
87 if (cvar("g_casings") >= 2)
88 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);
90 self.campingrifle_bulletcounter = self.campingrifle_bulletcounter - 1;
93 void W_Campingrifle_Attack()
95 W_CampingRifle_FireBullet(cvar("g_balance_campingrifle_primary_spread"), cvar("g_balance_campingrifle_primary_damage"), cvar("g_balance_campingrifle_primary_headshotaddeddamage"), cvar("g_balance_campingrifle_primary_force"), cvar("g_balance_campingrifle_primary_speed"), cvar("g_balance_campingrifle_primary_lifetime"), cvar("g_balance_campingrifle_primary_ammo"), WEP_CAMPINGRIFLE, cvar("g_balance_campingrifle_primary_bulletconstant"));
98 void W_Campingrifle_Attack2()
100 W_CampingRifle_FireBullet(cvar("g_balance_campingrifle_secondary_spread"), cvar("g_balance_campingrifle_secondary_damage"), cvar("g_balance_campingrifle_secondary_headshotaddeddamage"), cvar("g_balance_campingrifle_secondary_force"), cvar("g_balance_campingrifle_secondary_speed"), cvar("g_balance_campingrifle_secondary_lifetime"), cvar("g_balance_campingrifle_secondary_ammo"), WEP_CAMPINGRIFLE | HITTYPE_SECONDARY, cvar("g_balance_campingrifle_secondary_bulletconstant"));
103 void spawnfunc_weapon_campingrifle (void)
105 weapon_defaultspawnfunc(WEP_CAMPINGRIFLE);
108 .float bot_secondary_campingriflemooth;
109 float w_campingrifle(float req)
114 self.BUTTON_ATCK=FALSE;
115 self.BUTTON_ATCK2=FALSE;
116 if(vlen(self.origin-self.enemy.origin) > 1000)
117 self.bot_secondary_campingriflemooth = 0;
118 if(self.bot_secondary_campingriflemooth == 0)
120 if(bot_aim(cvar("g_balance_campingrifle_primary_speed"), 0, cvar("g_balance_campingrifle_primary_lifetime"), TRUE))
122 self.BUTTON_ATCK = TRUE;
123 if(random() < 0.01) self.bot_secondary_campingriflemooth = 1;
128 if(bot_aim(cvar("g_balance_campingrifle_secondary_speed"), 0, cvar("g_balance_campingrifle_secondary_lifetime"), TRUE))
130 self.BUTTON_ATCK2 = TRUE;
131 if(random() < 0.03) self.bot_secondary_campingriflemooth = 0;
135 else if (req == WR_THINK)
137 if(self.campingrifle_bulletcounter < 0) // forced reload (e.g. because interrupted)
139 if(self.switchweapon == self.weapon)
140 if(self.weaponentity.state == WS_READY)
141 W_Campingrifle_Reload();
145 if (self.BUTTON_ATCK)
146 if (weapon_prepareattack(0, cvar("g_balance_campingrifle_primary_refire")))
148 W_Campingrifle_Attack();
149 weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_campingrifle_primary_animtime"), W_Campingrifle_CheckReloadAndReady);
151 if (self.BUTTON_ATCK2)
152 if (weapon_prepareattack(1, cvar("g_balance_campingrifle_secondary_refire")))
154 W_Campingrifle_Attack2();
155 weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_campingrifle_secondary_animtime"), W_Campingrifle_CheckReloadAndReady);
159 else if (req == WR_PRECACHE)
161 precache_model ("models/weapons/g_campingrifle.md3");
162 precache_model ("models/weapons/v_campingrifle.md3");
163 precache_model ("models/weapons/h_campingrifle.dpm");
164 precache_sound ("weapons/campingrifle_reload.wav");
165 precache_sound ("weapons/campingrifle_fire.wav");
166 precache_sound ("weapons/campingrifle_fire2.wav");
168 else if (req == WR_SETUP)
170 weapon_setup(WEP_CAMPINGRIFLE);
172 full = W_CampingRifle_CheckMaxBullets();
173 if(cvar("g_balance_campingrifle_auto_reload_after_changing_weapons"))
175 self.campingrifle_bulletcounter = -1;
177 else if (req == WR_CHECKAMMO1)
178 return self.ammo_nails >= cvar("g_balance_campingrifle_primary_ammo");
179 else if (req == WR_CHECKAMMO2)
180 return self.ammo_nails >= cvar("g_balance_campingrifle_secondary_ammo");
181 else if (req == WR_SUICIDEMESSAGE)
183 if(w_deathtype & HITTYPE_SECONDARY)
184 w_deathtypestring = "shot himself automatically";
186 w_deathtypestring = "sniped himself somehow";
188 else if (req == WR_KILLMESSAGE)
190 if(w_deathtype & HITTYPE_SECONDARY)
192 if(w_deathtype & HITTYPE_BOUNCE)
193 w_deathtypestring = "failed to hide from #'s bullet hail";
195 w_deathtypestring = "died in #'s bullet hail";
199 if(w_deathtype & HITTYPE_BOUNCE)
201 // TODO special headshot message here too?
202 w_deathtypestring = "failed to hide from #'s rifle";
206 if(w_deathtype & HITTYPE_HEADSHOT)
207 w_deathtypestring = "got hit in the head by #";
209 w_deathtypestring = "was sniped by #";
213 else if (req == WR_RELOAD)
215 W_Campingrifle_Reload();