Git Repos / fte_dogmode / qc / monsters / shalrath.qc
Last update to this file was on 2024-06-15 at 19:50.
Show shalrath.qc
//==============================================================================
// SHAL-RATH
//==============================================================================
//======================================================================
// constants
//======================================================================
const float SHALRATH_HEALTH = 400; // id1 400
const float SHALRATH_HEALTH_CORPSE = 80;
const vector SHALRATH_HEAD_MINS = '-19.85 -19.09 -1.44';
const vector SHALRATH_HEAD_MAXS = '13.72 16.8 30';
const vector SHALRATH_CORPSE_MINS = '-41.41 -40.06 -49.38';
const vector SHALRATH_CORPSE_MAXS = '34.52 24.32 30';
const vector SHALRATH_CORPSE_Z_MINS = '-20 -20 -24';
const vector SHALRATH_CORPSE_Z_MAXS = '20 20 -8';
//======================================================================
// forward declarations
//======================================================================
// monster_shalrath
void() monster_shalrath_sightsound; // AI, animation, & thinking
void() shal_walk1; void() shal_walk2; void() shal_walk3; void() shal_walk4;
void() shal_walk5; void() shal_walk6; void() shal_walk7; void() shal_walk8;
void() shal_walk9; void() shal_walk10; void() shal_walk11; void() shal_walk12;
void() shal_run1; void() shal_run2; void() shal_run3; void() shal_run4;
void() shal_run5; void() shal_run6; void() shal_run7; void() shal_run8;
void() shal_run9; void() shal_run10; void() shal_run11; void() shal_run12;
void() shal_atk1; void() shal_atk2; void() shal_atk3; void() shal_atk4;
void() shal_atk5; void() shal_atk6; void() shal_atk7; void() shal_atk8;
void() shal_atk9; void() shal_atk10; void() shal_atk11;
void() shal_tur_atk1; void() shal_tur_atk2; void() shal_tur_atk3;
void() shal_tur_atk4; void() shal_tur_atk5; void() shal_tur_atk6;
void() shal_tur_atk7; void() shal_tur_atk8; void() shal_tur_atk9;
void() shal_tur_atk10; void() shal_tur_atk11; void() shal_tur_atk12;
void() shal_tur_atk13; void() shal_tur_atk14; void() shal_tur_atk15;
void() shal_seek_stand1; void() shal_seek_stand2;
void() shal_pain1; void() shal_pain2; void() shal_pain3; void() shal_pain4;
void() shal_pain5;
void() shal_death1; void() shal_death2; void() shal_death3; void() shal_death4;
void() shal_death5; void() shal_death6; void() shal_death7;
void(entity attacker, float damage) monster_shalrath_pain; // interaction
void(vector dir) monster_shalrath_destroy;
entity(vector org, vector ang, float sflags, float yaw, float angry)
spawn_monster_shalrath; // initialization
void(entity e) monster_shalrath_init;
void() monster_shalrath;
// gib_head_shalrath
void(entity act, vector dir, float dmg) throw_gib_head_shalrath;
void(entity e) gib_head_shalrath_init;
void() gib_head_shalrath;
// monster_dead_shalrath
void(entity e) monster_dead_shalrath_init;
void() monster_dead_shalrath;
//======================================================================
// frame macros
//======================================================================
$cd id1/models/shalrath
$origin 0 0 24
$base base
$skin skin
$scale 0.7
$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8
$frame attack9 attack10 attack11
$frame pain1 pain2 pain3 pain4 pain5
$frame death1 death2 death3 death4 death5 death6 death7
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10
$frame walk11 walk12
//------------------------------------------------------------------------------
/*QUAKED monster_shalrath (1 0 0) (-32 -32 -24) (32 32 48) AMBUSH X X TRIGGER_SPAWNED 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
{
model ({ "path" : "progs/shalrath.mdl", "frame": 23 });
}
Vore.
Default health = 400
snd_death(string) : "Path to custom death sound"
snd_pain(string) : "Path to custom pain sound"
snd_sight(string) : "Path to custom sight sound"
snd_attack(string) : "Path to custom attack sound (VORE SNARL)"
snd_idle(string) : "Path to custom idle sound"
snd_misc(string) : "Path to custom attack2 sound (VOREBALL FIRE)"
mdl_head(string) : "Path to custom head model"
mdl_body(string) : "Path to custom body model"
mdl_proj(string) : "Path to custom projectile model"
skin_head(float) : "Skin index of custom head model"
skin_proj(float) : "Skin index of custom projectile model"
mdl_gib1(string) : "Path to custom 1st gib model"
mdl_gib2(string) : "Path to custom 2nd gib model"
mdl_gib3(string) : "Path to custom 3rd gib model"
effects(choices) : "Add a visual effect to an entity"
0 : "None (Default)"
1 : "Brightfield (yellow particles)"
4 : "Bright light"
8 : "Dim light"
berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
0 : "Off (Default)"
1 : "Berserk (skip pain animations)"
delay(float) : "Delay spawn in for this amount of time"
wait(choices) : "Play an effect when trigger spawned?"
0 : "Teleport Effects (Default)"
1 : "Spawn Silently"
spawn_angry(Choices)
0 : "Only when trigger spawned, default behavior - not angry"
1 : "Only when trigger spawned, set to 1 to spawn angry at player"
infight_mode(Choices)
0 : "Default behavior, only with different classnames"
1 : "Infight with monsters with the same classname but a different mdl_body"
2 : "Infight with monsters with the same classname and model but a different skin"
3 : "Infight no matter what"
health(integer) : "Set this to a custom health amount"
pain_target(string) : "Fire this target when pain_threshold is reached"
pain_threshold(integer) : "Fire pain_target when health drops below this amount"
sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
homing(float) : "Amount that the projectile should home in target. 1 is default, 0 is none."
*/
//----------------------------------------------------------------------
// class monster_shalrath: base_walkmonster
// {
//--------------------------------------------------------------
void() monster_shalrath_sightsound =
{
sound_sight (self, CHAN_VOICE, "shalrath/sight.wav",
VOL_HIGH, ATTN_NORM);
};
//--------------------------------------------------------------
// Shalrath Standing (only one frame)
//--------------------------------------------------------------
void() shal_stand1 = [$walk1, shal_stand1] { ai_stand (); };
//--------------------------------------------------------------
// Shalrath Walking functions
//--------------------------------------------------------------
void() shal_walk1 = [$walk2, shal_walk2]
{
if (random() < 0.2)
sound_idle (self, CHAN_VOICE, "shalrath/idle.wav",
VOL_HIGH, ATTN_IDLE);
ai_walk (6);
};
void() shal_walk2 = [$walk3, shal_walk3] { ai_walk (4); };
void() shal_walk3 = [$walk4, shal_walk4] { ai_walk (0); };
void() shal_walk4 = [$walk5, shal_walk5] { ai_walk (0); };
void() shal_walk5 = [$walk6, shal_walk6] { ai_walk (0); };
void() shal_walk6 = [$walk7, shal_walk7] { ai_walk (0); };
void() shal_walk7 = [$walk8, shal_walk8] { ai_walk (5); };
void() shal_walk8 = [$walk9, shal_walk9] { ai_walk (6); };
void() shal_walk9 = [$walk10, shal_walk10] { ai_walk (5); };
void() shal_walk10 = [$walk11, shal_walk11] { ai_walk (0); };
void() shal_walk11 = [$walk12, shal_walk12] { ai_walk (4); };
void() shal_walk12 = [$walk1, shal_walk1] { ai_walk (5); };
//--------------------------------------------------------------
// Shalrath Run functions
//--------------------------------------------------------------
void() shal_run1 = [$walk2, shal_run2]
{
if (random() < 0.2)
sound_idle (self, CHAN_VOICE, "shalrath/idle.wav",
VOL_HIGH, ATTN_IDLE);
ai_run (6);
};
void() shal_run2 = [$walk3, shal_run3] { ai_run (4); };
void() shal_run3 = [$walk4, shal_run4] { ai_run (0); };
void() shal_run4 = [$walk5, shal_run5] { ai_run (0); };
void() shal_run5 = [$walk6, shal_run6] { ai_run (0); };
void() shal_run6 = [$walk7, shal_run7] { ai_run (0); };
void() shal_run7 = [$walk8, shal_run8] { ai_run (5); };
void() shal_run8 = [$walk9, shal_run9] { ai_run (6); };
void() shal_run9 = [$walk10, shal_run10] { ai_run (5); };
void() shal_run10 = [$walk11, shal_run11] { ai_run (0); };
void() shal_run11 = [$walk12, shal_run12] { ai_run (4); };
void() shal_run12 = [$walk1, shal_run1] { ai_run (5); };
//--------------------------------------------------------------
// Shalrath Attack functions
//--------------------------------------------------------------
void() shal_atk1 = [$attack1, shal_atk2]
{
sound_attack (self, CHAN_VOICE, "shalrath/attack.wav",
VOL_HIGH, ATTN_NORM);
ai_face ();
};
void() shal_atk2 = [$attack2, shal_atk3] { ai_face (); };
void() shal_atk3 = [$attack3, shal_atk4] { ai_face (); };
void() shal_atk4 = [$attack4, shal_atk5] { ai_face (); };
void() shal_atk5 = [$attack5, shal_atk6] { ai_face (); };
void() shal_atk6 = [$attack6, shal_atk7] { ai_face (); };
void() shal_atk7 = [$attack7, shal_atk8] { ai_face (); };
void() shal_atk8 = [$attack8, shal_atk9] { ai_face (); };
void() shal_atk9 = [$attack9, shal_atk10]
{
base_monster_fire_voreball (self.origin + '0 0 10',
(self.enemy.origin + '0 0 10') - self.origin);
};
void() shal_atk10 = [$attack10, shal_atk11] { ai_face (); };
void() shal_atk11 = [$attack11, shal_run1] { };
////////////////////////////////////////
/// new frames for turret mode START ///
////////////////////////////////////////
//--------------------------------------------------------------
// Shalrath Turret Attack
//--------------------------------------------------------------
void() shal_tur_atk1 = [$attack1, shal_tur_atk2]
{
sound_attack (self, CHAN_VOICE, "shalrath/attack.wav",
VOL_HIGH, ATTN_NORM);
ai_face ();
};
void() shal_tur_atk2 = [$attack2, shal_tur_atk3] { ai_face (); };
void() shal_tur_atk3 = [$attack3, shal_tur_atk4] { ai_face (); };
void() shal_tur_atk4 = [$attack4, shal_tur_atk5] { ai_face (); };
void() shal_tur_atk5 = [$attack5, shal_tur_atk6] { ai_face (); };
void() shal_tur_atk6 = [$attack6, shal_tur_atk7] { ai_face (); };
void() shal_tur_atk7 = [$attack7, shal_tur_atk8] { ai_face (); };
void() shal_tur_atk8 = [$attack8, shal_tur_atk9] { ai_face (); };
void() shal_tur_atk9 = [$attack9, shal_tur_atk10]
{
base_monster_fire_voreball (self.origin + '0 0 10',
(self.enemy.origin + '0 0 10') - self.origin);
};
void() shal_tur_atk10 = [$attack10, shal_tur_atk11] { ai_face (); };
void() shal_tur_atk11 = [$attack11, shal_tur_atk12] { ai_face (); };
void() shal_tur_atk12 = [$walk1, shal_tur_atk13] { ai_face (); };
void() shal_tur_atk13 = [$walk1, shal_tur_atk14] { ai_face (); };
void() shal_tur_atk14 = [$walk1, shal_tur_atk15] { ai_face (); };
void() shal_tur_atk15 = [$walk1, shal_seek_stand1] { ai_run (0); };
//--------------------------------------------------------------
// Shalrath Turret Standing/Seeeking
//--------------------------------------------------------------
void() shal_seek_stand1 = [$walk1, shal_seek_stand2] { ai_run (0); };
void() shal_seek_stand2 = [$walk1, shal_seek_stand1] { ai_run (0); };
////////////////////////////////////////
/// new frames for turret mode END ///
////////////////////////////////////////
//--------------------------------------------------------------
// Shalrath Pain State
//--------------------------------------------------------------
void() shal_pain1 = [$pain1, shal_pain2] { };
void() shal_pain2 = [$pain2, shal_pain3] { };
void() shal_pain3 = [$pain3, shal_pain4] { };
void() shal_pain4 = [$pain4, shal_pain5] { };
void() shal_pain5 = [$pain5, shal_run1] { };
//--------------------------------------------------------------
// Shalrath Death State
//--------------------------------------------------------------
void() shal_death1 = [$death1, shal_death2]
{
base_entity_aligntoground (self);
};
void() shal_death2 = [$death2, shal_death3] { };
void() shal_death3 = [$death3, shal_death4] { };
void() shal_death4 = [$death4, shal_death5] { };
void() shal_death5 = [$death5, shal_death6] { };
void() shal_death6 = [$death6, shal_death7]
{
become_base_corpse (self, SHALRATH_HEALTH_CORPSE);
setsize (self, SHALRATH_CORPSE_Z_MINS, SHALRATH_CORPSE_Z_MAXS);
};
void() shal_death7 = [$death7, shal_death7] { };
//==============================================================
// Interaction
//==============================================================
//--------------------------------------------------------------
// shalrath_pain
//--------------------------------------------------------------
void(entity attacker, float damage) monster_shalrath_pain =
{
if (self.pain_finished > time)
return;
// CHAN_AUTO was voice - dumptruck_ds
sound_pain (self, CHAN_AUTO, "shalrath/pain.wav",
VOL_HIGH, ATTN_NORM);
self.pain_finished = time + 3;
if (self.spawnflags & I_AM_TURRET)
return;
else
shal_pain1 ();
};
//--------------------------------------------------------------
// shalrath_die
//--------------------------------------------------------------
void(vector dir) monster_shalrath_destroy =
{
// check if we're dead already
if (self.classgroup & CG_CORPSE)
{
sound (self, CHAN_VOICE, "player/udeath.wav",
VOL_HIGH, ATTN_NORM);
throw_gib_head_shalrath (self, dir, self.health);
throw_gib_1 (self, dir, self.health);
throw_gib_2 (self, dir, self.health);
throw_gib_3 (self, dir, self.health);
return;
}
// check for gib
if (self.health < -90)
{
sound (self, CHAN_VOICE, "player/udeath.wav",
VOL_HIGH, ATTN_NORM);
throw_gib_head_shalrath (self, dir, self.health);
throw_gib_1 (self, dir, self.health);
throw_gib_2 (self, dir, self.health);
throw_gib_3 (self, dir, self.health);
base_item_drop_stuff (self);
return;
}
// insert death sounds here
sound_death (self, CHAN_VOICE, "shalrath/death.wav",
VOL_HIGH, ATTN_NORM);
self.solid = SOLID_NOT;
base_item_drop_stuff (self);
shal_death1 ();
};
//==============================================================
// Initialization
//==============================================================
//--------------------------------------------------------------
entity(vector org, vector ang, float sflags, float yaw, float angry)
spawn_monster_shalrath =
{
return spawn_base_monster (org, ang, sflags, yaw, angry,
monster_shalrath_init);
};
//--------------------------------------------------------------
void(entity e) monster_shalrath_init =
{
if (deathmatch)
{
remove (e);
return;
}
e.classname = "monster_shalrath";
e.classtype = CT_MONSTER_VORE;
// dumptruck_ds custom_mdls
precache_body_model2 (e, "progs/shalrath.mdl");
precache_head_model2 (e, "progs/h_shal.mdl");
precache_proj_model2 (e, "progs/v_spike.mdl");
// dumptruck_ds
precache_sound2_attack (e, "shalrath/attack.wav");
precache_sound2_misc (e, "shalrath/attack2.wav");
precache_sound2_death (e, "shalrath/death.wav");
precache_sound2_idle (e, "shalrath/idle.wav");
precache_sound2_pain (e, "shalrath/pain.wav");
precache_sound2_sight (e, "shalrath/sight.wav");
precache_gib1 (e, "progs/gib1.mdl");
precache_gib2 (e, "progs/gib2.mdl");
precache_gib3 (e, "progs/gib3.mdl");
e.solid = SOLID_SLIDEBOX;
e.movetype = MOVETYPE_STEP;
body_model (e, "progs/shalrath.mdl");
// setmodel (e, "progs/shalrath.mdl");
setsize (e, VEC_HULL2_MIN, VEC_HULL2_MAX);
if (!e.health)
// thanks RennyC -- dumptruck_ds
e.health = SHALRATH_HEALTH;
if (!e.proj_speed_mod)
e.proj_speed_mod = 1;
if (!e.homing)
// default to normal
e.homing = 1;
else if (e.homing < 0)
// disable with negative
e.homing = 0;
e.th_stand = shal_stand1;
e.th_walk = shal_walk1;
if (e.spawnflags & I_AM_TURRET)
e.th_run = shal_seek_stand1;
else
e.th_run = shal_run1;
e.destroy = monster_shalrath_destroy;
// Berserk test from
// http://celephais.net/board/view_thread.php?id=4&start=3465
// -- dumptruck_ds
if !(e.berserk)
e.th_pain = monster_shalrath_pain;
else
e.th_pain = sub_nullpain;
e.th_missile = shal_atk1;
e.th_turret = shal_tur_atk1;
// walkmonster_start
base_walkmonster_init (e);
};
//--------------------------------------------------------------
void() monster_shalrath =
{
// new spawnflags for all entities -- iw
if (SUB_Inhibit())
return;
monster_shalrath_init (self);
};
// };
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
// Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
/*QUAKED gib_head_shalrath (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID 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
{
model ("progs/h_shal.mdl");
}*/
//----------------------------------------------------------------------
// class gib_head_shalrath: base_gib_head
// {
//--------------------------------------------------------------
// ThrowHead
//--------------------------------------------------------------
void(entity act, vector dir, float dmg) throw_gib_head_shalrath =
{
base_gib_head_throw (act, dir, dmg, gib_head_shalrath_init);
};
//--------------------------------------------------------------
void(entity e) gib_head_shalrath_init =
{
e.classname = "gib_head_shalrath";
e.classtype = CT_GORE_HEAD_SHALRATH;
// gib_init interprets spawnflags and will set .solid -- CEV
base_gib_head_init (e);
if (e.mdl_head != "")
{
precache_model (e.mdl_head);
setmodel (e, e.mdl_head);
}
else
{
precache_model ("progs/h_shal.mdl");
setmodel (e, "progs/h_shal.mdl");
if (e.solid == SOLID_BBOX)
setsize (e, SHALRATH_HEAD_MINS,
SHALRATH_HEAD_MAXS);
else if (e.solid == SOLID_TRIGGER)
setsize (e, '-16 -16 0', '16 16 56');
}
e.frame = 0;
};
//--------------------------------------------------------------
void() gib_head_shalrath =
{
// new spawnflags for all entities -- iw
if (SUB_Inhibit())
return;
gib_head_shalrath_init (self);
};
// };
/*QUAKED monster_dead_shalrath (0 0.5 0.8) (-32 -32 -24) (32 32 64) SOLID 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
{
model ({"path":"progs/shalrath.mdl","frame":22});
}
*/
//----------------------------------------------------------------------
// class monster_dead_shalrath: base_corpse
// {
//--------------------------------------------------------------
void(entity e) monster_dead_shalrath_init =
{
base_corpse_init (e);
precache_model ("progs/shalrath.mdl");
setmodel (e, "progs/shalrath.mdl");
e.frame = $death7;
if (e.solid == SOLID_BBOX)
setsize (e, SHALRATH_CORPSE_MINS, SHALRATH_CORPSE_MAXS);
}
//--------------------------------------------------------------
void() monster_dead_shalrath =
{
// new spawnflags for all entities -- iw
if (SUB_Inhibit())
return;
monster_dead_shalrath_init (self);
};
// };
Return to the top of this page or return to the overview of this repo.
Log shalrath.qc
Date | Commit Message | Author | + | - |
---|---|---|---|---|
2024-06-15 | Major update, committing as-is, will have bugs | cev | +80 | -36 |
2024-04-12 | Moveable gibs, heads, some bugfixes | cev | +76 | -29 |
2024-04-08 | Registered monsters, projectile bugfixes | cev | +206 | -172 |
2024-02-18 | Client/player, projectiles, entrypoints refactor | cev | +23 | -111 |
2024-01-31 | Class based monster refactor & start projectiles | cev | +391 | -317 |
2024-01-13 | Refactored items into classes, fix teleporttrain | cev | +2 | -2 |
2024-01-09 | Continue OO / Class-based refactor | cev | +2 | -2 |
2023-10-13 | New movement code based on SV_RunClientCommand | cev | +433 | -433 |
2023-10-13 | Rename "qc-server" dir to "qc" | cev | +433 |
Return to the top of this page or return to the overview of this repo.