]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/w_minstanex.qc
Remove the switchable check and do all checks in the WR_CHECKAMMO checks. Only fixed...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / w_minstanex.qc
1 #ifdef REGISTER_WEAPON
2 REGISTER_WEAPON(MINSTANEX, w_minstanex, IT_CELLS, 7, WEP_FLAG_HIDDEN | WEP_FLAG_CANCLIMB | WEP_TYPE_HITSCAN, BOT_PICKUP_RATING_HIGH, "minstanex", "minstanex", _("MinstaNex"))
3 #else
4 #ifdef SVQC
5 .float minstanex_lasthit;
6
7 void W_Minstanex_SetAmmoCounter()
8 {
9         // set clip_load to the weapon we have switched to, if the gun uses reloading
10         if(!autocvar_g_balance_minstanex_reload_ammo)
11                 self.clip_load = 0; // also keeps crosshair ammo from displaying
12         else
13         {
14                 self.clip_load = self.minstanex_load;
15                 self.clip_size = autocvar_g_balance_minstanex_reload_ammo; // for the crosshair ammo display
16         }
17 }
18
19 void W_Minstanex_ReloadedAndReady()
20 {
21         float t;
22
23         // now do the ammo transfer
24         self.clip_load = self.old_clip_load; // restore the ammo counter, in case we still had ammo in the weapon before reloading
25         while(self.clip_load < autocvar_g_balance_minstanex_reload_ammo && self.ammo_cells) // make sure we don't add more ammo than we have
26         {
27                 self.clip_load += 1;
28                 self.ammo_cells -= 1;
29         }
30         self.minstanex_load = self.clip_load;
31
32         t = ATTACK_FINISHED(self) - autocvar_g_balance_minstanex_reload_time - 1;
33         ATTACK_FINISHED(self) = t;
34         w_ready();
35 }
36
37 void W_Minstanex_Reload()
38 {
39         // return if reloading is disabled for this weapon
40         if(!autocvar_g_balance_minstanex_reload_ammo)
41                 return;
42
43         if(autocvar_g_balance_minstanex_laser_ammo)
44         {
45                 if(!W_ReloadCheck(self.ammo_cells, min(autocvar_g_balance_minstanex_ammo, autocvar_g_balance_minstanex_laser_ammo)))
46                         return;
47         }
48         else if(!W_ReloadCheck(self.ammo_cells, autocvar_g_balance_minstanex_ammo))
49                 return;
50
51         float t;
52
53         sound (self, CHAN_WEAPON2, "weapons/reload.wav", VOL_BASE, ATTN_NORM);
54
55         t = max(time, ATTACK_FINISHED(self)) + autocvar_g_balance_minstanex_reload_time + 1;
56         ATTACK_FINISHED(self) = t;
57
58         weapon_thinkf(WFRAME_RELOAD, autocvar_g_balance_minstanex_reload_time, W_Minstanex_ReloadedAndReady);
59
60         self.old_clip_load = self.clip_load;
61         self.clip_load = -1;
62 }
63
64 void W_MinstaNex_Attack (void)
65 {
66         float flying;
67         flying = IsFlying(self); // do this BEFORE to make the trace values from FireRailgunBullet last
68
69         W_SetupShot (self, TRUE, 0, "weapons/minstanexfire.wav", CHAN_WEAPON, 10000);
70
71         yoda = 0;
72         damage_goodhits = 0;
73         headshot = 0;
74         FireRailgunBullet (w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, 10000, 800, 0, 0, 0, 0, WEP_MINSTANEX);
75
76         if(g_minstagib)
77         {
78                 if(yoda)
79                         AnnounceTo(self, "yoda");
80         }
81         else
82         {
83                 if(yoda && flying)
84                         AnnounceTo(self, "yoda");
85                 if(headshot)
86                 {
87                         AnnounceTo(self, "headshot");
88                 }
89                 if(damage_goodhits && self.minstanex_lasthit)
90                 {
91                         if(AnnounceTo(self, "impressive"))
92                                 damage_goodhits = 0; // only every second time
93                 }
94         }
95
96         self.minstanex_lasthit = damage_goodhits;
97
98         pointparticles(particleeffectnum("nex_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
99
100         // teamcolor / hit beam effect
101         vector v;
102         v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
103         if(teams_matter)
104         {
105             switch(self.team)
106             {
107             case COLOR_TEAM1:   // Red
108                 if(damage_goodhits)
109                     WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3RED_HIT"), w_shotorg, v);
110                 else
111                     WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3RED"), w_shotorg, v);
112                 break;
113             case COLOR_TEAM2:   // Blue
114                 if(damage_goodhits)
115                     WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3BLUE_HIT"), w_shotorg, v);
116                 else
117                     WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3BLUE"), w_shotorg, v);
118                 break;
119             case COLOR_TEAM3:   // Yellow
120                 if(damage_goodhits)
121                     WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3YELLOW_HIT"), w_shotorg, v);
122                 else
123                     WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3YELLOW"), w_shotorg, v);
124                 break;
125             case COLOR_TEAM4:   // Pink
126                 if(damage_goodhits)
127                     WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3PINK_HIT"), w_shotorg, v);
128                 else
129                     WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3PINK"), w_shotorg, v);
130                 break;
131             }
132         }
133         else
134         WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3"), w_shotorg, v);
135
136         // flash and burn the wall
137         if (trace_ent.solid == SOLID_BSP && !(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT))
138                 Damage_DamageInfo(trace_endpos, 10000, 0, 0, 800 * w_shotdir, WEP_MINSTANEX, self);
139
140         // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
141         if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
142         {
143                 if(autocvar_g_balance_minstanex_reload_ammo)
144                 {
145                         if (g_minstagib)
146                                 self.clip_load -= - 1;
147                         else
148                                 self.clip_load -= autocvar_g_balance_minstanex_ammo;
149                         self.minstanex_load = self.clip_load;
150                 }
151                 else
152                 {
153                         if (g_minstagib)
154                                 self.ammo_cells -= - 1;
155                         else
156                                 self.ammo_cells -= autocvar_g_balance_minstanex_ammo;
157                 }
158         }
159 }
160
161
162 .float minstagib_nextthink;
163 void minstagib_ammocheck (void)
164 {
165         if (time < self.minstagib_nextthink || self.deadflag || gameover)
166                 return;
167
168         if (self.ammo_cells <= 0)
169         {
170                 if (self.health == 5)
171                 {
172                         centerprint(self, "you're dead now...\n");
173                         Damage(self, self, self, 5, DEATH_NOAMMO, self.origin, '0 0 0');
174                         AnnounceTo(self, "terminated");
175                 }
176                 else if (self.health == 10)
177                 {
178                         centerprint(self, "^11^7 second left to find some ammo\n");
179                         Damage(self, self, self, 5, DEATH_NOAMMO, self.origin, '0 0 0');
180                         AnnounceTo(self, "1");
181                 }
182                 else if (self.health == 20)
183                 {
184                         centerprint(self, "^12^7 seconds left to find some ammo\n");
185                         Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
186                         AnnounceTo(self, "2");
187                 }
188                 else if (self.health == 30)
189                 {
190                         centerprint(self, "^13^7 seconds left to find some ammo\n");
191                         Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
192                         AnnounceTo(self, "3");
193                 }
194                 else if (self.health == 40)
195                 {
196                         centerprint(self, "^14^7 seconds left to find some ammo\n");
197                         Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
198                         AnnounceTo(self, "4");
199                 }
200                 else if (self.health == 50)
201                 {
202                         centerprint(self, "^15^7 seconds left to find some ammo\n");
203                         Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
204                         AnnounceTo(self, "5");
205                 }
206                 else if (self.health == 60)
207                 {
208                         centerprint(self, "^36^7 seconds left to find some ammo\n");
209                         Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
210                         AnnounceTo(self, "6");
211                 }
212                 else if (self.health == 70)
213                 {
214                         centerprint(self, "^37^7 seconds left to find some ammo\n");
215                         Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
216                         AnnounceTo(self, "7");
217                 }
218                 else if (self.health == 80)
219                 {
220                         centerprint(self, "^38^7 seconds left to find some ammo\n");
221                         Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
222                         AnnounceTo(self, "8");
223                 }
224                 else if (self.health == 90)
225                 {
226                         centerprint(self, "^39^7 seconds left to find some ammo\n");
227                         Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
228                         AnnounceTo(self, "9");
229                 }
230                 else if (self.health == 100)
231                 {
232                         centerprint(self, "get some ammo or\nyou'll be dead in ^310^7 seconds...");
233                         Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
234                         if not(self.flags & FL_GODMODE)
235                                 AnnounceTo(self, "10");
236                 }
237         }
238         self.minstagib_nextthink = time + 1;
239 }
240
241 void spawnfunc_weapon_minstanex (void); // defined in t_items.qc
242
243 float minstanex_ammo;
244 float w_minstanex(float req)
245 {
246         if (req == WR_AIM)
247         {
248                 if(self.ammo_cells > 0)
249                         self.BUTTON_ATCK = bot_aim(1000000, 0, 1, FALSE);
250                 else
251                         self.BUTTON_ATCK2 = bot_aim(autocvar_g_balance_laser_primary_speed, 0, autocvar_g_balance_laser_primary_lifetime, FALSE);
252         }
253         else if (req == WR_THINK)
254         {
255                 if(g_minstagib)
256                         minstanex_ammo = 1;
257                 else
258                         minstanex_ammo = autocvar_g_balance_minstanex_ammo;
259
260                 // if the laser uses load, we also consider its ammo for reloading
261                 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
262                         W_Minstanex_Reload();
263                 else if(autocvar_g_balance_minstanex_reload_ammo && self.clip_load < minstanex_ammo) // forced reload
264                         W_Minstanex_Reload();
265                 else if (self.BUTTON_ATCK)
266                 {
267                         if (weapon_prepareattack(0, autocvar_g_balance_minstanex_refire))
268                         {
269                                 W_MinstaNex_Attack();
270                                 weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_minstanex_animtime, w_ready);
271                         }
272                 }
273                 else if (self.BUTTON_ATCK2)
274                 {
275                         if (self.jump_interval <= time)
276                         {
277                                 self.jump_interval = time + autocvar_g_balance_laser_primary_refire * W_WeaponRateFactor();
278
279                                 // decrease ammo for the laser?
280                                 if(autocvar_g_balance_minstanex_laser_ammo)
281                                 {
282                                         if(autocvar_g_balance_minstanex_reload_ammo)
283                                                 self.clip_load -= autocvar_g_balance_minstanex_laser_ammo;
284                                         else
285                                                 self.ammo_cells -= autocvar_g_balance_minstanex_laser_ammo;
286                                 }
287
288                                 // ugly minstagib hack to reuse the fire mode of the laser
289                                 float w;
290                                 w = self.weapon;
291                                 self.weapon = WEP_LASER;
292                                 W_Laser_Attack(2);
293                                 self.weapon = w;
294                         }
295                 }
296         if(self.wish_reload)
297         {
298             if(self.switchweapon == self.weapon)
299             {
300                 if(self.weaponentity.state == WS_READY)
301                 {
302                     self.wish_reload = 0;
303                     W_Minstanex_Reload();
304                 }
305             }
306         }
307         }
308         else if (req == WR_PRECACHE)
309         {
310                 precache_model ("models/nexflash.md3");
311                 precache_model ("models/weapons/g_minstanex.md3");
312                 precache_model ("models/weapons/v_minstanex.md3");
313                 precache_model ("models/weapons/h_minstanex.iqm");
314                 precache_sound ("weapons/minstanexfire.wav");
315                 precache_sound ("weapons/nexwhoosh1.wav");
316                 precache_sound ("weapons/nexwhoosh2.wav");
317                 precache_sound ("weapons/nexwhoosh3.wav");
318                 precache_sound ("weapons/reload.wav");
319                 w_laser(WR_PRECACHE);
320         }
321         else if (req == WR_SETUP)
322         {
323                 weapon_setup(WEP_MINSTANEX);
324                 W_Minstanex_SetAmmoCounter();
325                 self.minstanex_lasthit = 0;
326         }
327         else if (req == WR_CHECKAMMO1)
328         {
329                 if(autocvar_g_balance_minstanex_reload_ammo)
330                         return self.clip_load >= minstanex_ammo;
331                 else
332                         return self.ammo_cells >= minstanex_ammo;
333         }
334         else if (req == WR_CHECKAMMO2)
335         {
336                 if(!autocvar_g_balance_minstanex_laser_ammo)
337                         return TRUE;
338                 if(autocvar_g_balance_minstanex_reload_ammo)
339                         return self.clip_load >= autocvar_g_balance_minstanex_laser_ammo;
340                 else
341                         return self.ammo_cells >= autocvar_g_balance_minstanex_laser_ammo;
342         }
343         else if (req == WR_RESETPLAYER)
344         {
345                 self.minstanex_lasthit = 0;
346         }
347         else if (req == WR_RELOAD)
348         {
349                 W_Minstanex_Reload();
350         }
351         return TRUE;
352 };
353 #endif
354 #ifdef CSQC
355 float w_minstanex(float req)
356 {
357         if(req == WR_IMPACTEFFECT)
358         {
359                 vector org2;
360                 org2 = w_org + w_backoff * 6;
361                 pointparticles(particleeffectnum("nex_impact"), org2, '0 0 0', 1);
362                 if(!w_issilent)
363                         sound(self, CHAN_PROJECTILE, "weapons/neximpact.wav", VOL_BASE, ATTN_NORM);
364         }
365         else if(req == WR_PRECACHE)
366         {
367                 precache_sound("weapons/neximpact.wav");
368         }
369         else if (req == WR_SUICIDEMESSAGE)
370                 w_deathtypestring = "%s did the impossible";
371         else if (req == WR_KILLMESSAGE)
372                 w_deathtypestring = "%s has been vaporized by %s";
373         return TRUE;
374 }
375 #endif
376 #endif