This code just makes it so you can throw knives (and pick them up). Players get unlimited knives, must have the knife selected, and can only throw one knife every 30 seconds
In g_cmds.c
Just before:
/*
=================
ClientCommand
=================
*/
void ClientCommand( int clientNum ) {
Add:
/*
==============
touchKnife
==============
*/
void touchKnife( gentity_t *ent, gentity_t *other, trace_t *trace) {
qboolean hurt = qfalse;
ent->active = qfalse; // just incase
// only damage clients
if (!other->client)
return;
// the knife is still moving and not on the ground
if ( VectorLength(ent->s.pos.trDelta) != 0 ) {
// ff on = only enemies, else = everybody
if ( (g_friendlyFire.integer && !OnSameTeam(other, ent->parent)) || (!g_friendlyFire.integer) ) {
int i;
int sound;
int damage = 30;
damage -= rand()%20; // subtract 0-19 to make it varied
// this should be client-side, the sound part
// pick a random sound
i = (rand()%3) + 1;
sound = G_SoundIndex( va( "sound/weapons/knife/knife_hit%d.wav", i) );
G_Sound(other, sound);
G_Damage(other, ent->parent, ent->parent, NULL, trace->endpos, damage, 0, MOD_KNIFE);
hurt = qtrue;
}
}
// we didn't hit anybody
if (hurt == qfalse) {
if ( other->client->ps.ammo[BG_FindClipForWeapon(WP_KNIFE)] < 10 )
other->client->ps.ammo[BG_FindClipForWeapon(WP_KNIFE)]++;
else
return;
// pickup sound
if (ent->noise_index)
G_AddEvent(other, EV_GENERAL_SOUND, ent->noise_index);
// send the pickup event
if (other->client->pers.predictItemPickup)
G_AddPredictableEvent(other, EV_ITEM_PICKUP, ent->s.modelindex);
else
G_AddEvent(other, EV_ITEM_PICKUP, ent->s.modelindex);
}
ent->freeAfterEvent = qtrue;
ent->flags |= FL_NODRAW;
ent->r.svFlags |= SVF_NOCLIENT;
ent->s.eFlags |= EF_NODRAW;
ent->r.contents = 0;
ent->nextthink = 0;
ent->think = 0;
}
/*
==============
Cmd_ThrowKnife_f
==============
*/
void Cmd_ThrowKnife_f( gentity_t *ent ) {
vec3_t velocity, offset, org, mins, maxs;
trace_t tr;
gentity_t *traceEnt;
gitem_t *item = BG_FindItemForWeapon(WP_KNIFE);
// can only throw 1 knife every 30 seconds
if ( level.time - ent->specialTime < 30000 ) {
float wait = (level.time - ent->specialTime) * 0.001;
trap_SendServerCommand(ent-g_entities, va("cp \"You must wait %d %s
\"", wait, wait < 2 ? "second" : "seconds" ));
return;
}
// we have to have a throwing knife left
// give us unlimited knifes
/*if ( ent->client->ps.ammo[BG_FindAmmoForWeapon(WP_KNIFE)] == 0 ) {
trap_SendServerCommand(ent-g_entities, "cp \"You do not have any knives
\"");
return;
}*/
// our currently selected weapon must be the knife
if (ent->s.weapon != WP_KNIFE) {
return;
}
AngleVectors(ent->client->ps.viewangles, velocity, NULL, NULL);
VectorScale(velocity, 64, offset);
offset[2] += ent->client->ps.viewheight / 2;
VectorScale(velocity, 800, velocity); // somewhat realistic knife movement
velocity[2] += 50 + rand()%35;
VectorAdd(ent->client->ps.origin, offset, org);
VectorSet( mins, -ITEM_RADIUS, -ITEM_RADIUS, 0);
VectorSet( maxs, ITEM_RADIUS, ITEM_RADIUS, 2 * ITEM_RADIUS);
trap_Trace( &tr, ent->client->ps.origin, mins, maxs, org, ent->s.number, MASK_SOLID);
VectorCopy(tr.endpos, org);
// ideally we want to make a sound play from the client
G_Sound(ent, G_SoundIndex( "sound/weapons/knife/knife_splash1.wav" ));
traceEnt = LaunchItem(item, org, velocity, ent->client->ps.clientNum);
traceEnt->touch = touchKnife;
traceEnt->parent = ent;
// we lose a knife
ent->client->ps.ammo[BG_FindClipForWeapon(WP_KNIFE)]--;
// we should make this throwTime or something so it doesn't interfere with other things that use this...
ent->specialTime = level.time;
}
Then in ClientCommand()
Find:
} else if( !Q_stricmp( cmd, "forcetapout" ) ) {
And above that add:
} else if (Q_stricmp( cmd, "throwknife") == 0) {
Cmd_ThrowKnife_f( ent );
return;
Now open up pak0.pk3 and extract the file weapons/knife.weap, edit it in notepad.
Change:
pickupModel ""
To:
pickupModel "models/multiplayer/knife/knife.md3"
Now you have throwable knives 


