4 void ra_nade_timer_think()
6 self.skin = 8 - (self.owner.wait - time) / (autocvar_g_riflearena_nade_lifetime / 10);
8 if(!self.owner || wasfreed(self.owner))
13 void ra_nade_burn_spawn(entity nade)
15 switch(nade.realowner.team)
18 CSQCProjectile(nade, TRUE, PROJECTILE_NADE_RED_BURN, TRUE);
21 CSQCProjectile(nade, TRUE, PROJECTILE_NADE_BLUE_BURN, TRUE);
24 CSQCProjectile(nade, TRUE, PROJECTILE_NADE_RED_BURN, TRUE);
29 void ra_nade_spawn(entity nade)
31 entity timer = spawn();
32 setmodel(timer, "models/ok_nade_counter/ok_nade_counter.md3");
33 setattachment(timer, nade, "");
34 timer.classname = "nade_timer";
35 timer.colormap = nade.colormap;
36 timer.glowmod = nade.glowmod;
37 timer.think = ra_nade_timer_think;
38 timer.nextthink = time;
39 timer.wait = nade.wait;
43 CSQCProjectile(nade, TRUE, ((nade.realowner.team == NUM_TEAM_2) ? PROJECTILE_NADE_BLUE: PROJECTILE_NADE_RED) , TRUE);
47 void ra_nade_boom() // TODO: DamageInfo
49 sound(self, CH_SHOTS_SINGLE, "misc/null.wav", VOL_BASE, ATTN_NORM);
50 sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
51 pointparticles(particleeffectnum((self.realowner.team == NUM_TEAM_2) ? "nade_blue_explode" : "nade_red_explode"), self.origin + '0 0 1', '0 0 0', 1);
54 self.takedamage = DAMAGE_NO;
55 RadiusDamage(self, self.realowner, autocvar_g_riflearena_nade_damage, autocvar_g_riflearena_nade_edgedamage,
56 autocvar_g_riflearena_nade_radius, self, autocvar_g_riflearena_nade_force, self.projectiledeathtype, self.enemy);
64 setsize(self, '-2 -2 -2', '2 2 2');
65 UpdateCSQCProjectile(self);
66 if(self.health == autocvar_g_riflearena_nade_health)
68 spamsound(self, CH_SHOTS, strcat("weapons/grenade_bounce", ftos(1 + rint(random() * 5)), ".wav"), VOL_BASE, ATTN_NORM);
78 sound(self, CH_SHOTS_SINGLE, "overkill/grenadebip.wav", VOL_BASE, 0.5 *(ATTN_LARGE + ATTN_MAX));
79 self.think = ra_nade_boom;
80 self.nextthink = max(self.wait, time);
83 void ra_nade_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
85 if(DEATH_ISWEAPON(deathtype, WEP_LASER))
88 self.velocity += force;
93 if(self.health == autocvar_g_riflearena_nade_health)
95 sound(self, CH_SHOTS_SINGLE, "misc/null.wav", VOL_BASE, 0.5 *(ATTN_LARGE + ATTN_MAX));
96 self.nextthink = max(time + autocvar_g_riflearena_nade_lifetime, time);
97 self.think = ra_nade_beep;
100 self.health -= damage;
101 self.realowner = attacker;
104 W_PrepareExplosionByDamage(attacker, ra_nade_boom);
106 ra_nade_burn_spawn(self);
109 void ra_toss_nade(vector _velocity, float _time)
111 entity _nade = self.ra_nade;
112 self.ra_nade = world;
114 setorigin(_nade, gettaginfo(_nade, gettagindex(_nade, "Object001")));
115 setattachment(_nade, world, "");
116 PROJECTILE_MAKETRIGGER(_nade);
117 setsize(_nade, '-16 -16 -16', '16 16 16');
118 _nade.movetype = MOVETYPE_BOUNCE;
121 _nade.velocity = '0 0 -10';
122 else if(autocvar_g_riflearena_nade_newton_style == 1)
123 _nade.velocity = self.velocity + _velocity;
124 else if(autocvar_g_riflearena_nade_newton_style == 2)
125 _nade.velocity = _velocity;
127 _nade.velocity = W_CalculateProjectileVelocity(self.velocity, _velocity, FALSE);
129 _nade.solid = SOLID_BBOX;
130 _nade.touch = ra_nade_touch;
131 _nade.health = autocvar_g_riflearena_nade_health;
132 _nade.takedamage = DAMAGE_YES;
133 _nade.event_damage = ra_nade_damage;
134 _nade.teleportable = TRUE;
136 ra_nade_spawn(_nade);
140 _nade.think = ra_nade_boom;
141 _nade.nextthink = _time;
144 _nade.projectiledeathtype = DEATH_NADE_NORMAL;
146 self.ra_nade_refire = time + autocvar_g_riflearena_nade_refire;
152 remove(self.ra_nade);
154 self.ra_nade = spawn();
155 setmodel(self.ra_nade, "models/weapons/h_ok_grenade.iqm");
156 setattachment(self.ra_nade, self.weaponentity, "");
157 self.ra_nade.classname = "nade";
158 self.ra_nade.realowner = self;
159 self.ra_nade.colormap = self.colormap;
160 self.ra_nade.glowmod = self.glowmod;
161 self.ra_nade.wait = time + autocvar_g_riflearena_nade_lifetime;
162 self.ra_nade.cnt = time;
163 self.ra_nade.think = ra_nade_beep;
164 self.ra_nade.nextthink = max(self.ra_nade.wait - 3, time);
165 self.ra_nade.projectiledeathtype = DEATH_NADE_NORMAL;
168 MUTATOR_HOOKFUNCTION(ra_PlayerDamage)
170 if(IS_PLAYER(frag_attacker))
172 if (DEATH_ISWEAPON(frag_deathtype, WEP_LASER))
174 if(frag_attacker == frag_target)
178 if (frag_target != frag_attacker)
180 if (frag_target.health >= 1 && IS_PLAYER(frag_target))
181 centerprint(frag_attacker, "Laser inflicts no damage!");
182 frag_force = '0 0 0';
190 MUTATOR_HOOKFUNCTION(ra_PlayerSpawn)
192 WEPSET_CLEAR_E(self);
193 WEPSET_OR_EW(self, WEP_RIFLE);
194 WEPSET_OR_EW(self, WEP_LASER);
196 self.ra_nade_refire = time + 1;
201 MUTATOR_HOOKFUNCTION(ra_FilterItem)
213 MUTATOR_HOOKFUNCTION(ra_PlayerThink)
216 if(self.ra_nade.wait - 0.1 <= time)
217 ra_toss_nade('0 0 0', time + 0.05);
219 if(self.ra_nade_refire < time)
226 else if(time - self.ra_nade.cnt >= 1)
230 makevectors(self.v_angle);
231 float _force = time - self.ra_nade.cnt;
232 _force /= autocvar_g_riflearena_nade_lifetime;
233 _force = autocvar_g_riflearena_nade_minforce + (_force * (autocvar_g_riflearena_nade_maxforce - autocvar_g_riflearena_nade_minforce));
234 ra_toss_nade((v_forward * 0.7 + v_up * 0.2 + v_right * 0.1) * _force, 0);
239 self.hasweapon_complain_spam = time + 5; // this isn't needed, so keep it off
244 MUTATOR_HOOKFUNCTION(ra_RemovePlayer)
247 remove(self.ra_nade);
252 MUTATOR_HOOKFUNCTION(ra_StartItems)
254 start_items |= IT_UNLIMITED_AMMO;
255 start_ammo_nails = 100;
257 g_grappling_hook = 0;
262 MUTATOR_HOOKFUNCTION(ra_PlayerDies)
265 ra_toss_nade('0 0 100', max(self.ra_nade.wait, time + 0.05));
270 MUTATOR_HOOKFUNCTION(ra_ForbidThrowCurrentWeapon)
272 if(self.freezetag_frozen || !autocvar_g_riflearena_nades || self.vehicle)
277 if(self.ra_nade_refire < time)
279 Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_NADE);
281 self.ra_nade_refire = time + autocvar_g_riflearena_nade_refire;
286 if(time - self.ra_nade.cnt >= 1)
288 makevectors(self.v_angle);
289 float _force = time - self.ra_nade.cnt;
290 _force /= autocvar_g_riflearena_nade_lifetime;
291 _force = autocvar_g_riflearena_nade_minforce + (_force * (autocvar_g_riflearena_nade_maxforce - autocvar_g_riflearena_nade_minforce));
292 ra_toss_nade((v_forward * 0.75 + v_up * 0.2 + v_right * 0.05) * _force, 0);
298 MUTATOR_HOOKFUNCTION(ra_BuildMutatorsString)
300 ret_string = strcat(ret_string, ":RA");
304 MUTATOR_HOOKFUNCTION(ra_BuildMutatorsPrettyString)
306 ret_string = strcat(ret_string, ", Rifle Arena");
310 MUTATOR_HOOKFUNCTION(ra_SetModname)
312 modname = "Rifle Arena";
316 MUTATOR_DEFINITION(mutator_riflearena)
318 MUTATOR_HOOK(PlayerDamage_Calculate, ra_PlayerDamage, CBC_ORDER_ANY);
319 MUTATOR_HOOK(PlayerSpawn, ra_PlayerSpawn, CBC_ORDER_ANY);
320 MUTATOR_HOOK(FilterItem, ra_FilterItem, CBC_ORDER_ANY);
321 MUTATOR_HOOK(SetStartItems, ra_StartItems, CBC_ORDER_ANY);
322 MUTATOR_HOOK(MakePlayerObserver, ra_RemovePlayer, CBC_ORDER_ANY);
323 MUTATOR_HOOK(ClientDisconnect, ra_RemovePlayer, CBC_ORDER_ANY);
324 MUTATOR_HOOK(PlayerDies, ra_PlayerDies, CBC_ORDER_ANY);
325 MUTATOR_HOOK(PlayerPreThink, ra_PlayerThink, CBC_ORDER_ANY);
326 MUTATOR_HOOK(ForbidThrowCurrentWeapon, ra_ForbidThrowCurrentWeapon, CBC_ORDER_ANY);
327 MUTATOR_HOOK(BuildMutatorsString, ra_BuildMutatorsString, CBC_ORDER_ANY);
328 MUTATOR_HOOK(BuildMutatorsPrettyString, ra_BuildMutatorsPrettyString, CBC_ORDER_ANY);
332 cvar_settemp("g_balance_rifle_secondary_spread", "0");
333 cvar_settemp("g_balance_rifle_secondary_shots", "1");
334 cvar_settemp("g_balance_rifle_secondary_animtime", "0.15");
335 cvar_settemp("g_balance_rifle_secondary_refire", "0.15");
336 cvar_settemp("g_balance_rifle_secondary_damage", "40");
337 precache_model("models/ok_nade_counter/ok_nade_counter.md3");
339 precache_model("models/weapons/h_ok_grenade.iqm");
340 precache_model("models/weapons/v_ok_grenade.md3");
341 precache_sound("weapons/rocket_impact.wav");
342 precache_sound("weapons/grenade_bounce1.wav");
343 precache_sound("weapons/grenade_bounce2.wav");
344 precache_sound("weapons/grenade_bounce3.wav");
345 precache_sound("weapons/grenade_bounce4.wav");
346 precache_sound("weapons/grenade_bounce5.wav");
347 precache_sound("weapons/grenade_bounce6.wav");
348 precache_sound("overkill/grenadebip.wav");
350 weapon_action(WEP_LASER, WR_PRECACHE);
351 weapon_action(WEP_RIFLE, WR_PRECACHE);
353 get_weaponinfo(WEP_HOOK).spawnflags |= WEP_FLAG_MUTATORBLOCKED;
356 MUTATOR_ONROLLBACK_OR_REMOVE
358 get_weaponinfo(WEP_HOOK).spawnflags &~= WEP_FLAG_MUTATORBLOCKED;
363 print("This cannot be removed at runtime\n");