1 void nade_timer_think()
3 self.skin = 8 - (self.owner.wait - time) / (autocvar_g_nades_nade_lifetime / 10);
5 if(!self.owner || wasfreed(self.owner))
10 void nade_burn_spawn(entity _nade)
14 switch(_nade.realowner.team)
16 case NUM_TEAM_1: p = PROJECTILE_NADE_RED_BURN; break;
17 case NUM_TEAM_2: p = PROJECTILE_NADE_BLUE_BURN; break;
18 case NUM_TEAM_3: p = PROJECTILE_NADE_YELLOW_BURN; break;
19 case NUM_TEAM_4: p = PROJECTILE_NADE_PINK_BURN; break;
20 default: p = PROJECTILE_NADE_BURN; break;
23 CSQCProjectile(_nade, TRUE, p, TRUE);
26 void nade_spawn(entity _nade)
29 entity timer = spawn();
30 setmodel(timer, "models/ok_nade_counter/ok_nade_counter.md3");
31 setattachment(timer, _nade, "");
32 timer.classname = "nade_timer";
33 timer.colormap = _nade.colormap;
34 timer.glowmod = _nade.glowmod;
35 timer.think = nade_timer_think;
36 timer.nextthink = time;
37 timer.wait = _nade.wait;
41 switch(_nade.realowner.team)
43 case NUM_TEAM_1: p = PROJECTILE_NADE_RED; break;
44 case NUM_TEAM_2: p = PROJECTILE_NADE_BLUE; break;
45 case NUM_TEAM_3: p = PROJECTILE_NADE_YELLOW; break;
46 case NUM_TEAM_4: p = PROJECTILE_NADE_PINK; break;
47 default: p = PROJECTILE_NADE; break;
50 CSQCProjectile(_nade, TRUE, p, TRUE);
58 switch(self.realowner.team)
60 case NUM_TEAM_1: expef = "nade_red_explode"; break;
61 case NUM_TEAM_2: expef = "nade_blue_explode"; break;
62 case NUM_TEAM_3: expef = "nade_yellow_explode"; break;
63 case NUM_TEAM_4: expef = "nade_pink_explode"; break;
64 default: expef = "nade_explode"; break;
67 sound(self, CH_SHOTS_SINGLE, "misc/null.wav", VOL_BASE, ATTEN_NORM);
68 sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM);
69 pointparticles(particleeffectnum(expef), self.origin + '0 0 1', '0 0 0', 1);
71 Damage_DamageInfo(self.origin, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage, autocvar_g_nades_nade_radius, '1 1 1' * autocvar_g_nades_nade_force, self.projectiledeathtype, 0, self);
73 self.takedamage = DAMAGE_NO;
74 RadiusDamage(self, self.realowner, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage,
75 autocvar_g_nades_nade_radius, self, world, autocvar_g_nades_nade_force, self.projectiledeathtype, self.enemy);
83 //setsize(self, '-2 -2 -2', '2 2 2');
84 //UpdateCSQCProjectile(self);
85 if(self.health == self.max_health)
87 spamsound(self, CH_SHOTS, strcat("weapons/grenade_bounce", ftos(1 + rint(random() * 5)), ".wav"), VOL_BASE, ATTEN_NORM);
97 sound(self, CH_SHOTS_SINGLE, "overkill/grenadebip.ogg", VOL_BASE, 0.5 *(ATTEN_LARGE + ATTEN_MAX));
98 self.think = nade_boom;
99 self.nextthink = max(self.wait, time);
102 void nade_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
104 if(DEATH_ISWEAPON(deathtype, WEP_BLASTER))
107 if(DEATH_ISWEAPON(deathtype, WEP_VORTEX) || DEATH_ISWEAPON(deathtype, WEP_VAPORIZER))
110 damage = self.max_health * 0.55;
113 if(DEATH_ISWEAPON(deathtype, WEP_MACHINEGUN))
114 damage = self.max_health * 0.1;
116 if((DEATH_ISWEAPON(deathtype, WEP_SHOCKWAVE) || DEATH_ISWEAPON(deathtype, WEP_SHOTGUN)) && !(deathtype & HITTYPE_SECONDARY)) // WEAPONTODO
117 damage = self.max_health * 1.1;
119 if((DEATH_ISWEAPON(deathtype, WEP_SHOCKWAVE) || DEATH_ISWEAPON(deathtype, WEP_SHOTGUN)) && (deathtype & HITTYPE_SECONDARY))
121 damage = self.max_health * 0.1;
125 self.velocity += force;
127 if(!damage || (self.flags & FL_ONGROUND && IS_PLAYER(attacker)))
130 if(self.health == self.max_health)
132 sound(self, CH_SHOTS_SINGLE, "misc/null.wav", VOL_BASE, 0.5 *(ATTEN_LARGE + ATTEN_MAX));
133 self.nextthink = max(time + autocvar_g_nades_nade_lifetime, time);
134 self.think = nade_beep;
137 self.health -= damage;
138 self.realowner = attacker;
141 W_PrepareExplosionByDamage(attacker, nade_boom);
143 nade_burn_spawn(self);
146 void toss_nade(entity e, vector _velocity, float _time)
148 entity _nade = e.nade;
154 makevectors(e.v_angle);
156 W_SetupShot(e, FALSE, FALSE, "", CH_WEAPON_A, 0);
158 Kill_Notification(NOTIF_ONE_ONLY, e, MSG_CENTER_CPID, CPID_NADES);
160 //setorigin(_nade, CENTER_OR_VIEWOFS(e) + (v_right * 10) * -1);
161 setorigin(_nade, w_shotorg + (v_right * 25) * -1);
162 setmodel(_nade, "models/weapons/v_ok_grenade.md3");
163 setattachment(_nade, world, "");
164 PROJECTILE_MAKETRIGGER(_nade);
165 setsize(_nade, '-16 -16 -16', '16 16 16');
166 _nade.movetype = MOVETYPE_BOUNCE;
168 tracebox(_nade.origin, _nade.mins, _nade.maxs, _nade.origin, FALSE, _nade);
169 if (trace_startsolid)
170 setorigin(_nade, e.origin);
172 if(self.v_angle_x >= 70 && self.v_angle_x <= 110)
173 _nade.velocity = '0 0 100';
174 else if(autocvar_g_nades_nade_newton_style == 1)
175 _nade.velocity = e.velocity + _velocity;
176 else if(autocvar_g_nades_nade_newton_style == 2)
177 _nade.velocity = _velocity;
179 _nade.velocity = W_CalculateProjectileVelocity(e.velocity, _velocity, TRUE);
181 _nade.touch = nade_touch;
182 _nade.health = autocvar_g_nades_nade_health;
183 _nade.max_health = _nade.health;
184 _nade.takedamage = DAMAGE_AIM;
185 _nade.event_damage = nade_damage;
186 _nade.teleportable = TRUE;
187 _nade.pushable = TRUE;
189 _nade.missile_flags = MIF_SPLASH | MIF_ARC;
190 _nade.damagedbycontents = TRUE;
191 _nade.angles = vectoangles(_nade.velocity);
192 _nade.flags = FL_PROJECTILE;
198 _nade.think = nade_boom;
199 _nade.nextthink = _time;
202 e.nade_refire = time + autocvar_g_nades_nade_refire;
211 remove(self.fake_nade);
214 setmodel(self.nade, "null");
215 setattachment(self.nade, self, "bip01 l hand");
216 self.nade.classname = "nade";
217 self.nade.realowner = self;
218 self.nade.colormap = self.colormap;
219 self.nade.glowmod = self.glowmod;
220 self.nade.wait = time + autocvar_g_nades_nade_lifetime;
221 self.nade.lifetime = time;
222 self.nade.think = nade_beep;
223 self.nade.nextthink = max(self.nade.wait - 3, time);
224 self.nade.projectiledeathtype = DEATH_NADE;
226 self.fake_nade = spawn();
227 setmodel(self.fake_nade, "models/weapons/h_ok_grenade.iqm");
228 setattachment(self.fake_nade, self.weaponentity, "");
229 self.fake_nade.classname = "fake_nade";
230 //self.fake_nade.viewmodelforclient = self;
231 self.fake_nade.realowner = self.fake_nade.owner = self;
232 self.fake_nade.colormap = self.colormap;
233 self.fake_nade.glowmod = self.glowmod;
234 self.fake_nade.think = SUB_Remove;
235 self.fake_nade.nextthink = self.nade.wait;
246 if(self.deadflag != DEAD_NO)
249 if (!autocvar_g_nades)
250 return FALSE; // allow turning them off mid match
252 if(forbidWeaponUse())
255 if (!IS_PLAYER(self))
261 void nades_CheckThrow()
268 if(self.nade_refire < time)
270 Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_NADE_THROW);
272 self.nade_refire = time + autocvar_g_nades_nade_refire;
277 if(time - self.nade.lifetime >= 1)
279 makevectors(self.v_angle);
280 float _force = time - self.nade.lifetime;
281 _force /= autocvar_g_nades_nade_lifetime;
282 _force = autocvar_g_nades_nade_minforce + (_force * (autocvar_g_nades_nade_maxforce - autocvar_g_nades_nade_minforce));
283 toss_nade(self, (v_forward * 0.75 + v_up * 0.2 + v_right * 0.05) * _force, 0);
288 MUTATOR_HOOKFUNCTION(nades_VehicleEnter)
291 toss_nade(other, '0 0 100', max(other.nade.wait, time + 0.05));
296 MUTATOR_HOOKFUNCTION(nades_PlayerPreThink)
298 float key_pressed = ((g_grappling_hook || client_hasweapon(self, WEP_HOOK, FALSE, FALSE) || (weaponsInMap & WEPSET_HOOK)) ? self.button16 : self.BUTTON_HOOK);
301 if(self.nade.wait - 0.1 <= time)
302 toss_nade(self, '0 0 0', time + 0.05);
305 if(self.nade_refire < time)
312 else if(time - self.nade.lifetime >= 1)
316 makevectors(self.v_angle);
317 float _force = time - self.nade.lifetime;
318 _force /= autocvar_g_nades_nade_lifetime;
319 _force = autocvar_g_nades_nade_minforce + (_force * (autocvar_g_nades_nade_maxforce - autocvar_g_nades_nade_minforce));
320 toss_nade(self, (v_forward * 0.7 + v_up * 0.2 + v_right * 0.1) * _force, 0);
328 MUTATOR_HOOKFUNCTION(nades_PlayerSpawn)
330 if(autocvar_g_nades_spawn)
331 self.nade_refire = time + autocvar_g_spawnshieldtime;
333 self.nade_refire = time + autocvar_g_nades_nade_refire;
338 MUTATOR_HOOKFUNCTION(nades_PlayerDies)
341 toss_nade(self, '0 0 100', max(self.nade.wait, time + 0.05));
346 MUTATOR_HOOKFUNCTION(nades_RemovePlayer)
352 remove(self.fake_nade);
357 MUTATOR_HOOKFUNCTION(nades_BuildMutatorsString)
359 ret_string = strcat(ret_string, ":Nades");
363 MUTATOR_HOOKFUNCTION(nades_BuildMutatorsPrettyString)
365 ret_string = strcat(ret_string, ", Nades");
369 MUTATOR_DEFINITION(mutator_nades)
371 MUTATOR_HOOK(VehicleEnter, nades_VehicleEnter, CBC_ORDER_ANY);
372 MUTATOR_HOOK(PlayerPreThink, nades_PlayerPreThink, CBC_ORDER_ANY);
373 MUTATOR_HOOK(PlayerSpawn, nades_PlayerSpawn, CBC_ORDER_ANY);
374 MUTATOR_HOOK(PlayerDies, nades_PlayerDies, CBC_ORDER_ANY);
375 MUTATOR_HOOK(MakePlayerObserver, nades_RemovePlayer, CBC_ORDER_ANY);
376 MUTATOR_HOOK(ClientDisconnect, nades_RemovePlayer, CBC_ORDER_ANY);
377 MUTATOR_HOOK(BuildMutatorsString, nades_BuildMutatorsString, CBC_ORDER_ANY);
378 MUTATOR_HOOK(BuildMutatorsPrettyString, nades_BuildMutatorsPrettyString, CBC_ORDER_ANY);
382 precache_model("models/ok_nade_counter/ok_nade_counter.md3");
384 precache_model("models/weapons/h_ok_grenade.iqm");
385 precache_model("models/weapons/v_ok_grenade.md3");
386 precache_sound("weapons/rocket_impact.wav");
387 precache_sound("weapons/grenade_bounce1.wav");
388 precache_sound("weapons/grenade_bounce2.wav");
389 precache_sound("weapons/grenade_bounce3.wav");
390 precache_sound("weapons/grenade_bounce4.wav");
391 precache_sound("weapons/grenade_bounce5.wav");
392 precache_sound("weapons/grenade_bounce6.wav");
393 precache_sound("overkill/grenadebip.ogg");