Forum

Ogres shooting rockets - misfiring?

Discuss programming in the QuakeC language.

Moderator: InsideQC Admins

Ogres shooting rockets - misfiring?

Postby dayfive » Fri Dec 15, 2006 1:26 pm

Ok, so if someone could help me understand this, I would be most grateful!

so I thought it would be neat if Ogres randomly shoot rockets half the time so I added this extra function in Ogres.qc

Code: Select all
void() OgreRocketTouch =
{
   local float   damg;

   if (other == self.owner)
      return;      // don't explode on owner

   if (pointcontents(self.origin) == CONTENT_SKY)
   {
      remove(self);
      return;
   }

   damg = 50 + random()*20;
   
   if (other.health)
   {
      if (other.classname == "monster_shambler")
         damg = damg * 0.5;   // mostly immune
      T_Damage (other, self, self.owner, damg );
   }

   /* dont need extra radius damage since it returns the OgreGrenadeExplode() anyway */
//   T_RadiusDamage (self, self.owner, 40, other);

//   sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
   self.origin = self.origin - 8*normalize(self.velocity);

   WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
   WriteByte (MSG_BROADCAST, TE_EXPLOSION);
   WriteCoord (MSG_BROADCAST, self.origin_x);
   WriteCoord (MSG_BROADCAST, self.origin_y);
   WriteCoord (MSG_BROADCAST, self.origin_z);

   OgreGrenadeExplode ();
};


then I changed OgreFireGrenade() to this

Code: Select all
void() OgreFireGrenade =
{
   local   entity missile, mpuff;
   
   if (random() < 0.5)
   {
   self.effects = self.effects | EF_MUZZLEFLASH;

   sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);

   missile = spawn ();
   missile.owner = self;
   missile.movetype = MOVETYPE_BOUNCE;
   missile.solid = SOLID_BBOX;
      
// set missile speed   

   makevectors (self.angles);

   missile.velocity = normalize(self.enemy.origin - self.origin);
   missile.velocity = missile.velocity * 600;
   missile.velocity_z = 200;

   missile.avelocity = '300 300 300';

   missile.angles = vectoangles(missile.velocity);
   
   missile.touch = OgreGrenadeTouch;
   
// set missile duration
   missile.nextthink = time + 2.5;
   missile.think = OgreGrenadeExplode;

   setmodel (missile, "progs/grenade.mdl");
   setsize (missile, '0 0 0', '0 0 0');      
   setorigin (missile, self.origin);
   return;
   }


   if (random() > 0.5)
   {
   self.effects = self.effects | EF_MUZZLEFLASH;

   sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);

   missile = spawn ();
   missile.owner = self;
   missile.movetype = MOVETYPE_FLYMISSILE;
   missile.solid = SOLID_BBOX;
      
// set missile speed   

   makevectors (self.v_angle);
   missile.velocity = normalize(self.enemy.origin - self.origin);
   missile.velocity = missile.velocity * 1000;
   missile.angles = vectoangles(missile.velocity);
   
   missile.touch = OgreRocketTouch;
   
// set missile duration
   missile.nextthink = time + 2.5;
   missile.think = OgreGrenadeExplode;

   setmodel (missile, "progs/missile.mdl");
   setsize (missile, '0 0 0', '0 0 0');      
   setorigin (missile, self.origin + v_forward*8 + '0 0 16');
   return;
   }

};


and it pretty much does what I want, but I'm wondering why sometimes the Ogres will play the "firing grenade" animation but not shoot either a rocket or grenade (they shoot nothing as if a misfire)

what is the cause of this?
User avatar
dayfive
 
Posts: 77
Joined: Fri Nov 10, 2006 9:48 pm

Postby dayfive » Fri Dec 15, 2006 1:36 pm

also, if i comment out the "return;" lines, they still misfire but sometimes will fire a rocket AND grenade simultaneously!?

halp plz
User avatar
dayfive
 
Posts: 77
Joined: Fri Nov 10, 2006 9:48 pm

Postby dayfive » Fri Dec 15, 2006 1:47 pm

ok, ok, thanks to krimzon on IRC, i seem to have found a solution

here's what he said

