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