Forum

Damagable Chthon - printing health?

Discuss programming in the QuakeC language.

Moderator: InsideQC Admins

Damagable Chthon - printing health?

Postby dayfive » Mon Dec 18, 2006 5:14 am

hi

i was looking at some of the tutorials and i saw the damageable Chthon one and I was wondering what might be the best way to print Chthon's current health when he's damaged

here's the code i have, which is loosely based on http://www.inside3d.com/showtutorial.php?id=78 relevant parts to this question are in yellow

Code: Select all
/*
==============================================================================

BOSS-ONE

==============================================================================
*/
$cd id1/models/boss1
$origin 0 0 -15
$base base
$skin skin
$scale 5

$frame rise1 rise2 rise3 rise4 rise5 rise6 rise7 rise8 rise9 rise10
$frame rise11 rise12 rise13 rise14 rise15 rise16 rise17

$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8
$frame walk9 walk10 walk11 walk12 walk13 walk14 walk15
$frame walk16 walk17 walk18 walk19 walk20 walk21 walk22
$frame walk23 walk24 walk25 walk26 walk27 walk28 walk29 walk30 walk31

$frame death1 death2 death3 death4 death5 death6 death7 death8 death9

$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8
$frame attack9 attack10 attack11 attack12 attack13 attack14 attack15
$frame attack16 attack17 attack18 attack19 attack20 attack21 attack22
$frame attack23

$frame shocka1 shocka2 shocka3 shocka4 shocka5 shocka6 shocka7 shocka8
$frame shocka9 shocka10

$frame shockb1 shockb2 shockb3 shockb4 shockb5 shockb6

$frame shockc1 shockc2 shockc3 shockc4 shockc5 shockc6 shockc7 shockc8
$frame shockc9 shockc10


void() print_health =
{

// where's the best place to call this function?
// adding it to every other boss function in this file works,
// but it always updates AFTER all damage is
// registered. How can it be instantaneously registered?
// Does it have to be called from each weapon firing
// function???


local string h;
h = ftos(self.health);

centerprint(self.enemy, h);
};

Code: Select all
void(vector p) boss_missile;

void() boss_face =
{
   
// go for another player if multi player
   if (self.enemy.health <= 0 || random() < 0.02)
   {
      self.enemy = find(self.enemy, classname, "player");
      if (!self.enemy)
         self.enemy = find(self.enemy, classname, "player");
   }
   ai_face();
};

void() boss_rise1   =[   $rise1, boss_rise2 ] {
sound (self, CHAN_WEAPON, "boss1/out1.wav", 1, ATTN_NORM);
};
void() boss_rise2   =[   $rise2, boss_rise3 ] {
sound (self, CHAN_VOICE, "boss1/sight1.wav", 1, ATTN_NORM);
};
void() boss_rise3   =[   $rise3, boss_rise4 ] {};
void() boss_rise4   =[   $rise4, boss_rise5 ] {};
void() boss_rise5   =[   $rise5, boss_rise6 ] {};
void() boss_rise6   =[   $rise6, boss_rise7 ] {};
void() boss_rise7   =[   $rise7, boss_rise8 ] {};
void() boss_rise8   =[   $rise8, boss_rise9 ] {};
void() boss_rise9   =[   $rise9, boss_rise10 ] {};
void() boss_rise10   =[   $rise10, boss_rise11 ] {};
void() boss_rise11   =[   $rise11, boss_rise12 ] {};
void() boss_rise12   =[   $rise12, boss_rise13 ] {};
void() boss_rise13   =[   $rise13, boss_rise14 ] {};
void() boss_rise14   =[   $rise14, boss_rise15 ] {};
void() boss_rise15   =[   $rise15, boss_rise16 ] {};
void() boss_rise16   =[   $rise16, boss_rise17 ] {};
void() boss_rise17   =[   $rise17, boss_missile1 ] {};

