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