Forum

Lava Launcher

Discuss programming in the QuakeC language.

Moderator: InsideQC Admins

Lava Launcher

Postby redrum » Mon Oct 06, 2008 9:05 pm

Guys, I changed the Lightning Gun into a Lava Launcher.
Normally, the lava ball has a life span of 3 seconds. I want that when it hits water that it only has a life span of .5 seconds.
While the player is under water and he fires a lava ball it works fine. The problem arises when the player is out of water and the lava ball goes into the water it keeps it's 3 second life span.
The lines of code where I'm attempting this are at the bottom of void() W_FireLightning.
Here's my code:

Code: Select all
void(vector org) Flame_Burn =
{
        flame = spawn ();
        flame.owner = self;
        flame.classname = "lava";
        flame.movetype = MOVETYPE_FLYMISSILE;
        flame.solid = SOLID_NOT;
        flame.origin = org;
        flame.velocity = '0 0 75';
        setmodel (flame, "progs/flame2.mdl");
        setsize (flame, '0 0 0', '0 0 0');
        flame.nextthink = time + .01;
        flame.think = s_explode1;
};

void() Flame_Think =
{
        if (self.enemy.waterlevel == 3 || self.enemy.health <= 0)
        {
                BecomeExplosion ();
                return;
        }
        self.origin = self.enemy.origin + '0 0 25';
        if (random() < 0.66)                                                     
                  {
                  self.enemy.deathtype = "flame";
                  T_Damage (self.enemy, self, self.owner, .003);               
                  }
        self.nextthink = time + 0.01;
        self.classname = "lava";                         
};

void(vector org, entity e) Flame_Onfire =
{
        flame = spawn ();
        flame.owner = self.owner;
        flame.enemy = e;
        flame.classname = "lava";
        flame.movetype = MOVETYPE_NONE;
        flame.solid = SOLID_NOT;
        flame.origin = org;
        flame.velocity = '0 0 0';
        setmodel (flame, "progs/flame2.mdl");             
        setsize (flame, '0 0 -15', '0 0 0');
        flame.nextthink = time + 0.01;
        flame.think = Flame_Think;
        flame.effects = flame.effects | EF_DIMLIGHT;
};

void() Lava_Touch =
{
        local float    r;
        local vector   org;

   if (self.voided)
        {
             return;
   }

   self.voided = 1;
                                  
        T_RadiusDamage (self, self.owner, 10, self.owner, "lava");           

        Multi_Finish ();

        if (other != world)
           remove (self);

                r = random ();

                  if (r < 0.15)                                                                             
                  {
                        if ((other.classname == "player"))
                        {
                                centerprint (other,"You are on fire!\n\nFind WATER fast");
                                stuffcmd (other,"bf\n");
                        }
                        Flame_Onfire (org, other);
                  }
};

void() W_FireLightning =                                                                               
{
   if (self.ammo_cells < 1)
   {
      self.weapon = W_BestWeapon ();
      W_SetCurrentAmmo ();
      return;
   }
   
   self.currentammo = self.ammo_cells = self.ammo_cells - 1;
   
   sound (self, CHAN_WEAPON, "weapons/lava.wav", .8, ATTN_NORM);

        makevectors (self.angles);
        self.velocity = self.velocity - v_forward * 50;                                               
         
        if (self.health >= 1 && self.health <= 25)
        {
        makevectors (self.angles);
        self.velocity = self.velocity - v_forward * 100;                                               
        } 

   msg_entity = self;

   flame = spawn ();
   flame.voided=0;
   flame.owner = self;
   flame.movetype = MOVETYPE_BOUNCE;     
   flame.solid = SOLID_BBOX;
   flame.classname = "lava";   

   makevectors (self.v_angle);

   if (self.v_angle_x)
      flame.velocity = v_forward*500 + v_up * 225 + crandom()*v_right*25 + crandom()*v_up*25;
   else
   {
      flame.velocity = aim(self, 10000);
      flame.velocity = flame.velocity * 400;
      flame.velocity_z = 100;
   }

   flame.avelocity = '300 300 300';
   flame.angles = vectoangles(newmis.velocity);
   
   flame.touch = Lava_Touch;
        setmodel (flame, "progs/lavaball.mdl");
   setsize (flame, '0 0 0', '0 0 0');             
   setorigin (flame, self.origin);

   flame.nextthink = time + 3;

        if (flame.watertype == CONTENT_WATER)   //here's where I'm attempting the solution
           flame.nextthink = time + .5;

   if (pointcontents(flame.origin) == CONTENT_WATER)   //here's another attempt
      flame.nextthink = time + .5;
               
   flame.think = SUB_Remove;
};


Any help would be appreciated. Thanks in advance.
Welcome to the Overlook Hotel: The-Overlook-Hotel.game-server.cc
User avatar
redrum
 