void() boss_idle1   =[   $walk1, boss_idle2 ]
{
// look for other players
};
void() boss_idle2   =[   $walk2, boss_idle3 ] {boss_face();};
void() boss_idle3   =[   $walk3, boss_idle4 ] {boss_face();};
void() boss_idle4   =[   $walk4, boss_idle5 ] {boss_face();};
void() boss_idle5   =[   $walk5, boss_idle6 ] {boss_face();};
void() boss_idle6   =[   $walk6, boss_idle7 ] {boss_face();};
void() boss_idle7   =[   $walk7, boss_idle8 ] {boss_face();};
void() boss_idle8   =[   $walk8, boss_idle9 ] {boss_face();};
void() boss_idle9   =[   $walk9, boss_idle10 ] {boss_face();};
void() boss_idle10   =[   $walk10, boss_idle11 ] {boss_face();};
void() boss_idle11   =[   $walk11, boss_idle12 ] {boss_face();};
void() boss_idle12   =[   $walk12, boss_idle13 ] {boss_face();};
void() boss_idle13   =[   $walk13, boss_idle14 ] {boss_face();};
void() boss_idle14   =[   $walk14, boss_idle15 ] {boss_face();};
void() boss_idle15   =[   $walk15, boss_idle16 ] {boss_face();};
void() boss_idle16   =[   $walk16, boss_idle17 ] {boss_face();};
void() boss_idle17   =[   $walk17, boss_idle18 ] {boss_face();};
void() boss_idle18   =[   $walk18, boss_idle19 ] {boss_face();};
void() boss_idle19   =[   $walk19, boss_idle20 ] {boss_face();};
void() boss_idle20   =[   $walk20, boss_idle21 ] {boss_face();};
void() boss_idle21   =[   $walk21, boss_idle22 ] {boss_face();};
void() boss_idle22   =[   $walk22, boss_idle23 ] {boss_face();};
void() boss_idle23   =[   $walk23, boss_idle24 ] {boss_face();};
void() boss_idle24   =[   $walk24, boss_idle25 ] {boss_face();};
void() boss_idle25   =[   $walk25, boss_idle26 ] {boss_face();};
void() boss_idle26   =[   $walk26, boss_idle27 ] {boss_face();};
void() boss_idle27   =[   $walk27, boss_idle28 ] {boss_face();};
void() boss_idle28   =[   $walk28, boss_idle29 ] {boss_face();};
void() boss_idle29   =[   $walk29, boss_idle30 ] {boss_face();};
void() boss_idle30   =[   $walk30, boss_idle31 ] {boss_face();};
void() boss_idle31   =[   $walk31, boss_idle1 ] {boss_face();};

void() boss_missile1   =[   $attack1, boss_missile2 ] {boss_missile('100 100 200');};
void() boss_missile2   =[   $attack2, boss_missile3 ] {boss_face();};
void() boss_missile3   =[   $attack3, boss_missile4 ] {boss_face();};
void() boss_missile4   =[   $attack4, boss_missile5 ] {boss_face();};
void() boss_missile5   =[   $attack5, boss_missile6 ] {boss_missile('100 100 200');};
void() boss_missile6   =[   $attack6, boss_missile7 ] {boss_face();};
void() boss_missile7   =[   $attack7, boss_missile8 ] {boss_missile('100 -100 200');};
void() boss_missile8   =[   $attack8, boss_missile9 ] {boss_face();};
void() boss_missile9   =[   $attack9, boss_missile10 ] {boss_face();};
void() boss_missile10   =[   $attack10, boss_missile11 ] {boss_face();};
void() boss_missile11   =[   $attack11, boss_missile12 ] {boss_missile('100 -100 200');};
void() boss_missile12   =[   $attack12, boss_missile13 ] {boss_face();};
void() boss_missile13   =[   $attack13, boss_missile14 ] {boss_missile('100 100 200');};
void() boss_missile14   =[   $attack14, boss_missile15 ] {boss_face();};
void() boss_missile15   =[   $attack15, boss_missile16 ] {boss_face();};
void() boss_missile16   =[   $attack16, boss_missile17 ] {boss_face();};
void() boss_missile17   =[   $attack17, boss_missile18 ] {boss_missile('100 100 200');};
void() boss_missile18   =[   $attack18, boss_missile19 ] {boss_face();};
void() boss_missile19   =[   $attack19, boss_missile20 ] {boss_face();};
void() boss_missile20   =[   $attack20, boss_missile21 ] {boss_missile('100 -100 200');};
void() boss_missile21   =[   $attack21, boss_missile22 ] {boss_face();};
void() boss_missile22   =[   $attack22, boss_missile23 ] {boss_missile('100 100 200');};
void() boss_missile23   =[   $attack23, boss_missile1 ] {boss_face();};

void() boss_shocka1 =[   $shocka1, boss_shocka2 ] {boss_missile('100 100 200');};
void() boss_shocka2 =[   $shocka2, boss_shocka3 ] {boss_face();};
void() boss_shocka3 =[   $shocka3, boss_shocka4 ] {boss_face();};
void() boss_shocka4 =[   $shocka4, boss_shocka5 ] {boss_face();};
void() boss_shocka5 =[   $shocka5, boss_shocka6 ] {boss_missile('100 -100 200');};
void() boss_shocka6 =[   $shocka6, boss_shocka7 ] {boss_face();};
void() boss_shocka7 =[   $shocka7, boss_shocka8 ] {boss_face();};
void() boss_shocka8 =[   $shocka8, boss_shocka9 ] {boss_face();};
void() boss_shocka9 =[   $shocka9, boss_shocka10 ] {boss_face();};
void() boss_shocka10 =[   $shocka10, boss_missile1 ] {boss_missile('100 -100 200');};

