Forum

Trying to make force field

Discuss programming in the QuakeC language.

Moderator: InsideQC Admins

Trying to make force field

Postby Orion » Fri Jan 12, 2007 6:46 pm

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

Postby Orion » Fri Jan 12, 2007 6:47 pm

PS: when I destroy both of them, they work normally.
User avatar
Orion
 
Posts: 476
Joined: Fri Jan 12, 2007 6:32 pm
Location: Brazil

Postby Dr. Shadowborg » Fri Jan 12, 2007 7:20 pm

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.
User avatar
Dr. Shadowborg
InsideQC Staff
 
Posts: 1110
Joined: Sat Oct 16, 2004 3:34 pm


Return to QuakeC Programming

Who is online

Users browsing this forum: No registered users and 1 guest