2 REGISTER_WEAPON(NEX, w_nex, IT_CELLS, 7, WEP_FLAG_NORMAL | WEP_TYPE_HITSCAN, BOT_PICKUP_RATING_HIGH, "nex", "nex", _("Nex"))
6 void W_Nex_SetAmmoCounter()
8 // set clip_load to the weapon we have switched to, if the gun uses reloading
9 if(!autocvar_g_balance_nex_reload_ammo)
10 self.clip_load = 0; // also keeps crosshair ammo from displaying
13 self.clip_load = self.weapon_load[WEP_NEX];
14 self.clip_size = autocvar_g_balance_nex_reload_ammo; // for the crosshair ammo display
20 self.reload_ammo_player = ammo_cells;
21 self.reload_ammo_min = min(autocvar_g_balance_nex_primary_ammo, autocvar_g_balance_nex_secondary_ammo);
22 self.reload_ammo_amount = autocvar_g_balance_nex_reload_ammo;
23 self.reload_time = autocvar_g_balance_nex_reload_time;
24 self.reload_sound = "weapons/reload.wav";
29 void SendCSQCNexBeamParticle(float charge) {
31 v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
32 WriteByte(MSG_BROADCAST, SVC_TEMPENTITY);
33 WriteByte(MSG_BROADCAST, TE_CSQC_NEXGUNBEAMPARTICLE);
34 WriteCoord(MSG_BROADCAST, w_shotorg_x);
35 WriteCoord(MSG_BROADCAST, w_shotorg_y);
36 WriteCoord(MSG_BROADCAST, w_shotorg_z);
37 WriteCoord(MSG_BROADCAST, v_x);
38 WriteCoord(MSG_BROADCAST, v_y);
39 WriteCoord(MSG_BROADCAST, v_z);
40 WriteByte(MSG_BROADCAST, bound(0, 255 * charge, 255));
43 void W_Nex_Attack (float issecondary)
45 float mydmg, myforce, mymindist, mymaxdist, myhalflife, myforcehalflife, myammo, charge;
48 mydmg = autocvar_g_balance_nex_secondary_damage;
49 myforce = autocvar_g_balance_nex_secondary_force;
50 mymindist = autocvar_g_balance_nex_secondary_damagefalloff_mindist;
51 mymaxdist = autocvar_g_balance_nex_secondary_damagefalloff_maxdist;
52 myhalflife = autocvar_g_balance_nex_secondary_damagefalloff_halflife;
53 myforcehalflife = autocvar_g_balance_nex_secondary_damagefalloff_forcehalflife;
54 myammo = autocvar_g_balance_nex_secondary_ammo;
58 mydmg = autocvar_g_balance_nex_primary_damage;
59 myforce = autocvar_g_balance_nex_primary_force;
60 mymindist = autocvar_g_balance_nex_primary_damagefalloff_mindist;
61 mymaxdist = autocvar_g_balance_nex_primary_damagefalloff_maxdist;
62 myhalflife = autocvar_g_balance_nex_primary_damagefalloff_halflife;
63 myforcehalflife = autocvar_g_balance_nex_primary_damagefalloff_forcehalflife;
64 myammo = autocvar_g_balance_nex_primary_ammo;
68 flying = IsFlying(self); // do this BEFORE to make the trace values from FireRailgunBullet last
70 if(autocvar_g_balance_nex_charge)
72 charge = autocvar_g_balance_nex_charge_mindmg / mydmg + (1 - autocvar_g_balance_nex_charge_mindmg / mydmg) * self.nex_charge;
73 self.nex_charge *= autocvar_g_balance_nex_charge_shot_multiplier; // do this AFTER setting mydmg/myforce
74 // O RLY? -- divVerent
82 W_SetupShot (self, TRUE, 5, "weapons/nexfire.wav", CHAN_WEAPON, mydmg);
83 if(charge > autocvar_g_balance_nex_charge_limit && autocvar_g_balance_nex_charge_limit) // if the Nex is overcharged, we play an extra sound
85 sound (self, CHAN_WEAPON2, "weapons/nexcharge.wav", VOL_BASE * (charge - 0.5 * autocvar_g_balance_nex_charge_limit) / (1 - 0.5 * autocvar_g_balance_nex_charge_limit), ATTN_NORM);
89 FireRailgunBullet (w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, mydmg, myforce, mymindist, mymaxdist, myhalflife, myforcehalflife, WEP_NEX);
92 AnnounceTo(self, "yoda");
94 //beam and muzzle flash done on client
95 SendCSQCNexBeamParticle(charge);
97 // flash and burn the wall
98 if (trace_ent.solid == SOLID_BSP && !(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT))
99 Damage_DamageInfo(trace_endpos, mydmg, 0, 0, myforce * w_shotdir, WEP_NEX, self);
101 // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
102 if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
104 if(autocvar_g_balance_nex_reload_ammo)
106 self.clip_load -= myammo;
107 self.weapon_load[WEP_NEX] = self.clip_load;
110 self.ammo_cells -= myammo;
114 void spawnfunc_weapon_nex (void); // defined in t_items.qc
116 .float nex_chargepool_pauseregen_finished;
117 float w_nex(float req)
123 self.BUTTON_ATCK = bot_aim(1000000, 0, 1, FALSE);
124 self.BUTTON_ATCK2 = bot_aim(1000000, 0, 1, FALSE);
126 else if (req == WR_THINK)
128 if(autocvar_g_balance_nex_charge && self.nex_charge < autocvar_g_balance_nex_charge_limit)
129 self.nex_charge = min(1, self.nex_charge + autocvar_g_balance_nex_charge_rate * frametime / W_TICSPERFRAME);
131 if(autocvar_g_balance_nex_secondary_chargepool)
132 if(self.nex_chargepool_ammo < 1)
134 if(self.nex_chargepool_pauseregen_finished < time)
135 self.nex_chargepool_ammo = min(1, self.nex_chargepool_ammo + autocvar_g_balance_nex_secondary_chargepool_regen * frametime / W_TICSPERFRAME);
136 self.pauseregen_finished = max(self.pauseregen_finished, time + autocvar_g_balance_nex_secondary_chargepool_pause_health_regen);
139 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
143 if (self.BUTTON_ATCK)
145 if (weapon_prepareattack(0, autocvar_g_balance_nex_primary_refire))
148 weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_nex_primary_animtime, w_ready);
151 if ((autocvar_g_balance_nex_secondary_charge && !autocvar_g_balance_nex_secondary) ? self.BUTTON_ZOOM : self.BUTTON_ATCK2)
153 if(autocvar_g_balance_nex_secondary_charge)
155 self.nex_charge_rottime = time + autocvar_g_balance_nex_charge_rot_pause;
156 dt = frametime / W_TICSPERFRAME;
158 if(self.nex_charge < 1)
160 if(autocvar_g_balance_nex_secondary_chargepool)
162 if(autocvar_g_balance_nex_secondary_ammo)
164 // always deplete if secondary is held
165 self.nex_chargepool_ammo = max(0, self.nex_chargepool_ammo - autocvar_g_balance_nex_secondary_ammo * dt);
167 dt = min(dt, (1 - self.nex_charge) / autocvar_g_balance_nex_secondary_charge_rate);
168 self.nex_chargepool_pauseregen_finished = time + autocvar_g_balance_nex_secondary_chargepool_pause_regen;
169 dt = min(dt, self.nex_chargepool_ammo);
172 self.nex_charge += dt * autocvar_g_balance_nex_secondary_charge_rate;
176 else if(autocvar_g_balance_nex_secondary_ammo)
178 if(self.BUTTON_ATCK2) // only eat ammo when the button is pressed
180 dt = min(dt, (1 - self.nex_charge) / autocvar_g_balance_nex_secondary_charge_rate);
181 if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
183 // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
184 if(autocvar_g_balance_nex_reload_ammo)
186 dt = min(dt, (self.clip_load - autocvar_g_balance_nex_primary_ammo) / autocvar_g_balance_nex_secondary_ammo);
190 self.clip_load = max(autocvar_g_balance_nex_secondary_ammo, self.clip_load - autocvar_g_balance_nex_secondary_ammo * dt);
192 self.weapon_load[WEP_NEX] = self.clip_load;
196 dt = min(dt, (self.ammo_cells - autocvar_g_balance_nex_primary_ammo) / autocvar_g_balance_nex_secondary_ammo);
200 self.ammo_cells = max(autocvar_g_balance_nex_secondary_ammo, self.ammo_cells - autocvar_g_balance_nex_secondary_ammo * dt);
204 self.nex_charge += dt * autocvar_g_balance_nex_secondary_charge_rate;
210 dt = min(dt, (1 - self.nex_charge) / autocvar_g_balance_nex_secondary_charge_rate);
211 self.nex_charge += dt * autocvar_g_balance_nex_secondary_charge_rate;
215 else if(autocvar_g_balance_nex_secondary)
217 if (weapon_prepareattack(0, autocvar_g_balance_nex_secondary_refire))
220 weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_nex_secondary_animtime, w_ready);
226 if(autocvar_g_balance_nex_charge)
228 self.weaponentity_glowmod_x = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_red_half * min(1, self.nex_charge / autocvar_g_balance_nex_charge_limit);
229 self.weaponentity_glowmod_y = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_green_half * min(1, self.nex_charge / autocvar_g_balance_nex_charge_limit);
230 self.weaponentity_glowmod_z = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_blue_half * min(1, self.nex_charge / autocvar_g_balance_nex_charge_limit);
232 if(self.nex_charge > autocvar_g_balance_nex_charge_limit)
234 self.weaponentity_glowmod_x = self.weaponentity_glowmod_x + autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_red_full * (self.nex_charge - autocvar_g_balance_nex_charge_limit) / (1 - autocvar_g_balance_nex_charge_limit);
235 self.weaponentity_glowmod_y = self.weaponentity_glowmod_y + autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_green_full * (self.nex_charge - autocvar_g_balance_nex_charge_limit) / (1 - autocvar_g_balance_nex_charge_limit);
236 self.weaponentity_glowmod_z = self.weaponentity_glowmod_z + autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_blue_full * (self.nex_charge - autocvar_g_balance_nex_charge_limit) / (1 - autocvar_g_balance_nex_charge_limit);
240 else if (req == WR_PRECACHE)
242 precache_model ("models/nexflash.md3");
243 precache_model ("models/weapons/g_nex.md3");
244 precache_model ("models/weapons/v_nex.md3");
245 precache_model ("models/weapons/h_nex.iqm");
246 precache_sound ("weapons/nexfire.wav");
247 precache_sound ("weapons/nexcharge.wav");
248 precache_sound ("weapons/nexwhoosh1.wav");
249 precache_sound ("weapons/nexwhoosh2.wav");
250 precache_sound ("weapons/nexwhoosh3.wav");
251 precache_sound ("weapons/reload.wav");
253 else if (req == WR_SETUP)
255 weapon_setup(WEP_NEX);
256 W_Nex_SetAmmoCounter();
258 else if (req == WR_CHECKAMMO1)
260 ammo_amount = self.ammo_cells >= autocvar_g_balance_nex_primary_ammo;
261 ammo_amount += (autocvar_g_balance_nex_reload_ammo && self.weapon_load[WEP_NEX] >= autocvar_g_balance_nex_primary_ammo);
264 else if (req == WR_CHECKAMMO2)
266 // don't allow charging if we don't have enough ammo
267 ammo_amount = self.ammo_cells >= autocvar_g_balance_nex_secondary_ammo;
268 ammo_amount += self.weapon_load[WEP_NEX] >= autocvar_g_balance_nex_secondary_ammo;
271 else if (req == WR_RELOAD)
280 float w_nex(float req)
282 if(req == WR_IMPACTEFFECT)
285 org2 = w_org + w_backoff * 6;
286 pointparticles(particleeffectnum("nex_impact"), org2, '0 0 0', 1);
288 sound(self, CHAN_PROJECTILE, "weapons/neximpact.wav", VOL_BASE, ATTN_NORM);
290 else if(req == WR_PRECACHE)
292 precache_sound("weapons/neximpact.wav");
294 else if (req == WR_SUICIDEMESSAGE)
295 w_deathtypestring = _("%s did the impossible");
296 else if (req == WR_KILLMESSAGE)
297 w_deathtypestring = _("%s has been vaporized by %s");