void() boss_shockb1 =[   $shockb1, boss_shockb2 ] {boss_missile('100 -100 200');};
void() boss_shockb2 =[   $shockb2, boss_shockb3 ] {boss_face();};
void() boss_shockb3 =[   $shockb3, boss_shockb4 ] {boss_face();};
void() boss_shockb4 =[   $shockb4, boss_shockb5 ] {boss_face();};
void() boss_shockb5 =[   $shockb5, boss_shockb6 ] {boss_missile('100 -100 200');};
void() boss_shockb6 =[   $shockb6, boss_shockb7 ] {boss_face();};
void() boss_shockb7 =[   $shockb1, boss_shockb8 ] {boss_face();};
void() boss_shockb8 =[   $shockb2, boss_shockb9 ] {boss_face();};
void() boss_shockb9 =[   $shockb3, boss_shockb10 ] {boss_face();};
void() boss_shockb10 =[   $shockb4, boss_missile1 ] {boss_missile('100 100 200');};

void() boss_shockc1 =[   $shockc1, boss_shockc2 ] {};
void() boss_shockc2 =[   $shockc2, boss_shockc3 ] {};
void() boss_shockc3 =[   $shockc3, boss_shockc4 ] {};
void() boss_shockc4 =[   $shockc4, boss_shockc5 ] {};
void() boss_shockc5 =[   $shockc5, boss_shockc6 ] {};
void() boss_shockc6 =[   $shockc6, boss_shockc7 ] {};
void() boss_shockc7 =[   $shockc7, boss_shockc8 ] {};
void() boss_shockc8 =[   $shockc8, boss_shockc9 ] {};
void() boss_shockc9 =[   $shockc9, boss_shockc10 ] {};
void() boss_shockc10 =[   $shockc10, boss_death1 ] {};

void() boss_pain1 =[ $shocka1, boss_pain2 ] {};
void() boss_pain2 =[ $shocka1, boss_pain3 ] {};
void() boss_pain3 =[ $shocka1, boss_pain4 ] {
sound (self, CHAN_VOICE, "boss1/pain.wav", 1, ATTN_NORM);};  // pain sound
void() boss_pain4 =[ $shocka1, boss_pain5 ] {};
void() boss_pain5 =[ $shocka1, boss_pain6 ] {};
void() boss_pain6 =[ $shocka1, boss_pain7 ] {};
void() boss_pain7 =[ $shocka1, boss_pain8 ] {};
void() boss_pain8 =[ $shocka1, boss_pain9 ] {};
void() boss_pain9 =[ $shocka1, boss_missile1 ] {};  // auto shoot lavaball


void() boss_death1 = [$death1, boss_death2] {
sound (self, CHAN_VOICE, "boss1/death.wav", 1, ATTN_NORM);
};
void() boss_death2 = [$death2, boss_death3] {};
void() boss_death3 = [$death3, boss_death4] {};
void() boss_death4 = [$death4, boss_death5] {};
void() boss_death5 = [$death5, boss_death6] {};
void() boss_death6 = [$death6, boss_death7] {};
void() boss_death7 = [$death7, boss_death8] {};
void() boss_death8 = [$death8, boss_death9] {};
void() boss_death9 = [$death9, boss_death10]
{
   sound (self, CHAN_BODY, "boss1/out1.wav", 1, ATTN_NORM);
   WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
   WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
   WriteCoord (MSG_BROADCAST, self.origin_x);
   WriteCoord (MSG_BROADCAST, self.origin_y);
   WriteCoord (MSG_BROADCAST, self.origin_z);
};


void() boss_death10 = [$death9, boss_death10]
{
   killed_monsters = killed_monsters + 1;
   WriteByte (MSG_ALL, SVC_KILLEDMONSTER);   // FIXME: reliable broadcast
   SUB_UseTargets ();
   remove (self);
};

void(vector p) boss_missile =
{
   local   vector   offang;
   local   vector   org, vec, d;
   local   float   t;
   
   offang = vectoangles (self.enemy.origin - self.origin);   
   makevectors (offang);

   org = self.origin + p_x*v_forward + p_y*v_right + p_z*'0 0 1';
   
// lead the player on hard mode
   if (skill > 1)
   {
      t = vlen(self.enemy.origin - org) / 300;
      vec = self.enemy.velocity;
      vec_z = 0;
      d = self.enemy.origin + t * vec;      
   }
   else
   {
      d = self.enemy.origin;
   }
   
   vec = normalize (d - org);

   launch_spike (org, vec);
   setmodel (newmis, "progs/lavaball.mdl");
   newmis.avelocity = '200 100 300';
   setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);      
   newmis.velocity = vec*300;
   newmis.touch = T_MissileTouch; // rocket explosion
   sound (self, CHAN_WEAPON, "boss1/throw.wav", 1, ATTN_NORM);

// check for dead enemy
   if (self.enemy.health <= 0)
      boss_idle1 ();
   
};


