djcev.com

//

Git Repos / fte_dogmode / qc / monsters / boss.qc

Last update to this file was on 2024-04-05 at 14:18.

Show boss.qc

//==============================================================================
// BOSS-ONE
//==============================================================================

//======================================================================
// globals
//======================================================================

entity le1, le2;
float lightning_end;

//======================================================================
// forward declarations
//======================================================================

// monster_boss
void() monster_boss_face; // AI & firing
void(vector p) monster_boss_missile; // thinking & animation below
void() boss_idle1; void() boss_idle2; void() boss_idle3; void() boss_idle4;
void() boss_idle5; void() boss_idle6; void() boss_idle7; void() boss_idle8;
void() boss_idle9; void() boss_idle10; void() boss_idle11; void() boss_idle12;
void() boss_idle13; void() boss_idle14; void() boss_idle15; void() boss_idle16;
void() boss_idle17; void() boss_idle18; void() boss_idle19; void() boss_idle20;
void() boss_idle21; void() boss_idle22; void() boss_idle23; void() boss_idle24;
void() boss_idle25; void() boss_idle26; void() boss_idle27; void() boss_idle28;
void() boss_idle29; void() boss_idle30; void() boss_idle31;
void() boss_rise1; void() boss_rise2; void() boss_rise3; void() boss_rise4;
void() boss_rise5; void() boss_rise6; void() boss_rise7; void() boss_rise8;
void() boss_rise9; void() boss_rise10; void() boss_rise11; void() boss_rise12;
void() boss_rise13; void() boss_rise14; void() boss_rise15; void() boss_rise16;
void() boss_rise17;
void() boss_atk1; void() boss_atk2; void() boss_atk3; void() boss_atk4;
void() boss_atk5; void() boss_atk6; void() boss_atk7; void() boss_atk8;
void() boss_atk9; void() boss_atk10; void() boss_atk11; void() boss_atk12;
void() boss_atk13; void() boss_atk14; void() boss_atk15; void() boss_atk16;
void() boss_atk17; void() boss_atk18; void() boss_atk19; void() boss_atk20;
void() boss_atk21; void() boss_atk22; void() boss_atk23;
void() boss_shocka1; void() boss_shocka2; void() boss_shocka3;
void() boss_shocka4; void() boss_shocka5; void() boss_shocka6;
void() boss_shocka7; void() boss_shocka8; void() boss_shocka9;
void() boss_shocka10;
void() boss_shockb1; void() boss_shockb2; void() boss_shockb3;
void() boss_shockb4; void() boss_shockb5; void() boss_shockb6;
void() boss_shockb7; void() boss_shockb8; void() boss_shockb9;
void() boss_shockb10;
void() boss_shockc1; void() boss_shockc2; void() boss_shockc3;
void() boss_shockc4; void() boss_shockc5; void() boss_shockc6;
void() boss_shockc7; void() boss_shockc8; void() boss_shockc9;
void() boss_shockc10;
void() boss_death1; void() boss_death2; void() boss_death3; void() boss_death4;
void() boss_death5; void() boss_death6; void() boss_death7; void() boss_death8;
void() boss_death9; void() boss_death10;
void() monster_boss_use; // interaction & initialization
void(entity e) monster_boss_init;
void() monster_boss;

// event_lightning
void() event_lightning_fire;
void() event_lightning_use;
void(entity e) event_lightning_init;
void() event_lightning;

//======================================================================
// frame macros
//======================================================================

$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

//------------------------------------------------------------------------------

/*QUAKED monster_boss (1 0 0) (-128 -128 -24) (128 128 256)
*/
//----------------------------------------------------------------------
// class monster_boss: base_monster
// {
//--------------------------------------------------------------
void() monster_boss_face =
{
// go for another player if multi player
if (self.enemy.health <= 0 || random() < 0.02)
{
self.enemy = findfloat (self.enemy, classtype,
CT_PLAYER);
if (!self.enemy)
self.enemy = findfloat (self.enemy, classtype,
CT_PLAYER);
}

ai_face ();
};

//--------------------------------------------------------------
// boss_missile
//--------------------------------------------------------------
void(vector p) monster_boss_missile =
{
local vector org, d;
local float t;

makevectors (vectoangles(self.enemy.origin - self.origin));

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;
d = self.enemy.velocity;
d_z = 0;
d = self.enemy.origin + t * d;
}
else
{
d = self.enemy.origin;
}

base_monster_fire_lavaball (org, d - org, LAVABALL_SPEED);