krimzon wrote:07:29 < krimzon> float r; r = random(); if (r > 0.5) OgreShootMissile(); else
OgreShootRocket();
07:30 < krimzon> uhgjhg
07:30 < krimzon> float r; r = random(); if (r > 0.5) OgreShootMissile(); else
OgreShootGrenade();
07:31 < krimzon> actually, just remove the second if random() part
07:31 < krimzon> the first random picks the random number, half of the time it'll be less
than 0.5 and you'll shoot a grenade, then return
07:32 < krimzon> any code after that will be executed half the time
07:32 < krimzon> but then what you have is picking another random number, so shooting a
missile only half the time that a grenade isnt fired
07:32 < krimzon> so a quarter of the time nothing will be fired


and here's the revised OgreFireGrenade() function, a change from above is that the ogres will only fire rockets if on Hard or Nightmare skill.

Code: Select all
void() OgreFireGrenade =
{
   local   entity missile, mpuff;
   local   float r;
   r = random();

   if (skill == 3 || skill == 2)
   {
      if (r < 0.5)
      {
      self.effects = self.effects | EF_MUZZLEFLASH;
   
      sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
   
      missile = spawn ();
      missile.owner = self;
      missile.movetype = MOVETYPE_BOUNCE;
      missile.solid = SOLID_BBOX;
         
   // set missile speed   
   
      makevectors (self.angles);
   
      missile.velocity = normalize(self.enemy.origin - self.origin);
      missile.velocity = missile.velocity * 600;
      missile.velocity_z = 200;
   
      missile.avelocity = '300 300 300';
   
      missile.angles = vectoangles(missile.velocity);
      
      missile.touch = OgreGrenadeTouch;
      
   // set missile duration
      missile.nextthink = time + 2.5;
      missile.think = OgreGrenadeExplode;
   
      setmodel (missile, "progs/grenade.mdl");
      setsize (missile, '0 0 0', '0 0 0');      
      setorigin (missile, self.origin);
      return;
      }
   
   
      if (r > 0.5)
      {
      self.effects = self.effects | EF_MUZZLEFLASH;
   
      sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
   
      missile = spawn ();
      missile.owner = self;
      missile.movetype = MOVETYPE_FLYMISSILE;
      missile.solid = SOLID_BBOX;
         
   // set missile speed   
   
      makevectors (self.v_angle);
      missile.velocity = normalize(self.enemy.origin - self.origin);
      missile.velocity = missile.velocity * 1000;
      missile.angles = vectoangles(missile.velocity);
      
      missile.touch = OgreRocketTouch;
      
   // set missile duration
      missile.nextthink = time + 2.5;
      missile.think = OgreGrenadeExplode;
   
      setmodel (missile, "progs/missile.mdl");
      setsize (missile, '0 0 0', '0 0 0');      
      setorigin (missile, self.origin + v_forward*8 + '0 0 16');
      return;
      }
   }

   if (skill == 0 || skill == 1)
   {
   self.effects = self.effects | EF_MUZZLEFLASH;

   sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);

   missile = spawn ();
   missile.owner = self;
   missile.movetype = MOVETYPE_BOUNCE;
   missile.solid = SOLID_BBOX;
      
// set missile speed   

   makevectors (self.angles);

   missile.velocity = normalize(self.enemy.origin - self.origin);
   missile.velocity = missile.velocity * 600;
   missile.velocity_z = 200;

   missile.avelocity = '300 300 300';

   missile.angles = vectoangles(missile.velocity);
   
   missile.touch = OgreGrenadeTouch;
   
// set missile duration
   missile.nextthink = time + 2.5;
   missile.think = OgreGrenadeExplode;

   setmodel (missile, "progs/grenade.mdl");
   setsize (missile, '0 0 0', '0 0 0');      
   setorigin (missile, self.origin);
   }

};
User avatar
dayfive
 
Posts: 77
Joined: Fri Nov 10, 2006 9:48 pm

Postby Lardarse » Tue Dec 19, 2006 1:20 pm

You might also wanjt to check that the rocket is likely to reach its target, and not just fire straight into a wall.
User avatar
Lardarse
 
Posts: 266
Joined: Sat Nov 05, 2005 1:58 pm
Location: Bristol, UK


Return to QuakeC Programming

Who is online

Users browsing this forum: No registered users and 1 guest