void() boss_awake =
{   
   self.solid = SOLID_SLIDEBOX;
   self.movetype = MOVETYPE_STEP;
   self.takedamage = DAMAGE_YES;
   
   setmodel (self, "progs/boss.mdl");
   setsize (self, '-128 -128 -24', '128 128 256');
   
   if (skill == 0)
      self.health = 1000;
   else
      self.health = 3000;

   self.th_die = boss_death1;
   self.enemy = activator;
   
   WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
   WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
   WriteCoord (MSG_BROADCAST, self.origin_x);
   WriteCoord (MSG_BROADCAST, self.origin_y);
   WriteCoord (MSG_BROADCAST, self.origin_z);

   self.yaw_speed = 20;
   boss_rise1 ();
};


/*QUAKED monster_boss (1 0 0) (-128 -128 -24) (128 128 256)
*/
void() monster_boss =
{   
   if (deathmatch)
   {
      remove(self);
      return;
   }
   precache_model ("progs/boss.mdl");
   precache_model ("progs/lavaball.mdl");

   precache_sound ("weapons/rocket1i.wav");
   precache_sound ("boss1/out1.wav");
   precache_sound ("boss1/sight1.wav");
   precache_sound ("misc/power.wav");
   precache_sound ("boss1/throw.wav");
   precache_sound ("boss1/pain.wav");
   precache_sound ("boss1/death.wav");
   
   total_monsters = total_monsters + 1;

   self.use = boss_awake;
   
   if (!(self.th_die))
   {
      if(random() < 0.25)
      {
         self.th_pain = boss_shocka1;
      }
      else
      {
         self.th_pain = boss_shockb1;
      }
   }
};

//===========================================================================

entity   le1, le2;
float   lightning_end;

void() lightning_fire =
{
   local vector p1, p2;
   
   if (time >= lightning_end)
   {   // done here, put the terminals back up
      self = le1;
      door_go_down ();
      self = le2;
      door_go_down ();
      return;
   }
   
   p1 = (le1.mins + le1.maxs) * 0.5;
   p1_z = le1.absmin_z - 16;
   
   p2 = (le2.mins + le2.maxs) * 0.5;
   p2_z = le2.absmin_z - 16;
   
   // compensate for length of bolt
   p2 = p2 - normalize(p2-p1)*100;

   self.nextthink = time + 0.1;
   self.think = lightning_fire;

   WriteByte (MSG_ALL, SVC_TEMPENTITY);
   WriteByte (MSG_ALL, TE_LIGHTNING3);
   WriteEntity (MSG_ALL, world);
   WriteCoord (MSG_ALL, p1_x);
   WriteCoord (MSG_ALL, p1_y);
   WriteCoord (MSG_ALL, p1_z);
   WriteCoord (MSG_ALL, p2_x);
   WriteCoord (MSG_ALL, p2_y);
   WriteCoord (MSG_ALL, p2_z);
};

void() lightning_use =
{
   if (lightning_end >= time + 1)
      return;

   le1 = find( world, target, "lightning");
   le2 = find( le1, target, "lightning");
   if (!le1 || !le2)
   {
      dprint ("missing lightning targets\n");
      return;
   }
   
   if (
    (le1.state != STATE_TOP && le1.state != STATE_BOTTOM)
   || (le2.state != STATE_TOP && le2.state != STATE_BOTTOM)
   || (le1.state != le2.state) )
   {
//      dprint ("not aligned\n");
      return;
   }

// don't let the electrodes go back up until the bolt is done
   le1.nextthink = -1;
   le2.nextthink = -1;
   lightning_end = time + 1;

   sound (self, CHAN_VOICE, "misc/power.wav", 1, ATTN_NORM);
   lightning_fire ();      

// advance the boss pain if down
   self = find (world, classname, "monster_boss");
   if (!self)
      return;
   self.enemy = activator;
   if (le1.state == STATE_TOP && self.health > 0)
   {
      sound (self, CHAN_VOICE, "boss1/pain.wav", 1, ATTN_NORM);
      self.health = self.health - 250;
      if (self.health >= 800)
         boss_shocka1();
      else if (self.health == 500)
         boss_shockb1();
      else if (self.health == 0)
         boss_shockc1();
   }   
};


/*QUAKED event_lightning (0 1 1) (-16 -16 -16) (16 16 16)
Just for boss level.
*/
void() event_lightning =
{
   self.use = lightning_use;
};
User avatar
dayfive
 
Posts: 77
Joined: Fri Nov 10, 2006 9:48 pm

Postby Entar » Mon Dec 18, 2006 8:42 am

You'll want it somewhere in the boss_pain stuff, I should think.
User avatar
Entar
 
Posts: 439
Joined: Fri Nov 05, 2004 7:27 pm
Location: At my computer

Postby dayfive » Mon Dec 18, 2006 8:01 pm

Entar wrote:You'll want it somewhere in the boss_pain stuff, I should think.


