Git Repos / fte_dogmode / qc / monsters / hknight.qc
Last update to this file was on 2024-06-15 at 19:50.
Show hknight.qc
//==============================================================================
// DEATH KNIGHT / HELL KNIGHT
//==============================================================================
// hknight_type is now .animtype -- CEV
//======================================================================
// constants
//======================================================================
const float HELL_KNIGHT_HEALTH = 250; // id1 250
const float HELL_KNIGHT_HEALTH_CORPSE = 60;
const vector HELL_KNIGHT_HEAD_MINS = '-7.9 -12.97 -0.63';
const vector HELL_KNIGHT_HEAD_MAXS = '10.55 8.87 21.06';
const vector HELL_KNIGHT_CORPSE_MINS = '-42.05 -31.07 -51.56';
const vector HELL_KNIGHT_CORPSE_MAXS = '46.34 25.02 30';
const vector HELL_KNIGHT_CORPSE_B_MINS = '-68.96 -20.43 -53.98';
const vector HELL_KNIGHT_CORPSE_B_MAXS = '34.8 21.15 30';
const vector HELL_KNIGHT_CORPSE_Z_MINS = '-16 -16 -24';
const vector HELL_KNIGHT_CORPSE_Z_MAXS = '16 16 -8';
//======================================================================
// forward declarations
//======================================================================
// monster_hell_knight
void() monster_hell_knight_sightsound; // AI & attacks
void() monster_hell_knight_checkforcharge;
void() monster_hell_knight_checkcontinuecharge;
void() monster_hell_knight_attack_lightning;
void() monster_hell_knight_attack_melee;
void(float offset) monster_hell_knight_attack_shot;
void() monster_hell_knight_idlesound;
void() hkn_stand1; void() hkn_stand2; void() hkn_stand3; void() hkn_stand4;
void() hkn_stand5; void() hkn_stand6; void() hkn_stand7; void() hkn_stand8;
void() hkn_stand9;
void() hkn_walk1; void() hkn_walk2; void() hkn_walk3; void() hkn_walk4;
void() hkn_walk5; void() hkn_walk6; void() hkn_walk7; void() hkn_walk8;
void() hkn_walk9; void() hkn_walk10; void() hkn_walk11; void() hkn_walk12;
void() hkn_walk13; void() hkn_walk14; void() hkn_walk15; void() hkn_walk16;
void() hkn_walk17; void() hkn_walk18; void() hkn_walk19; void() hkn_walk20;
void() hkn_run1; void() hkn_run2; void() hkn_run3; void() hkn_run4;
void() hkn_run5; void() hkn_run6; void() hkn_run7; void() hkn_run8;
void() hkn_char_a1; void() hkn_char_a2; void() hkn_char_a3;
void() hkn_char_a4; void() hkn_char_a5; void() hkn_char_a6;
void() hkn_char_a7; void() hkn_char_a8; void() hkn_char_a9;
void() hkn_char_a10; void() hkn_char_a11; void() hkn_char_a12;
void() hkn_char_a13; void() hkn_char_a14; void() hkn_char_a15;
void() hkn_char_a16;
void() hkn_char_b1; void() hkn_char_b2; void() hkn_char_b3;
void() hkn_char_b4; void() hkn_char_b5; void() hkn_char_b6;
void() hkn_slice1; void() hkn_slice2; void() hkn_slice3; void() hkn_slice4;
void() hkn_slice5; void() hkn_slice6; void() hkn_slice7; void() hkn_slice8;
void() hkn_slice9; void() hkn_slice10;
void() hkn_smash1; void() hkn_smash2; void() hkn_smash3; void() hkn_smash4;
void() hkn_smash5; void() hkn_smash6; void() hkn_smash7; void() hkn_smash8;
void() hkn_smash9; void() hkn_smash10; void() hkn_smash11;
void() hkn_watk1; void() hkn_watk2; void() hkn_watk3; void() hkn_watk4;
void() hkn_watk5; void() hkn_watk6; void() hkn_watk7; void() hkn_watk8;
void() hkn_watk9; void() hkn_watk10; void() hkn_watk11; void() hkn_watk12;
void() hkn_watk13; void() hkn_watk14; void() hkn_watk15; void() hkn_watk16;
void() hkn_watk17; void() hkn_watk18; void() hkn_watk19; void() hkn_watk20;
void() hkn_watk21; void() hkn_watk22;
void() hkn_magica1; void() hkn_magica2; void() hkn_magica3; void() hkn_magica4;
void() hkn_magica5; void() hkn_magica6; void() hkn_magica7; void() hkn_magica8;
void() hkn_magica9; void() hkn_magica10; void() hkn_magica11;
void() hkn_magica12; void() hkn_magica13; void() hkn_magica14;
void() hkn_magicb1; void() hkn_magicb2; void() hkn_magicb3; void() hkn_magicb4;
void() hkn_magicb5; void() hkn_magicb6; void() hkn_magicb7; void() hkn_magicb8;
void() hkn_magicb9; void() hkn_magicb10; void() hkn_magicb11;
void() hkn_magicb12; void() hkn_magicb13;
void() hkn_magicc1; void() hkn_magicc2; void() hkn_magicc3; void() hkn_magicc4;
void() hkn_magicc5; void() hkn_magicc6; void() hkn_magicc7; void() hkn_magicc8;
void() hkn_magicc9; void() hkn_magicc10; void() hkn_magicc11;
void() hkn_seek_stand1; void() hkn_seek_stand2; void() hkn_seek_stand3;
void() hkn_seek_stand4; void() hkn_seek_stand5; void() hkn_seek_stand6;
void() hkn_seek_stand7; void() hkn_seek_stand8; void() hkn_seek_stand9;
void() hkn_tur_magb1; void() hkn_tur_magb2; void() hkn_tur_magb3;
void() hkn_tur_magb4; void() hkn_tur_magb5; void() hkn_tur_magb6;
void() hkn_tur_magb7; void() hkn_tur_magb8; void() hkn_tur_magb9;
void() hkn_tur_magb10; void() hkn_tur_magb11; void() hkn_tur_magb12;
void() hkn_tur_magb13;
void() hkn_tur_magc1; void() hkn_tur_magc2; void() hkn_tur_magc3;
void() hkn_tur_magc4; void() hkn_tur_magc5; void() hkn_tur_magc6;
void() hkn_tur_magc7; void() hkn_tur_magc8; void() hkn_tur_magc9;
void() hkn_tur_magc10; void() hkn_tur_magc11; void() hkn_tur_magc12;
void() hkn_tur_magc13; void() hkn_tur_magc14; void() hkn_tur_magc15;
void() hkn_pain1; void() hkn_pain2; void() hkn_pain3; void() hkn_pain4;
void() hkn_pain5;
void() hkn_die1; void() hkn_die2; void() hkn_die3; void() hkn_die4;
void() hkn_die5; void() hkn_die6; void() hkn_die7; void() hkn_die8;
void() hkn_die9; void() hkn_die10; void() hkn_die11; void() hkn_die12;
void() hkn_dieb1; void() hkn_dieb2; void() hkn_dieb3; void() hkn_dieb4;
void() hkn_dieb5; void() hkn_dieb6; void() hkn_dieb7; void() hkn_dieb8;
void() hkn_dieb9;
void(entity attacker, float damage) monster_hell_knight_pain; // interaction
void(vector dir) monster_hell_knight_destroy;
entity(vector org, vector ang, float sflags, float yaw, float angry)
spawn_monster_hell_knight; // initialization
void(entity e) monster_hell_knight_init;
void() monster_hell_knight;
// gib_head_hell_knight
void(entity act, vector dir, float dmg) throw_gib_head_hell_knight;
void(entity e) gib_head_hell_knight_init;
void() gib_head_hell_knight;
// monster_dead_hell_knight
void(entity e) monster_dead_hell_knight_init;
void() monster_dead_hell_knight;
//======================================================================
// frame macros
//======================================================================
$cd id1/models/knight2
$origin 0 0 24
$base base
$skin skin
$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9
$frame walk10 walk11 walk12 walk13 walk14 walk15 walk16 walk17
$frame walk18 walk19 walk20
$frame run1 run2 run3 run4 run5 run6 run7 run8
$frame pain1 pain2 pain3 pain4 pain5
$frame death1 death2 death3 death4 death5 death6 death7 death8
$frame death9 death10 death11 death12
$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
$frame deathb9
$frame char_a1 char_a2 char_a3 char_a4 char_a5 char_a6 char_a7 char_a8
$frame char_a9 char_a10 char_a11 char_a12 char_a13 char_a14 char_a15 char_a16
$frame magica1 magica2 magica3 magica4 magica5 magica6 magica7 magica8
$frame magica9 magica10 magica11 magica12 magica13 magica14
$frame magicb1 magicb2 magicb3 magicb4 magicb5 magicb6 magicb7 magicb8
$frame magicb9 magicb10 magicb11 magicb12 magicb13
$frame char_b1 char_b2 char_b3 char_b4 char_b5 char_b6
$frame slice1 slice2 slice3 slice4 slice5 slice6 slice7 slice8 slice9 slice10
$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7 smash8 smash9 smash10
$frame smash11
$frame w_attack1 w_attack2 w_attack3 w_attack4 w_attack5 w_attack6 w_attack7
$frame w_attack8 w_attack9 w_attack10 w_attack11 w_attack12 w_attack13 w_attack14
$frame w_attack15 w_attack16 w_attack17 w_attack18 w_attack19 w_attack20
$frame w_attack21 w_attack22
$frame magicc1 magicc2 magicc3 magicc4 magicc5 magicc6 magicc7 magicc8
$frame magicc9 magicc10 magicc11
//------------------------------------------------------------------------------
/*QUAKED monster_hell_knight (1 0 0) (-16 -16 -24) (16 16 40) 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 ("progs/hknight.mdl");
}
Hellknight.
Default health = 250"
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 (MAGIC BOING)"
snd_idle(string) : Path to custom idle sound"
snd_misc(string) : Path to custom SWORD SLASH sound"
mdl_head(string) : "Path to custom head model"
mdl_body(string) : "Path to custom body model"
mdl_proj(string) : "Path to custom projectile model"
mdl_exproj(string) : "Path to custom projectile model for exploding projectiles"
skin_head(float) : "Skin index of custom head model"
skin_proj(float) : "Skin index of custom projectile model"
skin_exproj(float) : "Skin index of custom projectile model for exploding projectiles"
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"
projexpl(choices) : "Exploding projectiles"
0 : "No explosions"
1 : "All projectiles explode"
2 : "Every other projectile explodes"
3 : "Random per projectile"
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)"
*/
//----------------------------------------------------------------------
// class monster_hell_knight: base_walkmonster
// {
//--------------------------------------------------------------
void() monster_hell_knight_sightsound =
{
sound_sight (self, CHAN_VOICE, "hknight/sight1.wav",
VOL_HIGH, ATTN_NORM);
};
//--------------------------------------------------------------
// CheckForCharge
//--------------------------------------------------------------
void() monster_hell_knight_checkforcharge =
{
// check for mad charge
if (!enemy_vis)
return;
if (time < self.attack_finished)
return;
if (fabs(self.origin_z - self.enemy.origin_z) > 20)
// too much height change
return;
if (vlen(self.origin - self.enemy.origin) < 80)
// use regular attack
return;
// charge
sub_attackfinished (2);
hkn_char_a1 ();
};
//--------------------------------------------------------------
// CheckContinueCharge
//--------------------------------------------------------------
void() monster_hell_knight_checkcontinuecharge =
{
if (time > self.attack_finished)
{
sub_attackfinished (3);
hkn_run1 ();
// done charging
return;
}
if (random() > 0.5)
sound (self, CHAN_WEAPON, "knight/sword2.wav",
VOL_HIGH, ATTN_NORM);
else
sound (self, CHAN_WEAPON, "knight/sword1.wav",
VOL_HIGH, ATTN_NORM);
};
//--------------------------------------------------------------
// HellKnightLightning
//--------------------------------------------------------------
void() monster_hell_knight_attack_lightning =
{
local vector org, dir;
self.effects = self.effects | EF_MUZZLEFLASH;
sound_attack(self, CHAN_WEAPON, "weapons/lstart.wav",
VOL_HIGH, ATTN_NORM);
ai_face ();
makevectors (self.angles);
org = self.origin + v_forward * 50 + '0 0 20';
dir = self.enemy.origin - self.enemy.velocity * 0.075;
dir = normalize (dir - org + '0 0 16');
if (self.spawnflags & I_AM_TURRET)
traceline (org, self.origin + dir * 900, TRUE, self);
else
traceline (org, self.origin + dir * 600, TRUE, self);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_LIGHTNING1);
WriteEntity (MSG_BROADCAST, self);
WriteCoord (MSG_BROADCAST, org_x);
WriteCoord (MSG_BROADCAST, org_y);
WriteCoord (MSG_BROADCAST, org_z);
WriteCoord (MSG_BROADCAST, trace_endpos_x);
WriteCoord (MSG_BROADCAST, trace_endpos_y);
WriteCoord (MSG_BROADCAST, trace_endpos_z);
fire_lightning (org, trace_endpos, self, 20);
};
//--------------------------------------------------------------
// hknight_melee
//--------------------------------------------------------------
void() monster_hell_knight_attack_melee =
{
self.animtype = self.animtype + 1;
sound_misc (self, CHAN_WEAPON, "hknight/slash1.wav",
VOL_HIGH, ATTN_NORM);
if (self.animtype == 1)
{
hkn_slice1 ();
}
else if (self.animtype == 2)
{
hkn_smash1 ();
}
else if (self.animtype == 3)
{
hkn_watk1 ();
self.animtype = 0;
}
};
//--------------------------------------------------------------
// hknight_shot
//--------------------------------------------------------------
void(float offset) monster_hell_knight_attack_shot =
{
local vector offang, org;
offang = vectoangles (self.enemy.origin - self.origin);
offang_y = offang_y + offset * 6;
makevectors (offang);
org = self.origin + self.mins + self.size * 0.5 +
v_forward * 20;
base_monster_fire_hknightspell (org, v_forward, offset);
};
//--------------------------------------------------------------
// hk_idle_sound
//--------------------------------------------------------------
void() monster_hell_knight_idlesound =
{
if (random() < 0.2)
sound_idle (self, CHAN_VOICE, "hknight/idle.wav",
VOL_HIGH, ATTN_NORM);
};
//--------------------------------------------------------------
// Death Knight Standing functions
//--------------------------------------------------------------
void() hkn_stand1 = [$stand1, hkn_stand2] { ai_stand (); };
void() hkn_stand2 = [$stand2, hkn_stand3] { ai_stand (); };
void() hkn_stand3 = [$stand3, hkn_stand4] { ai_stand (); };
void() hkn_stand4 = [$stand4, hkn_stand5] { ai_stand (); };
void() hkn_stand5 = [$stand5, hkn_stand6] { ai_stand (); };
void() hkn_stand6 = [$stand6, hkn_stand7] { ai_stand (); };
void() hkn_stand7 = [$stand7, hkn_stand8] { ai_stand (); };
void() hkn_stand8 = [$stand8, hkn_stand9] { ai_stand (); };
void() hkn_stand9 = [$stand9, hkn_stand1] { ai_stand (); };
//--------------------------------------------------------------
// Death Knight Walking functions
//--------------------------------------------------------------
void() hkn_walk1 = [$walk1, hkn_walk2]
{
monster_hell_knight_idlesound ();
ai_walk (2);
};
void() hkn_walk2 = [$walk2, hkn_walk3] { ai_walk (5); };
void() hkn_walk3 = [$walk3, hkn_walk4] { ai_walk (5); };
void() hkn_walk4 = [$walk4, hkn_walk5] { ai_walk (4); };
void() hkn_walk5 = [$walk5, hkn_walk6] { ai_walk (4); };
void() hkn_walk6 = [$walk6, hkn_walk7] { ai_walk (2); };
void() hkn_walk7 = [$walk7, hkn_walk8] { ai_walk (2); };
void() hkn_walk8 = [$walk8, hkn_walk9] { ai_walk (3); };
void() hkn_walk9 = [$walk9, hkn_walk10] { ai_walk (3); };
void() hkn_walk10 = [$walk10, hkn_walk11] { ai_walk (4); };
void() hkn_walk11 = [$walk11, hkn_walk12] { ai_walk (3); };
void() hkn_walk12 = [$walk12, hkn_walk13] { ai_walk (4); };
void() hkn_walk13 = [$walk13, hkn_walk14] { ai_walk (6); };
void() hkn_walk14 = [$walk14, hkn_walk15] { ai_walk (2); };
void() hkn_walk15 = [$walk15, hkn_walk16] { ai_walk (2); };
void() hkn_walk16 = [$walk16, hkn_walk17] { ai_walk (4); };
void() hkn_walk17 = [$walk17, hkn_walk18] { ai_walk (3); };
void() hkn_walk18 = [$walk18, hkn_walk19] { ai_walk (3); };
void() hkn_walk19 = [$walk19, hkn_walk20] { ai_walk (3); };
void() hkn_walk20 = [$walk20, hkn_walk1] { ai_walk (2); };
//--------------------------------------------------------------
// Death Knight Running functions
//--------------------------------------------------------------
void() hkn_run1 = [$run1, hkn_run2]
{
monster_hell_knight_idlesound ();
ai_run (20);
monster_hell_knight_checkforcharge ();
};
void() hkn_run2 = [$run2, hkn_run3] { ai_run (25); };
void() hkn_run3 = [$run3, hkn_run4] { ai_run (18); };
void() hkn_run4 = [$run4, hkn_run5] { ai_run (16); };
void() hkn_run5 = [$run5, hkn_run6] { ai_run (14); };
void() hkn_run6 = [$run6, hkn_run7] { ai_run (25); };
void() hkn_run7 = [$run7, hkn_run8] { ai_run (21); };
void() hkn_run8 = [$run8, hkn_run1] { ai_run (13); };
//--------------------------------------------------------------
// Death Knight Charge A
//--------------------------------------------------------------
void() hkn_char_a1 = [$char_a1, hkn_char_a2] { ai_charge (20); };
void() hkn_char_a2 = [$char_a2, hkn_char_a3] { ai_charge (25); };
void() hkn_char_a3 = [$char_a3, hkn_char_a4] { ai_charge (18); };
void() hkn_char_a4 = [$char_a4, hkn_char_a5] { ai_charge (16); };
void() hkn_char_a5 = [$char_a5, hkn_char_a6] { ai_charge (14); };
void() hkn_char_a6 = [$char_a6, hkn_char_a7]
{
ai_charge (20);
ai_melee ();
};
void() hkn_char_a7 = [$char_a7, hkn_char_a8]
{
ai_charge (21);
ai_melee ();
};
void() hkn_char_a8 = [$char_a8, hkn_char_a9]
{
ai_charge (13);
ai_melee ();
};
void() hkn_char_a9 = [$char_a9, hkn_char_a10]
{
ai_charge (20);
ai_melee ();
};
void() hkn_char_a10 = [$char_a10, hkn_char_a11]
{
ai_charge (20);
ai_melee ();
};
void() hkn_char_a11 = [$char_a11, hkn_char_a12]
{
ai_charge (18);
ai_melee ();
};
void() hkn_char_a12 = [$char_a12, hkn_char_a13] { ai_charge (16); };
void() hkn_char_a13 = [$char_a13, hkn_char_a14] { ai_charge (14); };
void() hkn_char_a14 = [$char_a14, hkn_char_a15] { ai_charge (25); };
void() hkn_char_a15 = [$char_a15, hkn_char_a16] { ai_charge (21); };
void() hkn_char_a16 = [$char_a16, hkn_run1] { ai_charge (13); };
//--------------------------------------------------------------
// Death Knight Charge B
//--------------------------------------------------------------
void() hkn_char_b1 = [$char_b1, hkn_char_b2]
{
monster_hell_knight_checkcontinuecharge ();
ai_charge (23);
ai_melee ();
};
void() hkn_char_b2 = [$char_b2, hkn_char_b3]
{
ai_charge (17);
ai_melee ();
};
void() hkn_char_b3 = [$char_b3, hkn_char_b4]
{
ai_charge (12);
ai_melee ();
};
void() hkn_char_b4 = [$char_b4, hkn_char_b5]
{
ai_charge (22);
ai_melee ();
};
void() hkn_char_b5 = [$char_b5, hkn_char_b6]
{
ai_charge (18);
ai_melee ();
};
void() hkn_char_b6 = [$char_b6, hkn_char_b1]
{
ai_charge (8);
ai_melee ();
};
//--------------------------------------------------------------
// Death Knight Slice Attack
//--------------------------------------------------------------
void() hkn_slice1 = [$slice1, hkn_slice2] { ai_charge (9); };
void() hkn_slice2 = [$slice2, hkn_slice3] { ai_charge (6); };
void() hkn_slice3 = [$slice3, hkn_slice4] { ai_charge (13); };
void() hkn_slice4 = [$slice4, hkn_slice5] { ai_charge (4); };
void() hkn_slice5 = [$slice5, hkn_slice6]
{
ai_charge (7);
ai_melee ();
};
void() hkn_slice6 = [$slice6, hkn_slice7]
{
ai_charge (15);
ai_melee ();
};
void() hkn_slice7 = [$slice7, hkn_slice8]
{
ai_charge (8);
ai_melee ();
};
void() hkn_slice8 = [$slice8, hkn_slice9]
{
ai_charge (2);
ai_melee ();
};
void() hkn_slice9 = [$slice9, hkn_slice10] { ai_melee (); };
void() hkn_slice10 = [$slice10, hkn_run1] { ai_charge (3); };
//--------------------------------------------------------------
// Death Knight Smash Attack
//--------------------------------------------------------------
void() hkn_smash1 = [$smash1, hkn_smash2] { ai_charge (1); };
void() hkn_smash2 = [$smash2, hkn_smash3] { ai_charge (13); };
void() hkn_smash3 = [$smash3, hkn_smash4] { ai_charge (9); };
void() hkn_smash4 = [$smash4, hkn_smash5] { ai_charge (11); };
void() hkn_smash5 = [$smash5, hkn_smash6]
{
ai_charge (10);
ai_melee ();
};
void() hkn_smash6 = [$smash6, hkn_smash7]
{
ai_charge (7);
ai_melee ();
};
void() hkn_smash7 = [$smash7, hkn_smash8]
{
ai_charge (12);
ai_melee ();
};
void() hkn_smash8 = [$smash8, hkn_smash9]
{
ai_charge (2);
ai_melee ();
};
void() hkn_smash9 = [$smash9, hkn_smash10]
{
ai_charge (3);
ai_melee ();
};
void() hkn_smash10 = [$smash10, hkn_smash11] { ai_charge (0); };
void() hkn_smash11 = [$smash11, hkn_run1] { ai_charge (0); };
//--------------------------------------------------------------
// Death Knight W (?) Attack
//--------------------------------------------------------------
void() hkn_watk1 = [$w_attack1, hkn_watk2] { ai_charge (2); };
void() hkn_watk2 = [$w_attack2, hkn_watk3] { ai_charge (0); };
void() hkn_watk3 = [$w_attack3, hkn_watk4] { ai_charge (0); };
void() hkn_watk4 = [$w_attack4, hkn_watk5] { ai_melee (); };
void() hkn_watk5 = [$w_attack5, hkn_watk6] { ai_melee (); };
void() hkn_watk6 = [$w_attack6, hkn_watk7] { ai_melee (); };
void() hkn_watk7 = [$w_attack7, hkn_watk8] { ai_charge (1); };
void() hkn_watk8 = [$w_attack8, hkn_watk9] { ai_charge (4); };
void() hkn_watk9 = [$w_attack9, hkn_watk10] { ai_charge (5); };
void() hkn_watk10 = [$w_attack10, hkn_watk11]
{
ai_charge (3);
ai_melee ();
};
void() hkn_watk11 = [$w_attack11, hkn_watk12]
{
ai_charge (2);
ai_melee ();
};
void() hkn_watk12 = [$w_attack12, hkn_watk13]
{
ai_charge (2);
ai_melee ();
};
void() hkn_watk13 = [$w_attack13, hkn_watk14] { ai_charge (0); };
void() hkn_watk14 = [$w_attack14, hkn_watk15] { ai_charge (0); };
void() hkn_watk15 = [$w_attack15, hkn_watk16] { ai_charge (0); };
void() hkn_watk16 = [$w_attack16, hkn_watk17] { ai_charge (1); };
void() hkn_watk17 = [$w_attack17, hkn_watk18]
{
ai_charge (1);
ai_melee ();
};
void() hkn_watk18 = [$w_attack18, hkn_watk19]
{
ai_charge (3);
ai_melee ();
};
void() hkn_watk19 = [$w_attack19, hkn_watk20]
{
ai_charge (4);
ai_melee ();
};
void() hkn_watk20 = [$w_attack20, hkn_watk21] { ai_charge (6); };
void() hkn_watk21 = [$w_attack21, hkn_watk22] { ai_charge (7); };
void() hkn_watk22 = [$w_attack22, hkn_run1] { ai_charge (3); };
//--------------------------------------------------------------
// Death Knight Magic A
//--------------------------------------------------------------
void() hkn_magica1 = [$magica1, hkn_magica2] { ai_face (); };
void() hkn_magica2 = [$magica2, hkn_magica3] { ai_face (); };
void() hkn_magica3 = [$magica3, hkn_magica4] { ai_face (); };
void() hkn_magica4 = [$magica4, hkn_magica5] { ai_face (); };
void() hkn_magica5 = [$magica5, hkn_magica6] { ai_face (); };
void() hkn_magica6 = [$magica6, hkn_magica7] { ai_face (); };
void() hkn_magica7 = [$magica7, hkn_magica8]
{
monster_hell_knight_attack_shot (-2);
};
void() hkn_magica8 = [$magica8, hkn_magica9]
{
monster_hell_knight_attack_shot (-1);
};
void() hkn_magica9 = [$magica9, hkn_magica10]
{
monster_hell_knight_attack_shot (0);
};
void() hkn_magica10 = [$magica10, hkn_magica11]
{
monster_hell_knight_attack_shot (1);
};
void() hkn_magica11 = [$magica11, hkn_magica12]
{
monster_hell_knight_attack_shot (2);
};
void() hkn_magica12 = [$magica12, hkn_magica13]
{
monster_hell_knight_attack_shot (3);
};
void() hkn_magica13 = [$magica13, hkn_magica14] { ai_face (); };
void() hkn_magica14 = [$magica14, hkn_run1] { ai_face (); };
//--------------------------------------------------------------
// Death Knight Magic B
//--------------------------------------------------------------
void() hkn_magicb1 = [$magicb1, hkn_magicb2] { ai_face (); };
void() hkn_magicb2 = [$magicb2, hkn_magicb3] { ai_face (); };
void() hkn_magicb3 = [$magicb3, hkn_magicb4] { ai_face (); };
void() hkn_magicb4 = [$magicb4, hkn_magicb5] { ai_face (); };
void() hkn_magicb5 = [$magicb5, hkn_magicb6] { ai_face (); };
void() hkn_magicb6 = [$magicb6, hkn_magicb7] { ai_face (); };
void() hkn_magicb7 = [$magicb7, hkn_magicb8] { ai_face (); };
void() hkn_magicb8 = [$magicb8, hkn_magicb9] { ai_face (); };
void() hkn_magicb9 = [$magicb9, hkn_magicb10] { ai_face (); };
void() hkn_magicb10 = [$magicb10, hkn_magicb11]
{
ai_face ();
sound_misc2 (self, CHAN_WEAPON, "shambler/sboom.wav",
VOL_HIGH, ATTN_NORM);
monster_hell_knight_attack_lightning ();
};
void() hkn_magicb11 = [$magicb11, hkn_magicb12] { ai_face (); };
void() hkn_magicb12 = [$magicb12, hkn_magicb13] { ai_face (); };
void() hkn_magicb13 = [$magicb13, hkn_run1] { ai_face (); };
//--------------------------------------------------------------
// Death Knight Magic C
//--------------------------------------------------------------
void() hkn_magicc1 = [$magicc1, hkn_magicc2] { ai_face (); };
void() hkn_magicc2 = [$magicc2, hkn_magicc3] { ai_face (); };
void() hkn_magicc3 = [$magicc3, hkn_magicc4] { ai_face (); };
void() hkn_magicc4 = [$magicc4, hkn_magicc5] { ai_face (); };
void() hkn_magicc5 = [$magicc5, hkn_magicc6] { ai_face (); };
void() hkn_magicc6 = [$magicc6, hkn_magicc7]
{
monster_hell_knight_attack_shot (-2);
};
void() hkn_magicc7 = [$magicc7, hkn_magicc8]
{
monster_hell_knight_attack_shot (-1);
};
void() hkn_magicc8 = [$magicc8, hkn_magicc9]
{
monster_hell_knight_attack_shot (0);
};
void() hkn_magicc9 = [$magicc9, hkn_magicc10]
{
monster_hell_knight_attack_shot (1);
};
void() hkn_magicc10 = [$magicc10, hkn_magicc11]
{
monster_hell_knight_attack_shot(2);
};
void() hkn_magicc11 = [$magicc11, hkn_run1]
{
monster_hell_knight_attack_shot (3);
};
/////////////////////////////////////////////
////// turret frames START - revisions //////
/////////////////////////////////////////////
//--------------------------------------------------------------
// Death Knight Seek / Standing Frames
//--------------------------------------------------------------
void() hkn_seek_stand1 = [$stand1, hkn_seek_stand2] { ai_run (0); };
void() hkn_seek_stand2 = [$stand2, hkn_seek_stand3] { ai_run (0); };
void() hkn_seek_stand3 = [$stand3, hkn_seek_stand4] { ai_run (0); };
void() hkn_seek_stand4 = [$stand4, hkn_seek_stand5] { ai_run (0); };
void() hkn_seek_stand5 = [$stand5, hkn_seek_stand6] { ai_run (0); };
void() hkn_seek_stand6 = [$stand6, hkn_seek_stand7] { ai_run (0); };
void() hkn_seek_stand7 = [$stand7, hkn_seek_stand8] { ai_run (0); };
void() hkn_seek_stand8 = [$stand8, hkn_seek_stand9] { ai_run (0); };
void() hkn_seek_stand9 = [$stand9, hkn_seek_stand1] { ai_run (0); };
//--------------------------------------------------------------
// Death Knight Turret Magic B (fnames shortened -- CEV)
//--------------------------------------------------------------
void() hkn_tur_magb1 = [$magicb1, hkn_tur_magb2] { ai_face (); };
void() hkn_tur_magb2 = [$magicb2, hkn_tur_magb3] { ai_face (); };
void() hkn_tur_magb3 = [$magicb3, hkn_tur_magb4] { ai_face (); };
void() hkn_tur_magb4 = [$magicb4, hkn_tur_magb5] { ai_face (); };
void() hkn_tur_magb5 = [$magicb5, hkn_tur_magb6] { ai_face (); };
void() hkn_tur_magb6 = [$magicb6, hkn_tur_magb7] { ai_face (); };
void() hkn_tur_magb7 = [$magicb7, hkn_tur_magb8] { ai_face (); };
void() hkn_tur_magb8 = [$magicb8, hkn_tur_magb9] { ai_face (); };
void() hkn_tur_magb9 = [$magicb9, hkn_tur_magb10] { ai_face (); };
void() hkn_tur_magb10 = [$magicb10, hkn_tur_magb11]
{
ai_face ();
sound_misc2 (self, CHAN_WEAPON, "shambler/sboom.wav",
VOL_HIGH, ATTN_NORM);
monster_hell_knight_attack_lightning ();
};
void() hkn_tur_magb11 = [$magicb11, hkn_tur_magb12] { ai_face (); };
void() hkn_tur_magb12 = [$magicb12, hkn_tur_magb13] { ai_face (); };
void() hkn_tur_magb13 = [$magicb13, hkn_seek_stand1] { ai_face (); };
//--------------------------------------------------------------
// Death Knight Turret Magic C (fnames shortened -- CEV)
//--------------------------------------------------------------
void() hkn_tur_magc1 = [$magicc1, hkn_tur_magc2] { ai_face (); };
void() hkn_tur_magc2 = [$magicc2, hkn_tur_magc3] { ai_face (); };
void() hkn_tur_magc3 = [$magicc3, hkn_tur_magc4] { ai_face (); };
void() hkn_tur_magc4 = [$magicc4, hkn_tur_magc5] { ai_face (); };
void() hkn_tur_magc5 = [$magicc5, hkn_tur_magc6] { ai_face (); };
void() hkn_tur_magc6 = [$magicc6, hkn_tur_magc7]
{
monster_hell_knight_attack_shot (-2);
};
void() hkn_tur_magc7 = [$magicc7, hkn_tur_magc8]
{
monster_hell_knight_attack_shot (-1);
};
void() hkn_tur_magc8 = [$magicc8, hkn_tur_magc9]
{
monster_hell_knight_attack_shot (0);
};
void() hkn_tur_magc9 = [$magicc9, hkn_tur_magc10]
{
monster_hell_knight_attack_shot (1);
};
void() hkn_tur_magc10 = [$magicc10, hkn_tur_magc11]
{
monster_hell_knight_attack_shot (2);
};
void() hkn_tur_magc11 = [$magicc11, hkn_tur_magc12] { ai_face (); };
void() hkn_tur_magc12 = [$stand1, hkn_tur_magc13] { ai_face (); };
void() hkn_tur_magc13 = [$stand2, hkn_tur_magc14] { ai_face (); };
void() hkn_tur_magc14 = [$stand3, hkn_tur_magc15] { ai_face (); };
void() hkn_tur_magc15 = [$stand4, hkn_seek_stand1] { ai_run (0); };
/////////////////////////////////////////////
////// turret frames END //////
/////////////////////////////////////////////
//--------------------------------------------------------------
// Death Knight pain state
//--------------------------------------------------------------
void() hkn_pain1 = [$pain1, hkn_pain2]
{
sound_pain (self, CHAN_VOICE, "hknight/pain1.wav",
VOL_HIGH, ATTN_NORM);
};
void() hkn_pain2 = [$pain2, hkn_pain3] { };
void() hkn_pain3 = [$pain3, hkn_pain4] { };
void() hkn_pain4 = [$pain4, hkn_pain5] { };
void() hkn_pain5 = [$pain5, hkn_run1] { };
//--------------------------------------------------------------
// Death Knight death state A
//--------------------------------------------------------------
void() hkn_die1 = [$death1, hkn_die2]
{
ai_forward (10);
base_entity_aligntoground (self);
};
void() hkn_die2 = [$death2, hkn_die3] { ai_forward (8); };
void() hkn_die3 = [$death3, hkn_die4]
{
self.solid = SOLID_NOT;
ai_forward (7);
};
void() hkn_die4 = [$death4, hkn_die5] { };
void() hkn_die5 = [$death5, hkn_die6] { };
void() hkn_die6 = [$death6, hkn_die7] { };
void() hkn_die7 = [$death7, hkn_die8] { };
void() hkn_die8 = [$death8, hkn_die9] { ai_forward (10); };
void() hkn_die9 = [$death9, hkn_die10] { ai_forward (11); };
void() hkn_die10 = [$death10, hkn_die11] { };
void() hkn_die11 = [$death11, hkn_die12]
{
become_base_corpse (self, HELL_KNIGHT_HEALTH_CORPSE);
setsize (self, HELL_KNIGHT_CORPSE_Z_MINS,
HELL_KNIGHT_CORPSE_Z_MAXS);
};
void() hkn_die12 = [$death12, hkn_die12] { };
//--------------------------------------------------------------
// Death Knight death state B
//--------------------------------------------------------------
void() hkn_dieb1 = [$deathb1, hkn_dieb2]
{
base_entity_aligntoground (self);
};
void() hkn_dieb2 = [$deathb2, hkn_dieb3] { };
void() hkn_dieb3 = [$deathb3, hkn_dieb4]
{
self.solid = SOLID_NOT;
};
void() hkn_dieb4 = [$deathb4, hkn_dieb5] { };
void() hkn_dieb5 = [$deathb5, hkn_dieb6] { };
void() hkn_dieb6 = [$deathb6, hkn_dieb7] { };
void() hkn_dieb7 = [$deathb7, hkn_dieb8] { };
void() hkn_dieb8 = [$deathb8, hkn_dieb9]
{
become_base_corpse (self, HELL_KNIGHT_HEALTH_CORPSE);
setsize (self, HELL_KNIGHT_CORPSE_Z_MINS,
HELL_KNIGHT_CORPSE_Z_MAXS);
};
void() hkn_dieb9 = [$deathb9, hkn_dieb9] { };
//==============================================================
// Interaction
//==============================================================
//--------------------------------------------------------------
// hknight_pain
//--------------------------------------------------------------
void(entity attacker, float damage) monster_hell_knight_pain =
{
local float r;
r = random ();
if (self.pain_finished > time)
return;
if (self.spawnflags & I_AM_TURRET)
{
if (r < 0.5)
{
self.pain_finished = time + 1.5;
sound_pain (self, CHAN_VOICE,
"hknight/pain1.wav",
VOL_HIGH, ATTN_NORM);
}
return;
}
sound_pain (self, CHAN_VOICE, "hknight/pain1.wav",
VOL_HIGH, ATTN_NORM);
if (time - self.pain_finished > 5)
{
// always go into pain frame if it has been a while
hkn_pain1 ();
self.pain_finished = time + 1;
return;
}
if ((random() * 30 > damage))
// didn't flinch
return;
self.pain_finished = time + 1;
hkn_pain1 ();
};
//--------------------------------------------------------------
// hknight_die
//--------------------------------------------------------------
void(vector dir) monster_hell_knight_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_hell_knight (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 < -40)
{
sound (self, CHAN_VOICE, "player/udeath.wav",
VOL_HIGH, ATTN_NORM);
throw_gib_head_hell_knight (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;
}
// regular death
sound_death (self, CHAN_VOICE, "hknight/death1.wav",
VOL_HIGH, ATTN_NORM);
base_item_drop_stuff (self);
if (random() > 0.5)
hkn_die1 ();
else
hkn_dieb1 ();
};
//==============================================================
// Initialization
//==============================================================
//--------------------------------------------------------------
entity(vector org, vector ang, float sflags, float yaw, float angry)
spawn_monster_hell_knight =
{
return spawn_base_monster (org, ang, sflags, yaw, angry,
monster_hell_knight_init);
};
//--------------------------------------------------------------
void(entity e) monster_hell_knight_init =
{
if (deathmatch)
{
remove (e);
return;
}
e.classname = "monster_hell_knight";
e.classtype = CT_MONSTER_DEATHKNIGHT;
precache_model2 ("progs/hknight.mdl");
precache_model2 ("progs/k_spike.mdl");
precache_model2 ("progs/k_spike2.mdl");
precache_model2 ("progs/h_hellkn.mdl");
// dumptruck_ds custom_mdls
precache_body_model2 (e, "progs/hknight.mdl");
precache_head_model2 (e, "progs/h_hellkn.mdl");
precache_proj_model2 (e, "progs/k_spike.mdl");
// this needed a unique name defined in custom_mdls.qc
// -- dumptruck_ds
precache_exproj_model2 (e, "progs/k_spike2.mdl");
// dumptruck_ds
precache_sound2_attack (e, "hknight/attack1.wav");
precache_sound2_death (e, "hknight/death1.wav");
precache_sound2_pain (e, "hknight/pain1.wav");
precache_sound2_sight (e, "hknight/sight1.wav");
// used by C code, so don't sound2
precache_sound ("hknight/hit.wav");
precache_sound2_misc (e, "hknight/slash1.wav");
precache_sound2_idle (e, "hknight/idle.wav");
// what??? never knew about e! -- dumptruck_ds
precache_sound2 ("hknight/grunt.wav");
precache_sound ("knight/sword1.wav");
precache_sound ("knight/sword2.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;
// custom_mdls dumptruck_ds
body_model (e, "progs/hknight.mdl");
// setmodel (e, "progs/hknight.mdl");
setsize (e, '-16 -16 -24', '16 16 40');
// thanks RennyC -- dumptruck_ds
if (!e.health)
e.health = HELL_KNIGHT_HEALTH;
if (!e.proj_speed_mod)
e.proj_speed_mod = 1;
e.sightsound = monster_hell_knight_sightsound;
e.th_stand = hkn_stand1;
e.th_walk = hkn_walk1;
if (e.spawnflags & I_AM_TURRET)
e.th_run = hkn_seek_stand1;
else
e.th_run = hkn_run1;
e.th_melee = monster_hell_knight_attack_melee;
if (e.style == 1)
{
e.th_missile = hkn_magicb1;
e.th_turret = hkn_tur_magb1;
}
else
{
e.th_missile = hkn_magicc1;
e.th_turret = hkn_tur_magc1;
}
// Berserk test from
// http://celephais.net/board/view_thread.php?id=4&start=3465
// -- dumptruck_ds
if !(e.berserk)
e.th_pain = monster_hell_knight_pain;
else
e.th_pain = sub_nullpain;
e.destroy = monster_hell_knight_destroy;
// walkmonster_start
base_walkmonster_init (e);
};
//--------------------------------------------------------------
void() monster_hell_knight =
{
// new spawnflags for all entities -- iw
if (SUB_Inhibit())
return;
monster_hell_knight_init (self);
};
// };
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
// Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
/*QUAKED gib_head_hell_knight (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_hellkn.mdl");
}*/
//----------------------------------------------------------------------
// class gib_head_hell_knight: base_gib_head
// {
//--------------------------------------------------------------
// ThrowHead
//--------------------------------------------------------------
void(entity act, vector dir, float dmg) throw_gib_head_hell_knight =
{
base_gib_head_throw (act, dir, dmg, gib_head_hell_knight_init);
};
//--------------------------------------------------------------
void(entity e) gib_head_hell_knight_init =
{
e.classname = "gib_head_hell_knight";
e.classtype = CT_GORE_HEAD_HELL_KNIGHT;
// 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_hellkn.mdl");
setmodel (e, "progs/h_hellkn.mdl");
if (e.solid == SOLID_BBOX)
setsize (e, HELL_KNIGHT_HEAD_MINS,
HELL_KNIGHT_HEAD_MAXS);
else if (e.solid == SOLID_TRIGGER)
setsize (e, '-16 -16 0', '16 16 56');
}
e.frame = 0;
};
//--------------------------------------------------------------
void() gib_head_hell_knight =
{
// new spawnflags for all entities -- iw
if (SUB_Inhibit())
return;
gib_head_hell_knight_init (self);
};
// };
/*QUAKED monster_dead_hell_knight (0 0.5 0.8) (-16 -16 -24) (16 16 32) 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/hknight.mdl","frame":62});
}
*/
//----------------------------------------------------------------------
// class monster_dead_hell_knight: base_corpse
// {
//--------------------------------------------------------------
void(entity e) monster_dead_hell_knight_init =
{
base_corpse_init (e);
precache_model ("progs/hknight.mdl");
setmodel (e, "progs/hknight.mdl");
if (e.spawnflags & 2)
{
e.frame = $deathb9;
if (e.solid == SOLID_BBOX)
setsize (e, HELL_KNIGHT_CORPSE_B_MINS,
HELL_KNIGHT_CORPSE_B_MAXS);
}
else
{
e.frame = $death12;
if (e.solid == SOLID_BBOX)
setsize (e, HELL_KNIGHT_CORPSE_MINS,
HELL_KNIGHT_CORPSE_MAXS);
}
};
//--------------------------------------------------------------
void() monster_dead_hell_knight =
{
// new spawnflags for all entities -- iw
if (SUB_Inhibit())
return;
monster_dead_hell_knight_init (self);
};
// };
Return to the top of this page or return to the overview of this repo.
Log hknight.qc
Date | Commit Message | Author | + | - |
---|---|---|---|---|
2024-06-15 | Major update, committing as-is, will have bugs | cev | +113 | -58 |
2024-04-12 | Moveable gibs, heads, some bugfixes | cev | +79 | -29 |
2024-04-08 | Registered monsters, projectile bugfixes | cev | +491 | -365 |
2024-02-18 | Client/player, projectiles, entrypoints refactor | cev | +3 | -47 |
2024-01-31 | Class based monster refactor & start projectiles | cev | +801 | -578 |
2024-01-13 | Refactored items into classes, fix teleporttrain | cev | +2 | -2 |
2024-01-09 | Continue OO / Class-based refactor | cev | +1 | -1 |
2023-10-13 | New movement code based on SV_RunClientCommand | cev | +755 | -755 |
2023-10-13 | Rename "qc-server" dir to "qc" | cev | +755 |
Return to the top of this page or return to the overview of this repo.