sound_attack (self, CHAN_WEAPON, "boss1/throw.wav",
1, ATTN_NORM);

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

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

//--------------------------------------------------------------
// Chthon Rises
//--------------------------------------------------------------
void() boss_rise1 = [$rise1, boss_rise2]
{
sound_move (self, CHAN_WEAPON, "boss1/out1.wav", 1, ATTN_NORM);
};
void() boss_rise2 = [$rise2, boss_rise3]
{
sound_sight (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_atk1] { };

//--------------------------------------------------------------
// Chthon Attack Lavaball
//--------------------------------------------------------------
void() boss_atk1 = [$attack1, boss_atk2] { monster_boss_face (); };
void() boss_atk2 = [$attack2, boss_atk3] { monster_boss_face (); };
void() boss_atk3 = [$attack3, boss_atk4] { monster_boss_face (); };
void() boss_atk4 = [$attack4, boss_atk5] { monster_boss_face (); };
void() boss_atk5 = [$attack5, boss_atk6] { monster_boss_face (); };
void() boss_atk6 = [$attack6, boss_atk7] { monster_boss_face (); };
void() boss_atk7 = [$attack7, boss_atk8] { monster_boss_face (); };
void() boss_atk8 = [$attack8, boss_atk9] { monster_boss_face (); };
void() boss_atk9 = [$attack9, boss_atk10]
{
monster_boss_missile ('100 100 200');
};
void() boss_atk10 = [$attack10, boss_atk11] { monster_boss_face (); };
void() boss_atk11 = [$attack11, boss_atk12] { monster_boss_face (); };
void() boss_atk12 = [$attack12, boss_atk13] { monster_boss_face (); };
void() boss_atk13 = [$attack13, boss_atk14] { monster_boss_face (); };
void() boss_atk14 = [$attack14, boss_atk15] { monster_boss_face (); };
void() boss_atk15 = [$attack15, boss_atk16] { monster_boss_face (); };
void() boss_atk16 = [$attack16, boss_atk17] { monster_boss_face (); };
void() boss_atk17 = [$attack17, boss_atk18] { monster_boss_face (); };
void() boss_atk18 = [$attack18, boss_atk19] { monster_boss_face (); };
void() boss_atk19 = [$attack19, boss_atk20] { monster_boss_face (); };
void() boss_atk20 = [$attack20, boss_atk21]
{
monster_boss_missile ('100 -100 200');
};
void() boss_atk21 = [$attack21, boss_atk22] { monster_boss_face (); };
void() boss_atk22 = [$attack22, boss_atk23] { monster_boss_face (); };
void() boss_atk23 = [$attack23, boss_atk1] { monster_boss_face (); };

//--------------------------------------------------------------
// Chthon Shock! A
//--------------------------------------------------------------
void() boss_shocka1 = [$shocka1, boss_shocka2] { };
void() boss_shocka2 = [$shocka2, boss_shocka3] { };
void() boss_shocka3 = [$shocka3, boss_shocka4] { };
void() boss_shocka4 = [$shocka4, boss_shocka5] { };
void() boss_shocka5 = [$shocka5, boss_shocka6] { };
void() boss_shocka6 = [$shocka6, boss_shocka7] { };
void() boss_shocka7 = [$shocka7, boss_shocka8] { };
void() boss_shocka8 = [$shocka8, boss_shocka9] { };
void() boss_shocka9 = [$shocka9, boss_shocka10] { };
void() boss_shocka10 = [$shocka10, boss_atk1] { };

//--------------------------------------------------------------
// Chthon Shock! B
//--------------------------------------------------------------
void() boss_shockb1 = [$shockb1, boss_shockb2] { };
void() boss_shockb2 = [$shockb2, boss_shockb3] { };
void() boss_shockb3 = [$shockb3, boss_shockb4] { };
void() boss_shockb4 = [$shockb4, boss_shockb5] { };
void() boss_shockb5 = [$shockb5, boss_shockb6] { };
void() boss_shockb6 = [$shockb6, boss_shockb7] { };
void() boss_shockb7 = [$shockb1, boss_shockb8] { };
void() boss_shockb8 = [$shockb2, boss_shockb9] { };
void() boss_shockb9 = [$shockb3, boss_shockb10] { };
void() boss_shockb10 = [$shockb4, boss_atk1] { };

//--------------------------------------------------------------
// Chthon Shock! C
//--------------------------------------------------------------
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] { };

