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