Quake DeveLS - How do want your Strogg? Rare, medium, or Well Done?

Author: Cryect
Difficulty: Hard

Well here is a new weapon a flamethrower. This was by request. Make note this has some problems with lagging servers I have some special lag code but I removed it to prevent confusing people.

Create a new file called "w_flamethrower.c". Put into it this code.

#include "g_local.h"
/*
=======================
Flamethrower
=======================
*/
void Fire_Think (edict_t *self)
{
	vec3_t dir;
	int damage;
	float	points;
	vec3_t	v;

	if (level.time > self->delay)
	{
		self->owner->Flames--;
		G_FreeEdict (self);
		return;
	}
	//if (self->owner->takedamage = DAMAGE_NO)
	//{
	//	self->owner->Flames--;
	//	G_FreeEdict (self);
//		return;
//	}
	if (!self->owner)
	{
		G_FreeEdict (self);
		return;
	}
	if (self->owner->waterlevel)
	{
		self->owner->Flames--;
		G_FreeEdict (self);
		return;
	}
	damage = rndnum (1,self->FlameDamage);	
	VectorAdd (self->orb->mins, self->orb->maxs, v);
	VectorMA (self->orb->s.origin, 0.5, v, v);
	VectorSubtract (self->s.origin, v, v);
	points = damage - 0.5 * (VectorLength (v));
	VectorSubtract (self->owner->s.origin, self->s.origin, dir);

	if (self->PlasmaDelay < level.time)
	{
		T_Damage (self->owner, self, self->orb, dir, self->owner->s.origin,vec3_origin, damage, 0, DAMAGE_NO_KNOCKBACK,MOD_WF_FLAME);
		self->FlameDelay = level.time + 0.8;
	}
	VectorCopy(self->owner->s.origin,self->s.origin);
	self->nextthink = level.time + .2;
}

void burn_person(edict_t *target, edict_t *owner, int damage)
{
	edict_t	*flame;

	if (target->Flames > 1)//This number sets the allowed amount of flames per person
		return;
	target->Flames++;
	flame = G_Spawn();
	flame->movetype = MOVETYPE_NOCLIP;
	flame->clipmask = MASK_SHOT;
	flame->solid = SOLID_NOT;
	flame->s.effects |= EF_ANIM_ALLFAST|EF_BFG|EF_HYPERBLASTER;//|EF_GRENADE|EF_BLASTER;
	flame->velocity[0] = target->velocity[0];
	flame->velocity[1] = target->velocity[1];
	flame->velocity[2] = target->velocity[2];

	VectorClear (flame->mins);
	VectorClear (flame->maxs);
	flame->s.modelindex = gi.modelindex ("sprites/fire.sp2");
	flame->owner = target;
	flame->orb = owner;
	flame->delay = level.time + 5;//8;//Jr Shorten it so it goes away faster
	flame->nextthink = level.time + .8;
	flame->FlameDelay = level.time + 0.8;
	flame->think = Fire_Think;
	flame->FlameDamage = damage+2;//JR increased that
	flame->classname = "fire";
	flame->s.sound = gi.soundindex ("weapons/bfg__l1a.wav");
	gi.linkentity (flame);

	VectorCopy(target->s.origin,flame->s.origin);
}
void flame_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
{

	if (other == self->owner)
		return;

	// clean up laser entities

	if (surf && (surf->flags & SURF_SKY))
	{
		G_FreeEdict (self);
		return;
	}

	if (self->owner->client)
		PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT);
	T_Damage (other, self, self->owner, self->velocity, self->s.origin, plane->normal, 6, 0, 0,MOD_WF_FLAME);
	// core explosion - prevents firing it into the wall/floor
	if (other->health)
	{
		burn_person(other, self->owner, self->SniperDamage);
	}
	G_FreeEdict (self);


}