//--------------------------------------------------------------
// Chthon Death state
//--------------------------------------------------------------
void() boss_death1 = [$death1, boss_death2]
{
sound_death (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_move (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;
// FIXME: reliable broadcast
WriteByte (MSG_ALL, SVC_KILLEDMONSTER);
sub_usetargets ();
remove (self);
};

//==============================================================
// Interaction
//==============================================================

//--------------------------------------------------------------
// boss_awake
//--------------------------------------------------------------
void() monster_boss_use =
{
self.solid = SOLID_SLIDEBOX;
self.movetype = MOVETYPE_STEP;
self.takedamage = DAMAGE_NO;

body_model (self, "progs/boss.mdl");
// custom_mdl -- dumptruck_ds
// setmodel (self, "progs/boss.mdl");
setsize (self, '-128 -128 -24', '128 128 256');

if (skill == 0)
self.health = 1;
else
self.health = 3;

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 ();
};

//==============================================================
// Initialization
//==============================================================

//--------------------------------------------------------------
void(entity e) monster_boss_init =
{
if (e.spawnflags & I_AM_TURRET)
objerror ("Incompatible spawnflag: TURRET_MODE\n");

if (deathmatch)
{
remove (e);
return;
}

e.classname = "monster_boss";
e.classtype = CT_MONSTER_BOSS_CHTHON;
base_monster_init (e);

// precache_model ("progs/boss.mdl");
precache_body_model (e, "progs/boss.mdl");
precache_head_model (e, "progs/h_boss.mdl");

precache_model ("progs/lavaball.mdl");

precache_sound ("weapons/rocket1i.wav");
precache_sound_move (e, "boss1/out1.wav");
precache_sound_sight (e, "boss1/sight1.wav");
precache_sound ("misc/power.wav");
precache_sound_attack (e, "boss1/throw.wav");
precache_sound_pain (e, "boss1/pain.wav");
precache_sound_death (e, "boss1/death.wav");

total_monsters = total_monsters + 1;

e.flags = FL_MONSTER;
e.use = monster_boss_use;
};

//--------------------------------------------------------------
void() monster_boss =
{
// new spawnflags for all entities -- iw
if (SUB_Inhibit())
return;

monster_boss_init (self);
};
// };

//----------------------------------------------------------------------
// Event Lightning
//----------------------------------------------------------------------

/*QUAKED event_lightning (0 1 1) (-16 -16 -16) (16 16 16) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
Just for boss level.
*/
//----------------------------------------------------------------------
// class event_lightning: base_mapentity
// {
//--------------------------------------------------------------
void() event_lightning_fire =
{
local vector p1, p2;

if (time >= lightning_end)
{
// done here, put the terminals back up
sub_runvoidas (le1, func_door_think_go_down);
sub_runvoidas (le2, func_door_think_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 = event_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() event_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 != FUNC_STATE_TOP &&
le1.state != FUNC_STATE_BOTTOM) ||
(le2.state != FUNC_STATE_TOP &&
le2.state != FUNC_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);
event_lightning_fire ();

// advance the boss pain if down
local entity boss;
boss = findfloat (world, classtype, CT_MONSTER_BOSS_CHTHON);
if (!boss)
return;

boss.enemy = activator;
if (le1.state == FUNC_STATE_TOP && boss.health > 0)
{
sound_pain (boss, CHAN_VOICE, "boss1/pain.wav",
1, ATTN_NORM);
boss.health = boss.health - 1;
if (boss.health >= 2)
sub_runvoidas (boss, boss_shocka1);
else if (boss.health == 1)
sub_runvoidas (boss, boss_shockb1);
else if (boss.health == 0)
sub_runvoidas (boss, boss_shockc1);
}
};

//--------------------------------------------------------------
void(entity e) event_lightning_init =
{
e.classname = "event_lightning";
e.classtype = CT_MISC_EVENTLIGHTNING;
base_mapentity_init (e);
e.use = event_lightning_use;
};

//--------------------------------------------------------------
void() event_lightning =
{
// new spawnflags for all entities -- iw
if (SUB_Inhibit())
return;

event_lightning_init (self);
};
// };

Return to the top of this page or return to the overview of this repo.

Log boss.qc

Date Commit Message Author + -
2024-04-05 Player footsteps, shareware monsters, misc? cev +347 -265
2024-02-18 Client/player, projectiles, entrypoints refactor cev +8 -34
2024-01-31 Class based monster refactor & start projectiles cev +339 -278
2024-01-09 Continue OO / Class-based refactor cev +5 -7
2023-10-13 New movement code based on SV_RunClientCommand cev +415 -415
2023-10-13 Rename "qc-server" dir to "qc" cev +415  

Return to the top of this page or return to the overview of this repo.