|
Here is a little know tutorial I once posted. When you hit your aliased key,
all the rockets you fire will be converted to rocket propelled grenades. This
means that when you fire a rocket, if it his an entity which is damageable,
it explodes and acts just like a rocket. But, if you fire it over the
badguy's heads and into a solid surface, then when the rocket impacts the
wall grenades come flying out of the fireball and bounce around killing
people they contact and killing others with radius damage! But.. you have to
have rockets and you have to have the 5 grenades in your inventory.
Easy mod! And remember,
fire into the wall above their head!
Here it is::
First, Add this new var
to your gclient_t struct;
int rgrenade;
Add these routines right above your fire_grenade() function in g_weapon.c
//======================================================
void spawn_into_grenades(vec3_t origin,int numgrenades) {
trace_t tr;
gitem_t *item=NULL;
edict_t *grenade=NULL;
vec3_t offset;
int i,j;
vec3_t spray[]={ { 25, 00, 40 },
{ 17,-17, 40 },
{ 00,-25, 40 },
{ -17,-17, 40 },
{ -25, 00, 40 },
{ -17,-17, 40 },
{ -25, 00, 40 },
{ -17, 17, 40 },
{ 00, 25, 40 },
{ 17, 17, 40 }};
vec3_t dir,forward,right,up;
VectorClear(offset);
for (j=1; j<=numgrenades; j++) {
i=(j>10)?j%10+1:j;
grenade = G_Spawn();
grenade->owner=world;
VectorSet(offset,spray[i-1][0],spray[i-1][1],spray[i-1][2]);
offset[0]+=(crandom()*16.0)-8.0;
offset[1]+=(crandom()*16.0)-8.0;
offset[2]+=(crandom()*16.0)-8.0;
vectoangles(offset,dir);
AngleVectors(dir,forward,right,up);
VectorSet(grenade->mins,-8,-8,-8);
VectorSet(grenade->maxs,8,8,8);
G_ProjectSource(origin,offset,forward,right,grenade->s.origin);
tr=gi.trace(origin,grenade->mins,grenade->maxs,grenade->s.origin,NULL,CONTENTS_SOLID);
VectorCopy(tr.endpos,grenade->s.origin);
VectorScale(offset,crandom()*10.0,grenade->velocity);
grenade->velocity[2]=300;
grenade->movetype=MOVETYPE_BOUNCE;
grenade->classname="grenade";
grenade->spawnflags=MOD_GRENADE;
item=item_grenades;
grenade->clipmask=MASK_SHOT;
grenade->solid=SOLID_BBOX;
grenade->s.effects |= EF_GRENADE;
grenade->dmg=40;
grenade->dmg_radius=120;
grenade->model = "models/objects/grenade/tris.md2";
grenade->s.modelindex=gi.modelindex(grenade->model);
grenade->touch=Grenade_Touch;
grenade->think=Grenade_Explode;
grenade->nextthink = level.time+5.0+(random()*10.0);
gi.linkentity(grenade); }
}
//======================================================
void rocketgrenade_touch(edict_t *ent,edict_t *other,cplane_t *plane,csurface_t *surface) {
vec3_t origin;
if (surface && (surface->flags & SURF_SKY)) {
G_FreeEdict(ent);
return; }
VectorMA(ent->s.origin,-0.02,ent->velocity,origin);
G_Spawn_Explosion(TE_ROCKET_EXPLOSION,origin);
if (other->takedamage)
T_Damage(other,ent,ent->owner,ent->velocity,ent->s.origin,plane->normal,ent->dmg,0,0,MOD_ROCKET);
else {
spawn_into_grenades(ent->s.origin,5);
G_FreeEdict(ent);
return; }
T_RadiusDamage(ent,ent->owner,ent->radius_dmg,other,ent->dmg_radius,MOD_R_SPLASH);
G_FreeEdict(ent);
}
//============================================================
void fire_rocketgrenade(edict_t *self,vec3_t start,vec3_t dir,int damage,int speed,float damage_radius,int radius_damage) {
edict_t *rocket;
rocket=G_Spawn();
VectorCopy(start,rocket->s.origin);
VectorCopy(dir,rocket->movedir);
vectoangles(dir,rocket->s.angles);
VectorScale(dir,speed,rocket->velocity);
rocket->movetype=MOVETYPE_FLYMISSILE;
rocket->clipmask=MASK_SHOT;
rocket->solid=SOLID_BBOX;
rocket->s.effects |= EF_ROCKET;
VectorClear(rocket->mins);
VectorClear(rocket->maxs);
rocket->s.modelindex=gi.modelindex("models/objects/rocket/tris.md2");
rocket->owner=self;
rocket->touch=rocketgrenade_touch;
rocket->nextthink=level.time+8000/speed;
rocket->think=G_FreeEdict;
rocket->dmg=damage;
rocket->radius_dmg=radius_damage;
rocket->dmg_radius=damage_radius;
rocket->s.sound=gi.soundindex("weapons/rockfly.wav");
rocket->classname="rocket";
gi.linkentity(rocket);
}
//======================================================
void fire_grenade(edict_t *attacker,vec3_t start,vec3_t aimdir,int damage,int speed,float timer,float damage_radius) {
vec3_t dir,forward,right,up;
if (attacker->client->rgrenade==1)
if (attacker->client->pers.inventory[ITEM_INDEX(item_grenades)] >= 5) {
attacker->client->pers.inventory[ITEM_INDEX(item_grenades)] -= 5;
fire_rocketgrenade(attacker,start,forward,(attacker->client->quad_framenum>level.framenum)?(4*(100+(int)(20*random()))):(100+(int)(20*random())),650,120,(attacker->client->quad_framenum>level.framenum)?480:120);
return; }
edict_t *grenade=G_Spawn();
vectoangles(aimdir,dir);
AngleVectors(dir,forward,right,up);
VectorCopy(start,grenade->s.origin);
VectorScale(aimdir,speed,grenade->velocity);
VectorMA(grenade->velocity,200+10*crandom(),up,grenade->velocity);
VectorMA(grenade->velocity,10*crandom(),right,grenade->velocity);
VectorSet(grenade->avelocity,300,300,300);
grenade->movetype=MOVETYPE_BOUNCE;
grenade->clipmask=MASK_SHOT;
grenade->solid=SOLID_BBOX;
grenade->s.effects |= EF_GRENADE;
VectorClear(grenade->mins);
VectorClear(grenade->maxs);
grenade->s.modelindex=gi.modelindex("models/objects/grenade/tris.md2");
grenade->owner=attacker;
grenade->dmg=damage;
grenade->dmg_radius=damage_radius;
grenade->classname="grenade";
grenade->touch=Grenade_Touch;
grenade->think=Grenade_Explode;
grenade->nextthink=level.time + timer;
gi.linkentity(grenade);
}
Now, add this to the very top of fire_grenade() like so:
//======================================================
void fire_grenade(edict_t *attacker,vec3_t start,vec3_t aimdir,int damage,int speed,float timer,float damage_radius) {
vec3_t dir,forward,right,up;
// Add this stuff right here..
if (attacker->client->rgrenade==1)
if (attacker->client->pers.inventory[ITEM_INDEX(item_grenades)] >= 5) {
attacker->client->pers.inventory[ITEM_INDEX(item_grenades)] -= 5;
fire_rocketgrenade(attacker,start,forward,(attacker->client->quad_framenum>level.framenum)?(4*(100+(int)(20*random()))):(100+(int)(20*random())),650,120,(attacker->client->quad_framenum>level.framenum)?480:120);
return; }
Lastly, add this to your ClientCommand() in g_cmds.c like so:
else if (!stricmp(gi.argv(0),"rgrenade")) {
ent->client->rgrenade=abs(ent->client->rgrenade-1);
gi_centerprintf(ent,"ROCKET PROPELLED GRENADES %s!\n",!ent->client->rgrenade?"DISABLED":"ENABLED");}
Play around with it to
add some variations if you'd like!
That's it!
Have fun!
Maj.Bitch
|