Thank you! That does the trick. It seems so obvious now.

Here is the fixed version (boss.c)

Code: Select all
/*
==============================================================================

BOSS-ONE

Directly damageable and skill based health points.

./d5

==============================================================================
*/
$cd id1/models/boss1
$origin 0 0 -15
$base base
$skin skin
$scale 5

$frame rise1 rise2 rise3 rise4 rise5 rise6 rise7 rise8 rise9 rise10
$frame rise11 rise12 rise13 rise14 rise15 rise16 rise17

$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8
$frame walk9 walk10 walk11 walk12 walk13 walk14 walk15
$frame walk16 walk17 walk18 walk19 walk20 walk21 walk22
$frame walk23 walk24 walk25 walk26 walk27 walk28 walk29 walk30 walk31

$frame death1 death2 death3 death4 death5 death6 death7 death8 death9

$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8
$frame attack9 attack10 attack11 attack12 attack13 attack14 attack15
$frame attack16 attack17 attack18 attack19 attack20 attack21 attack22
$frame attack23

$frame shocka1 shocka2 shocka3 shocka4 shocka5 shocka6 shocka7 shocka8
$frame shocka9 shocka10

$frame shockb1 shockb2 shockb3 shockb4 shockb5 shockb6

$frame shockc1 shockc2 shockc3 shockc4 shockc5 shockc6 shockc7 shockc8
$frame shockc9 shockc10

void() print_health =
{
   local   string  h;
   h = ftos(self.health);
//   centerprint(self.enemy, "Chthon's Current Health: ");
   centerprint(self.enemy, h);
};

void(vector p) boss_missile;

void() boss_face =
{
   
// go for another player if multi player
   if (self.enemy.health <= 0 || random() < 0.02)
   {
      self.enemy = find(self.enemy, classname, "player");
      if (!self.enemy)
         self.enemy = find(self.enemy, classname, "player");
   }
   ai_face();
};

void() boss_rise1   =[   $rise1, boss_rise2 ] {
sound (self, CHAN_WEAPON, "boss1/out1.wav", 1, ATTN_NORM);
};
void() boss_rise2   =[   $rise2, boss_rise3 ] {
sound (self, CHAN_VOICE, "boss1/sight1.wav", 1, ATTN_NORM);
};
void() boss_rise3   =[   $rise3, boss_rise4 ] {};
void() boss_rise4   =[   $rise4, boss_rise5 ] {};
void() boss_rise5   =[   $rise5, boss_rise6 ] {};
void() boss_rise6   =[   $rise6, boss_rise7 ] {};
void() boss_rise7   =[   $rise7, boss_rise8 ] {};
void() boss_rise8   =[   $rise8, boss_rise9 ] {};
void() boss_rise9   =[   $rise9, boss_rise10 ] {};
void() boss_rise10   =[   $rise10, boss_rise11 ] {};
void() boss_rise11   =[   $rise11, boss_rise12 ] {};
void() boss_rise12   =[   $rise12, boss_rise13 ] {};
void() boss_rise13   =[   $rise13, boss_rise14 ] {};
void() boss_rise14   =[   $rise14, boss_rise15 ] {};
void() boss_rise15   =[   $rise15, boss_rise16 ] {};
void() boss_rise16   =[   $rise16, boss_rise17 ] {};
void() boss_rise17   =[   $rise17, boss_missile1 ] {};

void() boss_idle1   =[   $walk1, boss_idle2 ]
{
// look for other players
};
void() boss_idle2   =[   $walk2, boss_idle3 ] {boss_face();};
void() boss_idle3   =[   $walk3, boss_idle4 ] {boss_face();};
void() boss_idle4   =[   $walk4, boss_idle5 ] {boss_face();};
void() boss_idle5   =[   $walk5, boss_idle6 ] {boss_face();};
void() boss_idle6   =[   $walk6, boss_idle7 ] {boss_face();};
void() boss_idle7   =[   $walk7, boss_idle8 ] {boss_face();};
void() boss_idle8   =[   $walk8, boss_idle9 ] {boss_face();};
void() boss_idle9   =[   $walk9, boss_idle10 ] {boss_face();};
void() boss_idle10   =[   $walk10, boss_idle11 ] {boss_face();};
void() boss_idle11   =[   $walk11, boss_idle12 ] {boss_face();};
void() boss_idle12   =[   $walk12, boss_idle13 ] {boss_face();};
void() boss_idle13   =[   $walk13, boss_idle14 ] {boss_face();};
void() boss_idle14   =[   $walk14, boss_idle15 ] {boss_face();};
void() boss_idle15   =[   $walk15, boss_idle16 ] {boss_face();};
void() boss_idle16   =[   $walk16, boss_idle17 ] {boss_face();};
void() boss_idle17   =[   $walk17, boss_idle18 ] {boss_face();};
void() boss_idle18   =[   $walk18, boss_idle19 ] {boss_face();};
void() boss_idle19   =[   $walk19, boss_idle20 ] {boss_face();};
void() boss_idle20   =[   $walk20, boss_idle21 ] {boss_face();};
void() boss_idle21   =[   $walk21, boss_idle22 ] {boss_face();};
void() boss_idle22   =[   $walk22, boss_idle23 ] {boss_face();};
void() boss_idle23   =[   $walk23, boss_idle24 ] {boss_face();};
void() boss_idle24   =[   $walk24, boss_idle25 ] {boss_face();};
void() boss_idle25   =[   $walk25, boss_idle26 ] {boss_face();};
void() boss_idle26   =[   $walk26, boss_idle27 ] {boss_face();};
void() boss_idle27   =[   $walk27, boss_idle28 ] {boss_face();};
void() boss_idle28   =[   $walk28, boss_idle29 ] {boss_face();};
void() boss_idle29   =[   $walk29, boss_idle30 ] {boss_face();};
void() boss_idle30   =[   $walk30, boss_idle31 ] {boss_face();};
void() boss_idle31   =[   $walk31, boss_idle1 ] {boss_face();};

