Trying to make force field

Discuss programming in the QuakeC language.
Post Reply
Orion
Posts: 476
Joined: Fri Jan 12, 2007 6:32 pm
Location: Brazil

Trying to make force field

Post by Orion »

hi.

I'm trying to fix the bug of my force fields in Quake. they work correctly, but they have a bug. When one of the generators is destroyed, I build another, and no lightning between them... nor hurt... can somebody give me a help to fix that? i'll paste my code of forcefield.qc here:

thanks from now!

Code: Select all

/*
==============================================
FORCE FIELD
==============================================
*/
entity field1, field2;
.float has_field;
.entity maker;

void() ForceField_Lightning =
{
	local entity head;
	local vector org;
	
	self.nextthink = time + 0.1;
	
	if (pointcontents(field1.origin) == CONTENT_SOLID || pointcontents(field1.origin) == CONTENT_SKY)
	{
		sprint (self.maker, "Your force field fizzled out.\n");
		self.maker.has_field = 0;
		remove(self);
		return;
	}
	
	if (!field2)
		return;
	if (vlen(field2.origin - self.origin) > 600)
		return;
	
	if (self.t_width < time)
	{
		sound (self, CHAN_WEAPON, "ionfrigate/ionbeam.wav", 1, ATTN_NORM);
		sound (field2, CHAN_WEAPON, "ionfrigate/ionbeam.wav", 1, ATTN_NORM);
		
		self.t_width = time + 1.6;
	}
	
	org = self.origin + '0 0 24';
	
	traceline (org, field2.origin + '0 0 24', TRUE, self);
	
	WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
	WriteByte (MSG_BROADCAST, TE_LIGHTNING1);
	WriteEntity (MSG_BROADCAST, self);
	WriteCoord (MSG_BROADCAST, org_x);
	WriteCoord (MSG_BROADCAST, org_y);
	WriteCoord (MSG_BROADCAST, org_z);
	WriteCoord (MSG_BROADCAST, trace_endpos_x);
	WriteCoord (MSG_BROADCAST, trace_endpos_y);
	WriteCoord (MSG_BROADCAST, trace_endpos_z);
	
	head = findradius(self.origin, 999999);
	while (head)
	{
		if (head != self)
		{
			if (head != field2)
			{
				if (head != self.maker)
				{
					if (head.health > 0)
						LightningDamage (org, trace_endpos, self, 50000, "");
				}
			}
		}
		head = head.chain;
	}
};

void() NoFizzle =
{
	self.nextthink = time + 0.1;
	
	if (pointcontents(self.origin) == CONTENT_SOLID || pointcontents(self.origin) == CONTENT_SKY)
	{
		sprint (self.maker, "Your force field fizzled out.\n");
		self.maker.has_field = 0;
		remove(self);
		return;
	}
};

void() ForceField_Explode =
{
	local float r;
	
	if (self.maker.has_field > 1)
		sprint (self.maker, "One of your force fields was destroyed.\n");
	else
		sprint (self.maker, "Your force field was destroyed.\n");
	
	self.maker.has_field = self.maker.has_field - 1;
	
	r = floor(random()*3);
	
	if (r == 0)
		sound (self, CHAN_VOICE, "weapons/explode3.wav", 1, ATTN_NORM);
	if (r == 1)
		sound (self, CHAN_VOICE, "weapons/explode4.wav", 1, ATTN_NORM);
	if (r == 2)
		sound (self, CHAN_VOICE, "weapons/explode5.wav", 1, ATTN_NORM);
	
	particle (self.origin, '0 0 0', 75, 255);
	T_BerthaDamage (self, self, 70, 140, world, "ffield_explode");
	
	BecomeExplosion ();
};


/*
===================
Spawn_ForceField
===================
*/
void() Spawn_ForceField =
{
	if (self.has_field == 0)
	{
		self.has_field = self.has_field + 1;
		
		field1 = spawn ();
		field1.maker = self;
		field1.movetype = MOVETYPE_TOSS;
		field1.solid = SOLID_SLIDEBOX;
		
		field1.health = 200;
		field1.takedamage = DAMAGE_AIM;
		field1.th_die = ForceField_Explode;
		
		field1.angles_y = self.angles_y;
		
		field1.nextthink = time + 0.1;
		field1.think = ForceField_Lightning;
		
		setmodel (field1, "progs/ffield.mdl");
		setsize (field1, '-16 -16 0', '16 16 56');
		setorigin (field1, self.origin + v_forward*64 + '0 0 16');
	}
	else
	{
		if (self.has_field == 2)
			return;
		
		self.has_field = 2;
		
		field2 = spawn ();
		field2.maker = self;
		field2.movetype = MOVETYPE_TOSS;
		field2.solid = SOLID_SLIDEBOX;
		
		field2.health = 200;
		field2.takedamage = DAMAGE_AIM;
		field2.th_die = ForceField_Explode;
		
		field2.angles_y = self.angles_y;
		
		field2.nextthink = time + 0.1;
		field2.think = NoFizzle;
		
		setmodel (field2, "progs/ffield.mdl");
		setsize (field2, '-16 -16 0', '16 16 56');
		setorigin (field2, self.origin + v_forward*64 + '0 0 16');
	}
};
Orion
Posts: 476
Joined: Fri Jan 12, 2007 6:32 pm
Location: Brazil

Post by Orion »

PS: when I destroy both of them, they work normally.
Dr. Shadowborg
InsideQC Staff
Posts: 1120
Joined: Sat Oct 16, 2004 3:34 pm

Post by Dr. Shadowborg »

Just guessing, but I'd say that you're not really properly linking the two.

EDIT: You've got it so that only the first generator actually generates lightning. What's more, a source generator is only created when you've got 0 existing generators. Since existing generators is only reduced by 1 when one is destroyed... You have to destroy both of them in order to get another source generator.

A better way perhaps might be to do a .entity so that you can tell your forcefield generators who their partner is. i.e. once you've spawned both generators, have it find both of them (either by having the player keep track of them upon spawning them with two .entity fields such as ffieldowned1 and ffieldowned2, or do a find/findradius), then do something like self.partner = whateveritspartneris for both generators.

Also don't forget to add a check/action for a generator in it's think function in the event that it's partner has been destroyed, otherwise it might do odd / odd looking things.
Post Reply