Forum

Trouble with Chainlightning gun.

Discuss programming in the QuakeC language.

Moderator: InsideQC Admins

Trouble with Chainlightning gun.

Postby Orion » 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:
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:
User avatar
Orion
 
Posts: 476
Joined: Fri Jan 12, 2007 6:32 pm
Location: Brazil

Re: Trouble with Chainlightning gun.

Postby ceriux » Sat Oct 31, 2015 8:47 pm

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

Skip stuff?
User avatar
ceriux
 
Posts: 2223
Joined: Sat Sep 06, 2008 3:30 pm
Location: Indiana, USA

Re: Trouble with Chainlightning gun.

Postby frag.machine » Sat Oct 31, 2015 9:14 pm

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)
User avatar
frag.machine
 
Posts: 2062
Joined: Sat Nov 25, 2006 1:49 pm

Re: Trouble with Chainlightning gun.

Postby Orion » Sun Nov 01, 2015 1:13 am

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:
User avatar
Orion
 
Posts: 476
Joined: Fri Jan 12, 2007 6:32 pm
Location: Brazil

Re: Trouble with Chainlightning gun.

Postby frag.machine » Sun Nov 01, 2015 1:52 am

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)
User avatar
frag.machine
 
Posts: 2062
Joined: Sat Nov 25, 2006 1:49 pm


Return to QuakeC Programming

Who is online

Users browsing this forum: No registered users and 1 guest