void() boss_missile1   =[   $attack1, boss_missile2 ] {boss_missile('100 100 200');};
void() boss_missile2   =[   $attack2, boss_missile3 ] {boss_face();};
void() boss_missile3   =[   $attack3, boss_missile4 ] {boss_missile('100 -100 200');};
void() boss_missile4   =[   $attack4, boss_missile5 ] {boss_face();};
void() boss_missile5   =[   $attack5, boss_missile6 ] {boss_missile('100 100 200');};
void() boss_missile6   =[   $attack6, boss_missile7 ] {boss_face();};
void() boss_missile7   =[   $attack7, boss_missile8 ] {boss_missile('100 -100 200');};
void() boss_missile8   =[   $attack8, boss_missile9 ] {boss_face();};
void() boss_missile9   =[   $attack9, boss_missile10 ] {boss_face();};
void() boss_missile10   =[   $attack10, boss_missile11 ] {boss_face();};
void() boss_missile11   =[   $attack11, boss_missile12 ] {boss_missile('100 -100 200');};
void() boss_missile12   =[   $attack12, boss_missile13 ] {boss_face();};
void() boss_missile13   =[   $attack13, boss_missile14 ] {boss_missile('100 100 200');};
void() boss_missile14   =[   $attack14, boss_missile15 ] {boss_face();};
void() boss_missile15   =[   $attack15, boss_missile16 ] {boss_missile('100 -100 200');};
void() boss_missile16   =[   $attack16, boss_missile17 ] {boss_face();};
void() boss_missile17   =[   $attack17, boss_missile18 ] {boss_missile('100 100 200');};
void() boss_missile18   =[   $attack18, boss_missile19 ] {boss_face();};
void() boss_missile19   =[   $attack19, boss_missile20 ] {boss_face();};
void() boss_missile20   =[   $attack20, boss_missile21 ] {boss_missile('100 -100 200');};
void() boss_missile21   =[   $attack21, boss_missile22 ] {boss_face();};
void() boss_missile22   =[   $attack22, boss_missile23 ] {boss_missile('100 100 200');};
void() boss_missile23   =[   $attack23, boss_missile1 ] {boss_face();};

void() boss_shocka1 =[   $shocka1, boss_shocka2 ] {boss_missile('100 100 200');print_health();};
void() boss_shocka2 =[   $shocka2, boss_shocka3 ] {boss_face();};
void() boss_shocka3 =[   $shocka3, boss_shocka4 ] {boss_face();};
void() boss_shocka4 =[   $shocka4, boss_shocka5 ] {boss_face();sound (self, CHAN_VOICE, "boss1/pain.wav", 1, ATTN_NORM);};
void() boss_shocka5 =[   $shocka5, boss_shocka6 ] {boss_missile('100 -100 200');};
void() boss_shocka6 =[   $shocka6, boss_shocka7 ] {boss_face();};
void() boss_shocka7 =[   $shocka7, boss_shocka8 ] {boss_missile('100 -100 200');};
void() boss_shocka8 =[   $shocka8, boss_shocka9 ] {boss_face();};
void() boss_shocka9 =[   $shocka9, boss_shocka10 ] {boss_face();};
void() boss_shocka10 =[   $shocka10, boss_missile1 ] {boss_missile('100 -100 200');};

