]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/weapons/w_minstanex.qc
b5bfd6b973bde7295f16742dabd21fba19a3e2c6
[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(WEP_CVAR_PRI(blaster, speed), 0, WEP_CVAR_PRI(blaster, lifetime), FALSE); // WEAPONTODO: replace with proper minstanex cvars
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_BLASTER;
135                                         W_Blaster_Attack( // WEAPONTODO: replace with proper minstanex cvars
136                                                 WEP_CVAR_PRI(blaster, shotangle),
137                                                 WEP_CVAR_PRI(blaster, damage),
138                                                 WEP_CVAR_PRI(blaster, edgedamage),
139                                                 WEP_CVAR_PRI(blaster, radius),
140                                                 WEP_CVAR_PRI(blaster, force),
141                                                 WEP_CVAR_PRI(blaster, speed),
142                                                 WEP_CVAR_PRI(blaster, spread),
143                                                 WEP_CVAR_PRI(blaster, delay),
144                                                 WEP_CVAR_PRI(blaster, lifetime)
145                                         );
146                                         self.weapon = w;
147                                         
148                                         // now do normal refire
149                                         weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_minstanex_laser_animtime, w_ready);
150                                 }
151                         }
152                         
153                         return TRUE;
154                 }
155                 case WR_INIT:
156                 {
157                         precache_model ("models/nexflash.md3");
158                         precache_model ("models/weapons/g_minstanex.md3");
159                         precache_model ("models/weapons/v_minstanex.md3");
160                         precache_model ("models/weapons/h_minstanex.iqm");
161                         precache_sound ("weapons/minstanexfire.wav");
162                         precache_sound ("weapons/nexwhoosh1.wav");
163                         precache_sound ("weapons/nexwhoosh2.wav");
164                         precache_sound ("weapons/nexwhoosh3.wav");
165                         W_Blaster(WR_INIT); // Samual: Is this really the proper thing to do? Didn't we already run this previously? 
166                         return TRUE;
167                 }
168                 case WR_SETUP:
169                 {
170                         self.current_ammo = ammo_cells;
171                         self.minstanex_lasthit = 0;
172                         return TRUE;
173                 }
174                 case WR_CHECKAMMO1:
175                 {
176                         ammo_amount = self.ammo_cells >= minstanex_ammo;
177                         ammo_amount += self.(weapon_load[WEP_MINSTANEX]) >= minstanex_ammo;
178                         return ammo_amount;
179                 }
180                 case WR_CHECKAMMO2:
181                 {
182                         if(!autocvar_g_balance_minstanex_laser_ammo)
183                                 return TRUE;
184                         ammo_amount = self.ammo_cells >= autocvar_g_balance_minstanex_laser_ammo;
185                         ammo_amount += self.(weapon_load[WEP_MINSTANEX]) >= autocvar_g_balance_minstanex_laser_ammo;
186                         return ammo_amount;
187                 }
188                 case WR_RESETPLAYER:
189                 {
190                         self.minstanex_lasthit = 0;
191                         return TRUE;
192                 }
193                 case WR_RELOAD:
194                 {
195                         float used_ammo;
196                         if(autocvar_g_balance_minstanex_laser_ammo)
197                                 used_ammo = min(minstanex_ammo, autocvar_g_balance_minstanex_laser_ammo);
198                         else
199                                 used_ammo = minstanex_ammo;
200
201                         W_Reload(used_ammo, "weapons/reload.wav");
202                         return TRUE;
203                 }
204                 case WR_SUICIDEMESSAGE:
205                 {
206                         return WEAPON_THINKING_WITH_PORTALS;
207                 }
208                 case WR_KILLMESSAGE:
209                 {
210                         return WEAPON_MINSTANEX_MURDER;
211                 }
212         }
213         return TRUE;
214 }
215 #endif
216 #ifdef CSQC
217 float w_minstanex(float req)
218 {
219         switch(req)
220         {
221                 case WR_IMPACTEFFECT:
222                 {
223                         vector org2;
224                         org2 = w_org + w_backoff * 6;
225                         pointparticles(particleeffectnum("nex_impact"), org2, '0 0 0', 1);
226                         if(!w_issilent)
227                                 sound(self, CH_SHOTS, "weapons/neximpact.wav", VOL_BASE, ATTN_NORM);
228                                 
229                         return TRUE;
230                 }
231                 case WR_INIT:
232                 {
233                         precache_sound("weapons/neximpact.wav");
234                         return TRUE;
235                 }
236         }
237         return TRUE;
238 }
239 #endif
240 #endif