[code] Throwable Knives


(bacon) #1

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 :slight_smile:


(-xXx-Suicide) #2

Stupid question… how does one throw them? Is this just the normal fire?

Blar, and where are my manners. (ans: in my head not on the “paper”)

Thank you so very much for sharing this!!!


(bacon) #3

Use the command throwknife.


(-xXx-Suicide) #4

I had a feeling as I got further in, but wanted to check. You’ve answered so many questions for me in just this one thing. I also wanted to know how to add a command (to, well, throw a knife, mostly, but it’s still usefull!)


(-xXx-Suicide) #5

Did you give specialtime to gentity_s at some point? I’m getting build errors about it not being a member?


(bacon) #6

Oh yeah :smiley:
In g_local.h
Below:

g_constructible_stats_t	constructibleStats;

Add:

//bacon
	int		specialTime;		// used for various things

(-xXx-Suicide) #7

You are my hero. Thank you, and you are very much credited in the source, as you will be in the readme, if I may actually use any of this in a completed (free of charge of course,) mod.

And I guessed wrong; for some reason (i.e. big number slips in,) I thought it’d be a float. But then again,

<------- Coding n00b.

Again, thank you thank you thank you for helping a new guy learn C++ by the seat of his pants.


(-xXx-Suicide) #8

Well, perhaps there’s something I’m doing wrong, but the application crashes out sometimes, others get bad ghent error in console. It only seems to be when a client connects (i.e. the second PC on my lan.) Any thoughts as to what this might be? The only thing I don’t have are any pk3 files in this folder. This folder is just

qgame*.dll
cgame*.dll
readme.txt


(Demolama) #9

gotta have the dll’s in the pk3 winzip them and use the console to rename the zip to a pk3


(bani) #10

why not make altweapon throw a knife? then you don’t have to bind a separate command for it. it’s also more intuitive (imo).

to keep knife throwing abuse down, you can just limit players to 2 knifes or something, instead of a 30 sec delay which is non intuitive (and annoying).

a well aimed thrown knife in the back should count as a backstab :smiley:


(-xXx-Suicide) #11

I plan on implimenting as an alt-fire, but I haven’t figured out exactly how to do that yet. I’m sure if I fight enough with it I can figure that out :slight_smile:

How do you turn a zip to a PK3 via console?

Thanks!


(Sauron|EFG) #12
rename suicide.zip suicide.pk3

(Vetinari) #13

rotfl few weeks ago on a pub server some ppl fooled some newbies, that they don’t know how to throw knives :slight_smile: … and now this g :clap:


(-xXx-Suicide) #14

Thanks Sauron!


(-xXx-Suicide) #15

I still can’t get this to work for some reason. If I comment out the parts about picking up knives… well, I’ll just post it! =D

[edited out code, not needed now.]

As such it works, but if I start un-commenting things, it brreaks (game crashes to error as soon as a knife intersects something.)

Any thoughts on what I’m missing or doing wrong?

Also, how could I create my own knife.weap and have it point to that (more-encompassing question because I want to add sounds, vsays, etc.,) in my own pk3 file?

Thank you!

edit: I also added the return //by xxxx after I commented all the other stuff out. I don’t know if it was needed or not, but it felt needed :slight_smile:


(-xXx-Suicide) #16

OK, I managed to get all that fixed. Not sure what it was exactly, but I un-commented things until they broke… which they didn’t. Only thing I did different was take specialtime out of its placee in G_public.h, put it as just a global variable, hangin’ out at the end of the file. This was the only time the counter worked, but perhaps I was just missing something.

In any case, the one thing I can’t seem to do for the life of me is get it to show a model on the ground. I tried putting the /weapons/knife.weap in my own pk3 file with the appropriate adjustment. I tried it in pak000.pk3. No model. Any throughts on what I am doing wrong with that regard?


(-xXx-Suicide) #17

Maybe if I toss this in my etmain folder instead as -x-mod-stuff.pk3 or something happy like that…
Try this when I get home; perhaps it has to be in the etmain folder for path reasons?


(paryl) #18

Hello, I’m new here… and this is the first thing I’m doing to familiarize myself with the ET code. With that said, I have a few ideas…

First of all, I’m trying to figure out how to bind it to alt-fire instead of /throwknife, as mentioned earlier. I’m going to keep trying, but a hint would be nice :slight_smile:

I actually commented out the part about waiting 30 seconds because it crashed ET every time, whether packed or not. I think it makes more sense to simply get rid of the knife until the player picks another one up, y’know? But, is it possible to get rid of the knife, or will it always be unlimited?

I’m not sure why, but knife.weap referred to “models/multiplayer/knife/knife.md3”. I couldn’t find that file, but I could find knife.mdc. I changed that line, and it works. Hope it won’t come back to bite me later on?

Also, I was wondering if there is an easy way to change the flight characteristics of the knife… to make it more realistic, that is. I’d like it to either point in the direction that it is moving, or have it spin while in flight. Any ideas?

Again, I’m new… so take it easy on me. :smiley:


(bacon) #19

I’ll post some updated code later. The delay is shortened to 2.5 seconds and players are limited to 5 knifes.
There’s a few fixes within the code.

I’m not sure why, but knife.weap referred to “models/multiplayer/knife/knife.md3”. I couldn’t find that file, but I could find knife.mdc. I changed that line, and it works. Hope it won’t come back to bite me later on?

It makes no difference…


(paryl) #20

The delay is shortened to 2.5 seconds and players are limited to 5 knifes.

What I was actually trying to ask about, regarding that, is whether it is possible to keep the knife from being selected after it’s ammo has been depleted. Similar to grenades. Along with that, how would one go about reloading the knives from a supply rack or field op?