void() boss_shockb1 =[   $shockb1, boss_shockb2 ] {boss_missile('100 -100 200');print_health();};
void() boss_shockb2 =[   $shockb2, boss_shockb3 ] {boss_face();};
void() boss_shockb3 =[   $shockb3, boss_shockb4 ] {boss_missile('100 100 200');};
void() boss_shockb4 =[   $shockb4, boss_shockb5 ] {boss_face();sound (self, CHAN_VOICE, "boss1/sight1.wav", 1, ATTN_NORM);};
void() boss_shockb5 =[   $shockb5, boss_shockb6 ] {boss_missile('100 -100 200');};
void() boss_shockb6 =[   $shockb6, boss_shockb7 ] {boss_face();};
void() boss_shockb7 =[   $shockb1, boss_shockb8 ] {boss_face();};
void() boss_shockb8 =[   $shockb2, boss_shockb9 ] {boss_missile('100 -100 200');};
void() boss_shockb9 =[   $shockb3, boss_shockb10 ] {boss_face();};
void() boss_shockb10 =[   $shockb4, boss_missile1 ] {boss_missile('100 100 200');};

void() boss_shockc1 =[   $shockc1, boss_shockc2 ] {print_health();};
void() boss_shockc2 =[   $shockc2, boss_shockc3 ] {};
void() boss_shockc3 =[   $shockc3, boss_shockc4 ] {};
void() boss_shockc4 =[   $shockc4, boss_shockc5 ] {};
void() boss_shockc5 =[   $shockc5, boss_shockc6 ] {};
void() boss_shockc6 =[   $shockc6, boss_shockc7 ] {};
void() boss_shockc7 =[   $shockc7, boss_shockc8 ] {};
void() boss_shockc8 =[   $shockc8, boss_shockc9 ] {};
void() boss_shockc9 =[   $shockc9, boss_shockc10 ] {};
void() boss_shockc10 =[   $shockc10, boss_death1 ] {};

void() boss_pain1 =[ $shocka1, boss_pain2 ] {print_health();};
void() boss_pain2 =[ $shocka1, boss_pain3 ] {};
void() boss_pain3 =[ $shocka1, boss_pain4 ] {
sound (self, CHAN_VOICE, "boss1/pain.wav", 1, ATTN_NORM);};  // pain sound
void() boss_pain4 =[ $shocka1, boss_pain5 ] {};
void() boss_pain5 =[ $shocka1, boss_pain6 ] {};
void() boss_pain6 =[ $shocka1, boss_pain7 ] {};
void() boss_pain7 =[ $shocka1, boss_pain8 ] {};
void() boss_pain8 =[ $shocka1, boss_pain9 ] {};
void() boss_pain9 =[ $shocka1, boss_missile1 ] {};  // auto shoot lavaball


void() boss_death1 = [$death1, boss_death2] {
sound (self, CHAN_VOICE, "boss1/death.wav", 1, ATTN_NORM);
print_health();
};
void() boss_death2 = [$death2, boss_death3] {};
void() boss_death3 = [$death3, boss_death4] {};
void() boss_death4 = [$death4, boss_death5] {};
void() boss_death5 = [$death5, boss_death6] {};
void() boss_death6 = [$death6, boss_death7] {};
void() boss_death7 = [$death7, boss_death8] {};
void() boss_death8 = [$death8, boss_death9] {};
void() boss_death9 = [$death9, boss_death10]
{
   sound (self, CHAN_BODY, "boss1/out1.wav", 1, ATTN_NORM);
   WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
   WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
   WriteCoord (MSG_BROADCAST, self.origin_x);
   WriteCoord (MSG_BROADCAST, self.origin_y);
   WriteCoord (MSG_BROADCAST, self.origin_z);
};


void() boss_death10 = [$death9, boss_death10]
{
   killed_monsters = killed_monsters + 1;
   WriteByte (MSG_ALL, SVC_KILLEDMONSTER);   // FIXME: reliable broadcast
   SUB_UseTargets ();
   remove (self);
};

void(vector p) boss_missile =
{
   local   vector   offang;
   local   vector   org, vec, d;
   local   float   t;
   
   offang = vectoangles (self.enemy.origin - self.origin);   
   makevectors (offang);

   org = self.origin + p_x*v_forward + p_y*v_right + p_z*'0 0 1';
   
// lead the player on hard mode
   if (skill > 1)
   {
      t = vlen(self.enemy.origin - org) / 300;
      vec = self.enemy.velocity;
      vec_z = 0;
      d = self.enemy.origin + t * vec;      
   }
   else
   {
      d = self.enemy.origin;
   }
   
   vec = normalize (d - org);

   launch_spike (org, vec);
   setmodel (newmis, "progs/lavaball.mdl");
   newmis.avelocity = '200 100 300';
   setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);      
   newmis.velocity = vec*300;
   newmis.touch = T_MissileTouch; // rocket explosion
   sound (self, CHAN_WEAPON, "boss1/throw.wav", 1, ATTN_NORM);

// check for dead enemy
   if (self.enemy.health <= 0)
      boss_idle1 ();
   
};


