Trouble with Chainlightning gun.

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

Trouble with Chainlightning gun.

Post by Orion »

Hey, I've been trying to immitate Qtest's chainlightning gun, which is an LG that causes a chain reaction that when you shoot an enemy, he will also zap nearby entities and so on until no more entities are visible (really deadly), but I'm having no success so far, on rooms with more than 2 monsters I'm getting stack overflows. It only works fine when there are 2 visible monsters. I guess the cause is that after the third monster, it zaps back to a monster that has already been hit by lightning!

I'll post my code:

Code: Select all

void(entity e, entity from, entity last_from) ChainLightning =
{
	local vector org, vec;
	local entity head, found;
	local float best, d;
	
	org = (e.absmin + e.absmax) * 0.5;
	
	best = 600;
	head = findradius(org, best);
	while (head)
	{
		if (head != e)
		if (head != real_lg_owner)
		if (head != from)
		if (head != last_from)
		if (head.health > 0)
		if (head.takedamage == DAMAGE_AIM)
		{
			vec = (head.absmin + head.absmax) * 0.5;
			traceline (org, vec, FALSE, e);
			if (trace_ent == head)
			{
				d = vlen(vec - org);
				if (d < best)
				{
					best = d;
					found = head;
				}
			}
		}
		head = head.chain;
	}
	
	if (found)
	{
		vec = (found.absmin + found.absmax) * 0.5;
		traceline (org, vec, FALSE, e);
		WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
		WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
		WriteEntity (MSG_BROADCAST, e);
		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);
		if (trace_ent.takedamage)
		{
			particle (trace_endpos, '0 0 100', 225, 88);
			T_Damage (trace_ent, e, real_lg_owner, 22, "lightning");
			ChainLightning (trace_ent, e, from);
		}
	}
};
As you can see I created a new global real_lg_owner, which is the player who fired the LG so he doesn't get zapped back and get the proper frags. real_lg_owner is set before LightningDamage() in W_FireLightning().

And this is my modified LightningDamage(), only the center beam will trigger the chain reaction:

Code: Select all

void(vector p1, vector p2, entity from, float damage, string m) LightningDamage =
{
	local entity		e1, e2;
	local vector		f;
	local float t;
	
	f = normalize(p2 - p1);
	t = f_y;
	f_y = f_x;
	f_x = t * -1;
	f_z = 0;
	f = f*16;

	e1 = e2 = world;

	traceline (p1, p2, FALSE, from);
	if (trace_ent.takedamage)
	{
		particle (trace_endpos, '0 0 100', 225, damage*4);
		T_Damage (trace_ent, from, from, damage, m);
		if (real_lg_owner.classname == "player")
			ChainLightning (trace_ent, from, from);
	}
	e1 = trace_ent;

	traceline (p1 + f, p2 + f, FALSE, from);
	if (trace_ent != e1 && trace_ent.takedamage)
	{
		particle (trace_endpos, '0 0 100', 225, damage*4);
		T_Damage (trace_ent, from, from, damage, m);
	}
	e2 = trace_ent;
	
	traceline (p1 - f, p2 - f, FALSE, from);
	if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage)
	{
		particle (trace_endpos, '0 0 100', 225, damage*4);
		T_Damage (trace_ent, from, from, damage, m);
	}
};
I guess we have to mark entities already struck by lightning to be ignored, but I don't have a clue here.
Any help will be greatly appreciated. :mrgreen:
ceriux
Posts: 2230
Joined: Sat Sep 06, 2008 3:30 pm
Location: Indiana, USA

Re: Trouble with Chainlightning gun.

Post by ceriux »

Aren't enemies that are already dead, marked as dead? Try using that.if (enemy.state == dead_dead)

Skip stuff?
frag.machine
Posts: 2121
Joined: Sat Nov 25, 2006 1:49 pm

Re: Trouble with Chainlightning gun.

Post by frag.machine »

quick and dirty solution: reuse some float field (my favorites are aflag and cnt since monster code never refers them) as a "already hit" flag.

Also, you could have a counter limiting the number of lightnings fired at once.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
Orion
Posts: 476
Joined: Fri Jan 12, 2007 6:32 pm
Location: Brazil

Re: Trouble with Chainlightning gun.

Post by Orion »

Silly me, works like a charm. I also made the damage reduce by 40% as the lightning jumps further, until it reaches 1 and then no longer continues. :razz:
frag.machine
Posts: 2121
Joined: Sat Nov 25, 2006 1:49 pm

Re: Trouble with Chainlightning gun.

Post by frag.machine »

An interesting tweak would be to check the entity waterlevel and change the attenuation based on it.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
Post Reply