]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/weapons/w_minstanex.qc
Merge remote-tracking branch 'origin/master' into samual/weapons
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / weapons / w_minstanex.qc
1 #ifdef REGISTER_WEAPON
2 REGISTER_WEAPON(
3 /* WEP_##id */ MINSTANEX,
4 /* function */ w_minstanex,
5 /* ammotype */ IT_CELLS,
6 /* impulse  */ 7,
7 /* flags    */ WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_FLAG_SUPERWEAPON | WEP_TYPE_HITSCAN,
8 /* rating   */ BOT_PICKUP_RATING_HIGH,
9 /* model    */ "minstanex",
10 /* netname  */ "minstanex",
11 /* fullname */ _("MinstaNex")
12 );
13
14 #ifdef SVQC
15 .float minstanex_lasthit;
16 .float jump_interval;
17 #endif
18 #else
19 #ifdef SVQC
20 void spawnfunc_weapon_minstanex (void) { weapon_defaultspawnfunc(WEP_MINSTANEX); }
21
22 void W_MinstaNex_Attack (void)
23 {
24         float flying;
25         flying = IsFlying(self); // do this BEFORE to make the trace values from FireRailgunBullet last
26
27         W_SetupShot (self, TRUE, 0, "weapons/minstanexfire.wav", CH_WEAPON_A, 10000);
28
29         yoda = 0;
30         damage_goodhits = 0;
31         FireRailgunBullet (w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, 10000, 800, 0, 0, 0, 0, WEP_MINSTANEX);
32
33         if(yoda && flying)
34                 Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_ACHIEVEMENT_YODA);
35         if(damage_goodhits && self.minstanex_lasthit)
36         {
37                 Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_ACHIEVEMENT_IMPRESSIVE);
38                 damage_goodhits = 0; // only every second time
39         }
40
41         self.minstanex_lasthit = damage_goodhits;
42
43         pointparticles(particleeffectnum("nex_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
44
45         // teamcolor / hit beam effect
46         vector v;
47         v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
48         switch(self.team)
49         {
50                 case NUM_TEAM_1:   // 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 NUM_TEAM_2:   // 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 NUM_TEAM_3:   // 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 NUM_TEAM_4:   // 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                 default:
75                         if(damage_goodhits)
76                                 WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3_HIT"), w_shotorg, v);
77                         else
78                                 WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3"), w_shotorg, v);
79                         break;
80         }
81         
82         W_DecreaseAmmo(ammo_cells, ((g_minstagib) ? 1 : autocvar_g_balance_minstanex_ammo), autocvar_g_balance_minstanex_reload_ammo);
83 }
84
85 float w_minstanex(float req)
86 {
87         float ammo_amount;
88         float minstanex_ammo;
89
90         // now multiple WR_s use this
91         minstanex_ammo = ((g_minstagib) ? 1 : autocvar_g_balance_minstanex_ammo);
92
93         switch(req)
94         {
95                 case WR_AIM:
96                 {
97                         if(self.ammo_cells > 0)
98                                 self.BUTTON_ATCK = bot_aim(1000000, 0, 1, FALSE);
99                         else
100                                 self.BUTTON_ATCK2 = bot_aim(autocvar_g_balance_laser_primary_speed, 0, autocvar_g_balance_laser_primary_lifetime, FALSE);
101                                 
102                         return TRUE;
103                 }
104                 case WR_THINK:
105                 {
106                         // if the laser uses load, we also consider its ammo for reloading
107                         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
108                                 WEP_ACTION(self.weapon, WR_RELOAD);
109                         else if(autocvar_g_balance_minstanex_reload_ammo && self.clip_load < minstanex_ammo) // forced reload
110                                 WEP_ACTION(self.weapon, WR_RELOAD);
111                         else if (self.BUTTON_ATCK)
112                         {
113                                 if (weapon_prepareattack(0, autocvar_g_balance_minstanex_refire))
114                                 {
115                                         W_MinstaNex_Attack();
116                                         weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_minstanex_animtime, w_ready);
117                                 }
118                         }
119                         else if (self.BUTTON_ATCK2)
120                         {
121                                 if (self.jump_interval <= time)
122                                 if (weapon_prepareattack(1, -1))
123                                 {
124                                         // handle refire manually, so that primary and secondary can be fired without conflictions (important for minstagib)
125                                         self.jump_interval = time + autocvar_g_balance_minstanex_laser_refire * W_WeaponRateFactor();
126                                         
127                                         // decrease ammo for the laser?
128                                         if(autocvar_g_balance_minstanex_laser_ammo)
129                                                 W_DecreaseAmmo(ammo_cells, autocvar_g_balance_minstanex_laser_ammo, autocvar_g_balance_minstanex_reload_ammo);
130
131                                         // ugly minstagib hack to reuse the fire mode of the laser
132                                         float w;
133                                         w = self.weapon;
134                                         self.weapon = WEP_LASER;
135                                         W_Laser_Shockwave();
136                                         self.weapon = w;
137                                         
138                                         // now do normal refire
139                                         weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_minstanex_laser_animtime, w_ready);
140                                 }
141                         }
142                         
143                         return TRUE;
144                 }
145                 case WR_INIT:
146                 {
147                         precache_model ("models/nexflash.md3");
148                         precache_model ("models/weapons/g_minstanex.md3");
149                         precache_model ("models/weapons/v_minstanex.md3");
150                         precache_model ("models/weapons/h_minstanex.iqm");
151                         precache_sound ("weapons/minstanexfire.wav");
152                         precache_sound ("weapons/nexwhoosh1.wav");
153                         precache_sound ("weapons/nexwhoosh2.wav");
154                         precache_sound ("weapons/nexwhoosh3.wav");
155                         W_Laser(WR_INIT);
156                         return TRUE;
157                 }
158                 case WR_SETUP:
159                 {
160                         self.current_ammo = ammo_cells;
161                         self.minstanex_lasthit = 0;
162                         return TRUE;
163                 }
164                 case WR_CHECKAMMO1:
165                 {
166                         ammo_amount = self.ammo_cells >= minstanex_ammo;
167                         ammo_amount += self.(weapon_load[WEP_MINSTANEX]) >= minstanex_ammo;
168                         return ammo_amount;
169                 }
170                 case WR_CHECKAMMO2:
171                 {
172                         if(!autocvar_g_balance_minstanex_laser_ammo)
173                                 return TRUE;
174                         ammo_amount = self.ammo_cells >= autocvar_g_balance_minstanex_laser_ammo;
175                         ammo_amount += self.(weapon_load[WEP_MINSTANEX]) >= autocvar_g_balance_minstanex_laser_ammo;
176                         return ammo_amount;
177                 }
178                 case WR_RESETPLAYER:
179                 {
180                         self.minstanex_lasthit = 0;
181                         return TRUE;
182                 }
183                 case WR_RELOAD:
184                 {
185                         float used_ammo;
186                         if(autocvar_g_balance_minstanex_laser_ammo)
187                                 used_ammo = min(minstanex_ammo, autocvar_g_balance_minstanex_laser_ammo);
188                         else
189                                 used_ammo = minstanex_ammo;
190
191                         W_Reload(used_ammo, autocvar_g_balance_minstanex_reload_ammo, autocvar_g_balance_minstanex_reload_time, "weapons/reload.wav");
192                         return TRUE;
193                 }
194                 case WR_SUICIDEMESSAGE:
195                 {
196                         return WEAPON_THINKING_WITH_PORTALS;
197                 }
198                 case WR_KILLMESSAGE:
199                 {
200                         return WEAPON_MINSTANEX_MURDER;
201                 }
202         }
203         return TRUE;
204 }
205 #endif
206 #ifdef CSQC
207 float w_minstanex(float req)
208 {
209         switch(req)
210         {
211                 case WR_IMPACTEFFECT:
212                 {
213                         vector org2;
214                         org2 = w_org + w_backoff * 6;
215                         pointparticles(particleeffectnum("nex_impact"), org2, '0 0 0', 1);
216                         if(!w_issilent)
217                                 sound(self, CH_SHOTS, "weapons/neximpact.wav", VOL_BASE, ATTN_NORM);
218                                 
219                         return TRUE;
220                 }
221                 case WR_INIT:
222                 {
223                         precache_sound("weapons/neximpact.wav");
224                         return TRUE;
225                 }
226         }
227         return TRUE;
228 }
229 #endif
230 #endif