]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/w_crylink.qc
support for more weapon sounds
[divverent/nexuiz.git] / data / qcsrc / server / w_crylink.qc
1 .float gravity;
2 const vector proj_color = '1 1 1';
3
4 .entity realowner;
5
6 void W_Crylink_Touch (void)
7 {
8         float finalhit;
9         float f;
10         PROJECTILE_TOUCH;
11         sound (self, CHAN_PROJECTILE, "weapons/cryplink_impact.wav", VOL_BASE, ATTN_NORM);
12         pointparticles(particleeffectnum("crylink_impactbig"), self.origin, '0 0 0', 1);
13         finalhit = ((self.cnt <= 0) || (other.takedamage != DAMAGE_NO));
14         if(finalhit)
15                 f = 1;
16         else
17                 f = cvar("g_balance_crylink_primary_bouncedamagefactor");
18         if(self.alpha)
19                 f *= self.alpha;
20         RadiusDamage (self, self.realowner, cvar("g_balance_crylink_primary_damage") * f, cvar("g_balance_crylink_primary_edgedamage") * f, cvar("g_balance_crylink_primary_radius"), world, cvar("g_balance_crylink_primary_force") * f, self.projectiledeathtype, other);
21         if (finalhit)
22         {
23                 remove (self);
24                 return;
25         }
26         self.cnt = self.cnt - 1;
27         self.angles = vectoangles(self.velocity);
28         self.owner = world;
29         self.projectiledeathtype |= HITTYPE_BOUNCE;
30         //self.scale = 1 + self.cnt;
31 }
32
33 void W_Crylink_Touch2 (void)
34 {
35         float finalhit;
36         float f;
37         PROJECTILE_TOUCH;
38         sound (self, CHAN_PROJECTILE, "weapons/cryplink_impact2.wav", VOL_BASE, ATTN_NORM);
39         pointparticles(particleeffectnum("crylink_impact"), self.origin, '0 0 0', 1);
40         finalhit = ((self.cnt <= 0) || (other.takedamage != DAMAGE_NO));
41         if(finalhit)
42                 f = 1;
43         else
44                 f = cvar("g_balance_crylink_secondary_bouncedamagefactor");
45         if(self.alpha)
46                 f *= self.alpha;
47         RadiusDamage (self, self.realowner, cvar("g_balance_crylink_secondary_damage") * f, cvar("g_balance_crylink_secondary_edgedamage") * f, cvar("g_balance_crylink_secondary_radius"), world, cvar("g_balance_crylink_secondary_force") * f, self.projectiledeathtype, other);
48         if (finalhit)
49         {
50                 remove (self);
51                 return;
52         }
53         self.cnt = self.cnt - 1;
54         self.angles = vectoangles(self.velocity);
55         self.owner = world;
56         self.projectiledeathtype |= HITTYPE_BOUNCE;
57 //      self.scale = 1 + 1 * self.cnt;
58 }
59
60 void W_Crylink_Attack (void)
61 {
62         local float counter, shots;
63         local entity proj;
64         local vector s;
65
66         if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
67                 self.ammo_cells = self.ammo_cells - cvar("g_balance_crylink_primary_ammo");
68
69         W_SetupShot (self, '25 8 -8', FALSE, 2, "weapons/crylink_fire.wav");
70
71         shots = cvar("g_balance_crylink_primary_shots");
72         pointparticles(particleeffectnum("crylink_muzzleflash"), w_shotorg, w_shotdir * 1000, shots);
73         while (counter < shots)
74         {
75                 proj = spawn ();
76                 proj.realowner = proj.owner = self;
77                 proj.classname = "spike";
78                 proj.bot_dodge = TRUE;
79                 proj.bot_dodgerating = cvar("g_balance_crylink_primary_damage");
80
81                 proj.movetype = MOVETYPE_BOUNCEMISSILE;
82                 proj.solid = SOLID_BBOX;
83                 proj.projectiledeathtype = WEP_CRYLINK;
84                 //proj.gravity = 0.001;
85
86                 setmodel (proj, "models/plasmatrail.mdl"); // precision set below
87                 setsize (proj, '0 0 0', '0 0 0');
88                 setorigin (proj, w_shotorg);
89
90                 s = '0 0 0';
91                 if (counter == 0)
92                         s = '0 0 0';
93                 else if (counter == 1)
94                         s = '0 0 1';
95                 else if (counter == 2)
96                         s = '0 -0.71 -0.71';
97                 else if (counter == 3)
98                         s = '0 0.71 -0.71';
99                 else
100                         s = randomvec();
101                 s = s * cvar("g_balance_crylink_primary_spread");
102                 proj.velocity = (w_shotdir + v_right * s_y + v_up * s_z) * cvar("g_balance_crylink_primary_speed");
103 //              proj.velocity = (w_shotdir + randomvec() * cvar("g_balance_crylink_primary_spread")) * cvar("g_balance_crylink_primary_speed");
104                 W_SetupProjectileVelocity(proj);
105                 proj.touch = W_Crylink_Touch;
106                 if(counter == 0)
107                         SUB_SetFade(proj, time + cvar("g_balance_crylink_primary_middle_lifetime"), cvar("g_balance_crylink_primary_middle_fadetime"));
108                 else if(counter <= 3)
109                         SUB_SetFade(proj, time + cvar("g_balance_crylink_primary_star_lifetime"), cvar("g_balance_crylink_primary_star_fadetime"));
110                 else
111                         SUB_SetFade(proj, time + cvar("g_balance_crylink_primary_other_lifetime"), cvar("g_balance_crylink_primary_other_fadetime"));
112                 proj.cnt = cvar("g_balance_crylink_primary_bounces");
113                 proj.scale = 1 + 1 * proj.cnt;
114
115                 proj.angles = vectoangles (proj.velocity);
116
117                 //proj.glow_size = 20;
118
119                 proj.effects = EF_LOWPRECISION;
120                 proj.flags = FL_PROJECTILE;
121                 proj.colormod = proj_color;
122                 counter = counter + 1;
123         }
124 }
125
126 void W_Crylink_Attack2 (void)
127 {
128         local float counter, shots;
129         local entity proj;
130
131         if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
132                 self.ammo_cells = self.ammo_cells - cvar("g_balance_crylink_secondary_ammo");
133
134         W_SetupShot (self, '25 8 -8', FALSE, 2, "weapons/crylink_fire2.wav");
135
136         shots = cvar("g_balance_crylink_secondary_shots");
137         pointparticles(particleeffectnum("crylink_muzzleflash"), w_shotorg, w_shotdir * 1000, shots);
138         while (counter < shots)
139         {
140                 proj = spawn ();
141                 proj.realowner = proj.owner = self;
142                 proj.classname = "spike";
143                 proj.bot_dodge = TRUE;
144                 proj.bot_dodgerating = cvar("g_balance_crylink_secondary_damage");
145
146                 proj.movetype = MOVETYPE_BOUNCEMISSILE;
147                 proj.solid = SOLID_BBOX;
148                 proj.projectiledeathtype = WEP_CRYLINK | HITTYPE_SECONDARY;
149                 //proj.gravity = 0.001;
150
151                 setmodel (proj, "models/plasmatrail.mdl"); // precision set below
152                 setsize (proj, '0 0 0', '0 0 0');
153                 setorigin (proj, w_shotorg);
154
155                 proj.velocity = (w_shotdir + (((counter + 0.5) / shots) * 2 - 1) * v_right * cvar("g_balance_crylink_secondary_spread")) * cvar("g_balance_crylink_secondary_speed");
156                 W_SetupProjectileVelocity(proj);
157                 proj.touch = W_Crylink_Touch2;
158                 if(counter == (shots - 1) / 2)
159                         SUB_SetFade(proj, time + cvar("g_balance_crylink_secondary_middle_lifetime"), cvar("g_balance_crylink_secondary_middle_fadetime"));
160                 else
161                         SUB_SetFade(proj, time + cvar("g_balance_crylink_secondary_line_lifetime"), cvar("g_balance_crylink_secondary_line_fadetime"));
162                 proj.cnt = cvar("g_balance_crylink_secondary_bounces");
163                 proj.scale = 1 + 1 * proj.cnt;
164
165                 proj.angles = vectoangles (proj.velocity);
166
167                 //proj.glow_size = 20;
168
169                 proj.effects = EF_LOWPRECISION;
170                 proj.flags = FL_PROJECTILE;
171                 proj.colormod = proj_color;
172                 counter = counter + 1;
173         }
174 }
175
176
177 /*
178 // experimental lightning gun
179 void W_Crylink_Attack3 (void)
180 {
181         if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
182                 self.ammo_cells = self.ammo_cells - cvar("g_balance_crylink_primary_ammo");
183         W_SetupShot (self, '25 8 -8', TRUE, 0, "weapons/crylink_fire.wav");
184
185         traceline_antilag(self, w_shotorg, w_shotorg + w_shotdir * 1000, FALSE, self, self.ping * 0.001);
186
187         pointparticles(particleeffectnum("lightning_muzzleflash", w_shotorg, w_shotdir * 1000, 1);
188         pointparticles(particleeffectnum("lightning_impact", trace_endpos, trace_plane_normal * 1000, 1);
189         trailparticles(world, particleeffectnum("lightning_beam", w_shotorg, trace_endpos);
190
191         if (trace_fraction < 1)
192                 Damage(trace_ent, self, self, cvar("g_balance_crylink_primary_damage"), WEP_CRYLINK | HITTYPE_SECONDARY, trace_endpos, '0 0 0');
193 }
194 */
195
196 void spawnfunc_weapon_crylink (void)
197 {
198         weapon_defaultspawnfunc(WEP_CRYLINK);
199 }
200
201 float w_crylink(float req)
202 {
203         if (req == WR_AIM)
204         {
205                 if (random() > 0.15)
206                         self.BUTTON_ATCK = bot_aim(cvar("g_balance_crylink_primary_speed"), 0, cvar("g_balance_crylink_primary_middle_lifetime"), FALSE);
207                 else
208                         self.BUTTON_ATCK2 = bot_aim(cvar("g_balance_crylink_secondary_speed"), 0, cvar("g_balance_crylink_secondary_middle_lifetime"), FALSE);
209         }
210         else if (req == WR_THINK)
211         {
212                 if (self.BUTTON_ATCK)
213                 if (weapon_prepareattack(0, cvar("g_balance_crylink_primary_refire")))
214                 {
215                         W_Crylink_Attack();
216                         weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_crylink_primary_animtime"), w_ready);
217                 }
218                 if (self.BUTTON_ATCK2)
219                 if (weapon_prepareattack(1, cvar("g_balance_crylink_secondary_refire")))
220                 {
221                         W_Crylink_Attack2();
222                         weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_crylink_secondary_animtime"), w_ready);
223                 }
224         }
225         else if (req == WR_PRECACHE)
226         {
227                 precache_model ("models/plasma.mdl");
228                 precache_model ("models/plasmatrail.mdl");
229                 precache_model ("models/weapons/g_crylink.md3");
230                 precache_model ("models/weapons/v_crylink.md3");
231                 precache_model ("models/weapons/w_crylink.zym");
232                 precache_sound ("weapons/crylink_fire.wav");
233                 precache_sound ("weapons/crylink_fire2.wav");
234                 precache_sound ("weapons/crylink_impact.wav");
235                 precache_sound ("weapons/crylink_impact2.wav");
236         }
237         else if (req == WR_SETUP)
238                 weapon_setup(WEP_CRYLINK);
239         else if (req == WR_CHECKAMMO1)
240                 return self.ammo_cells >= cvar("g_balance_crylink_primary_ammo");
241         else if (req == WR_CHECKAMMO2)
242                 return self.ammo_cells >= cvar("g_balance_crylink_secondary_ammo");
243         else if (req == WR_SUICIDEMESSAGE)
244         {
245                 w_deathtypestring = "succeeded at self-destructing himself with the Crylink";
246         }
247         else if (req == WR_KILLMESSAGE)
248         {
249                 if(w_deathtype & HITTYPE_BOUNCE)
250                         w_deathtypestring = "could not hide from #'s Crylink"; // unchecked: SPLASH (SECONDARY can't be)
251                 else if(w_deathtype & HITTYPE_SPLASH)
252                         w_deathtypestring = "was too close to #'s Crylink"; // unchecked: SECONDARY
253                 else
254                         w_deathtypestring = "took a close look at #'s Crylink"; // unchecked: SECONDARY
255         }
256         return TRUE;
257 };