]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/w_minstanex.qc
Initial commit
[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_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_FLAG_SUPERWEAPON | WEP_TYPE_HITSCAN, BOT_PICKUP_RATING_HIGH, "minstanex", "minstanex", _("MinstaNex"))
3 #else
4 #ifdef SVQC
5 .float minstanex_lasthit;
6 .float jump_interval;
7
8 void W_MinstaNex_Attack (void)
9 {
10         float flying;
11         flying = IsFlying(self); // do this BEFORE to make the trace values from FireRailgunBullet last
12
13         W_SetupShot (self, TRUE, 0, "weapons/minstanexfire.wav", CH_WEAPON_A, 10000);
14
15         yoda = 0;
16         damage_goodhits = 0;
17         headshot = 0;
18         damage_headshotbonus = -1; // no extra damage, just count
19         FireRailgunBullet (w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, 10000, 800, 0, 0, 0, 0, WEP_MINSTANEX);
20         damage_headshotbonus = 0;
21
22         if(yoda && flying)
23                 AnnounceTo(self, "yoda");
24         if(headshot)
25         {
26                 AnnounceTo(self, "headshot");
27         }
28         if(damage_goodhits && self.minstanex_lasthit)
29         {
30                 if(AnnounceTo(self, "impressive"))
31                         damage_goodhits = 0; // only every second time
32         }
33
34         self.minstanex_lasthit = damage_goodhits;
35
36         pointparticles(particleeffectnum("nex_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
37
38         // teamcolor / hit beam effect
39         vector v;
40         v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
41         if(teamplay)
42         {
43             switch(self.team)
44             {
45             case COLOR_TEAM1:   // Red
46                 if(damage_goodhits)
47                     WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3RED_HIT"), w_shotorg, v);
48                 else
49                     WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3RED"), w_shotorg, v);
50                 break;
51             case COLOR_TEAM2:   // Blue
52                 if(damage_goodhits)
53                     WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3BLUE_HIT"), w_shotorg, v);
54                 else
55                     WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3BLUE"), w_shotorg, v);
56                 break;
57             case COLOR_TEAM3:   // Yellow
58                 if(damage_goodhits)
59                     WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3YELLOW_HIT"), w_shotorg, v);
60                 else
61                     WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3YELLOW"), w_shotorg, v);
62                 break;
63             case COLOR_TEAM4:   // Pink
64                 if(damage_goodhits)
65                     WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3PINK_HIT"), w_shotorg, v);
66                 else
67                     WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3PINK"), w_shotorg, v);
68                 break;
69             }
70         }
71         else
72         WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3"), w_shotorg, v);
73                 
74         W_DecreaseAmmo(ammo_cells, ((g_minstagib) ? 1 : autocvar_g_balance_minstanex_ammo), autocvar_g_balance_minstanex_reload_ammo);
75 }
76
77 void spawnfunc_weapon_minstanex (void); // defined in t_items.qc
78
79 float w_minstanex(float req)
80 {
81         float ammo_amount;
82         float minstanex_ammo;
83
84         // now multiple WR_s use this
85         minstanex_ammo = ((g_minstagib) ? 1 : autocvar_g_balance_minstanex_ammo);
86
87         if (req == WR_AIM)
88         {
89                 if(self.ammo_cells > 0)
90                         self.BUTTON_ATCK = bot_aim(1000000, 0, 1, FALSE);
91                 else
92                         self.BUTTON_ATCK2 = bot_aim(autocvar_g_balance_laser_primary_speed, 0, autocvar_g_balance_laser_primary_lifetime, FALSE);
93         }
94         else if (req == WR_THINK)
95         {
96                 // if the laser uses load, we also consider its ammo for reloading
97                 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
98                         weapon_action(self.weapon, WR_RELOAD);
99                 else if(autocvar_g_balance_minstanex_reload_ammo && self.clip_load < minstanex_ammo) // forced reload
100                         weapon_action(self.weapon, WR_RELOAD);
101                 else if (self.BUTTON_ATCK)
102                 {
103                         if (weapon_prepareattack(0, autocvar_g_balance_minstanex_refire))
104                         {
105                                 W_MinstaNex_Attack();
106                                 weapon_thinkf(WFRAME_FIRE1, autocvar_g_balance_minstanex_animtime, w_ready);
107                         }
108                 }
109                 else if (self.BUTTON_ATCK2)
110                 {
111                         if (self.jump_interval <= time)
112                         if (weapon_prepareattack(1, -1))
113                         {
114                                 // handle refire manually, so that primary and secondary can be fired without conflictions (important for minstagib)
115                                 self.jump_interval = time + autocvar_g_balance_minstanex_laser_refire * W_WeaponRateFactor();
116                                 
117                                 // decrease ammo for the laser?
118                                 if(autocvar_g_balance_minstanex_laser_ammo)
119                                         W_DecreaseAmmo(ammo_cells, autocvar_g_balance_minstanex_laser_ammo, autocvar_g_balance_minstanex_reload_ammo);
120
121                                 // ugly minstagib hack to reuse the fire mode of the laser
122                                 float w;
123                                 w = self.weapon;
124                                 self.weapon = WEP_LASER;
125                                 W_Laser_Attack(2);
126                                 self.weapon = w;
127                                 
128                                 // now do normal refire
129                                 weapon_thinkf(WFRAME_FIRE2, autocvar_g_balance_minstanex_laser_animtime, w_ready);
130                         }
131                 }
132         }
133         else if (req == WR_PRECACHE)
134         {
135                 precache_model ("models/nexflash.md3");
136                 precache_model ("models/weapons/g_minstanex.md3");
137                 precache_model ("models/weapons/v_minstanex.md3");
138                 precache_model ("models/weapons/h_minstanex.iqm");
139                 precache_sound ("weapons/minstanexfire.wav");
140                 precache_sound ("weapons/nexwhoosh1.wav");
141                 precache_sound ("weapons/nexwhoosh2.wav");
142                 precache_sound ("weapons/nexwhoosh3.wav");
143                 //precache_sound ("weapons/reload.wav"); // until weapons have individual reload sounds, precache the reload sound somewhere else
144                 w_laser(WR_PRECACHE);
145         }
146         else if (req == WR_SETUP)
147         {
148                 weapon_setup(WEP_MINSTANEX);
149                 self.current_ammo = ammo_cells;
150                 self.minstanex_lasthit = 0;
151         }
152         else if (req == WR_CHECKAMMO1)
153         {
154                 ammo_amount = self.ammo_cells >= minstanex_ammo;
155                 ammo_amount += self.(weapon_load[WEP_MINSTANEX]) >= minstanex_ammo;
156                 return ammo_amount;
157         }
158         else if (req == WR_CHECKAMMO2)
159         {
160                 if(!autocvar_g_balance_minstanex_laser_ammo)
161                         return TRUE;
162                 ammo_amount = self.ammo_cells >= autocvar_g_balance_minstanex_laser_ammo;
163                 ammo_amount += self.(weapon_load[WEP_MINSTANEX]) >= autocvar_g_balance_minstanex_laser_ammo;
164                 return ammo_amount;
165         }
166         else if (req == WR_RESETPLAYER)
167         {
168                 self.minstanex_lasthit = 0;
169         }
170         else if (req == WR_RELOAD)
171         {
172                 float used_ammo;
173                 if(autocvar_g_balance_minstanex_laser_ammo)
174                         used_ammo = min(minstanex_ammo, autocvar_g_balance_minstanex_laser_ammo);
175                 else
176                         used_ammo = minstanex_ammo;
177
178                 W_Reload(used_ammo, autocvar_g_balance_minstanex_reload_ammo, autocvar_g_balance_minstanex_reload_time, "weapons/reload.wav");
179         }
180         return TRUE;
181 }
182 #endif
183 #ifdef CSQC
184 float w_minstanex(float req)
185 {
186         if(req == WR_IMPACTEFFECT)
187         {
188                 vector org2;
189                 org2 = w_org + w_backoff * 6;
190                 pointparticles(particleeffectnum("nex_impact"), org2, '0 0 0', 1);
191                 if(!w_issilent)
192                         sound(self, CH_SHOTS, "weapons/neximpact.wav", VOL_BASE, ATTN_NORM);
193         }
194         else if(req == WR_PRECACHE)
195         {
196                 precache_sound("weapons/neximpact.wav");
197         }
198         else if (req == WR_SUICIDEMESSAGE)
199                 w_deathtypestring = _("%s is now thinking with portals");
200         else if (req == WR_KILLMESSAGE)
201                 w_deathtypestring = _("%s has been vaporized by %s's minstanex");
202         return TRUE;
203 }
204 #endif
205 #endif