Posts: 410
Joined: Wed Mar 28, 2007 11:35 pm
Location: Long Island, New York

Postby jim » Mon Oct 06, 2008 9:22 pm

I had similar problems with rockets that were supposed to travel at different speeds in water and air. So you fire the rocket under water and it go over water it keeps the under water speed, or fire from air to water, it keeps the air speed. I didn't solve it, I remember I had similar checks for the rocket too, but none worked.
zbang!
User avatar
jim
 
Posts: 599
Joined: Fri Aug 05, 2005 2:35 pm
Location: In The Sun

Postby r00k » Tue Oct 07, 2008 3:17 am

you're on the right track, the thing is that when the entity is spawned you are setting the think, and the nextthink at that instant.

Code: Select all
   flame.nextthink = time + 3;

        if (flame.watertype == CONTENT_WATER)   //here's where I'm attempting the solution
           flame.nextthink = time + .5;

   if (pointcontents(flame.origin) == CONTENT_WATER)   //here's another attempt
      flame.nextthink = time + .5;
               
   flame.think = SUB_Remove;


Basically means if the lava ball was spawned underwater it will set the removal 0.5 secods.
Instead, you must create another think function to be called during each frame (or so).
I had to do something very similar when I modified my ctf hook...

Add this function above void() W_FireLightning

Code: Select all
/*
Normally the lavaball would be removed in 3 seconds if out of water
Shooting into water will kill the ball in 1/2 a sec.
But shooting the ball out of water, into the air should sustain the ball's life at most 2.90 seconds.
*/

void() Lava_Check =
{
   if (pointcontents(self.origin) == CONTENT_WATER)
   {
      self.cnt = self.cnt - 0.3;//6x faster if touching water
   }
   else
   {
      self.cnt = self.cnt - 0.05;//Lava_check is called 20 times per second, so lets subtract the counter 1/20th per check
   }
   
   if (self.cnt < 1)
   {
      remove(self);
   }
   
   if (self)
   {
      self.nextthink = time + 0.05;
      self.think = Lava_Check;
   }   
}


then modify your void() W_FireLightning with this

Code: Select all
void() W_FireLightning =
{
   if (self.ammo_cells < 1)
   {
      self.weapon = W_BestWeapon ();
      W_SetCurrentAmmo ();
      return;
   }

   self.currentammo = self.ammo_cells = self.ammo_cells - 1;

   sound (self, CHAN_WEAPON, "weapons/lava.wav", .8, ATTN_NORM);

   makevectors (self.angles);
   self.velocity = self.velocity - v_forward * 50;

   if (self.health >= 1 && self.health <= 25)
   {
      makevectors (self.angles);
      self.velocity = self.velocity - v_forward * 100;
   }

   msg_entity = self;

   flame = spawn ();
   flame.voided=0;
   flame.owner = self;
   flame.movetype = MOVETYPE_BOUNCE;
   flame.solid = SOLID_BBOX;
   flame.classname = "lava";
   flame.cnt = 2.95;// R00k: Initial number of seconds we want the lavaball to die from time it was shot...
   
   makevectors (self.v_angle);

   if (self.v_angle_x)
   flame.velocity = v_forward*500 + v_up * 225 + crandom()*v_right*25 + crandom()*v_up*25;
   else
   {
      flame.velocity = aim(self, 10000);
      flame.velocity = flame.velocity * 400;
      flame.velocity_z = 100;
   }

   flame.avelocity = '300 300 300';
   flame.angles = vectoangles(newmis.velocity);

   flame.touch = Lava_Touch;
   setmodel (flame, "progs/lavaball.mdl");
   setsize (flame, '0 0 0', '0 0 0');
   setorigin (flame, self.origin);

//R00k: changed think function here
   flame.nextthink = time + 0.05;
   flame.think = Lava_Check;
};


Hope this helps :D
r00k
 
Posts: 1110
Joined: Sat Nov 13, 2004 10:39 pm

Postby redrum » Tue Oct 07, 2008 2:26 pm

Thanks! Can't wait to get home and try it. :D

Perfect solution!!! :D
Welcome to the Overlook Hotel: The-Overlook-Hotel.game-server.cc
User avatar
redrum
 
Posts: 410
Joined: Wed Mar 28, 2007 11:35 pm
Location: Long Island, New York

Postby r00k » Thu Oct 09, 2008 5:15 pm

Did it work for you as intended?
r00k
 
Posts: 1110
Joined: Sat Nov 13, 2004 10:39 pm

Postby redrum » Sat Oct 11, 2008 12:07 am

Yup! Exactly what I was looking for. Thanks!
Welcome to the Overlook Hotel: The-Overlook-Hotel.game-server.cc
User avatar
redrum
 
Posts: 410
Joined: Wed Mar 28, 2007 11:35 pm
Location: Long Island, New York


Return to QuakeC Programming

Who is online

Users browsing this forum: No registered users and 1 guest