Trouble with Chainlightning gun.
Posted: Sat Oct 31, 2015 7:22 pm
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:
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:
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.
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);
}
}
};
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);
}
};
Any help will be greatly appreciated.