void fire_flamethrower(edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius)
{
	edict_t	*flame;

	flame = G_Spawn();
        flame->wf_team = self->wf_team;
	VectorCopy (start, flame->s.origin);
	VectorCopy (dir, flame->movedir);
	vectoangles (dir, flame->s.angles);
	VectorScale (dir, speed, flame->velocity);
	flame->movetype = MOVETYPE_FLYMISSILE;
	flame->clipmask = MASK_SHOT;
	flame->solid = SOLID_BBOX;
	flame->s.effects |= EF_ANIM_ALLFAST|EF_BFG|EF_HYPERBLASTER;//EF_BLASTER|EF_GRENADE;
	VectorSet (flame->mins,-20,-20,-20);
	VectorSet (flame->maxs,20,20,20);
	flame->s.modelindex = gi.modelindex ("sprites/fire.sp2");
	flame->owner = self;
	flame->touch = flame_touch;
	flame->nextthink = level.time + 250/speed;
	flame->think = G_FreeEdict;
	flame->radius_dmg = damage;
	flame->FlameDamage = damage;
	flame->dmg_radius = damage_radius;
	flame->classname = "flame";
	flame->s.sound = gi.soundindex ("weapons/bfg__l1a.wav");


	if (self->client)
		check_dodge (self, flame->s.origin, dir, speed);

	gi.linkentity (flame);
}

void weapon_flamethrower_fire (edict_t *ent)
{
	vec3_t	offset, start;
	vec3_t	forward, right;
	int		damage = 5;
	float	damage_radius = 1000;
if (!(ent->client->buttons & BUTTON_ATTACK))
{
	ent->client->ps.gunframe = 33;
	return;
}
		// send muzzle flash
		gi.WriteByte (svc_muzzleflash);
		gi.WriteShort (ent-g_edicts);
		gi.WriteByte (MZ_ROCKET | is_silenced);
		gi.multicast (ent->s.origin, MULTICAST_PVS);



		PlayerNoise(ent, start, PNOISE_WEAPON);

	if (is_quad)
		damage *= 4;

	AngleVectors (ent->client->v_angle, forward, right, NULL);

	VectorSet(offset, 8, 8, ent->viewheight-8);
	P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);

	fire_flamethrower (ent, start, forward, damage, 500, damage_radius);


	ent->client->ps.gunframe++;

	PlayerNoise(ent, start, PNOISE_WEAPON);

	ent->client->pers.inventory[ent->client->ammo_index] -= ent->client->pers.weapon->quantity;
}

void Weapon_FlameThrower (edict_t *ent)
{
	static int	pause_frames[]	= {39, 45, 50, 55, 0};
	static int	fire_frames[]	= {9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 0};
	Weapon_Generic (ent, 8, 32, 55, 58, pause_frames, fire_frames, weapon_flamethrower_fire);
}

Put this into the edict_t structure. These are just some variables that are used.
	//Flamethrower and fire vars
	float	 FlameDelay;
	int	 Flames;
	int	 FlameDamage;

Now here is the item code for "g_items.c" you should know by now how to put this in.
	/*QUAKED weapon_flamethrower (.3 .3 1) (-16 -16 -16) (16 16 16)
*/
	{
		"weapon_flamethrower",
		Pickup_Weapon,
		Use_Weapon,
		Drop_Weapon,
		Weapon_FlameThrower,
		"misc/w_pkup.wav",
		"models/weapons/g_bfg/tris.md2", EF_ROTATE,
		"models/weapons/v_bfg/tris.md2",
/* icon */		"w_bfg",
/* pickup */	"FlameThrower",
		0,
		1,
		"Cells",
		IT_WEAPON,
		NULL,
		0,
/* precache */ "sprites/fire.sp2"
	},

Alright you will need the sprite fire.sp2. You can get it using a pak editor to extract it from the client file for WF. Thats at http://www.captured.com/weaponsfactory/. THis is just some sprite I created. Well I almost included a napalm grenade but decided that might be a little too much for now.

Tutorial by Cryect


This site, and all content and graphics displayed on it,
are ©opyrighted to the Quake DeveLS team. All rights received.
Got a suggestion? Comment? Question? Hate mail? Send it to us!
Oh yeah, this site is best viewed in 16 Bit or higher, with the resolution on 800*600.
Thanks to Planet Quake for there great help and support with hosting.
Best viewed with Netscape 4 or IE 3