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);
86 endFireBallisticBullet();
88 if (cvar("g_casings") >= 2)
89 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);
91 self.campingrifle_bulletcounter = self.campingrifle_bulletcounter - 1;
94 void W_Campingrifle_Attack()
96 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"));
99 void W_Campingrifle_Attack2()
101 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"));
104 void spawnfunc_weapon_campingrifle (void)
106 weapon_defaultspawnfunc(WEP_CAMPINGRIFLE);
109 .float bot_secondary_campingriflemooth;
110 float w_campingrifle(float req)
115 self.BUTTON_ATCK=FALSE;
116 self.BUTTON_ATCK2=FALSE;
117 if(vlen(self.origin-self.enemy.origin) > 1000)
118 self.bot_secondary_campingriflemooth = 0;
119 if(self.bot_secondary_campingriflemooth == 0)
121 if(bot_aim(cvar("g_balance_campingrifle_primary_speed"), 0, cvar("g_balance_campingrifle_primary_lifetime"), TRUE))
123 self.BUTTON_ATCK = TRUE;
124 if(random() < 0.01) self.bot_secondary_campingriflemooth = 1;
129 if(bot_aim(cvar("g_balance_campingrifle_secondary_speed"), 0, cvar("g_balance_campingrifle_secondary_lifetime"), TRUE))
131 self.BUTTON_ATCK2 = TRUE;
132 if(random() < 0.03) self.bot_secondary_campingriflemooth = 0;
136 else if (req == WR_THINK)
138 if(self.campingrifle_bulletcounter < 0) // forced reload (e.g. because interrupted)
140 if(self.switchweapon == self.weapon)
141 if(self.weaponentity.state == WS_READY)
142 W_Campingrifle_Reload();
146 if (self.BUTTON_ATCK)
147 if (weapon_prepareattack(0, cvar("g_balance_campingrifle_primary_refire")))
149 W_Campingrifle_Attack();
150 weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_campingrifle_primary_animtime"), W_Campingrifle_CheckReloadAndReady);
152 if (self.BUTTON_ATCK2)
153 if (weapon_prepareattack(1, cvar("g_balance_campingrifle_secondary_refire")))
155 W_Campingrifle_Attack2();
156 weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_campingrifle_secondary_animtime"), W_Campingrifle_CheckReloadAndReady);
160 else if (req == WR_PRECACHE)
162 precache_model ("models/weapons/g_campingrifle.md3");
163 precache_model ("models/weapons/v_campingrifle.md3");
164 precache_model ("models/weapons/h_campingrifle.dpm");
165 precache_sound ("weapons/campingrifle_reload.wav");
166 precache_sound ("weapons/campingrifle_fire.wav");
167 precache_sound ("weapons/campingrifle_fire2.wav");
169 else if (req == WR_SETUP)
171 weapon_setup(WEP_CAMPINGRIFLE);
173 full = W_CampingRifle_CheckMaxBullets();
174 if(cvar("g_balance_campingrifle_auto_reload_after_changing_weapons"))
176 self.campingrifle_bulletcounter = -1;
178 else if (req == WR_CHECKAMMO1)
179 return self.ammo_nails >= cvar("g_balance_campingrifle_primary_ammo");
180 else if (req == WR_CHECKAMMO2)
181 return self.ammo_nails >= cvar("g_balance_campingrifle_secondary_ammo");
182 else if (req == WR_SUICIDEMESSAGE)
184 if(w_deathtype & HITTYPE_SECONDARY)
185 w_deathtypestring = "shot himself automatically";
187 w_deathtypestring = "sniped himself somehow";
189 else if (req == WR_KILLMESSAGE)
191 if(w_deathtype & HITTYPE_SECONDARY)
193 if(w_deathtype & HITTYPE_BOUNCE)
194 w_deathtypestring = "failed to hide from #'s bullet hail";
196 w_deathtypestring = "died in #'s bullet hail";
200 if(w_deathtype & HITTYPE_BOUNCE)
202 // TODO special headshot message here too?
203 w_deathtypestring = "failed to hide from #'s rifle";
207 if(w_deathtype & HITTYPE_HEADSHOT)
208 w_deathtypestring = "got hit in the head by #";
210 w_deathtypestring = "was sniped by #";
214 else if (req == WR_RELOAD)
216 W_Campingrifle_Reload();