void() boss_awake =
{   
   self.solid = SOLID_SLIDEBOX;
   self.movetype = MOVETYPE_STEP;
   self.takedamage = DAMAGE_YES;
   
   setmodel (self, "progs/boss.mdl");
   setsize (self, '-128 -128 -24', '128 128 256');
   
   if (skill == 0)
      self.health = 3000;
   else
      self.health = 5000;

   self.th_die = boss_death1;
   self.enemy = activator;
   
   WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
   WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
   WriteCoord (MSG_BROADCAST, self.origin_x);
   WriteCoord (MSG_BROADCAST, self.origin_y);
   WriteCoord (MSG_BROADCAST, self.origin_z);

   self.yaw_speed = 20;
   boss_rise1 ();
};


/*QUAKED monster_boss (1 0 0) (-128 -128 -24) (128 128 256)
*/
void() monster_boss =
{   
   if (deathmatch)
   {
      remove(self);
      return;
   }
   precache_model ("progs/boss.mdl");
   precache_model ("progs/lavaball.mdl");

   precache_sound ("weapons/rocket1i.wav");
   precache_sound ("boss1/out1.wav");
   precache_sound ("boss1/sight1.wav");
   precache_sound ("misc/power.wav");
   precache_sound ("boss1/throw.wav");
   precache_sound ("boss1/pain.wav");
   precache_sound ("boss1/death.wav");
   
   total_monsters = total_monsters + 1;

   self.use = boss_awake;
   
   if (!(self.th_die))
   {
      if(random() < 0.25)
      {
         self.th_pain = boss_shocka1;
      }
      else
      {
         self.th_pain = boss_shockb1;
      }
   }
};

//===========================================================================

entity   le1, le2;
float   lightning_end;

void() lightning_fire =
{
   local vector p1, p2;
   
   if (time >= lightning_end)
   {   // done here, put the terminals back up
      self = le1;
      door_go_down ();
      self = le2;
      door_go_down ();
      return;
   }
   
   p1 = (le1.mins + le1.maxs) * 0.5;
   p1_z = le1.absmin_z - 16;
   
   p2 = (le2.mins + le2.maxs) * 0.5;
   p2_z = le2.absmin_z - 16;
   
   // compensate for length of bolt
   p2 = p2 - normalize(p2-p1)*100;

   self.nextthink = time + 0.1;
   self.think = lightning_fire;

   WriteByte (MSG_ALL, SVC_TEMPENTITY);
   WriteByte (MSG_ALL, TE_LIGHTNING3);
   WriteEntity (MSG_ALL, world);
   WriteCoord (MSG_ALL, p1_x);
   WriteCoord (MSG_ALL, p1_y);
   WriteCoord (MSG_ALL, p1_z);
   WriteCoord (MSG_ALL, p2_x);
   WriteCoord (MSG_ALL, p2_y);
   WriteCoord (MSG_ALL, p2_z);
};

void() lightning_use =
{
   if (lightning_end >= time + 1)
      return;

   le1 = find( world, target, "lightning");
   le2 = find( le1, target, "lightning");
   if (!le1 || !le2)
   {
      dprint ("missing lightning targets\n");
      return;
   }
   
   if (
    (le1.state != STATE_TOP && le1.state != STATE_BOTTOM)
   || (le2.state != STATE_TOP && le2.state != STATE_BOTTOM)
   || (le1.state != le2.state) )
   {
//      dprint ("not aligned\n");
      return;
   }

// don't let the electrodes go back up until the bolt is done
   le1.nextthink = -1;
   le2.nextthink = -1;
   lightning_end = time + 1;

   sound (self, CHAN_VOICE, "misc/power.wav", 1, ATTN_NORM);
   lightning_fire ();      

// advance the boss pain if down
   self = find (world, classname, "monster_boss");
   if (!self)
      return;
   self.enemy = activator;
   if (le1.state == STATE_TOP && self.health > 0)
   {
      sound (self, CHAN_VOICE, "boss1/pain.wav", 1, ATTN_NORM);
      self.health = self.health - 250;
      if (self.health >= 800)
         boss_shocka1();
      else if (self.health == 500)
         boss_shockb1();
      else if (self.health == 0)
         boss_shockc1();
   }   
};


/*QUAKED event_lightning (0 1 1) (-16 -16 -16) (16 16 16)
Just for boss level.
*/
void() event_lightning =
{
   self.use = lightning_use;
};


also add this to line 1456 of client.c for death messages
Code: Select all
         // hell if I know; he's just dead!!!
         if (attacker.classname == "monster_boss")
         {
            if (random () < 0.5)
            {
            bprint (" was defeated easily by the mighty Chthon\n");
            }
            else
            {
            bprint (" was obliterated by Chthon's volcanic barrage\n");
            }
         }
         else
         {
         bprint (" died\n");
         }
User avatar
dayfive
 
Posts: 77
Joined: Fri Nov 10, 2006 9:48 pm


Return to QuakeC Programming

Who is online

Users browsing this forum: No registered users and 1 guest