Quake Strogganoff Lesson: Smack Talk

Sat, Feb 22, 2020 2-minute read

Hey everyone, so today I thought we’d take a look at implementing smack talk ala build engine games like Duke Nukem 3D, Blood and Shadow Warrior. But first I’d like to take a moment to thank Preach who helped point me in the right direction on this over at func_msgboard, check out the tome of Preach.

So, what we’re going to do is, after the player kills an enemy (in some sort of spectacular fashion) is check the enemy classname and then select a random sound to be played by the attacking player, and set a nexttalktime so there’s no overlap and to keep the player from being too chatty.

Add this function above in combat.qc somewhere above void(entity targ, entity attacker) Killed =:

void(entity e, entity monster) PlayerRemarkOnKill =
{
	local float r;

	if (e.classname != "player")
		return;

	if (time < e.nextsmacktalktime)
		return;

		if (monster.classname == "monster_army" && monster.health < -20
		|| monster.classname == "monster_ogre" && monster.health < -10
		|| monster.classname == "monster_knight" && monster.health < -10
		|| monster.classname == "monster_demon1" && monster.health < -10)
    //etc...
		{
			e.nextsmacktalktime = time + 2;
			r = random() * 6;
			if (r < 1) sound(e, CHAN_VOICE, PLAYER_KILLCOMMENT_1, 1, ATTN_IDLE);
			else if (r < 2) sound(e, CHAN_VOICE, PLAYER_KILLCOMMENT_2, 1, ATTN_IDLE);
			else if (r < 3) sound(e, CHAN_VOICE, PLAYER_KILLCOMMENT_3, 1, ATTN_IDLE);
			else if (r < 4) sound(e, CHAN_VOICE, PLAYER_KILLCOMMENT_4, 1, ATTN_IDLE);
			else if (r < 5) sound(e, CHAN_VOICE, PLAYER_KILLCOMMENT_5, 1, ATTN_IDLE);
			else sound(e, CHAN_VOICE, PLAYER_KILLCOMMENT_6, 1, ATTN_IDLE);
		}

		e.nextsmacktalktime = time + 15;
		return;
};

NOTE: PLAYER_KILLCOMMENT_1-6 are #define’s that can go in your mod’s def file or you can toss them above the above function or you can replace them with strings like a traditional sound call if you want. The possibilities are endless. Actually that about covers the possibilities. Don’t forget to precache.

And also add nextsmacktalktime as a field float.

.float nextsmacktalktime;

#define PLAYER_KILLCOMMENT_1 "player/killcomment1.wav"
#define PLAYER_KILLCOMMENT_2 "player/killcomment2.wav"
#define PLAYER_KILLCOMMENT_3 "player/killcomment3.wav"
#define PLAYER_KILLCOMMENT_4 "player/killcomment4.wav"
#define PLAYER_KILLCOMMENT_5 "player/killcomment5.wav"
#define PLAYER_KILLCOMMENT_6 "player/killcomment6.wav"

In combat.qc within void(entity targ, entity attacker) Killed = just above ClientObituary(self, attacker); we’ll put our call:

if (random() < 0.5){
PlayerRemarkOnKill(attacker, self);
}

And that’s pretty much it. There’s a lot of room for improvement here but hopefully this covers the basics.

Happy modding!