1 void W_RicochetRocket_Explode ();
\r
3 void W_RicochetRocket_Damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
\r
5 self.health = self.health - damage;
\r
6 if (self.health <= 0)
\r
9 W_RicochetRocket_Explode();
\r
13 entity W_Launch_RicochetRocket (vector org, vector vel, float rocket_grav, float num, float totalbounces)
\r
18 gren.classname = "rocket";
\r
19 gren.solid = SOLID_BBOX;
\r
20 gren.movetype = MOVETYPE_BOUNCEMISSILE;
\r
21 gren.gravity = rocket_grav;//0.01;
\r
22 setmodel(gren, "models/rocket.md3");
\r
23 if(self.classname == "player")
\r
26 setsize(gren, '-6 -6 -3', '6 6 3');
\r
30 gren.owner = self.owner;
\r
31 setsize(gren, '0 0 0', '0 0 0');
\r
33 setorigin(gren, org);
\r
35 gren.cnt = num; // what # this one is
\r
36 gren.count = totalbounces; // how many missiles this missile splits into
\r
38 gren.nextthink = time + 10;
\r
39 gren.think = W_RicochetRocket_Explode;
\r
40 gren.touch = W_RicochetRocket_Explode;
\r
41 gren.velocity = vel;
\r
42 gren.angles = vectoangles (gren.velocity);
\r
44 gren.colormod = 2 * '1 1 0';
\r
49 // bounce off the wall, then become volatile
\r
50 void W_RicochetRocket_NullTouch ()
\r
52 self.delay = self.delay - 1;
\r
54 self.touch = SUB_Null;
\r
56 //self.touch = W_RicochetRocket_Explode;
\r
57 //self.think = self.touch;
\r
58 //self.nextthink = time + 10;
\r
59 //self.angles = vectoangles(self.velocity);
\r
62 void W_RicochetRocket_Update ()
\r
64 self.angles = vectoangles(self.velocity);
\r
65 if(self.wait < time && self.delay <= 0)
\r
67 self.touch = W_RicochetRocket_Explode;
\r
68 self.think = W_RicochetRocket_Explode;
\r
69 self.nextthink = time + 10;
\r
73 self.think = W_RicochetRocket_Update;
\r
74 self.nextthink = time + 0.1;
\r
78 void W_RicochetRocket_Explode ()
\r
80 vector org2, vel, dir;
\r
81 float num, spread, bouncecount;
\r
85 if(other != self && other.classname == self.classname)
\r
87 self.angles = vectoangles(self.velocity);
\r
88 return; // don't touch other ricochet rockets
\r
96 rocketid = ftos(self.cnt);
\r
98 spread = cvar(strcat("g_balance_ricochet_spread",rocketid));
\r
100 org2 = findbetterlocation (self.origin);
\r
101 te_explosion (org2);
\r
102 effect (org2, "models/sprites/rocketexplosion.spr32", 0, 20, 40);
\r
103 sound (self, CHAN_BODY, "weapons/rocket_impact.wav", 1, ATTN_NORM);
\r
105 self.event_damage = SUB_Null;
\r
106 RadiusDamage (self, self.owner, cvar(strcat("g_balance_ricochet_damage",rocketid)), cvar(strcat("g_balance_ricochet_edgedamage",rocketid)), cvar(strcat("g_balance_ricochet_radius",rocketid)), world, cvar(strcat("g_balance_ricochet_force",rocketid)), WEP_SOLDIER_SPECIAL);
\r
108 bouncecount = cvar("g_balance_ricochet_bouncecount");
\r
110 if(self.cnt >= bouncecount)
\r
112 // don't spawn more rockets
\r
117 self.solid = SOLID_NOT;
\r
119 self.cnt = self.cnt + 1;
\r
126 rocketid = ftos(self.cnt);
\r
128 //bprint("Rocket", ftos(self.cnt-1));
\r
129 //bprint(" splits ", ftos(self.count), "times\n");
\r
132 dir = normalize(self.velocity);
\r
135 vel_x = dir_x + crandom()*spread;
\r
136 vel_y = dir_y + crandom()*spread;
\r
137 vel_z = dir_z + crandom()*spread;
\r
138 vel = normalize(vel) * cvar(strcat("g_balance_ricochet_speed",rocketid));
\r
139 e = W_Launch_RicochetRocket(org2, vel,
\r
140 cvar(strcat("g_balance_ricochet_gravity",rocketid)),
\r
141 self.cnt, cvar(strcat("g_balance_ricochet_splitcount",rocketid)) );
\r
142 //if(other != self) // touched something else, not detonated by damage
\r
144 // going to hit the same thing that detonated this rocket;
\r
145 // avoid that by bouncing off before setting an explosion touch
\r
146 e.touch = W_RicochetRocket_NullTouch;
\r
147 e.delay = cvar("g_balance_ricochet_nulltouches");
\r
148 e.wait = time + cvar("g_balance_ricochet_nulltime");
\r
149 e.think = W_RicochetRocket_Update;
\r
150 e.nextthink = time + 0.1;//4;
\r
152 e.scale = 0.3 + 0.4*(1 - (self.cnt / bouncecount));
\r
159 void SoldierSpecial()
\r
162 if(self.special_time > time)
\r
164 self.special_time = time + cvar("g_balance_ricochet_firerate");
\r
168 sound (self, CHAN_WEAPON, "weapons/rocket_fire.wav", 1, ATTN_NORM);
\r
169 self.punchangle_x = -4;
\r
170 org = self.origin + self.view_ofs + v_forward * 15 + v_right * 5 + v_up * -12;
\r
171 e = W_Launch_RicochetRocket(org, v_forward * cvar("g_balance_ricochet_speed"), cvar("g_balance_ricochet_gravity"), 1, cvar("g_balance_ricochet_splitcount"));
\r
172 // first rocket takes damage, others don't
\r
173 e.takedamage = DAMAGE_YES;
\r
174 e.damageforcescale = 4;
\r
176 e.event_damage = W_RicochetRocket_Damage;
\r
181 void SoldierGrenade(float req)
\r
183 if(req == WR_GRENADE1)
\r
185 if(W_ThrowGrenade(W_MirvGrenade))
\r
186 self.grenade_time = time + cvar("g_balance_grenade_mirv_refire");
\r
188 else if(req == WR_GRENADE2)
\r
190 if(W_ThrowGrenade(W_FragGrenade))
\r
191 self.grenade_time = time + cvar("g_balance_grenade_frag_refire");
\r
195 void SoldierPreThink()
\r
199 void SoldierPostThink()
\r
203 void BecomeSoldier(float portion)
\r
205 self.max_health = cvar("g_balance_class_soldier_health") * portion;
\r
207 self.max_armor = cvar("g_balance_class_soldier_armor") * portion;
\r
209 self.mass = cvar("g_balance_class_soldier_mass");
\r
211 SetPlayerSpeed(self);
\r
213 self.items = IT_WEP1 | IT_WEP2 | IT_WEP3 | IT_WEP4;
\r
214 self.switchweapon = WEP4; // used to be WEP3
\r
215 self.ammo_shells = floor(20 * portion);
\r
216 self.ammo_nails = floor(150 * portion);
\r
217 self.ammo_rockets = floor(12 * portion);
\r
218 self.ammo_cells = floor(0 * portion);
\r
219 self.playerclass = TF_CLASS_SOLDIER; // TF P.C.
\r
220 SetMaxAmmoFor (CLASS_SOLDIER);
\r